]> Cypherpunks.ru repositories - pyderasn.git/blob - tests/test_crl.py
Raise copyright years
[pyderasn.git] / tests / test_crl.py
1 # coding: utf-8
2 # PyDERASN -- Python ASN.1 DER/CER/BER codec with abstract structures
3 # Copyright (C) 2017-2021 Sergey Matveev <stargrave@stargrave.org>
4 #
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.
8 #
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.
13 #
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
18 """
19
20 from io import BytesIO
21 from os.path import exists
22 from sys import getsizeof
23 from time import time
24 from unittest import skipIf
25 from unittest import TestCase
26
27 from six import PY2
28
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
35
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
42
43
44 class RevokedCertificate(Sequence):
45     schema = (
46         ("userCertificate", CertificateSerialNumber()),
47         ("revocationDate", Time()),
48         ("crlEntryExtensions", Extensions(optional=True)),
49     )
50
51
52 class RevokedCertificates(SequenceOf):
53     schema = RevokedCertificate()
54
55
56 class TBSCertList(Sequence):
57     schema = (
58         ("version", Version(optional=True)),
59         ("signature", AlgorithmIdentifier()),
60         ("issuer", Name()),
61         ("thisUpdate", Time()),
62         ("nextUpdate", Time(optional=True)),
63         ("revokedCertificates", RevokedCertificates(optional=True)),
64         ("crlExtensions", Extensions(expl=tag_ctxc(0), optional=True)),
65     )
66
67
68 class CertificateList(Sequence):
69     schema = (
70         ("tbsCertList", TBSCertList()),
71         ("signatureAlgorithm", AlgorithmIdentifier()),
72         ("signatureValue", BitString()),
73     )
74
75
76 CRL_PATH = "revoke.crl"
77
78
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:
83             raw = fd.read()
84         print("DER read")
85         start = time()
86         crl1 = CertificateList().decod(raw)
87         print("DER decoded", time() - start)
88         start = time()
89         der_raw = crl1.encode()
90         print("DER encoded", time() - start)
91         self.assertSequenceEqual(der_raw, raw)
92         buf = BytesIO()
93         start = time()
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)
99         start = time()
100         cer_raw = encode_cer(crl1)
101         print("CER encoded", time() - start)
102         start = time()
103         crl2 = CertificateList().decod(cer_raw, ctx={"bered": True})
104         print("CER decoded", time() - start)
105         self.assertEqual(crl2, crl1)
106
107     @skipIf(PY2, "Py27 mmap does not implement buffer protocol")
108     def test_mmaped(self):
109         fd = open(CRL_PATH, "rb")
110         start = time()
111         CertificateList().decod(file_mmaped(fd))
112         print("DER decoded", time() - start)
113
114     def test_evgens(self):
115         fd = open(CRL_PATH, "rb")
116         raw = memoryview(fd.read()) if PY2 else file_mmaped(fd)
117         print("CRL opened")
118         evgens_count = 0
119         revoked_certs_count = 0
120         start = time()
121         for decode_path, _, _ in CertificateList().decode_evgen(raw):
122             evgens_count += 1
123             if (
124                     len(decode_path) == 3 and
125                     decode_path[:2] == ("tbsCertList", "revokedCertificates")
126             ):
127                 revoked_certs_count += 1
128         print("CRL parsed", time() - start)
129         evgens_upto_count = 0
130         start = time()
131         for decode_path, _, _ in CertificateList().decode_evgen(raw, ctx={
132                 "evgen_mode_upto": (
133                     (("tbsCertList", "revokedCertificates", any), True),
134                 ),
135         }):
136             evgens_upto_count += 1
137         print("CRL upto parsed", time() - start)
138         self.assertEqual(
139             float(evgens_count - evgens_upto_count) / revoked_certs_count,
140             3,
141         )