5

I'm using openssl to parse X509 certificate. I manage to get extensions, but I don't know how to extract the extension value.

The code I am using is:

  X509_EXTENSION *extension =  sk_X509_EXTENSION_pop(exts);
  int critical =  X509_EXTENSION_get_critical(extension);

  ASN1_OBJECT *obj = extension-> object;
  ln = OBJ_nid2ln(OBJ_obj2nid(obj));
  if( !ln ) ln = "";
  OBJ_obj2txt(objbuf,sizeof(objbuf),obj,1);
  int nid = OBJ_txt2nid(ln);  

This code tells me whether the extension is critical or not and gives me nid of the extension.

I suppose value can be obtained by:

ASN1_OCTET_STRING *data= X509_EXTENSION_get_data(extension);

but I am not sure how to handle the retrieved data object. The data object is supposed to be der-encoded. Any idea on how to get the extension data?

EDIT: As suggested here, I was trying to do:

ASN1_OCTET_STRING* octet_str = X509_EXTENSION_get_data(extension);
const unsigned char* octet_str_data = octet_str->data;
long xlen;
int tag, xclass;
int ret = ASN1_get_object(&octet_str_data, &xlen, &tag, &xclass, octet_str->length);
printf(@"value: %s\n", octet_str_data);

but the string I get after decoding is the same as prior to it - something like: 4Á˃◊∫Ns∑äP∂W≠%£A

Community
  • 1
  • 1
Maggie
  • 7,823
  • 7
  • 45
  • 66
  • I think some example certificate(s) and code that compiles fine, just without the proper display of the extension values, would be incredibly helpful. – ThiefMaster Apr 09 '12 at 08:38
  • I am doing an iOS project, and openssl is compiled for the iOS. Still, if it helps, I'll add a link to it. – Maggie Apr 09 '12 at 08:40
  • iOS? Are you really using C or rather ObjC? – ThiefMaster Apr 09 '12 at 08:41
  • openssl is a C library, and therefore can be included in iOS just fine. the code regarding openssl is pure C code. – Maggie Apr 09 '12 at 08:44
  • 1
    @Maggie: FWIW: I feel your pain. The OpenSSL API is by far the worst API I have ever had the misfortune to work with. It's an abomination and I was happy to move on after I had handled my limited use case. – Roger Dahl Apr 09 '12 at 22:11

3 Answers3

1

This is very interesting. I've been watching the conversation transpire across the link you provided and here, and I concur with Roger Dahl on his comment in his answer's errata:

It appears that you are seeking a general solution on how to extract the information in an x509v3 extension. As the title of this question states, it is only about the special case of decoding a single OCTET STRING. Beyond that, I can only point you to the original suggestion of @Francois, which is to use an external ASN.1 parser, such as SNACC or libtasn1 and to look at the OpenSSL source code (around crypto/asn1/asn1_par.c:135).

(Link additions mine.)

The trick is you're trying to work with a modal extension model that isn't handled well generically. This answer provides a good overview on how that works. As for the rest of the answer, I concur with his observation that where the docs fail, reading the source is honestly the best solution.

Community
  • 1
  • 1
MrGomez
  • 23,788
  • 45
  • 72
  • thanks for your suggestions, I had a look at SNACC, but for now I'm sticking with openssl and using the solution Felipe suggested. – Maggie Apr 14 '12 at 17:31
1

If I was in your position I would seriously consider using one of the dedicated ASN.1 libraries to decode the certificates. Let OpenSSL do what it's good at, which is to validate your certificates against a trust chain. Once you know that you have a good certificate, pass it to an ASN.1 library and let it handle the rest. (SNACC looks good.) Note that the entire certificate is itself encoded with ASN.1, so the same library that you would use for handling the v3 extensions can be used for handling the entire certificate.

Roger Dahl
  • 15,132
  • 8
  • 62
  • 82
  • thanks for your suggestions, I had a look at SNACC, but for now I'm sticking with openssl and using the solution Felipe suggested. – Maggie Apr 14 '12 at 17:32
1

If you want to have a textual representation, you can use a memory BIO. I've answered how to this for a Key Usage extension in this thread, but the way to do it is the same for every extension.

Regards.

Community
  • 1
  • 1
Fauth
  • 737
  • 4
  • 11
  • 1
    According to this [link](http://www.openssl.org/docs/crypto/bio.html): A BIO is an I/O abstraction, it hides many of the underlying I/O details from an application. If an application uses a BIO for its I/O it can transparently handle SSL connections, unencrypted network connections and file I/O. – Fauth Apr 14 '12 at 16:37
  • 1
    In other words, a BIO works as a data stream to any I/O, including the memory itself. Thus a memory BIO is just a stream to or from the memory. BIO's can also be chained together with BIO_push() in a very useful way, such as explained [here](http://www.openssl.org/docs/crypto/BIO_push.html) – Fauth Apr 14 '12 at 16:56
  • 1
    this works, thank you so much, and here is your 200 reputation :) – Maggie Apr 14 '12 at 17:30