使用 openssl C 解析 asn1 文档 API

Parsing asn1 document with openssl C API

我想使用 openssl 库解析 asn1 格式的证书。 不幸的是,一些 API 命令缺少相关文档,所以我自己尝试了它们。我已经看到很多与此主题相关的内容,但没有准确的用法解释。

首先,我将考虑以下命令,该命令应该 return 一般 asn1 对象。

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

从网上找的例子来看,输入参数的描述好像是这样的:

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

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

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

pclass - 我不知道这是什么意思。

omax - 证书结束前的长度。

也许一些有 openssl 经验的用户可能会验证我上面的总结,并阐明 pclass 的含义。

谢谢

回答

pclass参数表示对象类型的Tag Number所在的TagClass


说明

首先,关于 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          |
     +-----------+-----+-----------------------------+

标签 Class 可能是 4 个东西之一 - 通用、应用程序、 特定于上下文或私有。 Universal class 包含类型 它们是 ASN.1 原生的(如 Integer 和 String)。除非你是 处理自定义类型,你可以期望 class 是通用的, 由 00 指定。这是通过 pclass 返回的内容 参数.

标记号是指定 class 中类型的 5 位。这通过 ptag 参数返回。例如,通用 class 中的整数具有标记号 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)

Summary: Decodes a BER/DER-encoded ASN.1 object into its type, length and starting position of its value.

Parameters:

**pp: A pointer to a pointer to the start of the BER/DER encoded object. When the function returns, this pointer is adjusted to point to the start of the ASN.1 value (the contents octets).

*plength: A pointer to a long. When the function returns, this contains the length of the ASN.1 value, specified as a number of octets. If the length was encoded in the indefinite form, plength will be 0.

*ptag: A pointer to an int. When the function returns, this contains the ASN.1 Tag Number, which defines the type of the value. Note this is only the Tag Number, and doesn't include the Tag Class or the Primitive/Constructed indicator.

*pclass: A pointer to an int. When the function returns, this contains the class of the ASN.1 Tag.

omax: The maximum length of the BER/DER encoded object. If the object is longer than this, an error occurs.

Returns: An integer. If the 8th bit is set (0x80) then an error occurred. If the 6th bit is set (0x20) then the type is a constructed type (i.e. the contents octets encode one or more data values). If the 1st bit is set (0x01) then the length of the value is indefinite, and the value will end with the 'end-of-contents octets'.