Skip to content

Commit 6bd3381

Browse files
committed
Update doc
1 parent fe8e488 commit 6bd3381

2 files changed

Lines changed: 185 additions & 52 deletions

File tree

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ include *.ini
2222
include *.yml
2323
include *.yaml
2424

25-
global-exclude *.py[cod] __pycache__ *.so *.dylib .DS_Store
25+
global-exclude *.py[cod] __pycache__ *.so *.dylib .DS_Store .mypy_cache
2626
exclude .python-version

docs/usage.rst

Lines changed: 184 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -21,35 +21,70 @@ constructed data types. Primitive data types can be encoded and decoded
2121
directly with `read()` and `write()` methods. For these types, ASN.1 types are
2222
mapped directly to Python types and vice versa, as per the table below:
2323

24-
================ ================= =============
25-
ASN.1 type Python type Default
26-
================ ================= =============
27-
Boolean bool yes
28-
Integer int yes
29-
OctetString bytes yes
30-
PrintableString str yes
31-
Null None yes
32-
ObjectIdentifier bytes no
33-
Enumerated int no
34-
================ ================= =============
35-
36-
The column **default** is relevant for encoding only. Because
37-
ASN.1 has more data types than Python, the situation arises that one Python
38-
type corresponds to multiple ASN.1 types. In this sitution the to be encoded
24+
================ ========== =========== =============
25+
ASN.1 type Tag Number Decoding Encoding
26+
================ ========== =========== =============
27+
Boolean 0x01 bool bool
28+
Integer 0x02 int int
29+
Null 0x05 None None
30+
ObjectIdentifier 0x06 str
31+
Real 0x09 float float
32+
Enumerated 0x0A int
33+
UTCTime 0x17
34+
GeneralizedTime 0x18
35+
Date 0x1F
36+
TimeOfDay 0x20
37+
DateTime 0x21
38+
Duration 0x22
39+
================ ========== =========== =============
40+
41+
Because ASN.1 has more data types than Python, the situation arises that one Python
42+
type corresponds to multiple ASN.1 types. In this situation, the to be encoded
3943
ASN.1 type cannot be determined from the Python type. The solution
4044
implemented in Python-ASN1 is that the most frequently used type will be the
41-
implicit default, and if another type is desired than that must be specified
45+
implicit default. This is indicated in the `Encoding` column.
46+
If another type is desired than that must be specified
4247
explicitly through the API.
4348

44-
For constructed types, no type mapping is done at all, even for types where
45-
such a mapping would be possible such as the ASN.1 type **sequence
46-
of** which could be mapped to a Python list. For such types a stack
47-
based approach is used instead. In this approach, the user needs to
48-
explicitly enter/leave the constructed type using the
49+
Some ASN.1 types can be either primitive or constructed. They can be encoded
50+
and decoded like primitive types. The following table shows the mapping between
51+
ASN.1 types and Python types.
52+
53+
================ ========== =========== =============
54+
ASN.1 type Tag Number Decoding Encoding
55+
================ ========== =========== =============
56+
BitString 0x03 bytes
57+
OctetString 0x04 bytes bytes
58+
UTF8String 0x0C str
59+
NumericString 0x12 str
60+
PrintableString 0x13 str str
61+
T61String 0x14 str
62+
VideotextString 0x15 str
63+
IA5String 0x16 str
64+
GraphicString 0x19 str
65+
VisibleString 0x1A str
66+
GeneralString 0x1B str
67+
UniversalString 0x1C str
68+
CharacterString 0x1D str
69+
UnicodeString 0x1E str
70+
================ ========== =========== =============
71+
72+
For constructed types, there are two possibilities. The first is to treat them
73+
as a sequence of types. In this case, the encoder and decoder will automatically
74+
map the ASN.1 types to Python types and vice versa.
75+
76+
================ ========== =========== =============
77+
ASN.1 type Tag Number Decoding Encoding
78+
================ ========== =========== =============
79+
Sequence 0x10 list list
80+
Set 0x11 list
81+
================ ========== =========== =============
82+
83+
The second possibility is to treat them as a stack of types. In this approach,
84+
the user needs to explicitly enter/leave the constructed type using the
4985
`Encoder.enter()` and `Encoder.leave()` methods of the encoder and the
5086
`Decoder.enter()` and `Decoder.leave()` methods of the decoder.
5187

52-
5388
Encoding
5489
--------
5590

@@ -61,9 +96,56 @@ If you want to encode data and retrieve its DER-encoded representation, use code
6196
6297
encoder = asn1.Encoder()
6398
encoder.start()
64-
encoder.write('1.2.3', asn1.ObjectIdentifier)
99+
encoder.write('1.2.3', asn1.Numbers.ObjectIdentifier)
65100
encoded_bytes = encoder.output()
66101
102+
It is also possible to encode data directly to a file or any stream:
103+
104+
.. code-block:: python
105+
106+
import asn1
107+
108+
with open('output.der', 'wb') as f:
109+
encoder = asn1.Encoder()
110+
encoder.start(f)
111+
encoder.write('1.2.3', asn1.Numbers.ObjectIdentifier)
112+
113+
You can encode complex data structures such as sequences and sets:
114+
115+
.. code-block:: python
116+
117+
import asn1
118+
119+
with open('output.der', 'wb') as f:
120+
encoder = asn1.Encoder()
121+
encoder.start(f)
122+
encoder.write(['test1', 'test2', [
123+
1,
124+
0.125,
125+
b'\x01\x02\x03'
126+
]])
127+
128+
ASN.1 types are automatically mapped to Python types.
129+
If you want to precisely specify the ASN.1 type, you have to use the `Encoder.enter()` and `Encoder.leave()` methods:
130+
131+
.. code-block:: python
132+
133+
import asn1
134+
135+
with open('output.der', 'wb') as f:
136+
encoder = asn1.Encoder()
137+
encoder.start(f)
138+
encoder.enter(asn1.Numbers.Sequence)
139+
encoder.write('test1', asn1.Numbers.PrintableString)
140+
encoder.write('test2', asn1.Numbers.PrintableString)
141+
encoder.enter(asn1.Numbers.Sequence)
142+
encoder.write(1, asn1.Numbers.Integer)
143+
encoder.write(0.125, asn1.Numbers.Real)
144+
encoder.write(b'\x01\x02\x03', asn1.Numbers.OctetString)
145+
encoder.leave()
146+
encoder.leave()
147+
148+
This also allows to encode data progressively, without having to keep everything in memory.
67149

68150
Decoding
69151
--------
@@ -78,54 +160,105 @@ If you want to decode ASN.1 from DER or BER encoded bytes, use code such as:
78160
decoder.start(encoded_bytes)
79161
tag, value = decoder.read()
80162
163+
It is also possible to decode data directly from a file or any stream:
164+
165+
.. code-block:: python
166+
167+
import asn1
168+
169+
with open('input.der', 'rb') as f:
170+
decoder = asn1.Decoder()
171+
decoder.start(f)
172+
tag, value = decoder.read()
173+
174+
You can decode complex data structures. The decoder will automatically map ASN.1 types to Python types:
175+
176+
.. code-block:: python
177+
178+
import asn1
179+
180+
with open('example7.der', 'rb') as f:
181+
decoder = asn1.Decoder()
182+
decoder.start(f)
183+
tag, value = decoder.read()
184+
print(tag)
185+
pprint.pprint(value)
81186
82187
Constants
83188
---------
84189

85190
A few constants are defined in the `asn1` module. The
86-
constants immediately below correspond to ASN.1 numbers. They can be used as
191+
constants immediately below correspond to ASN.1 tag numbers.
192+
They can be used as
87193
the ``nr`` parameter of the
88194
`Encoder.write()` method, and are returned as the
89195
first part of a ``(nr, typ, cls)`` tuple as returned by
90196
`Decoder.peek()` and
91197
`Decoder.read()`.
92198

93-
================ ===========
94-
Constant Value (hex)
95-
================ ===========
96-
Boolean 0x01
97-
Integer 0x02
98-
OctetString 0x04
99-
Null 0x05
100-
ObjectIdentifier 0x06
101-
Enumerated 0x0a
102-
Sequence 0x10
103-
Set 0x11
104-
================ ===========
199+
==================================== ===========
200+
Constant Value (hex)
201+
==================================== ===========
202+
Numbers.Boolean 0x01
203+
Numbers.Integer 0x02
204+
Numbers.BitString 0x03
205+
Numbers.OctetString 0x04
206+
Numbers.Null 0x05
207+
Numbers.ObjectIdentifier 0x06
208+
Numbers.ObjectDescriptor 0x07
209+
Numbers.External 0x08
210+
Numbers.Real 0x09
211+
Numbers.Enumerated 0x0a
212+
Numbers.EmbeddedPDV 0x0b
213+
Numbers.UTF8String 0x0c
214+
Numbers.RelativeOID 0x0d
215+
Numbers.Time 0x0e
216+
Numbers.Sequence 0x10
217+
Numbers.Set 0x11
218+
Numbers.NumericString 0x12
219+
Numbers.PrintableString 0x13
220+
Numbers.T61String 0x14
221+
Numbers.VideotextString 0x15
222+
Numbers.IA5String 0x16
223+
Numbers.UTCTime 0x17
224+
Numbers.GeneralizedTime 0x18
225+
Numbers.GraphicString 0x19
226+
Numbers.VisibleString 0x1a
227+
Numbers.GeneralString 0x1b
228+
Numbers.UniversalString 0x1c
229+
Numbers.CharacterString 0x1d
230+
Numbers.UnicodeString 0x1e
231+
Numbers.Date 0x1f
232+
Numbers.TimeOfDay 0x20
233+
Numbers.DateTime 0x21
234+
Numbers.Duration 0x22
235+
Numbers.OIDinternationalized 0x23
236+
Numbers.RelativeOIDinternationalized 0x24
237+
==================================== ===========
105238

106239
The following constants define the two available encoding types (primitive
107240
and constructed) for ASN.1 data types. As above they can be used with the
108241
`Encoder.write()` and are returned by
109242
`Decoder.peek()` and
110243
`Decoder.read()`.
111244

112-
================ ===========
113-
Constant Value (hex)
114-
================ ===========
115-
TypeConstructed 0x20
116-
TypePrimitive 0x00
117-
================ ===========
245+
================== ===========
246+
Constant Value (hex)
247+
================== ============
248+
Types.Constructed 0x20
249+
Types.Primitive 0x00
250+
================== ===========
118251

119-
Finally the constants below define the different ASN.1 classes. As above
252+
Finally the constants below define the different ASN.1 classes. As above
120253
they can be used with the `Encoder.write()` and are
121254
returned by `Decoder.peek()` and
122255
`Decoder.read()`.
123256

124-
================ ===========
125-
Constant Value (hex)
126-
================ ===========
127-
ClassUniversal 0x00
128-
ClassApplication 0x40
129-
ClassContext 0x80
130-
ClassPrivate 0xc0
131-
================ ===========
257+
=================== ===========
258+
Constant Value (hex)
259+
=================== ===========
260+
Classes.Universal 0x00
261+
Classes.Application 0x40
262+
Classes.Context 0x80
263+
Classes.Private 0xc0
264+
=================== ===========

0 commit comments

Comments
 (0)