设置组件时pyasn1和奇怪的不匹配

时间:2015-07-17 05:57:41

标签: python asn.1 pyasn1

使用pyasn1设置组件时遇到了一个奇怪的问题。我构建并清空证书并将证书签入其中:

empty = rfc2459.Certificate()
empty['tbsCertificate'] = rfc2459.TBSCertificate()

现在我想设置一个版本,该版本因实际版本对象而失败,但通过自动创建类型来工作:

empty['tbsCertificate']['version'] = rfc2459.Version('v3')
# PyAsn1Error: Component type error Version('v1') vs Version('v3')

empty['tbsCertificate']['version'] = 'v3'
# works

鉴于这两者比较相等,这很奇怪:

empty['tbsCertificate']['version'] == rfc2459.Version('v3')
# True

那为什么第一种方式不起作用呢?

1 个答案:

答案 0 :(得分:1)

这些版本正式属于不同类型,并且它们具有不同的BER标记。 rfc2459.Version是普通的INTEGER:

class Version(univ.Integer):
    namedValues = namedval.NamedValues(('v1', 0), ('v2', 1), ('v3', 2))

而rfc2459.TBSCertificate的'version'字段SEQUENCE包含Version的子类,它是通过附加标记定义的:

class TBSCertificate(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.DefaultedNamedType('version',Version('v1').subtype(
            explicitTag=tag.Tag(
                tag.tagClassContext, tag.tagFormatSimple, 0)
            )
        )...

这就是为什么你不能将Version对象放入TBSCertificate ['version']。如果可以,那将正式更改TBSCertificate数据类型及其BER表示。

同时TBSCertificate ['version'] ='v1'的工作原理是由于Python字符串'v1'通过其命名值(例如'v1')自动强制转换为Version子类型。

它们的有效载荷(例如0)确实比较相等,即使对于不同类型,有时也是可能的。考虑:

>>> float(0) == int(0)
True
>>> float == int
False

例如。

回答你的问题:我认为正确的方法是依靠“强制”。这将保证标签/类型的正确性,并将根据目标类型约束(例如值范围,大小等)验证初始化程序。因此,您最终会得到完全兼容的ASN.1结构实例。