使用openssl C API解析asn1文档

时间:2016-07-17 10:40:33

标签: c parsing openssl ssl-certificate x509certificate

我想使用openssl库解析asn1格式的证书。 不幸的是,一些API命令缺少相关文档,因此我自己尝试了这些文档。我已经看到很多关于这个主题的关系,但没有准确的用法说明。

开始我将考虑以下应该返回一般asn1对象的命令。

int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
                int *pclass, long omax);

从我在网上找到的例子来看,输入参数描述似乎如下:

pp - 指向对象(或证书)开头的指针,它可以更改,因为在应用函数后,此值将移动到下一个对象。

plength - 表示对象长度的输出。

ptag - 表示对象类型的输出(简单如INTEGER,或复杂的SEQUENCE)。

pclass - 我不知道它意味着什么。

omax - 证书结束前的长度。

也许一些有经验的用户可能会在上面验证我的摘要,并且要知道pclass的含义。

感谢

1 个答案:

答案 0 :(得分:2)

答案

pclass参数表示对象类型的标签号所在的标签类。


说明

首先,介绍ASN.1对象的一些背景。为了说明起见,我将在此处进行很多简化。当使用BER / DER编码对ASN.1对象进行编码时,通常 具有以下结构:

+-------------------+---------------+-----------------+
| Identifier octets | Length octets | Contents octets |
| (Type)            | (Length)      | (Value)         |
+-------------------+---------------+-----------------+

标识符八位字节为8位,用于指定值的类型。标识符八位字节通常是这样编码的:

     +-----+-----+-----+-----+-----+-----+-----+-----+
Bits |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
     +-----------+-----+-----------------------------+
     | Tag class | P/C |         Tag number          |
     +-----------+-----+-----------------------------+

标记类可能是以下四项之一-通用,应用, 特定于上下文的或专用的。通用类包含类型 这是ASN.1固有的(例如Integer和String)。除非你是 在处理自定义类型时,您可以期望该类是通用类, 由00指定。这就是通过pclass返回的内容 参数。

标记号是5位,用于指定该类中的类型。这是通过ptag参数返回的。例如,Universal类中的Integer具有标签号00010

例如,您可以通过以下方式测试您从ASN1_get_object获得了ASN.1整数:

ASN1_get_object(&pp, &plength, &ptag, &pclass, omax);
if (pclass == V_ASN1_UNIVERSAL && ptag == V_ASN1_INTEGER)
{
    // this is the native ASN.1 Integer type
}

如果您知道纯粹在处理通用类型,则可以决定测试pclass变量有点多余。


文档

您对参数作用的某些定义有些偏离。这是我对该功能的文档的尝试。我应该指出,我已经尝试通过查看代码和ASN.1规范自行解决此问题,因此,如果有任何错误,欢迎任何修改。

  
int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, int *pclass, long omax)
     

摘要:将BER / DER编码的ASN.1对象解码为其类型,长度和值的起始位置。

     

参数

     

**pp:指向BER / DER编码对象开始的指针的指针。当函数返回时,该指针将调整为指向ASN.1值的开头(内容八位字节)。

     

*plength:指向long的指针。函数返回时,它包含ASN.1值的长度,指定为八位字节数。如果长度以不确定形式编码,则plength将为0。

     

*ptag:指向int的指针。当函数返回时,它包含ASN.1标记号,它定义了值的类型。请注意,这只是标签编号,不包括标签类别或原始/构造的指示符。

     

*pclass:指向int的指针。函数返回时,它包含ASN.1标签的类。

     

omax:BER / DER编码对象的最大长度。如果对象的长度超过此长度,则会发生错误。

     

返回:一个整数。如果设置了第8位(0x80),则会发生错误。如果设置了第6位(0x20),则该类型为构造类型(即,内容八位位组编码一个或多个数据值)。如果设置了第一个位(0x01),则该值的长度是不确定的,并且该值将以“内容结尾八位字节”结尾。