如何解决不支持 RELATIVE-OID 的 ASN.1 库

How to work around ASN.1 library not supporting RELATIVE-OID

我正在尝试使用 asn1tools Python library to decode and encode BER messages conforming to the Ember+ 标准。

That standard’s DTD uses ASN.1’s RELATIVE-OID type in some places. However, asn1tools doesn’t know about this type, probably because the underlying pyasn1 library doesn’t implement it (not yet, there’s a pull request)。这就是为什么我不能在我的 Python 程序中使用那个 DTD。但我真的不得不。

在我看来,我的选择是创建包含 RELATIVE-OID PR 的 pyasn1 的补丁版本并使 asn1tools 使用它,或者以某种方式构建DTD 中的解决方法。

我已经尝试将RELATIVE-OID ::= [UNIVERSAL 13] OCTET STRING添加到DTD中,但现在asn1tools响应Expected RELATIVE-OID with tag '2d' at offset 10, but got '0d'.基本上它似乎接受我的定义,但使其成为“通用构造13”而消息将其标记为“通用 原始 13”。

我有办法解决这个问题吗?

这是我的限制条件:

我的 ASN.1 知识有限,我不擅长编写 DTD。也许有一种方法可以强制该类型成为“原始”类型?我很高兴提出任何建议。如果您想亲自尝试一下,请使用上面链接的 DTD。然后,使用以下 Python 代码:

import asn1tools

spec = asn1tools.compile_files('GlowDtd.asn1')

print(spec.decode('Root', b'`\x80k\x80\xa0\x80b\x80\xa0\x03\x02\x01 \xa1\x03\x02\x01\xff\x00\x00\x00\x00\x00\x00\x00\x00'))
# should result in ('elements', [('element', ('command', {'number': 32, 'options': ('dirFieldMask', -1)}))])

print(spec.decode('Root', b'`\x80k\x80\xa0\x80j\x80\xa0\x03\r\x01\x01\xa2\x80d\x80\xa0\x80b\x80\xa0\x03\x02\x01 \xa1\x03\x02\x01\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
# doesn't work because it uses RELATIVE-OID

尝试

RELATIVE-OID ::= [UNIVERSAL 13] IMPLICIT OCTET STRING