I’m trying to use the asn1tools
Python library to decode and encode BER messages conforming to the Ember+ standard.
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). Which is why I can’t use that DTD in my Python program. But I really have to.
My options, as I see them, are to either create a patched version of pyasn1
with the RELATIVE-OID
PR included and make asn1tools
work with it, or to somehow build a workaround in the DTD.
I’ve already tried adding RELATIVE-OID ::= [UNIVERSAL 13] OCTET STRING
to the DTD, but now asn1tools
responds with Expected RELATIVE-OID with tag '2d' at offset 10, but got '0d'.
Basically it seems to accept my definition, but makes it “universal constructed 13” while the message tags it as “universal primitive 13”.
Is there a way for me to work around this?
Here are my constraints:
asn1tools
, my code is already heavily depending on it.0d
.RELATIVE-OID
(but in what way?) or replacing every occurrence of RELATIVE-OID
with something else, as long as it will still work with the messages that tag the fields as 0d
.RELATIVE-OID
value as an opaque blob of bytes
or something, which is why I’ve tried the OCTET STRING
workaround in the first place.My ASN.1 knowledge is limited and I’m not proficient in writing DTDs. Maybe there’s a way to force the type to being “primitive”? I’m happy for any suggestions. If you’d like to try it out for yourself, use the DTD linked above. Then, use the following Python code:
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
Try
RELATIVE-OID ::= [UNIVERSAL 13] IMPLICIT OCTET STRING