- PVSM.RU - https://www.pvsm.ru -

Пакет Network Security Services и утилита oidcalc

При реализации проекта, связанного с использованием российской криптографических алгоритмов в почтовом клиенте KMail, в приложении Kleopatra и GnuPG [1], для перевода российских oid-ов из точечно-десятичной формы в DER-кодировку я решил воспользоваться утилитой oidcalc [2] из пакета NSS [3] (Network Security Services ), который предустановлен во всех дистрибутивах Linux, включая отечественные клоны. Полученный код использовался в работе.

И все шло хорошо, пока не попался oid, в котором был десятичная цифра 0 (нуль), а именно «1.2.643.2.2.36.0» (szOID_GostR3410_2001_CryptoPro_XchA_ParamSet).
И здесь меня ожидал неприятный сюрприз – мой код перестал работать. В какой-то момент я решил посмотреть, а во что же переводится этот oid:

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

Но должно было быть 0x2a, 0x85, 0x3, 0x2, 0x2, 0x24, 0x0, — завершающий шестнадцатеричный нуль отсутствовал.

Попробовал перевести другой oid «1.2.643.3.6.0.1» (КриптоПро УЦ, Срок действия сертификата 1 месяц):

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

Тот же печальный ркзультат – отсутствует предпоследний байт с нулем.

Стало ясно, что утилита oidcalc выбрасывает нули из oid-а. Следующий пример только подтвердил это предположение:

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

Для еще одной проверки пришлось воспользоваться утилитой oid [4] и получил тот результат, который ожидал:

# ./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
#

Утилита oid выводит результат уже в ASN1-кодировки, где первый байт определяет тип последовательности, второй байт – длину последовательности в байтах, а далее идет сам oid в шестнадцатеричном представлении.

После этого оставалось проанализировать исходный код утилиты oidcalc.c и вмести минимальные изменения:
...
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;
...

Теперь, если пересобрать утилиту, то все работает прекрасно:

#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,
#

В чем же ошибся разработчик утилиты? В мелочи. Для перевода числа из строки в целое автор использует функции atoi, которая возвращает 0 (нуль) и в случае перевода символа '0' и случае невозможности перевода (задано не число). Оказалось достаточным добавить дополнительную проверку и все заработало.
Писал ли я разработчикам NSS? Да, писал. Тем более, что пакет NSS является фактически криптографическим ядром приложений [5] от Mozilla, а также используется в браузерах Chrome от Google [6]. Ответа не последовало, код не исправлен. Поэтому и появилась эта заметка, чтобы кто-то другой не наступил на эти грабли как ваш покорный слуга. Ну и, конечно, будем надеяться, что поставщики отечественных клонов Linux [7] исправят в своих пакетах эту ошибку.

Автор: saipr

Источник [8]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/linux/204391

Ссылки в тексте:

[1] KMail, в приложении Kleopatra и GnuPG: http://soft.lissi.ru/articles/KleopatraKmailGnuPg/

[2] oidcalc: http://ftp.mozilla.org/pub/security/nss/releases/

[3] NSS: https://ru.wikipedia.org/wiki/Network_Security_Services

[4] oid: http://www.rtner.de/software/oid.html

[5] ядром приложений: http://soft.lissi.ru/solution/mozilla/

[6] браузерах Chrome от Google: http://soft.lissi.ru/articles/googlechromgost/

[7] отечественных клонов Linux: http://soft.lissi.ru/ls_product/os/

[8] Источник: https://geektimes.ru/post/282024/