obtaining the OCSP URL from certificate using openSSL API

Viewed 816

I have a certificate stored in an X509 structure and I want to obtain the URL to the OCSP responder from this. I found two ways to do this -

Method 1 -

First, I obtain an X509_EXTENSION structure in the following way :

    const STACK_OF(X509_EXTENSION)* ext_stack = NULL;
    ext_stack = X509_get0_extensions(cert);
    int ext_loc = X509v3_get_ext_by_NID(ext_stack, NID_info_access, -1);
    X509_EXTENSION *AIA = X509v3_get_ext(ext_stack, ext_loc);

But then I could not find any proper information on how to print the data in this structure. The best way I found was this :

    ASN1_OCTET_STRING *asn1_str = X509_EXTENSION_get_data(AIA);
    const unsigned char* str = asn1_str->data;
    long xlen;
    int tag, xclass;
    int ret = ASN1_get_object(&str, &xlen, &tag, &xclass, asn1_str->length);
    printf("str = %s\n",str);

This method sort of works but is unusable due to many unprintable characters littered in between.

Method 2 -

In command line, this can be achieved through the command :

openssl x509 -noout -ocsp_uri -in extracted.crt.pem

I dug through the source code of openSSL to see how it prints this information. I found the function X509_get1_ocsp() which returns STACK_OF(OPENSSL_STRINGS).

This piece of code prints the URL without any hassle :

    STACK_OF(OPENSSL_STRING) *str_stack = X509_get1_ocsp(cert);
    for(int i = 0;i < sk_OPENSSL_STRING_num(str_stack);i++)
        BIO_printf(outbio, "%s\n", sk_OPENSSL_STRING_value(str_stack, i));

However, I am hesitant to use this function since it is not mentioned anywhere other than the source code. Answers to other questions prefer using method 1. How do I go about it? Is there a better way to extract the required information using method 1 or should I stick to method 2?

1 Answers

Use method 2 :-)

Although undocumented, presumably because no one volunteered or donated, it's been in the officially exported declarations since 0.9.8j in 2009 (and 1.0.0 in 2010).

The data in an X509 extension is never as simple as a string; it must be a DER encoding of an ASN.1 type that depends on the OID, see Extension in rfc5280 sec 4. For AIA, it is the DER encoding of the type in 4.2.2.1. To do this yourself a la method 1, you need to parse with d2i_AUTHORITY_INFO_ACCESS and then go through the elements looking for those that are for OCSP (not all need be and possibly none are) and contain a URI (OCSP should, per rfc2560), and then clean up, much like the code in crypto/x509v3/v3_utl.c except you don't have to use STACK_OF(OPENSSL_STRING) for the results if you prefer something else.

Related