Introduction


The example 'C' program add_ev_oids.c demonstrates how to add missing/extra OID's to OpenSSL, using the OpenSSL library functions.

In my particular case, I noted that some OID's in EV certificates were not translated in OpenSSL. A quick check showed that OpenSSL comes with pre-defined definitions in objects.txt, and did not have some of the EV OID's that are specified in GUIDELINES FOR THE ISSUANCE AND MANAGEMENT OF EXTENDED VALIDATION CERTIFICATES. This occured for the OID

Per discussion, it is discouraged to modify the OpenSSL source (i.e. objects.txt) directly as values may be overwritten by future versions of OpenSSL. The recommended way of adding missing or defining extra OID's is to update OpenSSL's internal NID table by creating them using the OBJ_create() function. Below is a example test code to verify how it works.

Example Code Listing


/* ------------------------------------------------------------ *
 * file:        add_ev_oids.c                                   *
 * purpose:     Example how to add OID's to OpenSSL internals   *
 * author:      10/03/2012 Frank4DD                             *
 *                                                              *
 * gcc -o add_ev_oids add_ev_oids.c -lssl -lcrypto              *
 * ------------------------------------------------------------ */

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

/* ---------------------------------------------------------- *
 * This function adds missing OID's to the internal structure *
 * ---------------------------------------------------------- */
void add_missing_ev_oids();

int main() {

  const char cert_filestr[] = "./cert-file.pem";
  BIO              *certbio = NULL;
  BIO               *outbio = NULL;
  X509                *cert = NULL;
  X509_NAME    *certsubject = NULL;
  int ret;

  /* ---------------------------------------------------------- *
   * 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);
  }

  /* ---------------------------------------------------------- *
   * Print the certificate subject here                         *
   * ---------------------------------------------------------- */
  BIO_printf(outbio, "Before OBJ_create():\n");
  certsubject = X509_NAME_new();
  certsubject = X509_get_subject_name(cert);
  X509_NAME_print_ex(outbio, certsubject, 0, XN_FLAG_MULTILINE);
  BIO_printf(outbio, "\n\n");

  add_missing_ev_oids();

  BIO_printf(outbio, "After OBJ_create():\n");
  certsubject = X509_NAME_new();
  certsubject = X509_get_subject_name(cert);
  X509_NAME_print_ex(outbio, certsubject, 0, XN_FLAG_MULTILINE);
  BIO_printf(outbio, "\n");

  /* ---------------------------------------------------------- *
   * Free up all structures                                     *
   * ---------------------------------------------------------- */
  X509_free(cert);
  BIO_free_all(certbio);
  BIO_free_all(outbio);
  exit(0);
}

/* ---------------------------------------------------------- *
 * OpenSSL seems to lack a few OID's used for EV certificates *
 * ---------------------------------------------------------- */
void add_missing_ev_oids() {
  int nid;
  /* --------------------------------------------------------- *
   * OBJ_create():                                             *
   * First field is the OID, which will be converted to DER    *
   * encoding. Next are the short and long description of      *
   * this OID. The descriptions will not be included as the    *
   * extension identifier, but the DER encoding of the OID.    *
   * --------------------------------------------------------- */
  nid = OBJ_create("1.3.6.1.4.1.311.60.2.1.1",
                   "ASN.1 - X520LocalityName as specified in RFC 3280",
                   "jurisdictionOfIncorporationLocalityName");

  nid = OBJ_create("1.3.6.1.4.1.311.60.2.1.2",
                   "ASN.1 - X520StateOrProvinceName as specified in RFC 3280",
                   "jurisdictionOfIncorporationStateOrProvinceName");

  nid = OBJ_create("1.3.6.1.4.1.311.60.2.1.3",
                   "ASN.1 - X520countryName as specified in RFC 3280",
                   "jurisdictionOfIncorporationCountryName");
}

Compiling the Code


Compile the test program with:

fm@susie114:~>  gcc -o add_ev_oids add_ev_oids.ci -lssl -lcrypto

Example Output


The program expects a EV certificate file called cert-file.pem in the same directory. If the certificate is found and loaded, the following examplary output is produced (I used the certificate from www.isaca.org):

fm@susie114:~> ./add_ev_oids
Before OBJ_create():
businessCategory          = Private Organization
1.3.6.1.4.1.311.60.2.1.3 = US
1.3.6.1.4.1.311.60.2.1.2 = California
serialNumber              = c0583597
streetAddress             = Suite 1010
streetAddress             = 3701 Algonquin Road
postalCode                = 60008
countryName               = US
stateOrProvinceName       = IL
localityName              = Rolling Meadows
organizationName          = Information Systems Audit and Control Association, Inc.
organizationalUnitName    = IH
commonName                = www.isaca.org

After OBJ_create():
businessCategory          = Private Organization
jurisdictionOfIncorporationCountryName = US
jurisdictionOfIncorporationStateOrProvinceName = California
serialNumber              = c0583597
streetAddress             = Suite 1010
streetAddress             = 3701 Algonquin Road
postalCode                = 60008
countryName               = US
stateOrProvinceName       = IL
localityName              = Rolling Meadows
organizationName          = Information Systems Audit and Control Association, Inc.
organizationalUnitName    = IH
commonName                = www.isaca.org

Remarks


There seems to be a mix-up in the function OBJ_create() order of parameters. The docs say 1. NID, 2. ShortName, 3. LongName. However when I printed the NID's short and long names, after setting them, they came out the other way around. In my case, to avoid confusion, I decided to set ShortName and LongName identical (as ShortName).

If the OpenSSL commandline is used, the additional EV OID's can be added to /etc/ssl/openssl.cnf (the path could differ by distribution).

fm@susie114:/ # vi /etc/ssl/openssl.cnf

...
[ new_oids ]

# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
businessCategory=2.5.4.15
streetAddress=2.5.4.9
stateOrProvinceName=2.5.4.8
countryName=2.5.4.6
jurisdictionOfIncorporationStateOrProvinceName=1.3.6.1.4.1.311.60.2.1.2
jurisdictionOfIncorporationLocalityName=1.3.6.1.4.1.311.60.2.1.1
jurisdictionOfIncorporationCountryName=1.3.6.1.4.1.311.60.2.1.3

OpenSSL Logo

Topics:

Source:

Documentation: