• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
2.. _pyasn1:
3
4Library documentation
5=====================
6
7As of this moment, pyasn1 library implements all ASN.1 data
8types as Python objects in accordance with X.208 standard. Later,
9post-1995, revision (X.680) introduced some changes to the schema
10language which may not be fully supported by pyasn1. Aside from data
11types a collection of data transformation codecs comes with the
12pyasn1 package.
13
14As for ASN.1 schema language, pyasn1 package does
15not ship any compiler for it. However, there's a tool called
16`asn1late <https://github.com/kimgr/asn1ate>`_ which is an ASN.1
17grammar parser paired to code generator capable of generating pyasn1
18code. So this is an alternative (or at least a good start) to manual
19implementation of pyasn1 classes from ASN.1 specification.
20
21Both `pyasn1 <https://github.com/etingof/pyasn1>`_ and
22`pyasn1-modules <https://github.com/etingof/pyasn1-modules>`_ libraries
23can be used out-of-the-box with Python versions 2.4 through 3.7.
24No external dependencies required.
25
26.. _pyasn1-types:
27
28ASN.1 types
29-----------
30
31The ASN.1 data description
32`language <https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.208-198811-W!!PDF-E&type=items>`_
33defines a handful of built-in data types. ASN.1 types exhibit different
34semantics (e.g. number vs string) and can be distinguished from each other by
35:ref:`tags <type.tag>`.
36
37Subtypes can be created on top of base ASN.1 types by adding/overriding the
38:ref:`tags <type.tag>` and/or imposing additional
39:ref:`constraints <type.constraint>` on accepted values.
40
41ASN.1 types in pyasn1 are Python objects. One or more ASN.1 types
42comprise a *schema* describing data structures of unbounded complexity.
43
44.. code-block:: python
45
46   class RSAPublicKey(Sequence):
47       """
48       ASN.1 specification:
49
50       RSAPublicKey ::= SEQUENCE {
51           modulus           INTEGER,  -- n
52           publicExponent    INTEGER   -- e
53       }
54       """
55       componentType = NamedTypes(
56           NamedType('modulus', Integer()),
57           NamedType('publicExponent', Integer())
58       )
59
60ASN.1 schema can be "instantiated" by essentially putting some concrete value
61into the type container. Such instantiated schema object can still be
62used as a schema, but additionally it can play a role of a value in the
63context of any applicable operator (e.g. arithmetic etc.).
64
65.. code-block:: python
66
67   rsaPublicKey = RSAPublicKey()
68
69   # ASN.1 SEQUENCE type quacks like Python dict
70   rsaPublicKey['modulus'] = 280789907761334970323210643584308373
71   rsaPublicKey['publicExponent'] = 65537
72
73Main use of ASN.1 schemas is to guide data transformation. Instantiated
74ASN.1 schemas carry concrete data to/from data transformation services.
75
76.. _isValue:
77
78To tell instantiated schema object from just a schema, the *.isValue*
79property can come in handy:
80
81.. code-block:: python
82
83   schema = RSAPublicKey()
84
85   # non-instantiated schema
86   assert schema.isValue == False
87
88   rsaPublicKey['modulus'] = 280789907761334970323210643584308373
89
90   # partially instantiated schema
91   assert schema['modulus'].isValue == True
92   assert schema.isValue == False
93
94   rsaPublicKey['publicExponent'] = 65537
95
96   # fully instantiated schema
97   assert schema.isValue == True
98
99Copies of existing ASN.1 types can be created with *.clone()* method.
100All the existing properties of the prototype ASN.1 object get copied
101over the new type unless the replacements are given. Main use-case
102for *.clone()* is to instantiate a schema.
103
104.. _clone:
105
106.. code-block:: python
107
108   instantiated_schema_A = Integer(1)
109
110   # ASN.1 INTEGER type quacks like Python int
111   assert instantiated_schema_A == 1
112
113   instantiated_schema_B = instantiated_schema_A.clone(2)
114
115   assert instantiated_schema_B == 2
116
117.. _subtype:
118
119New ASN.1 types can be created on top of existing ASN.1 types with
120the *subtype()* method. Desired properties of the new type get
121merged with the corresponding properties of the old type. Main use-case
122for *.subtype()* is to assemble new ASN.1 types by :ref:`tagging <type.tag>`
123or applying additional :ref:`constraints <type.constraint>` to accepted
124type's values.
125
126.. code-block:: python
127
128   parent_type_schema = Integer()
129
130   child_type_schema = parent_type_schema.subtype(
131       explicitTag=Tag(tag.tagClassApplication, tag.tagFormatSimple, 0x06)
132   )
133
134   # test ASN.1 type relationships
135   assert child_type_schema.isSubtypeOf(parent_type_schema) == True
136   assert child_type_schema.isSameTypeWith(parent_type_schema) == False
137
138
139.. toctree::
140   :maxdepth: 2
141
142   /pyasn1/type/base/contents
143   /pyasn1/type/univ/contents
144   /pyasn1/type/char/contents
145   /pyasn1/type/useful/contents
146
147ASN.1 type harness
148++++++++++++++++++
149
150The identification and behaviour of ASN.1 types is determined by
151:ref:`tags <type.tag>` and :ref:`constraints <type.constraint>`.
152The inner structure of *constructed* ASN.1 types is defined by
153its :ref:`fields <type.namedtype>` specification.
154
155.. toctree::
156   :maxdepth: 2
157
158   /pyasn1/type/tag/contents
159   /pyasn1/type/constraint/contents
160   /pyasn1/type/namedtype/contents
161   /pyasn1/type/opentype/contents
162   /pyasn1/type/namedval/contents
163
164.. _pyasn1-codecs:
165
166Serialisation codecs
167--------------------
168
169Common use-case for pyasn1 is to instantiate ASN.1 schema with
170user-supplied values and pass instantiated schema to the encoder.
171The encoder will then turn the data structure into serialised form
172(stream of bytes) suitable for storing into a file or sending over
173the network.
174
175.. code-block:: python
176
177    value = 1
178    instantiated_schema = Integer(value)
179
180    serialised = encode(instantiated_schema)
181
182Alternatively, value and schema can be passed separately:
183
184.. code-block:: python
185
186    value = 1
187    schema = Integer()
188
189    serialised = encode(value, asn1Spec=schema)
190
191At the receiving end, a decoder would be invoked and given the
192serialised data as received from the network along with the ASN.1
193schema describing the layout of the data structures. The outcome
194would be an instance of ASN.1 schema filled with values as supplied
195by the sender.
196
197.. code-block:: python
198
199    serialised = b'\x01\x01\x01'
200    schema = Integer()
201
202    value, _ = decode(serialised, asn1Spec=schema)
203
204    assert value == 1
205
206Many distinct serialisation protocols exist for ASN.1, some are
207implemented in pyasn1.
208
209.. toctree::
210   :maxdepth: 2
211
212   /pyasn1/codec/ber/contents
213   /pyasn1/codec/cer/contents
214   /pyasn1/codec/der/contents
215   /pyasn1/codec/native/contents
216
217Exceptions
218----------
219
220Operations on PyASN1 schema and value objects might cause errors. These
221errors are manifested to the caller in form of Python exceptions.
222
223The exception hierarchy is as follows (ordered from least specific).
224
225.. toctree::
226   :maxdepth: 2
227
228   /pyasn1/error/contents
229