我最近在Linux系统中将openssl从1.0.2n更新为1.1.0g。
我以前使用过
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len)
功能。由于在openssl 1.1.0中删除了此功能,现在我将其替换为
ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
。
现在,当我运行我的应用程序时,我会得到警告
Warning:0:-- SSL Error queue report --
Warning:0: - asn1 encoding routines|d2i_ASN1_UINTEGER|expecting an integer:218718323
该问题的解决方案是什么?
答案 0 :(得分:2)
以下是一些使用 c2i_ASN1_INTEGER() 的代码示例。
ASN1_get_object(&ptr, &length, &type, &xclass, end - ptr);
if (type == V_ASN1_INTEGER) {
integer = c2i_ASN1_INTEGER(NULL, &ptr, length);
value = ASN1_INTEGER_get(integer);
ASN1_INTEGER_free(integer);
// do something with value
} else
ptr += length;
这是我修改代码以使用 d2i_ASN1_UINTEGER() 的方法。
save_ptr = ptr;
ASN1_get_object(&ptr, &length, &type, &xclass, end - ptr);
if (type == V_ASN1_INTEGER) {
ptr = save_ptr;
integer = d2i_ASN1_UINTEGER(NULL, &ptr, end - ptr);
value = ASN1_INTEGER_get(integer);
ASN1_INTEGER_free(integer);
// do something with value
} else
ptr += length;
首先我将ptr保存在save_ptr中。 ASN1_get_object() 将 ptr 指向 BER/DER 的开头。 ASN1_get_object() 更新 ptr 以指向内容。 c2i_ASN1_INTEGER() 获取指向内容的 ptr,将 ptr 前进到内容之外以指向下一个 BER/DER 的开头,并返回 ASN1_INTEGER。现在 d2i_ASN1_UINTEGER() 也返回 ASN1_INTEGER,但它需要将 ptr 指向 BER/DER 的开头。所以我只是在调用 ASN1_get_object() 之前将 ptr 设置回它的值。 d2i_ASN1_UINTEGER() 获取指向 BER/DER 开头的 ptr,将 ptr 前进到下一个 BER/DER 的开头,并返回 ASN1_INTEGER。
答案 1 :(得分:1)
INTEGER的ASN.1编码(如BER或DER)由1个或多个“标识符”八位字节(通常为1个)组成,后接1个或多个“ length”八位字节,然后是“ content”八位字节(长度为由前面的“长度”八位字节确定)。
函数c2i_ASN1_INTEGER
假定您已经解析了“标识符”和“长度”八位字节,并将“内容”字节转换为整数。已从OpenSSL 1.1.0中删除了该文件,因为这被认为是应用程序不应该直接调用的非常低级的解析操作。
函数d2i_ASN1_UINTEGER
不能直接代替c2i_ASN1_INTEGER
。它解析整个整数(包括“标识符”和“长度”八位位组)。如果只传递内容字节,则它将第一个字节解释为“标识符”字节。这可能是错误的整数值,因此这可能就是为什么您看到“期望整数”错误的原因。
您将需要重写代码以将整个整数传递给d2i_ASN1_UINTEGER
。