在 pyasn1 中处理嵌套的 DER,打包成 OCTET STRING

Handling nested DER, packed into OCTET STRINGs, in pyasn1

这是 RFC 5280 定义 X.509 扩展字段的方式:

Extension  ::=  SEQUENCE  {
     extnID      OBJECT IDENTIFIER,
     critical    BOOLEAN DEFAULT FALSE,
     extnValue   OCTET STRING
                 -- contains the DER encoding of an ASN.1 value
                 -- corresponding to the extension type identified
                 -- by extnID
     }

当我使用 pyasn1 解码器时,我会得到一个对象 foo,其 foo['extnValue'].asOctets() 可以进一步解码,使用适合 [=13= 的模式调用解码器].

问题: 假设我的应用程序中有一个特殊的 extnID,是否可以在 pyasn1 中定义一个 (a) 不接受任何对象的模式IDENTIFIER,只有特殊的那个; (b) 根据适当的特殊 "sub-schema" ?

通过 OCTET STRING 包装器解码有效负载

我可以通过代码中的特例逻辑来完成此操作,但如果支持的话,我更愿意定义一个特例模式。

您应该使用 OpenType 作为 extnValue 类型定义。当您将 extnID -> ASN.1 type 的映射传递给解码器时,解码器将越过最外面的 extnValue 包装器尝试解码其内容。

这是一个简单的例子:

openType = opentype.OpenType(
        'id',
        {1: univ.Integer(),
         2: univ.OctetString()}
    )
    self.s = univ.Sequence(
        componentType=namedtype.NamedTypes(
            namedtype.NamedType('id', univ.Integer()),
            namedtype.NamedType('blob', univ.Any(), openType=openType)
        )
    )

如果您希望解码器解包这些开放类型,请务必将 decodeOpenTypes=True 参数传递给 decode() 函数。

顺便说一句,如果您查看 pyasn1-modules,那张地图已经在那里了。如果您使用这些定义并仅将 decodeOpenTypes=True 关键字参数传递给解码器,您应该解开您的扩展。

没有现成的方法让解码器在未知情况下失败 extnID。您可能会建模,我给它您自己的地图(可能基于 dict),这将在不成功的 key in my_map 操作时失败。