ASN.1 tools

buildstatus coverage

About

A Python package for ASN.1 parsing, encoding and decoding.

This project is under development and does only support a subset of the ASN.1 specification syntax.

Codecs under development:

  • Basic Encoding Rules (BER)
  • Distinguished Encoding Rules (DER)
  • JSON Encoding Rules (JER)
  • Aligned Packed Encoding Rules (PER)
  • Unaligned Packed Encoding Rules (UPER)
  • XML Encoding Rules (XER)

Planned codecs:

  • Octet Encoding Rules (OER)

Project homepage: https://github.com/eerimoq/asn1tools

Documentation: http://asn1tools.readthedocs.org/en/latest

Installation

pip install asn1tools

Example Usage

This is an example ASN.1 specification defining the messages of a fictitious Foo protocol (based on the FooProtocol on Wikipedia).

Foo DEFINITIONS ::= BEGIN

    Question ::= SEQUENCE {
        id        INTEGER,
        question  IA5String
    }

    Answer ::= SEQUENCE {
        id        INTEGER,
        answer    BOOLEAN
    }

END

Scripting

Compile the ASN.1 specification, and encode and decode a question using the default codec (BER).

>>> import asn1tools
>>> foo = asn1tools.compile_files('tests/files/foo.asn')
>>> encoded = foo.encode('Question', {'id': 1, 'question': 'Is 1+1=3?'})
>>> encoded
bytearray(b'0\x0e\x02\x01\x01\x16\x09Is 1+1=3?')
>>> foo.decode('Question', encoded)
{'id': 1, 'question': 'Is 1+1=3?'}

The same ASN.1 specification, but using the PER codec.

>>> import asn1tools
>>> foo = asn1tools.compile_files('tests/files/foo.asn', 'per')
>>> encoded = foo.encode('Question', {'id': 1, 'question': 'Is 1+1=3?'})
>>> encoded
bytearray(b'\x01\x01\tIs 1+1=3?')
>>> foo.decode('Question', encoded)
{'id': 1, 'question': 'Is 1+1=3?'}

See the examples folder for additional examples.

Command line tool

Decode given encoded Question using the default codec (BER).

$ asn1tools decode tests/files/foo.asn Question 300e0201011609497320312b313d333f
id: 1
question: Is 1+1=3?
$

Decode given encoded Question using the UPER codec.

$ asn1tools decode --codec uper tests/files/foo.asn Question 01010993cd03156c5eb37e
id: 1
question: Is 1+1=3?
$

Contributing

  1. Fork the repository.

  2. Implement the new feature or bug fix.

  3. Implement test case(s) to ensure that future changes do not break legacy.

  4. Run the tests.

    make test
    
  5. Create a pull request.

Basic Usage

asn1tools.compile_files(filenames, codec='ber', any_defined_by_choices=None)[source]

Compile given ASN.1 specification file(s) and return a Specification object that can be used to encode and decode data structures with given codec codec. codec may be one of 'ber', 'der', jer, 'per', 'uper' and 'xer'.

>>> foo = asn1tools.compile_files('foo.asn')
class asn1tools.compiler.Specification(modules)[source]

This class is used to encode and decode ASN.1 types found in an ASN.1 specification.

Instances of this class are created by the factory functions compile_files(), compile_string() and compile_dict().

types

A dictionary of all types in the specification, or None if a type name was found in two or more modules.

modules

A dictionary of all modules in the specification.

encode(name, data)[source]

Encode given dictionary data as given type name and return the encoded data as a bytes object.

See Types for a mapping table from ASN.1 types to Python types.

>>> foo.encode('Question', {'id': 1, 'question': 'Is 1+1=3?'})
b'0\x0e\x02\x01\x01\x16\x09Is 1+1=3?'
decode(name, data)[source]

Decode given bytes object data as given type name and return the decoded data as a dictionary.

>>> foo.decode('Question', b'0\x0e\x02\x01\x01\x16\x09Is 1+1=3?')
{'id': 1, 'question': 'Is 1+1=3?'}

Types

ASN.1 types are mapped to Python types as shown in the table below.

ASN.1 type Python type Example
BOOLEAN bool True
INTEGER int 87
BIT STRING tuple (b'\x4b', 7)
OCTET STRING bytes b'\x44\x1e\xff'
NULL None
OBJECT IDENTIFIER str '1.33.2'
ObjectDescriptor
REAL float 33.12
ENUMERATED str 'one'
UTF8String str 'hello'
SEQUENCE dict {'a': 52, 'b': 1}
SEQUENCE OF list [1, 3]
SET dict {'foo': 'bar'}
SET OF list [3, 0, 7]
NumericString str '234359'
PrintableString str 'goo'
IA5String str 'name'
UTCTime str '170912120239'
VisibleString str 'gle'

Advanced Usage

asn1tools.compile_string(string, codec='ber', any_defined_by_choices=None)[source]

Compile given ASN.1 specification string and return a Specification object that can be used to encode and decode data structures with given codec codec. codec may be one of 'ber', 'der', jer, 'per', 'uper' and 'xer'.

>>> with open('foo.asn') as fin:
...     foo = asn1tools.compile_string(fin.read())
asn1tools.compile_dict(specification, codec='ber', any_defined_by_choices=None)[source]

Compile given ASN.1 specification dictionary and return a Specification object that can be used to encode and decode data structures with given codec codec. codec may be one of 'ber', 'der', jer, 'per', 'uper' and 'xer'.

>>> foo = asn1tools.compile_dict(asn1tools.parse_files('foo.asn'))
asn1tools.parse_files(filenames)[source]

Parse given ASN.1 specification file(s) and return a dictionary of its/their contents.

>>> foo = asn1tools.parse_files('foo.asn')
asn1tools.parse_string(string)[source]

Parse given ASN.1 specification string and return a dictionary of its contents.

>>> with open('foo.asn') as fin:
...     foo = asn1tools.parse_string(fin.read())