Month: September 2019

GUIDs to OIDs

I previously talked about OIDs and how they are used as globally unique identifiers through coordination. GUIDs on the other hand require no coordination, anyone can generate a GUID at any time they need. However there are situations where you don’t get a choice and you must use an OID. Getting an OID can be difficult and time consuming if you don’t already have a tree (although I set up a service to get a free instant one here).

The creators of the OID system came up with a solution for creating an instant OID that did not require coordination. Create a GUID and turn it into an OID. They set up a very nice spot right up high in the tree for it. 2.25 is the root OID for the tree containing GUIDS. A GUID is a 128 bit number and this 128 bit number can be represented as a decimal and then simply appended to 2.25.

For example the GUID {53c08bb6-b2eb-5038-bf28-ad41a08c50ef} can be made into the following OID: 2.25.111325678376819997685911819737516232943

This seems initially like a nice scheme however it has a big problem. Converting a 128 bit number into decimal is not something that is trivial in all computer languages. In Python it is very simple and can be done with in one line:

myOid = '2.25.%u' % int( myGuid.hex, 16 )

However this is not very easy in C as most compilers don’t have native 128 bit math. Additionally some implementations handling OIDs will store them internally using an array of integers, which will also not be able to handle a 128 bit number. Apart from the 2.25 branch, pretty much no other OID subcomponent will be a enormous number. So you can easily get away with just using 32 bit numbers for each oid part and you’ll be able to handle almost any OID presented. Except of course the enormous 2.25 OID.

Microsoft came up with a solution to this problem and reserved a branch in their OID space of 1.2.840.113556.1.8000.2554. Appended onto this is the GUID but broken down into several smaller sub parts. Again with my example GUID of {53c08bb6-b2eb-5038-bf28-ad41a08c50ef} the MS OID is: 1.2.840.113556.1.8000.2554.21440.35766.45803.20536.48936.11354528.9195759

MS provided a VBScript to convert a GUID into an OID if this type. Each component of the OID first within 32bits so is easy to handle in any language.

In Python you can create the MS OID with the following code

oidParts = [None] * 7
oidParts[0] = str( int( myGuid.hex[0:4], 16 ) )
oidParts[1] = str( int( myGuid.hex[4:8], 16 ) )
oidParts[2] = str( int( myGuid.hex[8:12], 16 ) )
oidParts[3] = str( int( myGuid.hex[12:16], 16 ) )
oidParts[4] = str( int( myGuid.hex[16:20], 16 ) )
oidParts[5] = str( int( myGuid.hex[20:26], 16 ) )
oidParts[6] = str( int( myGuid.hex[26:32], 16 ) )
myOid = '1.2.840.113556.1.8000.2554.%s' % '.'.join(oidParts)

The MS solution has one big problem as well. Because they gave it such a large prefix the entire OID string is pretty long. And some implementations handling OIDs are known to have a 64 character limit. This is not part of the standard, but an implementation limit. However you won’t be able to use the OID in these systems.

What would have been good is if the prefix could have been a tiny one like the 2.25 one. However only the ISO OID committee can allocate that. However I decided to do what I could to help the situation.

I have reserved the following OID for the use of converting a GUID to an OID: 1.3.6.1.4.1.54392.1

My scheme is simpler than the MS one. The GUID is broken into two 64 bit numbers and then appended. So again my example GUID {53c08bb6-b2eb-5038-bf28-ad41a08c50ef} becomes the OID: 1.3.6.1.4.1.54392.1.6034977117478539320.13774449957690691823

This OID is less than 64 characters long and it also can be created easily with any language that can handle 64 bit numbers.

Python code for this OID is:

oidParts = [None] * 2
oidParts[0] = str( int( myGuid.hex[0:16], 16 ) )
oidParts[1] = str( int( myGuid.hex[16:32], 16 ) )
myOid = '1.3.6.1.4.1.54392.1.%s' % '.'.join(oidParts)

This OID might still have the problem with systems that store the OID using 32 bit numbers for the parts. In which case I have also reserved the OID 1.3.6.1.4.1.54392.2 for breaking the GUID into 4 32 bit numbers. So again my example GUID {53c08bb6-b2eb-5038-bf28-ad41a08c50ef} becomes the OID: 1.3.6.1.4.1.54392.2.1405127606.3001765944.3207114049.2693550319 This is also under 64 characters in length and each sub part can be stored in 32 bit.

Python code for making the 32 bit compatible OID:

oidParts = [None] * 4
oidParts[0] = str( int( myGuid.hex[0:8], 16 ) )
oidParts[1] = str( int( myGuid.hex[8:16], 16 ) )
oidParts[2] = str( int( myGuid.hex[16:24], 16 ) )
oidParts[3] = str( int( myGuid.hex[24:32], 16 ) )
myOid = '1.3.6.1.4.1.54392.2.%s' % '.'.join(oidParts)

Finally for completeness I decided to reserve the OID 1.3.6.1.4.1.54392.3 for representing a GUID using 8 16 bit parts. This time my example GUID {53c08bb6-b2eb-5038-bf28-ad41a08c50ef} becomes the OID: 1.3.6.1.4.1.54392.3.21440.35766.45803.20536.48936.44353.41100.20719

Note however this final form is also over 64 characters in length so offers no advantage over the Microsoft version.

I have created a script that creates all 5 forms of OIDs from a GUID.

This script is public domain and you are free to use it how you wish. I’m hopeful that this will mean people can create OIDs from GUIDs that are fully useable in any implementation.

 

Advertisements