asn1tools
asn1tools is a Python package for ASN.1 parsing, encoding, and decoding. It provides functionality to compile ASN.1 specifications and then encode and decode data using various encoding rules such as Basic Encoding Rules (BER), Distinguished Encoding Rules (DER), Packed Encoding Rules (PER), Unaligned Packed Encoding Rules (UPER), and XML Encoding Rules (XER), among others. The library is currently at version 0.167.0 and is actively maintained with frequent releases addressing bug fixes and performance improvements.
Warnings
- gotcha asn1tools only supports a subset of the full ASN.1 specification syntax. Known unsupported features include the CLASS keyword (X.681), Parametrization (X.683), EMBEDDED PDV, ANY/ANY DEFINED BY types, WITH COMPONENT/WITH COMPONENTS constraints (except for OER REAL), and the DURATION type. Recursive types are also not supported.
- gotcha When encoding or decoding, setting `check_constraints=False` will skip validation against ASN.1 type constraints. While this can minimize runtime overhead, it allows the processing of values that do not fulfill the constraints, potentially leading to `DecodeError` exceptions or data corruption later on if the data is malformed.
- breaking Version 0.156.0 introduced support for decoding BER SET and SEQUENCE OF members in any order. Prior to this version, implementations might have relied on a specific order, and decoding data with out-of-order members could have failed or yielded incorrect results.
- gotcha The C code generator for OER and UPER has specific limitations, including support only for BOOLEAN, INTEGER, NULL, OCTET STRING, BIT STRING, ENUMERATED, SEQUENCE, SEQUENCE OF, and CHOICE types. All types must have a known maximum size (e.g., INTEGER (0..7)), INTEGERs must be 64 bits or less, and REAL types must be IEEE 754 binary32 or binary64. Extension additions (...) are only supported in the OER generator.
Install
-
pip install asn1tools
Imports
- asn1tools
import asn1tools
Quickstart
import asn1tools
import os
import tempfile
# Define an example ASN.1 specification
asn1_spec = """
Foo DEFINITIONS ::= BEGIN
Question ::= SEQUENCE {
id INTEGER,
question IA5String
}
Answer ::= SEQUENCE {
id INTEGER,
answer BOOLEAN
}
END
"""
# Create a temporary .asn file for the specification
with tempfile.NamedTemporaryFile(mode='w', suffix='.asn', delete=False) as f:
f.write(asn1_spec)
asn_filepath = f.name
try:
# Compile the ASN.1 specification using the default BER codec
# You can specify other codecs like 'per', 'uper', 'xer', etc.
foo = asn1tools.compile_files(asn_filepath, 'ber')
# Encode a Question message
question_data = {'id': 1, 'question': 'Is 1+1=3?'}
encoded_question = foo.encode('Question', question_data)
print(f"Encoded (BER): {encoded_question.hex()}")
# Decode the Question message
decoded_question = foo.decode('Question', encoded_question)
print(f"Decoded: {decoded_question}")
# Example with another message type (Answer)
answer_data = {'id': 1, 'answer': False}
encoded_answer = foo.encode('Answer', answer_data)
print(f"Encoded Answer (BER): {encoded_answer.hex()}")
decoded_answer = foo.decode('Answer', encoded_answer)
print(f"Decoded Answer: {decoded_answer}")
finally:
# Clean up the temporary file
os.remove(asn_filepath)