网络安全服务包和oidcalc实用程序

当在KMail邮件客户端中,在Kleopatra和GnuPG应用程序中实施与使用俄语密码算法有关的项目时,为了将俄语oid从点十进制转换为DER编码,我决定使用NSS(网络安全服务)软件包中oidcalc实用程序,它已预安装在所有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”(CryptoPro CA,证书有效期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实用程序并获得了我期望的结果:

# ./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开发人员了吗?是的,我写了。此外,带有支持PKCS#11接口的带有加密令牌/智能卡的插件的NSS软件包实际上是应用程序的加密核心来自Mozilla,也可用于Google的Chrome浏览器。没有回应,代码没有固定。因此,出现此注释是为了防止其他人作为您卑微的仆人踏上这耙。好吧,当然,我们希望Linux的国内fork / clone的供应商将在其软件包中修复此错误。

Source: https://habr.com/ru/post/zh-CN398783/


All Articles