【问题标题】:Parsing asn1 document with openssl C API使用 openssl C API 解析 asn1 文档
【发布时间】:2016-11-20 02:16:02
【问题描述】:

我想使用 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 - 直到证书结束的长度。

也许一些 openssl 经验丰富的用户可能会验证我上面的总结,并澄清 pclass 的含义。

谢谢

【问题讨论】:

  • 在这种情况下,似乎没有文档,即使是 OpenSSL 1.1.0(请查看 crypto 部分)。你必须去代码:cd <openssl src dir>; grep -IR ASN1_get_object *。然后,当您在源文件中找到匹配项时,您会对其进行研究。
  • @jww,感谢您的帮助,我确实做到了,写下了我理解的内容,并在我没有的地方寻求帮助。或许你知道 pclass 的含义?

标签: c parsing openssl ssl-certificate x509certificate


【解决方案1】:

回答

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


说明

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

标记类可以是 4 种事物之一 - 通用、应用程序、 特定于上下文的或私有的。通用类包含类型 它们是 ASN.1 的本机(如整数和字符串)。除非你是 处理自定义类型,您可以期望该类是通用的, 由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 Tag 的类。

omax:BER/DER 编码对象的最大长度。如果对象比这个长,就会发生错误。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多