blob: e3a06509fe23569afbf1768f123333ea6428454d [file] [log] [blame]
Paul Kehrerc33ffd72015-12-25 10:59:22 -06001# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import absolute_import, division, print_function
6
7import datetime
8
9import pytest
10
InvalidInterrupt8e66ca62016-08-16 19:39:31 -070011import pytz
12
Paul Kehrerc33ffd72015-12-25 10:59:22 -060013from cryptography import x509
14from cryptography.hazmat.backends.interfaces import X509Backend
15
16
17class TestRevokedCertificateBuilder(object):
18 def test_serial_number_must_be_integer(self):
19 with pytest.raises(TypeError):
20 x509.RevokedCertificateBuilder().serial_number("notanx509name")
21
22 def test_serial_number_must_be_non_negative(self):
23 with pytest.raises(ValueError):
24 x509.RevokedCertificateBuilder().serial_number(-1)
25
Коренберг Марк9e758302016-08-02 06:08:21 +050026 def test_serial_number_must_be_positive(self):
27 with pytest.raises(ValueError):
28 x509.RevokedCertificateBuilder().serial_number(0)
29
30 @pytest.mark.requires_backend_interface(interface=X509Backend)
31 def test_minimal_serial_number(self, backend):
32 revocation_date = datetime.datetime(2002, 1, 1, 12, 1)
33 builder = x509.RevokedCertificateBuilder().serial_number(
34 1
35 ).revocation_date(
36 revocation_date
37 )
38
39 revoked_certificate = builder.build(backend)
40 assert revoked_certificate.serial_number == 1
41
42 @pytest.mark.requires_backend_interface(interface=X509Backend)
43 def test_biggest_serial_number(self, backend):
44 revocation_date = datetime.datetime(2002, 1, 1, 12, 1)
45 builder = x509.RevokedCertificateBuilder().serial_number(
46 (1 << 159) - 1
47 ).revocation_date(
48 revocation_date
49 )
50
51 revoked_certificate = builder.build(backend)
52 assert revoked_certificate.serial_number == (1 << 159) - 1
53
Paul Kehrerc33ffd72015-12-25 10:59:22 -060054 def test_serial_number_must_be_less_than_160_bits_long(self):
55 with pytest.raises(ValueError):
Коренберг Марк9e758302016-08-02 06:08:21 +050056 x509.RevokedCertificateBuilder().serial_number(1 << 159)
Paul Kehrerc33ffd72015-12-25 10:59:22 -060057
58 def test_set_serial_number_twice(self):
59 builder = x509.RevokedCertificateBuilder().serial_number(3)
60 with pytest.raises(ValueError):
61 builder.serial_number(4)
62
InvalidInterrupt8e66ca62016-08-16 19:39:31 -070063 @pytest.mark.requires_backend_interface(interface=X509Backend)
64 def test_aware_revocation_date(self, backend):
65 time = datetime.datetime(2012, 1, 16, 22, 43)
66 tz = pytz.timezone("US/Pacific")
67 time = tz.localize(time)
68 utc_time = datetime.datetime(2012, 1, 17, 6, 43)
69 serial_number = 333
70 builder = x509.RevokedCertificateBuilder().serial_number(
71 serial_number
72 ).revocation_date(
73 time
74 )
75
76 revoked_certificate = builder.build(backend)
77 assert revoked_certificate.revocation_date == utc_time
78
Paul Kehrerc33ffd72015-12-25 10:59:22 -060079 def test_revocation_date_invalid(self):
80 with pytest.raises(TypeError):
81 x509.RevokedCertificateBuilder().revocation_date("notadatetime")
82
83 def test_revocation_date_before_unix_epoch(self):
84 with pytest.raises(ValueError):
85 x509.RevokedCertificateBuilder().revocation_date(
86 datetime.datetime(1960, 8, 10)
87 )
88
89 def test_set_revocation_date_twice(self):
90 builder = x509.RevokedCertificateBuilder().revocation_date(
91 datetime.datetime(2002, 1, 1, 12, 1)
92 )
93 with pytest.raises(ValueError):
94 builder.revocation_date(datetime.datetime(2002, 1, 1, 12, 1))
95
Paul Kehrere5f152b2015-12-25 23:55:47 -060096 def test_add_extension_checks_for_duplicates(self):
97 builder = x509.RevokedCertificateBuilder().add_extension(
98 x509.CRLReason(x509.ReasonFlags.ca_compromise), False
99 )
100
101 with pytest.raises(ValueError):
102 builder.add_extension(
103 x509.CRLReason(x509.ReasonFlags.ca_compromise), False
104 )
105
Paul Kehrer7dfaa402015-12-26 14:50:21 -0600106 def test_add_invalid_extension(self):
107 with pytest.raises(TypeError):
108 x509.RevokedCertificateBuilder().add_extension(
109 "notanextension", False
110 )
111
Paul Kehrerc33ffd72015-12-25 10:59:22 -0600112 @pytest.mark.requires_backend_interface(interface=X509Backend)
113 def test_no_serial_number(self, backend):
114 builder = x509.RevokedCertificateBuilder().revocation_date(
115 datetime.datetime(2002, 1, 1, 12, 1)
116 )
117
118 with pytest.raises(ValueError):
119 builder.build(backend)
120
121 @pytest.mark.requires_backend_interface(interface=X509Backend)
122 def test_no_revocation_date(self, backend):
123 builder = x509.RevokedCertificateBuilder().serial_number(3)
124
125 with pytest.raises(ValueError):
126 builder.build(backend)
127
128 @pytest.mark.requires_backend_interface(interface=X509Backend)
129 def test_create_revoked(self, backend):
130 serial_number = 333
131 revocation_date = datetime.datetime(2002, 1, 1, 12, 1)
132 builder = x509.RevokedCertificateBuilder().serial_number(
133 serial_number
134 ).revocation_date(
135 revocation_date
136 )
137
138 revoked_certificate = builder.build(backend)
139 assert revoked_certificate.serial_number == serial_number
140 assert revoked_certificate.revocation_date == revocation_date
141 assert len(revoked_certificate.extensions) == 0
Paul Kehrere5f152b2015-12-25 23:55:47 -0600142
143 @pytest.mark.parametrize(
144 "extension",
145 [
146 x509.InvalidityDate(datetime.datetime(2015, 1, 1, 0, 0)),
147 x509.CRLReason(x509.ReasonFlags.ca_compromise),
148 x509.CertificateIssuer([
149 x509.DNSName(u"cryptography.io"),
150 ])
151 ]
152 )
153 @pytest.mark.requires_backend_interface(interface=X509Backend)
154 def test_add_extensions(self, backend, extension):
155 serial_number = 333
156 revocation_date = datetime.datetime(2002, 1, 1, 12, 1)
157 builder = x509.RevokedCertificateBuilder().serial_number(
158 serial_number
159 ).revocation_date(
160 revocation_date
161 ).add_extension(
162 extension, False
163 )
164
165 revoked_certificate = builder.build(backend)
166 assert revoked_certificate.serial_number == serial_number
167 assert revoked_certificate.revocation_date == revocation_date
168 assert len(revoked_certificate.extensions) == 1
169 ext = revoked_certificate.extensions.get_extension_for_class(
170 type(extension)
171 )
172 assert ext.critical is False
173 assert ext.value == extension
174
175 @pytest.mark.requires_backend_interface(interface=X509Backend)
176 def test_add_multiple_extensions(self, backend):
177 serial_number = 333
178 revocation_date = datetime.datetime(2002, 1, 1, 12, 1)
179 invalidity_date = x509.InvalidityDate(
180 datetime.datetime(2015, 1, 1, 0, 0)
181 )
182 certificate_issuer = x509.CertificateIssuer([
183 x509.DNSName(u"cryptography.io"),
184 ])
185 crl_reason = x509.CRLReason(x509.ReasonFlags.aa_compromise)
186 builder = x509.RevokedCertificateBuilder().serial_number(
187 serial_number
188 ).revocation_date(
189 revocation_date
190 ).add_extension(
191 invalidity_date, True
192 ).add_extension(
193 crl_reason, True
194 ).add_extension(
195 certificate_issuer, True
196 )
197
198 revoked_certificate = builder.build(backend)
199 assert len(revoked_certificate.extensions) == 3
200 for ext_data in [invalidity_date, certificate_issuer, crl_reason]:
201 ext = revoked_certificate.extensions.get_extension_for_class(
202 type(ext_data)
203 )
204 assert ext.critical is True
205 assert ext.value == ext_data