我正在使用GnuTLS 3.4.1。我有一个带有一系列序列的x509证书。证书以这种方式存储在智能卡上。
GnuTLS正在通过函数WITH RunningTotal AS (
SELECT Id, ListItem, SUM(ListItem) OVER (ORDER BY Id) AS RT FROM @Table)
SELECT Id, ListItem, RT, CASE WHEN RT > 100 THEN RT % 50 + 50 ELSE RT END AS NewRT
FROM RunningTotal
重新排列序列,这似乎导致验证失败。
这里的序列是什么样的:
_asn1_ordering_set_of
OpenSSL(可能还有Java PKCS11提供程序)按原样加载此构造。
证书加载的GnuTLS在SEQUENCE :
...
SET :
SEQUENCE :
OBJECT_IDENTIFIER : 'CN (2.5.4.3)'
PrintableString : '0000'
SEQUENCE :
OBJECT_IDENTIFIER : 'SN (2.5.4.4)'
TeletexString : 'XXX'
SEQUENCE :
OBJECT_IDENTIFIER : 'G (2.5.4.42)'
TeletexString : 'YYY'
中对此构造进行排序。所以它变成了:
_asn1_ordering_set_of
为什么GnuTLS会对序列集进行排序?它应该以什么方式完成,是GnuTLS错误还是其他库只是省略了排序?
答案 0 :(得分:2)
RFC5280有:
4.1。基本证书字段
X.509 v3证书的基本语法如下。签名 计算时,使用ASN.1对要签名的数据进行编码 区分编码规则(DER)[X.690]。
所以在我看来,GnuTLS正在做正确的事。
它看起来似乎正在尝试编码一个专有名称,但是它做错了。它根据ASN1有效,因为规范真的很奇怪。每个零件可以有多个值。但是你想要CN,SN等各自的SET,所以那些SEQUENCE应该有自己的SET。
答案 1 :(得分:1)
应该采取什么方式......
国际电联建议使用BER对SET进行编码,只要不需要CER或DER即可。我能说的最好,没有必要。有关ITU和ASN.1领域的更详细说明,请参见下文。
然而 ,GnuTLS可能正在遵守创造需求的标准。在这种情况下,我不知道它是哪个标准。见Kurt的回答。
我看了RFC 5280, PKIX Certificate and CRL Profile,但我找不到限制。也许它在另一个PKIX文档中。
是GnuTLS错误还是其他库只是省略了排序?
我不相信它是GnuTLS 本身的错误。这就是图书馆做事的方式。以RFC或其他标准的形式提出这个模块的要求。
另请注意,其他库不会省略排序。他们使用证书中显示属性的顺序, 订购:)
(评论)问题是GNUTLS重新排列会导致SSL身份验证失败
这对我来说听起来像个错误(模数标准要求)。在这种情况下,错误是在签署TBS /证书后重新排序SET OF。
如果GnuTLS 构建TBS /证书,那么可以重新排序,直到签名被放置在其上。
(评论)GnuTLS是否根据DER规则以正确的顺序放置SET OF类型的元素
在ASN.1 encoding rules, X.690, BER/CER/DER中:
8.12一组值的编码
...
8.12.3编码和后续解码不需要保留数据值的顺序。
SET OF似乎没有被排序(例如,词典顺序),因此发送者可以按任何顺序放置它们,接收者可以重新排序它们。
然而,11.6说:
11 CER和DER使用的BER限制 ...
11.6组件组件
一组值的分量值的编码应按升序出现,编码作为八位字符串进行比较,较短的分量在其尾端用0-八位字节填充。 注 - 填充八位字节仅用于比较目的,不会出现在编码中。
在上文中,他们说BER可以是任何顺序,但CER和DER是升序。
最后但并非最不重要的是,导言说:
简介
...
...如果编码包含设定值或设定值,则基本编码规则比规范或区分编码规则更合适,并且不需要规范和区分编码规则强加的限制......
因此,引言建议SET为SET OF。
但总的来说:证书是BER。这就是签名的方式。由于证书数据的签名,GnuTLS一旦获得证书就无法更改。
GnuTLS可以自由地在DER编码中创建证书。他们只是不能在事后强加编码。
(评论)
gnutls_certificate_set_x509_key_file(xcred, CERT_URL, KEY_URL, GNUTLS_X509_FMT_PEM);
我查看了最新的GnuTLS来源。这似乎是src/serv.c
中使用的方式。
显然,_asn1_ordering_set_of
过去没有按预期工作。它在2014年4月得到了改进。请参阅GnuTLS邮件列表中的PATCH 1/3: Make _asn1_ordering_set_of() really sort(和朋友)。
以下是来源中的点击次数:
$ grep -R -n _asn1_ordering_set_of * | grep -v doc
lib/minitasn1/coding.c:832: /* Function : _asn1_ordering_set_of */
lib/minitasn1/coding.c:843: _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
lib/minitasn1/coding.c:1261: err = _asn1_ordering_set_of (der + len2, counter - len2, p);
第1261行周围的使用是asn1_der_coding
。 asn1_der_coding
在其他组件中使用频率更高......
(评论)但我不确定它是GNUTls中的错误而不是服务器端的错误,所以我想在做任何事情之前找出它应该如何工作
您可能应该与B.3 Bug Reports详细说明的GnuTLS人员联系。它看起来像处理非GnuTLS证书时的错误。
要明确的是,GnuTLS在创建证书时使用DER,这很好。但GnuTLS在收到非GnuTLS证书后不能强制进行排序,因为这会使签名无效。
他们的测试套件可能会错过它,因为GnuTLS DER编码SET OF。他们可能不知道它的发生。