• 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.6.
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/univ/contents
143   /pyasn1/type/char/contents
144   /pyasn1/type/useful/contents
145
146ASN.1 type harness
147++++++++++++++++++
148
149The identification and behaviour of ASN.1 types is determined by
150:ref:`tags <type.tag>` and :ref:`constraints <type.constraint>`.
151The inner structure of *constructed* ASN.1 types is defined by
152its :ref:`fields <type.namedtype>` specification.
153
154.. toctree::
155   :maxdepth: 2
156
157   /pyasn1/type/tag/contents
158   /pyasn1/type/constraint/contents
159   /pyasn1/type/namedtype/contents
160   /pyasn1/type/opentype/contents
161   /pyasn1/type/namedval/contents
162
163.. _pyasn1-codecs:
164
165Serialisation codecs
166--------------------
167
168Common use-case for pyasn1 is to instantiate ASN.1 schema with
169user-supplied values and pass instantiated schema to the encoder.
170The encoder will then turn the data structure into serialised form
171(stream of bytes) suitable for storing into a file or sending over
172the network.
173
174.. code-block:: python
175
176    value = 1
177    instantiated_schema = Integer(value)
178
179    serialised = encode(instantiated_schema)
180
181Alternatively, value and schema can be passed separately:
182
183.. code-block:: python
184
185    value = 1
186    schema = Integer()
187
188    serialised = encode(value, asn1Spec=schema)
189
190At the receiving end, a decoder would be invoked and given the
191serialised data as received from the network along with the ASN.1
192schema describing the layout of the data structures. The outcome
193would be an instance of ASN.1 schema filled with values as supplied
194by the sender.
195
196.. code-block:: python
197
198    serialised = b'\x01\x01\x01'
199    schema = Integer()
200
201    value, _ = decode(serialised, asn1Spec=schema)
202
203    assert value == 1
204
205Many distinct serialisation protocols exist for ASN.1, some are
206implemented in pyasn1.
207
208.. toctree::
209   :maxdepth: 2
210
211   /pyasn1/codec/ber/contents
212   /pyasn1/codec/cer/contents
213   /pyasn1/codec/der/contents
214   /pyasn1/codec/native/contents
215