2 # PyDERASN -- Python ASN.1 DER/CER/BER codec with abstract structures
3 # Copyright (C) 2017-2021 Sergey Matveev <stargrave@stargrave.org>
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Lesser General Public License as
7 # published by the Free Software Foundation, version 3 of the License.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this program. If not, see
16 # <http://www.gnu.org/licenses/>.
17 """CRL related schemas, just to test the performance with them
20 from io import BytesIO
21 from os.path import exists
22 from sys import getsizeof
24 from unittest import skipIf
25 from unittest import TestCase
29 from pyderasn import BitString
30 from pyderasn import encode_cer
31 from pyderasn import file_mmaped
32 from pyderasn import Sequence
33 from pyderasn import SequenceOf
34 from pyderasn import tag_ctxc
36 from tests.test_crts import AlgorithmIdentifier
37 from tests.test_crts import CertificateSerialNumber
38 from tests.test_crts import Extensions
39 from tests.test_crts import Name
40 from tests.test_crts import Time
41 from tests.test_crts import Version
44 class RevokedCertificate(Sequence):
46 ("userCertificate", CertificateSerialNumber()),
47 ("revocationDate", Time()),
48 ("crlEntryExtensions", Extensions(optional=True)),
52 class RevokedCertificates(SequenceOf):
53 schema = RevokedCertificate()
56 class TBSCertList(Sequence):
58 ("version", Version(optional=True)),
59 ("signature", AlgorithmIdentifier()),
61 ("thisUpdate", Time()),
62 ("nextUpdate", Time(optional=True)),
63 ("revokedCertificates", RevokedCertificates(optional=True)),
64 ("crlExtensions", Extensions(expl=tag_ctxc(0), optional=True)),
68 class CertificateList(Sequence):
70 ("tbsCertList", TBSCertList()),
71 ("signatureAlgorithm", AlgorithmIdentifier()),
72 ("signatureValue", BitString()),
76 CRL_PATH = "revoke.crl"
79 @skipIf(not exists(CRL_PATH), "CACert's revoke.crl not found")
80 class TestCACert(TestCase):
81 def test_cer_and_2pass(self):
82 with open(CRL_PATH, "rb") as fd:
86 crl1 = CertificateList().decod(raw)
87 print("DER decoded", time() - start)
89 der_raw = crl1.encode()
90 print("DER encoded", time() - start)
91 self.assertSequenceEqual(der_raw, raw)
94 _, state = crl1.encode1st()
95 print("1st pass state size", getsizeof(state))
96 crl1.encode2nd(buf.write, iter(state))
97 print("DER 2pass encoded", time() - start)
98 self.assertSequenceEqual(buf.getvalue(), raw)
100 cer_raw = encode_cer(crl1)
101 print("CER encoded", time() - start)
103 crl2 = CertificateList().decod(cer_raw, ctx={"bered": True})
104 print("CER decoded", time() - start)
105 self.assertEqual(crl2, crl1)
107 @skipIf(PY2, "Py27 mmap does not implement buffer protocol")
108 def test_mmaped(self):
109 fd = open(CRL_PATH, "rb")
111 CertificateList().decod(file_mmaped(fd))
112 print("DER decoded", time() - start)
114 def test_evgens(self):
115 fd = open(CRL_PATH, "rb")
116 raw = memoryview(fd.read()) if PY2 else file_mmaped(fd)
119 revoked_certs_count = 0
121 for decode_path, _, _ in CertificateList().decode_evgen(raw):
124 len(decode_path) == 3 and
125 decode_path[:2] == ("tbsCertList", "revokedCertificates")
127 revoked_certs_count += 1
128 print("CRL parsed", time() - start)
129 evgens_upto_count = 0
131 for decode_path, _, _ in CertificateList().decode_evgen(raw, ctx={
133 (("tbsCertList", "revokedCertificates", any), True),
136 evgens_upto_count += 1
137 print("CRL upto parsed", time() - start)
139 float(evgens_count - evgens_upto_count) / revoked_certs_count,