Introduction


The example 'C' program certextensions.c demonstrates how to extract the extensions from a X.509v3 digitial certificate, using the OpenSSL library functions.

Example Code Listing


/* ------------------------------------------------------------ *
 * file:        certextensions.c                                *
 * purpose:     Example code for OpenSSL certificate extensions *
 * author:      09/12/2012 Frank4DD                             *
 * based on:    openssl-[x.x.x]/crypto/asn1/t_x509.c            *
 *                                                              *
 * gcc -o certextensions certextensions.c -lssl -lcrypto        *
 * ------------------------------------------------------------ */

#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>

int main() {

  const char cert_filestr[] = "./cert-file.pem";
  BIO              *certbio = NULL;
  BIO               *outbio = NULL;
  X509                *cert = NULL;
  X509_CINF       *cert_inf = NULL;
  STACK_OF(X509_EXTENSION) *ext_list;
  int ret, i;

  /* ---------------------------------------------------------- *
   * These function calls initialize openssl for correct work.  *
   * ---------------------------------------------------------- */
  OpenSSL_add_all_algorithms();
  ERR_load_BIO_strings();
  ERR_load_crypto_strings();

  /* ---------------------------------------------------------- *
   * Create the Input/Output BIO's.                             *
   * ---------------------------------------------------------- */
  certbio = BIO_new(BIO_s_file());
  outbio  = BIO_new_fp(stdout, BIO_NOCLOSE);

  /* ---------------------------------------------------------- *
   * Load the certificate from file (PEM).                      *
   * ---------------------------------------------------------- */
  ret = BIO_read_filename(certbio, cert_filestr);
  if (! (cert = PEM_read_bio_X509(certbio, NULL, 0, NULL))) {
    BIO_printf(outbio, "Error loading cert into memory\n");
    exit(-1);
  }

  /* ---------------------------------------------------------- *
   * Extract the certificate's extensions                       *
   * ---------------------------------------------------------- */
  cert_inf = cert->cert_info;

  ext_list = cert_inf->extensions;

  if(sk_X509_EXTENSION_num(ext_list) <= 0) return 1;

  /* ---------------------------------------------------------- *
   * Print the extension value                                  *
   * ---------------------------------------------------------- */
  for (i=0; i<sk_X509_EXTENSION_num(ext_list); i++) {
    ASN1_OBJECT *obj;
    X509_EXTENSION *ext;

    ext = sk_X509_EXTENSION_value(ext_list, i);

    obj = X509_EXTENSION_get_object(ext);
    BIO_printf(outbio, "\n");
    BIO_printf(outbio, "Object %.2d: ", i);
    i2a_ASN1_OBJECT(outbio, obj);
    BIO_printf(outbio, "\n");

    X509V3_EXT_print(outbio, ext, NULL, NULL);
    BIO_printf(outbio, "\n");
  }

  X509_free(cert);
  BIO_free_all(certbio);
  BIO_free_all(outbio);
  exit(0);
}

Compiling the Code


Compile the test program with:

fm@susie114:~> gcc -o certextensions certextensions.c -lssl -lcrypto

Example Output


The program expects a certificate file called cert-file.pem in the same directory. In the example below, I used the server certificate from hp.com. If it is loaded, the following output is produced:

fm@susie114:~> ./certextensions
susie114:/home/fm # ./certextensions

Object 00: X509v3 Subject Alternative Name
DNS:h18000.www1.hp.com, DNS:ftp.hp.com, DNS:eds.com, DNS:h10004.www1.hp.com, DNS:h10048.www1.hp.com, DNS:h10018.www1.hp.com, DNS:www.eds.com, DNS:h17003.www1.hp.com, DNS:h10085.www1.hp.com, DNS:h10057.www1.hp.com, DNS:h10032.www1.hp.com, DNS:h10148.www1.hp.com, DNS:www.compaq.com, DNS:h10151.www1.hp.com, DNS:h10176.www1.hp.com, DNS:h10086.www1.hp.com, DNS:h10003.www1.hp.com, DNS:www-mo.eds.com, DNS:h10084.www1.hp.com, DNS:www.hp.com, DNS:h17004.www1.hp.com, DNS:h17005.www1.hp.com, DNS:h17006.www1.hp.com, DNS:h17007.www1.hp.com, DNS:h17008.www1.hp.com, DNS:h17009.www1.hp.com, DNS:h17010.www1.hp.com, DNS:www.3com.com, DNS:login.3com.com, DNS:threatlinq.tippingpoint.com, DNS:www.threatlinq.tippingpoint.com, DNS:b2bgw.3com.com

Object 01: X509v3 Basic Constraints
CA:FALSE

Object 02: X509v3 Key Usage
Digital Signature, Key Encipherment

Object 03: X509v3 CRL Distribution Points

Full Name:
  URI:http://SVRSecure-G3-crl.verisign.com/SVRSecureG3.crl


Object 04: X509v3 Certificate Policies
Policy: 2.16.840.1.113733.1.7.54
  CPS: https://www.verisign.com/cps


Object 05: X509v3 Extended Key Usage
TLS Web Server Authentication, TLS Web Client Authentication

Object 06: X509v3 Authority Key Identifier
keyid:0D:44:5C:16:53:44:C1:82:7E:1D:20:AB:25:F4:01:63:D8:BE:79:A5


Object 07: Authority Information Access
OCSP - URI:http://ocsp.verisign.com
CA Issuers - URI:http://SVRSecure-G3-aia.verisign.com/SVRSecureG3.cer

Remarks


Extensions, introduced with the X.509 standard version 3, allow to customize a certificate with extra fields. One of the most commonly used extensions is called KeyUsage, which defines a certificate purpose by limiting the use of its keys to particular, approved purposes. Another one is called AlternativeNames (Subject Alternative Name), which allows the certificate to be used under more then just one, single common name. X509 version 3 standard defines a list of extensions, however new extensions can be defined and added.


OpenSSL Logo

Topics:

Source:

Documentation: