📜 ⬆️ ⬇️

Network Security Services package and oidcalc utility

When implementing a project related to the use of Russian cryptographic algorithms in the KMail email client in the Kleopatra and GnuPG application , to convert Russian oid- s from dot-decimal form to DER-encoding, I decided to use the oidcalc utility from the NSS (Network Security Services) package , which is preinstalled in all Linux distributions, including domestic clones. The resulting code was used in the work.

And everything went well until an oid was found that had a decimal digit of 0 (zero), namely “1.2.643.2.2.36.0” (szOID_GostR3410_2001_CryptoPro_XchA_ParamSet). And here an unpleasant surprise was waiting for me - my code stopped working. At some point I decided to look, and what this oid means :

# oidcalc 1.2.643.2.2.36.0 0x2a, 0x85, 0x3, 0x2, 0x2, 0x24, # 

But it should have been 0x2a, 0x85, 0x3, 0x2, 0x2, 0x24, 0x0, - the trailing hex zero was missing.

I tried to translate another oid "1.2.643.3.6.0.1" (CryptoPro Pro, Certificate validity period 1 month):
')
 # oidcalc 1.2.643.3.6.0.1 0x2a, 0x85, 0x3, 0x3 0x3, 0x6, 0x1, # 

The same sad result - there is no penultimate byte with zero. It became clear that the oidcalc utility throws out zeros from the oid. The following example only confirmed this assumption:

 # oidcalc 1.2.643.3.6.1 0x2a, 0x85, 0x3, 0x3 0x3, 0x6, 0x1, # 

For another check, I had to use the oid utility and got the result I expected:

 # ./oid 1.2.643.2.2.36.0 06 07 2A 85 03 02 02 24 00 # ./oid 1.2.643.3.6.0.1 06 07 2A 85 03 03 06 00 01 # 

The oid utility displays the result already in ASN1-encoding, where the first byte determines the type of sequence, the second byte - the length of the sequence in bytes, and then the oid itself is in hexadecimal.

After that, it remained to analyze the source code of the oidcalc.c utility and together the minimal changes:

  . . . memset(buf, 0, sizeof(buf)); val = atoi(curstr); count = 0; /* */ if(curstr[0] != '0') while (val) { buf[count] = (val & 0x7f); val = val >> 7; count++; } /*   */ else buf[count++] = 0x00; . . . 

Now, if you rebuild the utility, then everything works fine:

 #oidcalc 1.2.643.2.2.36.0 0x2a, 0x85, 0x3, 0x2, 0x2, 0x24, 0x0, #oidcalc 1.2.643.3.6.0.1 0x2a, 0x85, 0x3, 0x3, 0x6, 0x0, 0x1, # 

What was wrong with the utility developer? In the little things. To translate a number from a string to an integer, the author uses the atoi functions, which returns 0 (zero) and in case of translating the character '0' and in case of impossibility of translation (no number is given). It turned out to be enough to add additional checks and it all worked.

Did I write to the NSS developers? Yes, he wrote. Moreover, the NSS package with plug-in cryptographic tokens / smartcards that support the PKCS # 11 interface is actually a cryptographic core of applications from Mozilla, and is also used in Google's Chrome browsers. No reply, code not corrected. Therefore, this note appeared so that someone else did not step on this rake as your humble servant. And, of course, we hope that the suppliers of domestic Linux forks / clones will fix this error in their packages.

Source: https://habr.com/ru/post/398783/


All Articles