Here's an example of some code that uses 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;
Here's how I modified the code to use d2i_ASN1_UINTEGER()
instead.
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;
First I saved ptr
in save_ptr
. ASN1_get_object()
takes ptr
pointing to the beginning of the BER/DER. ASN1_get_object()
updates ptr
to point to the content. c2i_ASN1_INTEGER()
takes ptr
pointing to the content, advances ptr
beyond the content to point to the beginning of the next BER/DER, and returns an ASN1_INTEGER
.
Now d2i_ASN1_UINTEGER()
returns an ASN1_INTEGER
too but it needs to take ptr
pointing to the beginning of the BER/DER. So I simply set ptr
back to its value before ASN1_get_object()
was called. d2i_ASN1_UINTEGER()
takes ptr
pointing the beginning of the BER/DER, advances ptr
to the beginning of the next BER/DER, and returns an ASN1_INTEGER
.