2 # PyDERASN -- Python ASN.1 DER/CER/BER codec with abstract structures
3 # Copyright (C) 2017-2024 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
27 from pyderasn import BitString
28 from pyderasn import encode_cer
29 from pyderasn import file_mmaped
30 from pyderasn import Sequence
31 from pyderasn import SequenceOf
32 from pyderasn import tag_ctxc
34 from tests.test_crts import AlgorithmIdentifier
35 from tests.test_crts import CertificateSerialNumber
36 from tests.test_crts import Extensions
37 from tests.test_crts import Name
38 from tests.test_crts import Time
39 from tests.test_crts import Version
42 class RevokedCertificate(Sequence):
44 ("userCertificate", CertificateSerialNumber()),
45 ("revocationDate", Time()),
46 ("crlEntryExtensions", Extensions(optional=True)),
50 class RevokedCertificates(SequenceOf):
51 schema = RevokedCertificate()
54 class TBSCertList(Sequence):
56 ("version", Version(optional=True)),
57 ("signature", AlgorithmIdentifier()),
59 ("thisUpdate", Time()),
60 ("nextUpdate", Time(optional=True)),
61 ("revokedCertificates", RevokedCertificates(optional=True)),
62 ("crlExtensions", Extensions(expl=tag_ctxc(0), optional=True)),
66 class CertificateList(Sequence):
68 ("tbsCertList", TBSCertList()),
69 ("signatureAlgorithm", AlgorithmIdentifier()),
70 ("signatureValue", BitString()),
74 CRL_PATH = "revoke.crl"
77 @skipIf(not exists(CRL_PATH), "CACert's revoke.crl not found")
78 class TestCACert(TestCase):
79 def test_cer_and_2pass(self):
80 with open(CRL_PATH, "rb") as fd:
84 crl1 = CertificateList().decod(raw)
85 print("DER decoded", time() - start)
87 der_raw = crl1.encode()
88 print("DER encoded", time() - start)
89 self.assertSequenceEqual(der_raw, raw)
92 _, state = crl1.encode1st()
93 print("1st pass state size", getsizeof(state))
94 crl1.encode2nd(buf.write, iter(state))
95 print("DER 2pass encoded", time() - start)
96 self.assertSequenceEqual(buf.getvalue(), raw)
98 cer_raw = encode_cer(crl1)
99 print("CER encoded", time() - start)
101 crl2 = CertificateList().decod(cer_raw, ctx={"bered": True})
102 print("CER decoded", time() - start)
103 self.assertEqual(crl2, crl1)
105 def test_mmaped(self):
106 fd = open(CRL_PATH, "rb")
108 CertificateList().decod(file_mmaped(fd))
109 print("DER decoded", time() - start)
111 def test_evgens(self):
112 fd = open(CRL_PATH, "rb")
113 raw = file_mmaped(fd)
116 revoked_certs_count = 0
118 for decode_path, _, _ in CertificateList().decode_evgen(raw):
121 len(decode_path) == 3 and
122 decode_path[:2] == ("tbsCertList", "revokedCertificates")
124 revoked_certs_count += 1
125 print("CRL parsed", time() - start)
126 evgens_upto_count = 0
128 for decode_path, _, _ in CertificateList().decode_evgen(raw, ctx={
130 (("tbsCertList", "revokedCertificates", any), True),
133 evgens_upto_count += 1
134 print("CRL upto parsed", time() - start)
136 float(evgens_count - evgens_upto_count) / revoked_certs_count,