pyasn1 vs indefinite-length structures

570 views Asked by At

Is it a bug that pyasn1 cannot parse unaided (without defining a new type) the indefinite-length constructed data described in the code snippet below, or is my example not valid BER-encoded ASN.1?

If pyasn1 can't handle this without help, is there another python library I could turn to?


# e7 80       : private, constructed, tag 7, indefinite length
#    02 01 44 : integer 0x44
#    02 01 55 : integer 0x55
#    00 00    : end of contents (terminating the 0xe7 object)
data = 'e7 80 02 01 44 02 01 55 00 00'

data = binascii.unhexlify( ''.join(data.split()) )

# throws pyasn1.error.PyAsn1Error: Missing end-of-octets terminator
pyasn1.codec.ber.decoder.decode(data)
2

There are 2 answers

0
YaFred On BEST ANSWER

Your example is perfectly valid (BER encoding)

You can even use https://asn1.io/asn1playground/ to prove that

Compile following schema:

Schema DEFINITIONS EXPLICIT TAGS ::= 
BEGIN
  ASequence::= [PRIVATE 7] IMPLICIT SEQUENCE       
  {                                                     
    num1 INTEGER,
    num2 INTEGER
  }                                                     
END

And decode e7 80 02 01 44 02 01 55 00 00

Result will be:

> OSS ASN-1Step Version 9.0.1 Copyright (C) 2019 OSS Nokalva, Inc.  All
> rights reserved. This product is licensed for use by "OSS Nokalva,
> Inc."
> 
> C0043I: 0 error messages, 0 warning messages and 0 informatory
> messages issued.
> 
> 
> ASN1STEP: Decoding PDU #1 :
> 
> ASequence SEQUENCE: tag = [PRIVATE 7] constructed; length = indef  
> num1 INTEGER: tag = [UNIVERSAL 2] primitive; length = 1
>     68   
> num2 INTEGER: tag = [UNIVERSAL 2] primitive; length = 1
>     85 
> EOC 
> Successfully decoded 10 bytes. rec1value ASequence ::=  {   num1 68,   num2 85 }

Note that you don't need a schema to decode that (you would just loose the semantic)

You will want insight from pyasn1. Try opening an issue here: https://github.com/etingof/pyasn1/issues

1
CryptoFool On

Your example data appears to be malformed. I don't know the details, but it seems to involve the first byte of your data, 'e7'. I understand this to be the "type" of the message. It seem that this type must expect more data than you're giving it.

I see examples that use '30' as the first byte, representing a "sequence". These examples are formatted much like yours. So I tried replacing 'e7' with '30' in your example data, and with this change, your code runs without errors.

To be clear in what I'm saying, this code runs for me without errors:

# 30 80       : sequence, indefinite length
#    02 01 44 : integer 0x44
#    02 01 55 : integer 0x55
#    00 00    : end of contents (terminating the 0x30 object)
data = '30 80 02 01 44 02 01 55 00 00'

data = binascii.unhexlify( ''.join(data.split()) )

# throws pyasn1.error.PyAsn1Error: Missing end-of-octets terminator
pyasn1.codec.ber.decoder.decode(data)

I believe that this shows you that your code is "correct". I wish I knew more about this stuff so I could be more help, like to explain to you whatn the "e7" type is all about. Without that, I hope this is still helpful.