]> Cypherpunks.ru repositories - pyderasn.git/blobdiff - doc/examples.rst
copy/pickle friendly Obj
[pyderasn.git] / doc / examples.rst
index 5f76200f7af150f6bc28d2e0f3300cf50afeea8a..6f16af663996897a56056fa5422b6b6b2cec4468 100644 (file)
@@ -177,108 +177,30 @@ We are ready to decode PayPal's certificate from Go `encoding/asn1
 <https://golang.org/pkg/encoding/asn1/>`__ test suite (assuming that
 it's DER encoded representation is already in ``raw`` variable)::
 
-    >>> crt, tail = Certificate().decode(raw)
+    >>> crt = Certificate().decod(raw)
     >>> crt
-    Certificate SEQUENCE[TBSCertificate SEQUENCE[[0] EXPLICIT Version
-        INTEGER v3 OPTIONAL, CertificateSerialNumber INTEGER 61595,
-        AlgorithmIdentifier SEQUENCE[OBJECT IDENTIFIER 1.2.840.113549.1.1.5...
-
-Pretty printing
----------------
-
-There is huge output. Let's pretty print it::
-
-    >>> print(pprint(crt))
-        0   [1,3,1604] Certificate SEQUENCE
-        4   [1,3,1453]  . tbsCertificate: TBSCertificate SEQUENCE
-       10-2 [1,1,   1]  . . version: [0] EXPLICIT Version INTEGER v3 OPTIONAL
-       13   [1,1,   3]  . . serialNumber: CertificateSerialNumber INTEGER 61595
-       18   [1,1,  13]  . . signature: AlgorithmIdentifier SEQUENCE
-       20   [1,1,   9]  . . . algorithm: OBJECT IDENTIFIER 1.2.840.113549.1.1.5
-       31   [0,0,   2]  . . . parameters: [UNIV 5] ANY OPTIONAL
-                        . . . . 05:00
-       33   [0,0, 278]  . . issuer: Name CHOICE rdnSequence
-       33   [1,3, 274]  . . . rdnSequence: RDNSequence SEQUENCE OF
-       37   [1,1,  11]  . . . . 0: RelativeDistinguishedName SET OF
-       39   [1,1,   9]  . . . . . 0: AttributeTypeAndValue SEQUENCE
-       41   [1,1,   3]  . . . . . . type: AttributeType OBJECT IDENTIFIER 2.5.4.6
-       46   [0,0,   4]  . . . . . . value: [UNIV 19] AttributeValue ANY
-                        . . . . . . . 13:02:45:53
-    [...]
-     1461   [1,1,  13]  . signatureAlgorithm: AlgorithmIdentifier SEQUENCE
-     1463   [1,1,   9]  . . algorithm: OBJECT IDENTIFIER 1.2.840.113549.1.1.5
-     1474   [0,0,   2]  . . parameters: [UNIV 5] ANY OPTIONAL
-                        . . . 05:00
-     1476   [1,2, 129]  . signatureValue: BIT STRING 1024 bits
-                        . . 68:EE:79:97:97:DD:3B:EF:16:6A:06:F2:14:9A:6E:CD
-                        . . 9E:12:F7:AA:83:10:BD:D1:7C:98:FA:C7:AE:D4:0E:2C
-     [...]
-
-    Trailing data: 0a
-
-Let's parse that output, human::
+    Certificate SEQUENCE[tbsCertificate: TBSCertificate SEQUENCE[
+        version: [0] EXPLICIT Version INTEGER v3 OPTIONAL;
+        serialNumber: CertificateSerialNumber INTEGER 61595;
+        signature: AlgorithmIdentifier SEQUENCE[OBJECT IDENTIFIER 1.2.840.113549.1.1.5...
 
-       10-2 [1,1,   1]  . . version: [0] EXPLICIT Version INTEGER v3 OPTIONAL
-       ^  ^  ^ ^    ^   ^   ^        ^            ^       ^       ^  ^
-       0  1  2 3    4   5   6        7            8       9       10 11
-
-::
-
-       20   [1,1,   9]  . . . algorithm: OBJECT IDENTIFIER 1.2.840.113549.1.1.5
-       ^     ^ ^    ^   ^     ^          ^                 ^
-       0     2 3    4   5     6          9                 10
-
-::
+:ref:`Look here <pprint_example>` for better pretty printing.
 
-       33   [0,0, 278]  . . issuer: Name CHOICE rdnSequence
-       ^     ^ ^    ^   ^   ^       ^    ^      ^
-       0     2 3    4   5   6       8    9      10
-
-:0:
- Offset of the object, where its DER encoding begins.
- Pay attention that it does **not** include explicit tag.
-:1:
- If explicit tag exists, then this is its length (tag + encoded length).
-:2:
- Length of object's tag. For example CHOICE does not have its own tag,
- so it is zero.
-:3:
- Length of encoded length.
-:4:
- Length of encoded value.
-:5:
- Visual indentation to show the depth of object in the hierarchy.
-:6:
- Object's name inside SEQUENCE/CHOICE.
-:7:
- If either IMPLICIT or EXPLICIT tag is set, then it will be shown
- here. "IMPLICIT" is omitted.
-:8:
- Object's class name, if set. Omitted if it is just an ordinary simple
- value (like with ``algorithm`` in example above).
-:9:
- Object's ASN.1 type.
-:10:
- Object's value, if set. Can consist of multiple words (like OCTET/BIT
- STRINGs above). We see ``v3`` value in Version, because it is named.
- ``rdnSequence`` is the choice of CHOICE type.
-:11:
- Possible other flags like OPTIONAL and DEFAULT, if value equals to the
- default one, specified in the schema.
+.. _cmdline:
 
 As command line utility
 -----------------------
 
-You can decode DER files using command line abilities and get the same
-picture as above by executing::
+You can decode DER/BER files using command line abilities and get the
+same picture as above by executing::
 
-    % python -mpyderasn --schema tests.test_crts:Certificate path/to/file
+    $ python -m pyderasn --schema tests.test_crts:Certificate path/to/file
 
 If there is no schema for you file, then you can try parsing it without,
 but of course IMPLICIT tags will often make it impossible. But result is
 good enough for the certificate above::
 
-    % python -mpyderasn path/to/file
+    $ python -m pyderasn path/to/file
         0   [1,3,1604]  . >: SEQUENCE OF
         4   [1,3,1453]  . . >: SEQUENCE OF
         8   [0,0,   5]  . . . . >: [0] ANY
@@ -307,6 +229,9 @@ good enough for the certificate above::
                         . . . 9E:12:F7:AA:83:10:BD:D1:7C:98:FA:C7:AE:D4:0E:2C
     [...]
 
+Human readable OIDs
+___________________
+
 If you have got dictionaries with ObjectIdentifiers, like example one
 from ``tests/test_crts.py``::
 
@@ -320,7 +245,7 @@ from ``tests/test_crts.py``::
 
 then you can pass it to pretty printer to see human readable OIDs::
 
-    % python -mpyderasn --oids tests.test_crts:some_oids path/to/file
+    $ python -m pyderasn --oids tests.test_crts:some_oids path/to/file
     [...]
        37   [1,1,  11]  . . . . . . >: SET OF
        39   [1,1,   9]  . . . . . . . . >: SEQUENCE OF
@@ -336,21 +261,56 @@ then you can pass it to pretty printer to see human readable OIDs::
        79   [1,1,   9]  . . . . . . . . . . >: PrintableString PrintableString Barcelona
     [...]
 
+Decode paths
+____________
+
+Each decoded element has so-called decode path: sequence of structure
+names it is passing during the decode process. Each element has its own
+unique path inside the whole ASN.1 tree. You can print it out with
+``--print-decode-path`` option::
+
+    $ python -m pyderasn --schema path.to:Certificate --print-decode-path path/to/file
+       0    [1,3,1604]  Certificate SEQUENCE []
+       4    [1,3,1453]   . tbsCertificate: TBSCertificate SEQUENCE [tbsCertificate]
+      10-2  [1,1,   1]   . . version: [0] EXPLICIT Version INTEGER v3 OPTIONAL [tbsCertificate:version]
+      13    [1,1,   3]   . . serialNumber: CertificateSerialNumber INTEGER 61595 [tbsCertificate:serialNumber]
+      18    [1,1,  13]   . . signature: AlgorithmIdentifier SEQUENCE [tbsCertificate:signature]
+      20    [1,1,   9]   . . . algorithm: OBJECT IDENTIFIER 1.2.840.113549.1.1.5 [tbsCertificate:signature:algorithm]
+      31    [0,0,   2]   . . . parameters: [UNIV 5] ANY OPTIONAL [tbsCertificate:signature:parameters]
+                         . . . . 05:00
+      33    [0,0, 278]   . . issuer: Name CHOICE rdnSequence [tbsCertificate:issuer]
+      33    [1,3, 274]   . . . rdnSequence: RDNSequence SEQUENCE OF [tbsCertificate:issuer:rdnSequence]
+      37    [1,1,  11]   . . . . 0: RelativeDistinguishedName SET OF [tbsCertificate:issuer:rdnSequence:0]
+      39    [1,1,   9]   . . . . . 0: AttributeTypeAndValue SEQUENCE [tbsCertificate:issuer:rdnSequence:0:0]
+      41    [1,1,   3]   . . . . . . type: AttributeType OBJECT IDENTIFIER 2.5.4.6 [tbsCertificate:issuer:rdnSequence:0:0:type]
+      46    [0,0,   4]   . . . . . . value: [UNIV 19] AttributeValue ANY [tbsCertificate:issuer:rdnSequence:0:0:value]
+                         . . . . . . . 13:02:45:53
+      46    [1,1,   2]   . . . . . . . DEFINED BY 2.5.4.6: CountryName PrintableString ES [tbsCertificate:issuer:rdnSequence:0:0:value:DEFINED BY 2.5.4.6]
+    [...]
+
+Now you can print only the specified tree, for example signature algorithm::
+
+    $ python -m pyderasn --schema path.to:Certificate --decode-path-only tbsCertificate:signature path/to/file
+      18    [1,1,  13]  AlgorithmIdentifier SEQUENCE
+      20    [1,1,   9]   . algorithm: OBJECT IDENTIFIER 1.2.840.113549.1.1.5
+      31    [0,0,   2]   . parameters: [UNIV 5] ANY OPTIONAL
+                         . . 05:00
+
 Descriptive errors
 ------------------
 
-If you have bad DER, then errors will show you where error occurred::
+If you have bad DER/BER, then errors will show you where error occurred::
 
-    % python -mpyderasn --schema tests.test_crts:Certificate path/to/bad/file
+    $ python -m pyderasn --schema tests.test_crts:Certificate path/to/bad/file
     Traceback (most recent call last):
     [...]
-    pyderasn.DecodeError: UTCTime (tbsCertificate.validity.notAfter.utcTime) (at 328) invalid UTCTime format
+    pyderasn.DecodeError: UTCTime (tbsCertificate:validity:notAfter:utcTime) (at 328) invalid UTCTime format
 
 ::
 
-    % python -mpyderasn path/to/bad/file
+    $ python -m pyderasn path/to/bad/file
     [...]
-    pyderasn.DecodeError: UTCTime (0.SequenceOf.4.SequenceOf.1.UTCTime) (at 328) invalid UTCTime format
+    pyderasn.DecodeError: UTCTime (0:SequenceOf:4:SequenceOf:1:UTCTime) (at 328) invalid UTCTime format
 
 You can see, so called, decode path inside the structures:
 ``tbsCertificate`` -> ``validity`` -> ``notAfter`` -> ``utcTime`` and
@@ -364,9 +324,10 @@ Let's create some simple self-signed X.509 certificate from the ground::
     tbs = TBSCertificate()
     tbs["serialNumber"] = CertificateSerialNumber(10143011886257155224)
 
-    sign_algo_id = AlgorithmIdentifier()
-    sign_algo_id["algorithm"] = ObjectIdentifier("1.2.840.113549.1.1.5")
-    sign_algo_id["parameters"] = Any(Null())
+    sign_algo_id = AlgorithmIdentifier((
+        ("algorithm", ObjectIdentifier("1.2.840.113549.1.1.5")),
+        ("parameters", Any(Null())),
+    ))
     tbs["signature"] = sign_algo_id
 
     rdnSeq = RDNSequence()
@@ -378,24 +339,30 @@ Let's create some simple self-signed X.509 certificate from the ground::
             ("2.5.4.3", PrintableString, "false.example.com"),
             ("1.2.840.113549.1.9.1", IA5String, "false@example.com"),
     ):
-        attr = AttributeTypeAndValue()
-        attr["type"] = AttributeType(oid)
-        attr["value"] = AttributeValue(klass(text))
-        rdn = RelativeDistinguishedName()
-        rdn.append(attr)
-        rdnSeq.append(rdn)
-    issuer = Name()
-    issuer["rdnSequence"] = rdnSeq
+        rdnSeq.append(
+            RelativeDistinguishedName((
+                AttributeTypeAndValue((
+                    ("type", AttributeType(oid)),
+                    ("value", AttributeValue(klass(text))),
+                )),
+            ))
+        )
+    issuer = Name(("rdnSequence", rdnSeq))
     tbs["issuer"] = issuer
     tbs["subject"] = issuer
 
-    validity = Validity()
-    validity["notBefore"] = Time(("utcTime", UTCTime(datetime(2009, 10, 8, 0, 25, 53))))
-    validity["notAfter"] = Time(("utcTime", UTCTime(datetime(2010, 10, 8, 0, 25, 53))))
+    validity = Validity((
+        ("notBefore", Time(
+            ("utcTime", UTCTime(datetime(2009, 10, 8, 0, 25, 53))),
+        )),
+        ("notAfter", Time(
+            ("utcTime", UTCTime(datetime(2010, 10, 8, 0, 25, 53))),
+        )),
+    ))
     tbs["validity"] = validity
 
     spki = SubjectPublicKeyInfo()
-    spki_algo_id = sign_algo_id.copy()
+    spki_algo_id = copy(sign_algo_id)
     spki_algo_id["algorithm"] = ObjectIdentifier("1.2.840.113549.1.1.1")
     spki["algorithm"] = spki_algo_id
     spki["subjectPublicKey"] = BitString(hexdec("".join((
@@ -415,3 +382,54 @@ Let's create some simple self-signed X.509 certificate from the ground::
     crt.encode()
 
 And we will get the same certificate used in Go's library tests.
+
+DEFINED BY fields
+-----------------
+
+Here is only very simple example how you can define Any/OctetString
+fields automatic decoding::
+
+    class AttributeTypeAndValue(Sequence):
+        schema = (
+            ((("type",), AttributeType(defines=((("value",), {
+                id_at_countryName: PrintableString(),
+                id_at_stateOrProvinceName: PrintableString(),
+                id_at_localityName: PrintableString(),
+                id_at_organizationName: PrintableString(),
+                id_at_commonName: PrintableString(),
+            }),)))),
+            ("value", AttributeValue()),
+        )
+
+And when you will try to decode X.509 certificate with it, your pretty
+printer will show::
+
+       34   [0,0, 149]  . . issuer: Name CHOICE rdnSequence
+       34   [1,2, 146]  . . . rdnSequence: RDNSequence SEQUENCE OF
+       37   [1,1,  11]  . . . . 0: RelativeDistinguishedName SET OF
+       39   [1,1,   9]  . . . . . 0: AttributeTypeAndValue SEQUENCE
+       41   [1,1,   3]  . . . . . . type: AttributeType OBJECT IDENTIFIER id-at-countryName (2.5.4.6)
+       46   [0,0,   4]  . . . . . . value: [UNIV 19] AttributeValue ANY
+                        . . . . . . . 13:02:58:58
+       46   [1,1,   2]  . . . . . . . DEFINED BY (2.5.4.6): PrintableString PrintableString XX
+       50   [1,1,  19]  . . . . 1: RelativeDistinguishedName SET OF
+       52   [1,1,  17]  . . . . . 0: AttributeTypeAndValue SEQUENCE
+       54   [1,1,   3]  . . . . . . type: AttributeType OBJECT IDENTIFIER id-at-stateOrProvinceName (2.5.4.8)
+       59   [0,0,  12]  . . . . . . value: [UNIV 19] AttributeValue ANY
+                        . . . . . . . 13:0A:53:6F:6D:65:2D:53:74:61:74:65
+       59   [1,1,  10]  . . . . . . . DEFINED BY (2.5.4.8): PrintableString PrintableString Some-State
+       71   [1,1,  13]  . . . . 2: RelativeDistinguishedName SET OF
+       73   [1,1,  11]  . . . . . 0: AttributeTypeAndValue SEQUENCE
+       75   [1,1,   3]  . . . . . . type: AttributeType OBJECT IDENTIFIER id-at-localityName (2.5.4.7)
+       80   [0,0,   6]  . . . . . . value: [UNIV 19] AttributeValue ANY
+                        . . . . . . . 13:04:43:69:74:79
+       80   [1,1,   4]  . . . . . . . DEFINED BY (2.5.4.7): PrintableString PrintableString City
+       86   [1,1,  33]  . . . . 3: RelativeDistinguishedName SET OF
+       88   [1,1,  31]  . . . . . 0: AttributeTypeAndValue SEQUENCE
+       90   [1,1,   3]  . . . . . . type: AttributeType OBJECT IDENTIFIER id-at-organizationName (2.5.4.10)
+       95   [0,0,  26]  . . . . . . value: [UNIV 19] AttributeValue ANY
+                        . . . . . . . 13:18:49:6E:74:65:72:6E:65:74:20:57:69:64:67:69
+                        . . . . . . . 74:73:20:50:74:79:20:4C:74:64
+       95   [1,1,  24]  . . . . . . . DEFINED BY (2.5.4.10): PrintableString PrintableString Internet Widgits Pty Ltd
+
+:ref:`Read more <definedby>` about that feature.