How do I convert an OID in string form into ASN.1 binary?
2 years ago
Originally Published: 2007-03-23
Article Number
000058416
Applies To
SSL-C
Issue
To convert an object identifier (OID) from a string in dotted decimal notation (e.g. 2.100.3) to BER-encoded hex binary form (e.g. 0x81 0x34 0x03)
Resolution
The BER encoding of an OBJECT IDENTIFIER (OID) follows these rules:
  • Each subidentifier is encoded in 7-bit base 128
  • The base 128 digits are encoded in hex (base 16)
  • For each value that requires more than one byte to encode, the leftmost bit is 1 in each byte except for the final one.  The final byte always has 0 for the leftmost bit.
  • The first two values of the OID are combined with the following formula
    • Given an OID of X.Y.Z, X and Y are combined as: X * 40 + Y
For example, for "2.100.3" (the example given in X.690 section 8.19):
  1. Combine 2 and 100 as follows: 2 * 40 + 100 = 180
  2. Now you have 2 numbers: 180 and 3.
  3. 180 in Base 128 = 128 + 52
    1. converted to hex, 180 in base 128 = 0x01 0x34
    2. Set the leftmost bit in the first byte: 0x81, 0x34
  4. 3 in Base 128 = 3
    1. converted to hex, 3 in base 128 = 0x03
    2. Since this is only one byte long, the lowest bit stays 0
  5. Combine the results to get: 0x81 0x34 0x03

The following psuedo code explains how to convert the string form of an OID into a binary form that SSL-C can understand:

For example, we'll encode 2.100.3:

Merge the first two values together with this formula: n1 * 40 + n2
   /* The first value (n1) is always 0, 1, or 2
      2 * 40 + 100 = 180

      we are now encoding 180 3 */

For each value
   Convert each value to base 128
      /* 180 (base 10) = 1 52 (base 128) 
           3 (base 10) = 3 (base 128)
       
         This can be understood as:
          
 180 = 1 * 128^1 + 52 * 128^0
             3 = 3 * 128 ^0
      
       180 = 128 + 52 =
0x01 (128's place) 0x34 (1's place)

         3 = 0x03*/

    For all bytes except the last one, set the left most bit
      /* 0x01 0x34 becomes 0x81 0x34

         0x03 stays 0x03 */

    Put these into a byte array with a trailing NULL.
      /* In C, this looks like:

           char oid[4] = { 0x81, 0x34, 0x03, '\0' };

       */


Notes
You may want to do a web search for "convert OID to binary code" to find code that will do this.