我想使用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的含义。
感谢
答案 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
),则该值的长度是不确定的,并且该值将以“内容结尾八位字节”结尾。