]> Cypherpunks.ru repositories - pyderasn.git/blobdiff - tests/test_crts.py
Fix invalid defines specification
[pyderasn.git] / tests / test_crts.py
index e3f84c6610e5d371d98e42b4a892e144cb22abe5..c9517b110fb967c10b96348d97c398b786af4aa4 100644 (file)
@@ -1,5 +1,5 @@
 # coding: utf-8
 # coding: utf-8
-# PyDERASN -- Python ASN.1 DER codec with abstract structures
+# PyDERASN -- Python ASN.1 DER/CER/BER codec with abstract structures
 # Copyright (C) 2017-2020 Sergey Matveev <stargrave@stargrave.org>
 #
 # This program is free software: you can redistribute it and/or modify
 # Copyright (C) 2017-2020 Sergey Matveev <stargrave@stargrave.org>
 #
 # This program is free software: you can redistribute it and/or modify
 # License along with this program.  If not, see
 # <http://www.gnu.org/licenses/>.
 
 # License along with this program.  If not, see
 # <http://www.gnu.org/licenses/>.
 
+from copy import copy
 from datetime import datetime
 from unittest import TestCase
 
 from datetime import datetime
 from unittest import TestCase
 
+from six import assertRaisesRegex
+from six.moves.cPickle import dumps as pickle_dumps
+from six.moves.cPickle import HIGHEST_PROTOCOL as pickle_proto
+from six.moves.cPickle import loads as pickle_loads
+
 from pyderasn import Any
 from pyderasn import BitString
 from pyderasn import Boolean
 from pyderasn import Choice
 from pyderasn import Any
 from pyderasn import BitString
 from pyderasn import Boolean
 from pyderasn import Choice
+from pyderasn import DecodeError
+from pyderasn import encode_cer
 from pyderasn import GeneralizedTime
 from pyderasn import hexdec
 from pyderasn import IA5String
 from pyderasn import GeneralizedTime
 from pyderasn import hexdec
 from pyderasn import IA5String
@@ -38,27 +46,29 @@ from pyderasn import tag_ctxc
 from pyderasn import tag_ctxp
 from pyderasn import TeletexString
 from pyderasn import UTCTime
 from pyderasn import tag_ctxp
 from pyderasn import TeletexString
 from pyderasn import UTCTime
-
-
-some_oids = {
-    "1.2.840.113549.1.1.1": "id-rsaEncryption",
-    "1.2.840.113549.1.1.5": "id-sha1WithRSAEncryption",
-    "1.2.840.113549.1.9.1": "id-emailAddress",
-    "2.5.29.14": "id-ce-subjectKeyIdentifier",
-    "2.5.29.15": "id-ce-keyUsage",
-    "2.5.29.17": "id-ce-subjectAltName",
-    "2.5.29.18": "id-ce-issuerAltName",
-    "2.5.29.19": "id-ce-basicConstraints",
-    "2.5.29.31": "id-ce-cRLDistributionPoints",
-    "2.5.29.35": "id-ce-authorityKeyIdentifier",
-    "2.5.29.37": "id-ce-extKeyUsage",
-    "2.5.4.3": "id-at-commonName",
-    "2.5.4.6": "id-at-countryName",
-    "2.5.4.7": "id-at-localityName",
-    "2.5.4.8": "id-at-stateOrProvinceName",
-    "2.5.4.10": "id-at-organizationName",
-    "2.5.4.11": "id-at-organizationalUnitName",
+from pyderasn import UTF8String
+
+
+name2oid = {
+    "id-rsaEncryption": ObjectIdentifier("1.2.840.113549.1.1.1"),
+    "id-sha1WithRSAEncryption": ObjectIdentifier("1.2.840.113549.1.1.5"),
+    "id-emailAddress": ObjectIdentifier("1.2.840.113549.1.9.1"),
+    "id-ce-subjectKeyIdentifier": ObjectIdentifier("2.5.29.14"),
+    "id-ce-keyUsage": ObjectIdentifier("2.5.29.15"),
+    "id-ce-subjectAltName": ObjectIdentifier("2.5.29.17"),
+    "id-ce-issuerAltName": ObjectIdentifier("2.5.29.18"),
+    "id-ce-basicConstraints": ObjectIdentifier("2.5.29.19"),
+    "id-ce-cRLDistributionPoints": ObjectIdentifier("2.5.29.31"),
+    "id-ce-authorityKeyIdentifier": ObjectIdentifier("2.5.29.35"),
+    "id-ce-extKeyUsage": ObjectIdentifier("2.5.29.37"),
+    "id-at-commonName": ObjectIdentifier("2.5.4.3"),
+    "id-at-countryName": ObjectIdentifier("2.5.4.6"),
+    "id-at-localityName": ObjectIdentifier("2.5.4.7"),
+    "id-at-stateOrProvinceName": ObjectIdentifier("2.5.4.8"),
+    "id-at-organizationName": ObjectIdentifier("2.5.4.10"),
+    "id-at-organizationalUnitName": ObjectIdentifier("2.5.4.11"),
 }
 }
+stroid2name = {str(oid): name for name, oid in name2oid.items()}
 
 
 class Version(Integer):
 
 
 class Version(Integer):
@@ -95,14 +105,21 @@ class OrganizationName(Choice):
     )
 
 
     )
 
 
+class CommonName(Choice):
+    schema = (
+        ("printableString", PrintableString()),
+        ("utf8String", UTF8String()),
+    )
+
+
 class AttributeTypeAndValue(Sequence):
     schema = (
 class AttributeTypeAndValue(Sequence):
     schema = (
-        ("type", AttributeType(defines=(((".", "value"), {
-            ObjectIdentifier("2.5.4.6"): PrintableString(),
-            ObjectIdentifier("2.5.4.8"): PrintableString(),
-            ObjectIdentifier("2.5.4.7"): PrintableString(),
-            ObjectIdentifier("2.5.4.10"): OrganizationName(),
-            ObjectIdentifier("2.5.4.3"): PrintableString(),
+        ("type", AttributeType(defines=((("value",), {
+            name2oid["id-at-countryName"]: PrintableString(),
+            name2oid["id-at-localityName"]: PrintableString(),
+            name2oid["id-at-stateOrProvinceName"]: PrintableString(),
+            name2oid["id-at-organizationName"]: OrganizationName(),
+            name2oid["id-at-commonName"]: CommonName(),
         }),))),
         ("value", AttributeValue()),
     )
         }),))),
         ("value", AttributeValue()),
     )
@@ -148,6 +165,15 @@ class UniqueIdentifier(BitString):
     pass
 
 
     pass
 
 
+class KeyIdentifier(OctetString):
+    pass
+
+
+class SubjectKeyIdentifier(KeyIdentifier):
+    pass
+
+
+
 class Extension(Sequence):
     schema = (
         ("extnID", ObjectIdentifier()),
 class Extension(Sequence):
     schema = (
         ("extnID", ObjectIdentifier()),
@@ -182,6 +208,7 @@ class Certificate(Sequence):
         ("signatureAlgorithm", AlgorithmIdentifier()),
         ("signatureValue", BitString()),
     )
         ("signatureAlgorithm", AlgorithmIdentifier()),
         ("signatureValue", BitString()),
     )
+    der_forced = True
 
 
 class TestGoSelfSignedVector(TestCase):
 
 
 class TestGoSelfSignedVector(TestCase):
@@ -205,8 +232,7 @@ class TestGoSelfSignedVector(TestCase):
             "ba3ca12568fdc6c7b4511cd40a7f659980402df2b998bb9a4a8cbeb34c0f0a78c",
             "f8d91ede14a5ed76bf116fe360aafa8821490435",
         )))
             "ba3ca12568fdc6c7b4511cd40a7f659980402df2b998bb9a4a8cbeb34c0f0a78c",
             "f8d91ede14a5ed76bf116fe360aafa8821490435",
         )))
-        crt, tail = Certificate().decode(raw)
-        self.assertSequenceEqual(tail, b"")
+        crt = Certificate().decod(raw)
         tbs = crt["tbsCertificate"]
         self.assertEqual(tbs["version"], 0)
         self.assertFalse(tbs["version"].decoded)
         tbs = crt["tbsCertificate"]
         self.assertEqual(tbs["version"], 0)
         self.assertFalse(tbs["version"].decoded)
@@ -221,7 +247,7 @@ class TestGoSelfSignedVector(TestCase):
             )
         assert_raw_equals(tbs["serialNumber"], Integer(10143011886257155224))
         algo_id = AlgorithmIdentifier((
             )
         assert_raw_equals(tbs["serialNumber"], Integer(10143011886257155224))
         algo_id = AlgorithmIdentifier((
-            ("algorithm", ObjectIdentifier("1.2.840.113549.1.1.5")),
+            ("algorithm", name2oid["id-sha1WithRSAEncryption"]),
             ("parameters", Any(Null())),
         ))
         self.assertEqual(tbs["signature"], algo_id)
             ("parameters", Any(Null())),
         ))
         self.assertEqual(tbs["signature"], algo_id)
@@ -259,7 +285,7 @@ class TestGoSelfSignedVector(TestCase):
         self.assertEqual(tbs["subject"], issuer)
         assert_raw_equals(tbs["subject"], issuer)
         spki = SubjectPublicKeyInfo()
         self.assertEqual(tbs["subject"], issuer)
         assert_raw_equals(tbs["subject"], issuer)
         spki = SubjectPublicKeyInfo()
-        algo_id["algorithm"] = ObjectIdentifier("1.2.840.113549.1.1.1")
+        algo_id["algorithm"] = name2oid["id-rsaEncryption"]
         spki["algorithm"] = algo_id
         spki["subjectPublicKey"] = BitString(hexdec("".join((
             "3048024100cdb7639c3278f006aa277f6eaf42902b592d8cbcbe38a1c92ba4695",
         spki["algorithm"] = algo_id
         spki["subjectPublicKey"] = BitString(hexdec("".join((
             "3048024100cdb7639c3278f006aa277f6eaf42902b592d8cbcbe38a1c92ba4695",
@@ -271,7 +297,7 @@ class TestGoSelfSignedVector(TestCase):
         self.assertNotIn("issuerUniqueID", tbs)
         self.assertNotIn("subjectUniqueID", tbs)
         self.assertNotIn("extensions", tbs)
         self.assertNotIn("issuerUniqueID", tbs)
         self.assertNotIn("subjectUniqueID", tbs)
         self.assertNotIn("extensions", tbs)
-        algo_id["algorithm"] = ObjectIdentifier("1.2.840.113549.1.1.5")
+        algo_id["algorithm"] = name2oid["id-sha1WithRSAEncryption"]
         self.assertEqual(crt["signatureAlgorithm"], algo_id)
         self.assertEqual(crt["signatureValue"], BitString(hexdec("".join((
             "a67b06ec5ece92772ca413cba3ca12568fdc6c7b4511cd40a7f659980402df2b",
         self.assertEqual(crt["signatureAlgorithm"], algo_id)
         self.assertEqual(crt["signatureValue"], BitString(hexdec("".join((
             "a67b06ec5ece92772ca413cba3ca12568fdc6c7b4511cd40a7f659980402df2b",
@@ -280,12 +306,13 @@ class TestGoSelfSignedVector(TestCase):
         self.assertSequenceEqual(crt.encode(), raw)
         pprint(crt)
         repr(crt)
         self.assertSequenceEqual(crt.encode(), raw)
         pprint(crt)
         repr(crt)
+        pickle_loads(pickle_dumps(crt, pickle_proto))
 
         tbs = TBSCertificate()
         tbs["serialNumber"] = CertificateSerialNumber(10143011886257155224)
 
         sign_algo_id = AlgorithmIdentifier((
 
         tbs = TBSCertificate()
         tbs["serialNumber"] = CertificateSerialNumber(10143011886257155224)
 
         sign_algo_id = AlgorithmIdentifier((
-            ("algorithm", ObjectIdentifier("1.2.840.113549.1.1.5")),
+            ("algorithm", name2oid["id-sha1WithRSAEncryption"]),
             ("parameters", Any(Null())),
         ))
         tbs["signature"] = sign_algo_id
             ("parameters", Any(Null())),
         ))
         tbs["signature"] = sign_algo_id
@@ -323,8 +350,8 @@ class TestGoSelfSignedVector(TestCase):
         tbs["validity"] = validity
 
         spki = SubjectPublicKeyInfo()
         tbs["validity"] = validity
 
         spki = SubjectPublicKeyInfo()
-        spki_algo_id = sign_algo_id.copy()
-        spki_algo_id["algorithm"] = ObjectIdentifier("1.2.840.113549.1.1.1")
+        spki_algo_id = copy(sign_algo_id)
+        spki_algo_id["algorithm"] = name2oid["id-rsaEncryption"]
         spki["algorithm"] = spki_algo_id
         spki["subjectPublicKey"] = BitString(hexdec("".join((
             "3048024100cdb7639c3278f006aa277f6eaf42902b592d8cbcbe38a1c92ba4695",
         spki["algorithm"] = spki_algo_id
         spki["subjectPublicKey"] = BitString(hexdec("".join((
             "3048024100cdb7639c3278f006aa277f6eaf42902b592d8cbcbe38a1c92ba4695",
@@ -341,9 +368,15 @@ class TestGoSelfSignedVector(TestCase):
             "998bb9a4a8cbeb34c0f0a78cf8d91ede14a5ed76bf116fe360aafa8821490435",
         ))))
         self.assertSequenceEqual(crt.encode(), raw)
             "998bb9a4a8cbeb34c0f0a78cf8d91ede14a5ed76bf116fe360aafa8821490435",
         ))))
         self.assertSequenceEqual(crt.encode(), raw)
+        self.assertEqual(
+            Certificate().decod(encode_cer(crt), ctx={"bered": True}),
+            crt,
+        )
 
 
 class TestGoPayPalVector(TestCase):
 
 
 class TestGoPayPalVector(TestCase):
+    """PayPal certificate with "www.paypal.com\x00ssl.secureconnection.cc" name
+    """
     def runTest(self):
         raw = hexdec("".join((
             "30820644308205ada003020102020300f09b300d06092a864886f70d010105050",
     def runTest(self):
         raw = hexdec("".join((
             "30820644308205ada003020102020300f09b300d06092a864886f70d010105050",
@@ -397,8 +430,5 @@ class TestGoPayPalVector(TestCase):
             "07ba44cce54a2d723f9847f626dc054605076321ab469b9c78d5545b3d0c1ec86",
             "48cb55023826fdbb8221c439607a8bb",
         )))
             "07ba44cce54a2d723f9847f626dc054605076321ab469b9c78d5545b3d0c1ec86",
             "48cb55023826fdbb8221c439607a8bb",
         )))
-        crt, tail = Certificate().decode(raw)
-        self.assertSequenceEqual(tail, b"")
-        self.assertSequenceEqual(crt.encode(), raw)
-        pprint(crt)
-        repr(crt)
+        with assertRaisesRegex(self, DecodeError, "non-printable"):
+            crt = Certificate().decod(raw)