LINUX.ORG.RU

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

 , , , ,


0

3

При реализации одного из проектов, связанного с использованием российских криптографических алгоритмов, для перевода российских oid-ов из точечно-десятичной формы в DER-кодировку была использована утилита oidcalc из пакета NSS (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 и был получен правильный результат, что только подтвердило наличие ошибки в утилите oidcalc из пакета NSS:

# ./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 является фактически криптографическим ядром для приложений от Mozilla, а также используется в браузерах Chrome от Google . Хочется надеяться, что поставщики отечественных клонов Linux исправят эту ошибку в своих пакетах NSS.