asn1tools icon indicating copy to clipboard operation
asn1tools copied to clipboard

encode_message() fails to validate ASN.1 BIT STRING SIZE constraints

Open doglman opened this issue 1 year ago • 0 comments

asn1tools has been amazing for the work I have been doing. However, I just resolved an issue that could have been more easily resolved with constraint checking on the part of asn1tools. I am running version 0.166.0

I am working with a set of ASN.1 files contained in the SAE J2735 Message Set Dictionary. I have successfully compiled these files and have been able to encode and decode valid messages from this dictionary. I am using the 'uper' encoding scheme.

I have found the check_constraints parameter of encode_message() to be invaluable at catching the little mistakes I make while attempting to encode messages. For the purposes of this discussion, it has been set to True.

The message I was encoding today is complex (containing several nested data structures), so I will refrain from describing the whole thing here. While trying to encode one particular portion of this message, I found that the entire message would encode without errors, but when decoding it would either produce a asn1tools.codecs.DecodeError exception, or the data following this particular portion of the message would be corrupted.

That particular portion of the message is an ASN.1 BIT STRING. An example of the ASN.1 source code for this string is:

SomeEnumerator ::= BIT STRING {
    valueOne (0),
    valueTwo (1),
    valueThree(2),
    valueFour(3),
    valueFive(4)
    } (SIZE (5))

My Python code looked something like:

return {
    # Get 5 random bits, mask off the most significant bit, convert to bytes, store in tuple
    "someKey": (random.getrandbits(5) & 15).to_bytes(1, 'big'), 4)
}

What I discovered was that when I was assembling my Python object to be encoded by encode_message(), for this particular value I had provided a Tuple (as described in the helpful Types table), but I had entered the wrong integer for the second item in the tuple. I had entered 4, instead of 5, and this was the result of the data corruption, since (according to my assumptions) asn1tools proceeded to pack 4 bits, even though the source code required 5.

Request: As a user, it would be valuable if check_constraints() enforced the ASN.1 SIZE constraint specified in the compiled ASN.1 code, especially if check_constraints=True.

Suggestion: It would also be valuable to have a little more description in the documentation of what that second, integer value inside of the Python tuple for a BIT STRING is intended to be. This could save future users a lot of troubleshooting. For example, when asn1tools processes that tuple, and has to select a portion of the provided bytes, which portion is used? The most significant bits, or the least?

Feel free to reply if I need to provide more information.

doglman avatar May 23 '23 22:05 doglman