使用 pyasn1 解析 X509 扩展
Parsing X509 extensions with pyasn1
我有一个扩展,描述如下:
Extension().setComponentByPosition(0, ObjectIdentifier(2.5.29.19))
.setComponentByPosition(1, Boolean('False'))
.setComponentByPosition(2, Any(hexValue='04023000'))
所以根据 id,它是一个 BasicConstraints
扩展。但是,如果我尝试将值解析为扩展本身,则会出现错误:
decoder.decode(decoder.decode(e['extnValue'])[0], rfc2459.BasicConstraints())
# PyAsn1Error: Uninitialized component #0 at BasicConstraints()
该字符串解码为空序列,因此它可以合法地成为 BasicConstraints
- name length
optional/missing 并且 ca
是默认值,因此未在 DER 中编码。
那么我在这里缺少什么?如何将此扩展解码为 BasicConstraints
class?
PS。这个问题似乎与 issue in mailing list 类似,但我使用的是 0.1.8,它应该已经包含了提到的修复
由于 BasicConstraints 是一个 SEQUENCE 导数,它的最小可能序列化是 SEQUENCE 标签和零长度。那么它的值可能是一个空字符串,正如你所建议的那样。事实上是这样的:
>>> derSerialisation, _ = decode(OctetString(hexValue='04023000'))
>>> derSerialisation.prettyPrint()
'0x3000'
>>> constraint, _ = decode(derSerialisation)
>>> constraint.prettyPrint()
'Sequence:\n'
ANY 值是不透明的(无标记),但嵌入式 DER 序列化本身编码为 OCTET STRING。因此,在将 DER 内容传递给解码器以恢复 BasicConstraints 之前,请确保从 OCTET STRING 序列化中提取 DER 内容。
邮件列表错误不相关 - 那是在不确定的编码模式下。
已更新
原来是 rfc2459.BasicConstraints 规范中的错误。虽然官方 fix/release 正在准备中,但我可以向 pyasn1_modules.rfc2459 建议以下猴子补丁:
>>> from pyasn1.type import namedtype
>>> from pyasn1_modules import rfc2459
>>> rfc2459.BasicConstraints.componentType = namedtype.NamedTypes(
... namedtype.DefaultedNamedType(*rfc2459.BasicConstraints.componentType[0]),
... rfc2459.BasicConstraints.componentType[1]
... )
基本上将 'cA' 组件标记为默认。一旦应用,您的序列化就可以被解码:
>>> s
Any(hexValue='04023000')
>>> basicConstraints, _ = decoder.decode(decoder.decode(s)[0], rfc2459.BasicConstraints())
>>> print(basicConstraints.prettyPrint())
BasicConstraints:
cA='False'
再次更新
上述错误已在 pyasn1-modules 中修复0.0.7
我有一个扩展,描述如下:
Extension().setComponentByPosition(0, ObjectIdentifier(2.5.29.19))
.setComponentByPosition(1, Boolean('False'))
.setComponentByPosition(2, Any(hexValue='04023000'))
所以根据 id,它是一个 BasicConstraints
扩展。但是,如果我尝试将值解析为扩展本身,则会出现错误:
decoder.decode(decoder.decode(e['extnValue'])[0], rfc2459.BasicConstraints())
# PyAsn1Error: Uninitialized component #0 at BasicConstraints()
该字符串解码为空序列,因此它可以合法地成为 BasicConstraints
- name length
optional/missing 并且 ca
是默认值,因此未在 DER 中编码。
那么我在这里缺少什么?如何将此扩展解码为 BasicConstraints
class?
PS。这个问题似乎与 issue in mailing list 类似,但我使用的是 0.1.8,它应该已经包含了提到的修复
由于 BasicConstraints 是一个 SEQUENCE 导数,它的最小可能序列化是 SEQUENCE 标签和零长度。那么它的值可能是一个空字符串,正如你所建议的那样。事实上是这样的:
>>> derSerialisation, _ = decode(OctetString(hexValue='04023000'))
>>> derSerialisation.prettyPrint()
'0x3000'
>>> constraint, _ = decode(derSerialisation)
>>> constraint.prettyPrint()
'Sequence:\n'
ANY 值是不透明的(无标记),但嵌入式 DER 序列化本身编码为 OCTET STRING。因此,在将 DER 内容传递给解码器以恢复 BasicConstraints 之前,请确保从 OCTET STRING 序列化中提取 DER 内容。
邮件列表错误不相关 - 那是在不确定的编码模式下。
已更新
原来是 rfc2459.BasicConstraints 规范中的错误。虽然官方 fix/release 正在准备中,但我可以向 pyasn1_modules.rfc2459 建议以下猴子补丁:
>>> from pyasn1.type import namedtype
>>> from pyasn1_modules import rfc2459
>>> rfc2459.BasicConstraints.componentType = namedtype.NamedTypes(
... namedtype.DefaultedNamedType(*rfc2459.BasicConstraints.componentType[0]),
... rfc2459.BasicConstraints.componentType[1]
... )
基本上将 'cA' 组件标记为默认。一旦应用,您的序列化就可以被解码:
>>> s
Any(hexValue='04023000')
>>> basicConstraints, _ = decoder.decode(decoder.decode(s)[0], rfc2459.BasicConstraints())
>>> print(basicConstraints.prettyPrint())
BasicConstraints:
cA='False'
再次更新
上述错误已在 pyasn1-modules 中修复0.0.7