Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
doglman opened this issue May 23, 2023 · 2 comments
Open

Comments

@doglman
Copy link

doglman commented May 23, 2023

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.

@aegirsystems
Copy link

interested to know how you made out with ASN1Tools for J2735 - Doing the same type project now and struggling with the compiler

@doglman
Copy link
Author

doglman commented Oct 19, 2024

I completed my purposes with ASN1Tools. The other ASN compilers I could find were just too hard to get going. I wish you the best outcome for your own project.

When setting up ASN1tools, I encountered an issue with asn1tools's compiler where it does not recognize the RELATIVE-OID base type defined in the ASN.1 standard.

I followed the advice found on StackOverflow. If you encounter this issue, it can be resolved by modifying the offending module, inserting the following line after the definition mentioning a RELATIVE-OID. In our case, this was inside J2735-Common-v6.asn, after line 1541:

-- (Original code definition in the file, i.e. line 1541)
RelativeRoadAuthorityID ::= RELATIVE-OID

-- Insertion necessary for the asn1tools compiler:
RELATIVE-OID ::= [UNIVERSAL 13] IMPLICIT OCTET STRING

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants