| |
| ASN.1 library for Python |
| ------------------------ |
| [](https://pypi.org/project/pyasn1) |
| [](https://pypi.org/project/pyasn1/) |
| [](https://secure.travis-ci.org/etingof/pyasn1) |
| [](https://codecov.io/github/etingof/pyasn1) |
| [](https://raw.githubusercontent.com/etingof/pyasn1/master/LICENSE.txt) |
| |
| This is a free and open source implementation of ASN.1 types and codecs |
| as a Python package. It has been first written to support particular |
| protocol (SNMP) but then generalized to be suitable for a wide range |
| of protocols based on |
| [ASN.1 specification](https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.208-198811-W!!PDF-E&type=items). |
| |
| Features |
| -------- |
| |
| * Generic implementation of ASN.1 types (X.208) |
| * Standards compliant BER/CER/DER codecs |
| * Dumps/loads ASN.1 structures from Python types |
| * 100% Python, works with Python 2.4 up to Python 3.7 |
| * MT-safe |
| * Contributed ASN.1 compiler [Asn1ate](https://github.com/kimgr/asn1ate) |
| |
| Why using pyasn1 |
| ---------------- |
| |
| ASN.1 solves the data serialisation problem. This solution was |
| designed long ago by the wise Ancients. Back then, they did not |
| have the luxury of wasting bits. That is why ASN.1 is designed |
| to serialise data structures of unbounded complexity into |
| something compact and efficient when it comes to processing |
| the data. |
| |
| That probably explains why many network protocols and file formats |
| still rely on the 30+ years old technology. Including a number of |
| high-profile Internet protocols and file formats. |
| |
| Quite a number of books cover the topic of ASN.1. |
| [Communication between heterogeneous systems](http://www.oss.com/asn1/dubuisson.html) |
| by Olivier Dubuisson is one of those high quality books freely |
| available on the Internet. |
| |
| The pyasn1 package is designed to help Python programmers tackling |
| network protocols and file formats at the comfort of their Python |
| prompt. The tool struggles to capture all aspects of a rather |
| complicated ASN.1 system and to represent it on the Python terms. |
| |
| How to use pyasn1 |
| ----------------- |
| |
| With pyasn1 you can build Python objects from ASN.1 data structures. |
| For example, the following ASN.1 data structure: |
| |
| ```bash |
| Record ::= SEQUENCE { |
| id INTEGER, |
| room [0] INTEGER OPTIONAL, |
| house [1] INTEGER DEFAULT 0 |
| } |
| ``` |
| |
| Could be expressed in pyasn1 like this: |
| |
| ```python |
| class Record(Sequence): |
| componentType = NamedTypes( |
| NamedType('id', Integer()), |
| OptionalNamedType( |
| 'room', Integer().subtype( |
| implicitTag=Tag(tagClassContext, tagFormatSimple, 0) |
| ) |
| ), |
| DefaultedNamedType( |
| 'house', Integer(0).subtype( |
| implicitTag=Tag(tagClassContext, tagFormatSimple, 1) |
| ) |
| ) |
| ) |
| ``` |
| |
| It is in the spirit of ASN.1 to take abstract data description |
| and turn it into a programming language specific form. |
| Once you have your ASN.1 data structure expressed in Python, you |
| can use it along the lines of similar Python type (e.g. ASN.1 |
| `SET` is similar to Python `dict`, `SET OF` to `list`): |
| |
| ```python |
| >>> record = Record() |
| >>> record['id'] = 123 |
| >>> record['room'] = 321 |
| >>> str(record) |
| Record: |
| id=123 |
| room=321 |
| >>> |
| ``` |
| |
| Part of the power of ASN.1 comes from its serialisation features. You |
| can serialise your data structure and send it over the network. |
| |
| ```python |
| >>> from pyasn1.codec.der.encoder import encode |
| >>> substrate = encode(record) |
| >>> hexdump(substrate) |
| 00000: 30 07 02 01 7B 80 02 01 41 |
| ``` |
| |
| Conversely, you can turn serialised ASN.1 content, as received from |
| network or read from a file, into a Python object which you can |
| introspect, modify, encode and send back. |
| |
| ```python |
| >>> from pyasn1.codec.der.decoder import decode |
| >>> received_record, rest_of_substrate = decode(substrate, asn1Spec=Record()) |
| >>> |
| >>> for field in received_record: |
| >>> print('{} is {}'.format(field, received_record[field])) |
| id is 123 |
| room is 321 |
| house is 0 |
| >>> |
| >>> record == received_record |
| True |
| >>> received_record.update(room=123) |
| >>> substrate = encode(received_record) |
| >>> hexdump(substrate) |
| 00000: 30 06 02 01 7B 80 01 7B |
| ``` |
| |
| The pyasn1 classes struggle to emulate their Python prototypes (e.g. int, |
| list, dict etc.). But ASN.1 types exhibit more complicated behaviour. |
| To make life easier for a Pythonista, they can turn their pyasn1 |
| classes into Python built-ins: |
| |
| ```python |
| >>> from pyasn1.codec.native.encoder import encode |
| >>> encode(record) |
| {'id': 123, 'room': 321, 'house': 0} |
| ``` |
| |
| Or vice-versa -- you can initialize an ASN.1 structure from a tree of |
| Python objects: |
| |
| ```python |
| >>> from pyasn1.codec.native.decoder import decode |
| >>> record = decode({'id': 123, 'room': 321, 'house': 0}, asn1Spec=Record()) |
| >>> str(record) |
| Record: |
| id=123 |
| room=321 |
| >>> |
| ``` |
| |
| With ASN.1 design, serialisation codecs are decoupled from data objects, |
| so you could turn every single ASN.1 object into many different |
| serialised forms. As of this moment, pyasn1 supports BER, DER, CER and |
| Python built-ins codecs. The extremely compact PER encoding is expected |
| to be introduced in the upcoming pyasn1 release. |
| |
| More information on pyasn1 APIs can be found in the |
| [documentation](http://snmplabs.com/pyasn1/), |
| compiled ASN.1 modules for different protocols and file formats |
| could be found in the pyasn1-modules |
| [repo](https://github.com/etingof/pyasn1-modules). |
| |
| How to get pyasn1 |
| ----------------- |
| |
| The pyasn1 package is distributed under terms and conditions of 2-clause |
| BSD [license](http://snmplabs.com/pyasn1/license.html). Source code is freely |
| available as a GitHub [repo](https://github.com/etingof/pyasn1). |
| |
| You could `pip install pyasn1` or download it from [PyPI](https://pypi.org/project/pyasn1). |
| |
| If something does not work as expected, |
| [open an issue](https://github.com/etingof/pyasn1/issues) at GitHub or |
| post your question [on Stack Overflow](https://stackoverflow.com/questions/ask) |
| or try browsing pyasn1 |
| [mailing list archives](https://sourceforge.net/p/pyasn1/mailman/pyasn1-users/). |
| |
| Copyright (c) 2005-2019, [Ilya Etingof](mailto:etingof@gmail.com). |
| All rights reserved. |