5.16.4 ATTRTYP-to-OID Conversion

This section describes the prefix mapping mechanism that allows the one-to-one mapping between OIDs and a 32-bit integer (ATTRTYP).

An OID can be represented in the binary form, with a BER encoding scheme. The standard BER encoding of an object identifier consists of three components, because the end-of-contents component is not present. Only the third component (contents octets) is used here; other components are omitted.

Note The BER encoding of an OID is described in [ITUX690] section 8.19. To avoid ambiguity, the non-encoded form of the OID is referred to as the original form in this section.

The prefix of an OID is the binary OID, excluding the last one or two bytes. If the number following the final period (.) in the original form of the OID is less than 128, only the last byte is excluded; otherwise, the last two bytes are excluded.

A PrefixTable is a sequence of tuples defined as follows.

 type PrefixTable = sequence of [
   prefixString: unicodestring, 
   prefixIndex: integer
 ]

where:

  • prefixString is the prefix of an OID.

  • prefixIndex is an integer in the range [0 .. 0x0000ffff].

The integer prefixIndex is called the prefix index of prefixString. To allow one-to-one mappings between the prefix strings and the prefix indexes in the table, each prefixString MUST occur at most once in the table, and each prefixIndex MUST occur at most once in the table.

An ATTRTYP is a 32-bit, unsigned integer. If attr is an ATTRTYP, define attr.upperWord to be the most significant 16 bits, and attr.lowerWord to be the least significant 16 bits.

The following types and helper procedures are used for mapping between OIDs and ATTRTYP.

  
 procedure ToBinary(st: unicodestring) : sequence of BYTE

Converts a string to a binary OID representation. For example, "\x55\x06" is the binary OID \x55\x06.

  
 procedure CatBinary(o: sequence of BYTE, b: BYTE) : sequence of BYTE

Concatenates a byte onto a binary OID. For example, \x02 concatenated onto \x55\x06 is \x55\x06\x02.

  
 procedure ToStringOID(o: sequence of BYTE) : unicodestring

Converts a binary OID to its string representation, as described in [ITUX690] section 8.19; returns null if the conversion fails. For example, the binary OID \x55\x06\x02 is converted to the OID string "2.5.6.2".

  
 procedure ToBinaryOID(s: unicodestring) : sequence of BYTE

Converts an OID string representation to a binary OID, as described in [ITUX690] section 8.19; returns null if the conversion fails. For example, the OID string "2.5.6.2" is converted to the binary form \x55\x06\x02.

  
 procedure ToByte(i: integer) : BYTE

Converts an integer into a byte representation, truncating to the least significant digits, if needed. For example, 2 converts to \x02.

  
 procedure SubBinary(b: sequence of BYTE, 
   start: integer, end: integer) : sequence of BYTE

Returns the sequence [start .. end] of bytes in b.

  
 procedure AddPrefixTableEntry(var t: PrefixTable, o: sequence of BYTE)

Sets t[t.length].prefixString to o. Generates a random number between 0 and 65535 that is unique in the values of prefixIndex in t, and sets t[t.length].prefixIndex to the generated random number. Increases t.length by one.

  
 procedure ToInteger(s: unicodestring) : integer

Converts a string to its integer representation. For example, "127" is 127. Strings with non-numeric characters are not defined for this procedure.

The following procedures are used for mapping between object identifiers and ATTRTYP representations.

  
 procedure MakeAttid(var t: PrefixTable, o: OID): ATTRTYP

Informative summary of behavior: This procedure converts an OID to a corresponding ATTRTYP representation.

  
   lastValueString: unicodestring
   lastValue, lowerWord: integer
   binaryOID, oidPrefix: sequence of BYTE 
   attr: ATTRTYP
   pos: integer
  
   /* get the last value in the original OID: the value 
    * after the last '.'*/
   lastValueString := SubString(o,
                                FindCharRev(o, o.length,'.'),
                                o.length)
   lastValue := ToInteger(lastValueString)
  
   /* convert the dotted form of OID into a BER encoded binary
    * format. The BER encoding of OID is described in section
    * 8.19 of [ITUX690]*/
   binaryOID := ToBinaryOid(o) 
  
   /* get the prefix of the OID*/
   if lastValue < 128 then
     oidPrefix := SubBinary(binaryOID, 0, binaryOID.length - 2)
   else
     oidPrefix := SubBinary(binaryOID, 0, binaryOID.length - 3)
   endif
  
   /* search the prefix in the prefix table, if none found, add
    * one entry for the new prefix.*/
   fToAdd := true
   for i := 0 to t.length
     if ToBinary(t[i].prefixString) = oidPrefix then
       fToAdd := false
       pos := i
     endif
   endfor
  
   if fToAdd then
     pos := t.length
     AddPrefixTableEntry(t, oidPrefix)
   endif
  
   /*compose the attid*/
   lowerWord := lastValue mod 16384
   if lastValue ≥ 16384 then
     /*mark it so that it is known to not be the whole lastValue*/
     lowerWord := lowerWord + 32768
   endif
   upperWord := t[pos].prefixIndex
   attr := upperWord * 65536 + lowerWord
  
   return attr
  
 procedure OidFromAttid(t: PrefixTable, attr: ATTRTYP): OID

Informative summary of behavior: This procedure converts an ATTRTYP representation to a corresponding OID.

  
   i, upperWord, lowerWord: integer
   binaryOID: sequence of BYTE
  
   binaryOID = null
  
   /* separate the ATTRTYP into two parts*/
   upperWord := attr / 65536
   lowerWord := attr mod 65536 
  
   /* search in the prefix table to find the upperWord, if found, 
    * construct the binary OID by appending lowerWord to the end of
    * found prefix.*/
   for i := 0 to t.length
     if t[i].prefixIndex = upperWord then
       if lowerWord < 128 then
         binaryOID := CatBinary(ToBinary(t[i].prefixString),  
             ToByte(lowerWord))
       else
         if lowerWord ≥ 32768 then 
           lowerWord := lowerWord - 32768
         endif
         binaryOID := CatBinary(ToBinary(t[i].prefixString), 
             ToByte(((lowerWord / 128) mod 128) + 128))
         binaryOID := CatBinary(binaryOID, ToByte(lowerWord mod 128))
       endif
     endif
   endfor
   if binaryOID = null then
     return null
   else
     return ToStringOID(binaryOID)
   endif
  
 procedure NewPrefixTable( ): PrefixTable

This procedure creates a new PrefixTable, inserts the following tuples into the table, and returns the table as the result.

 prefixString

 Length of prefixString

 prefixIndex

"\x55\x4"

2

0

"\x55\x6"

2

1

"\x2A\x86\x48\x86\xF7\x14\x01\x02"

8

2

"\x2A\x86\x48\x86\xF7\x14\x01\x03"

8

3

"\x60\x86\x48\x01\x65\x02\x02\x01"

8

4

"\x60\x86\x48\x01\x65\x02\x02\x03"

8

5

"\x60\x86\x48\x01\x65\x02\x01\x05"

8

6

"\x60\x86\x48\x01\x65\x02\x01\x04"

8

7

"\x55\x5"

2

8

"\x2A\x86\x48\x86\xF7\x14\x01\x04"

8

9

"\x2A\x86\x48\x86\xF7\x14\x01\x05"

8

10

"\x09\x92\x26\x89\x93\xF2\x2C\x64"

8

19

"\x60\x86\x48\x01\x86\xF8\x42\x03"

8

20

"\x09\x92\x26\x89\x93\xF2\x2C\x64\x01"

9

21

"\x60\x86\x48\x01\x86\xF8\x42\x03\x01"

9

22

"\x2A\x86\x48\x86\xF7\x14\x01\x05\xB6\x58"

10

23

"\x55\x15"

2

24

"\x55\x12"

2

25

"\x55\x14"

2

26

The following examples show the correspondence between OID and ATTRTYP by using the PrefixTable returned by the procedure NewPrefixTable.

  
 OID: 2.5.4.6 (countryName attribute)
 Binary: \x55\x04\x06
 Prefix string: "\x55\x04" 
 Prefix index: 0
 ATTRTYP: 0x00000006
  
 OID: 2.5.6.2 (country class)
 Binary: \x55\x06\x02
 Prefix string: "\x55\x06" 
 Prefix index: 1
 ATTRTYP: 0x00010002 
  
 OID: 1.2.840.113556.1.2.1 (instanceType attribute)
 Binary: \x2A\x86\x48\x86\xF7\x14\x01\x02\x01
 Prefix string: "\x2A\x86\x48\x86\xF7\x14\x01\x02" 
 Prefix index: 2
 ATTRTYP: 0x00020001
  
 OID: 1.2.840.113556.1.3.23 (container class)
 Binary: \x2A\x86\x48\x86\xF7\x14\x01\x03\x17
 Prefix string: "\x2A\x86\x48\x86\xF7\x14\x01\x03" 
 Prefix index: 3
 ATTRTYP: 0x00030017
  
 OID: 2.5.5.1 (attribute syntax: distinguished name)
 Binary: \x55\x5\x1
 Prefix string: "\x55\x5" 
 Prefix index: 8
 ATTRTYP: 0x00080001
  
 OID: 1.2.840.113556.1.4.1 (RDN attribute)
 Binary: \x2A\x86\x48\x86\xF7\x14\x01\x04\x01
 Prefix string: "\x2A\x86\x48\x86\xF7\x14\x01\x04" 
 Prefix index: 9
 ATTRTYP: 0x00090001
  
 OID: 1.2.840.113556.1.5.1 (securityObject class)
 Binary: \x2A\x86\x48\x86\xF7\x14\x01\x05\x01
 Prefix string: "\x2A\x86\x48\x86\xF7\x14\x01\x05" 
 Prefix index: 10
 ATTRTYP: 0x000a0001
  
 OID: 0.9.2342.19200300.100.1.1 (uid attribute)
 Binary: \x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x01
 Prefix string: "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01" 
 Prefix index: 21
 ATTRTYP: 0x00150001
  
 OID: 2.16.840.1.113730.3.1.1 (carLicense attribute)
 Binary: \x60\x86\x48\x01\x86\xF8\x42\x03\x01\x01
 Prefix string: "\x60\x86\x48\x01\x86\xF8\x42\x03\x01" 
 Prefix index: 22
 ATTRTYP: 0x00160001
  
 OID: 1.2.840.113556.1.5.7000.53 (crossRefContainer class)
 Binary: \x2A\x86\x48\x86\xF7\x14\x01\x05\xB6\x58\x35
 Prefix string: "\x2A\x86\x48\x86\xF7\x14\x01\x05\xB6\x58" 
 Prefix index: 23
 ATTRTYP: 0x00170035
  
 OID: 2.5.21.2 (ditContentRules attribute)
 Binary: \x55\x15\x02
 Prefix string: "\x55\x15" 
 Prefix index: 24
 ATTRTYP: 0x00180002
  
 OID: 2.5.18.1 (createTimeStamp attribute)
 Binary: \x55\x12\x01
 Prefix string: "\x55\x12" 
 Prefix index: 25
 ATTRTYP: 0x00190001
  
 OID: 2.5.20.1 (subSchema class)
 Binary: \x55\x14\x01
 Prefix string: "\x55\x14" 
 Prefix index: 26
 ATTRTYP: 0x001a0001