我正在尝试使用asn1tools
Python 库来解码和编码符合Ember+标准的 BER 消息。
该标准的 DTDRELATIVE-OID
在某些地方使用 ASN.1 的类型。但是,asn1tools
不知道这种类型,可能是因为底层pyasn1
库没有实现它(还没有,有一个拉请求)。这就是为什么我不能在我的 Python 程序中使用那个 DTD。但我真的必须这样做。
正如我所看到的,我的选择是创建一个包含 PR 的补丁版本pyasn1
并RELATIVE-OID
使用asn1tools
它,或者以某种方式在 DTD 中构建一个解决方法。
我已经尝试添加RELATIVE-OID ::= [UNIVERSAL 13] OCTET STRING
到 DTD,但现在asn1tools
响应Expected RELATIVE-OID with tag '2d' at offset 10, but got '0d'.
基本上它似乎接受我的定义,但将其设为“通用构造 13”,而消息将其标记为“通用原语13”。
我有办法解决这个问题吗?
这是我的限制:
- 我基本上必须使用
asn1tools
,我的代码已经严重依赖它。 - 我必须能够解析和创建与将这些字段标记为
0d
. - 我可以随意在 DTD 中进行编辑,例如添加定义的类型
RELATIVE-OID
(但以什么方式?)或用其他东西替换每次出现的RELATIVE-OID
,只要它仍然可以处理将字段标记为0d
. - 我完全可以将
RELATIVE-OID
值作为不透明的斑点bytes
或其他东西,这就是为什么我OCTET STRING
首先尝试了解决方法。
我的 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