Examples¶
Dump¶
This command line utility reads a X509.v3 certificate (in DER or PEM encoding), decodes it and outputs a textual representation. It more or less mimics openssl asn1parse:
$ python examples/dump.py examples/test.crt
[U] SEQUENCE
[U] SEQUENCE
[C] 0x0
[U] INTEGER: 2
[U] INTEGER: 5424
[U] SEQUENCE
[U] OBJECT: 1.2.840.113549.1.1.5
[U] NULL: None
[U] SEQUENCE
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.6
[U] PRINTABLESTRING: --
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.8
[U] PRINTABLESTRING: SomeState
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.7
[U] PRINTABLESTRING: SomeCity
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.10
[U] PRINTABLESTRING: SomeOrganization
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.11
[U] PRINTABLESTRING: SomeOrganizationalUnit
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.3
[U] PRINTABLESTRING: localhost.localdomain
[U] SET
[U] SEQUENCE
[U] OBJECT: 1.2.840.113549.1.9.1
[U] IA5STRING: root@localhost.localdomain
[U] SEQUENCE
[U] UTCTIME: 080205092331Z
[U] UTCTIME: 090204092331Z
[U] SEQUENCE
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.6
[U] PRINTABLESTRING: --
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.8
[U] PRINTABLESTRING: SomeState
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.7
[U] PRINTABLESTRING: SomeCity
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.10
[U] PRINTABLESTRING: SomeOrganization
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.11
[U] PRINTABLESTRING: SomeOrganizationalUnit
[U] SET
[U] SEQUENCE
[U] OBJECT: 2.5.4.3
[U] PRINTABLESTRING: localhost.localdomain
[U] SET
[U] SEQUENCE
[U] OBJECT: 1.2.840.113549.1.9.1
[U] IA5STRING: root@localhost.localdomain
[U] SEQUENCE
[U] SEQUENCE
[U] OBJECT: 1.2.840.113549.1.1.1
[U] NULL: None
[U] BIT STRING: 0xb'0030818902818100D51...10610203010001'
[C] BIT STRING
[U] SEQUENCE
[U] SEQUENCE
[U] OBJECT: 2.5.29.14
[U] OCTET STRING: 0xb'04140A4BFA8754177E30B4217156510FD291C3300236'
[U] SEQUENCE
[U] OBJECT: 2.5.29.35
[U] OCTET STRING: 0xb'3081DE80140A4...D61696E82021530'
[U] SEQUENCE
[U] OBJECT: 2.5.29.19
[U] OCTET STRING: 0xb'30030101FF'
[U] SEQUENCE
[U] OBJECT: 1.2.840.113549.1.1.5
[U] NULL: None
[U] BIT STRING: 0xb'004E124658A357C59AABFA3...8A6245C7FC58B45A'
The main function is pretty_print
:
1def pretty_print(input_stream, output_stream, indent=0):
2 """Pretty print ASN.1 data."""
3 while not input_stream.eof():
4 tag = input_stream.peek()
5 if tag.typ == asn1.Types.Primitive:
6 tag, value = input_stream.read()
7 output_stream.write(' ' * indent)
8 output_stream.write('[{}] {}: {}\n'.format(class_id_to_string(tag.cls),
9 tag_id_to_string(tag.nr), value_to_string(tag.nr, value)))
10 elif tag.typ == asn1.Types.Constructed:
11 output_stream.write(' ' * indent)
12 output_stream.write('[{}] {}\n'.format(class_id_to_string(tag.cls),
13 tag_id_to_string(tag.nr)))
14 input_stream.enter()
15 pretty_print(input_stream, output_stream, indent + 2)
16 input_stream.leave()
This code:
line 3: Loops until its reaches the end of the input stream (with
Decoder.eof()
).line 4: Looks (with
Decoder.peek()
) at the current tag.line 5: If the tag is primitive (
TypePrimitive
) …line 6: … the code reads (with
Decoder.read()
) the current tag.line 8: Then it displays its number and value (after some mapping to be more user-fiendly).
line 10: If the tag is constructed (
TypeConstructed
) …line 12: … the code displays its class and number.
line 14: Then it enters inside the tag and …
line 15: … calls itself recursively to decode the ASN.1 tags inside.
line 16: Leaves the current constructed tag (with
Decoder.leave()
) to continue the decoding of its siblings.