blob: c1512d5f9f8189af1844d1b7b38f6c7fc121a396 [file] [log] [blame]
Paul Kehrer8cf26422015-03-21 09:50:24 -05001# 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
Paul Kehrerfbb7ac82015-03-16 19:26:29 -05007import os
8
Paul Kehrer8cf26422015-03-21 09:50:24 -05009import pytest
10
11from cryptography import x509
Paul Kehrerfbb7ac82015-03-16 19:26:29 -050012from cryptography.hazmat.backends.interfaces import RSABackend, X509Backend
13
14from .test_x509 import _load_cert
Paul Kehrer8cf26422015-03-21 09:50:24 -050015
16
Paul Kehrer85894662015-03-22 13:19:31 -050017class TestExtension(object):
18 def test_not_an_oid(self):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -050019 bc = x509.BasicConstraints(ca=False, path_length=None)
Paul Kehrer85894662015-03-22 13:19:31 -050020 with pytest.raises(TypeError):
21 x509.Extension("notanoid", True, bc)
22
23 def test_critical_not_a_bool(self):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -050024 bc = x509.BasicConstraints(ca=False, path_length=None)
Paul Kehrer85894662015-03-22 13:19:31 -050025 with pytest.raises(TypeError):
26 x509.Extension(x509.OID_BASIC_CONSTRAINTS, "notabool", bc)
27
28 def test_repr(self):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -050029 bc = x509.BasicConstraints(ca=False, path_length=None)
Paul Kehrer85894662015-03-22 13:19:31 -050030 ext = x509.Extension(x509.OID_BASIC_CONSTRAINTS, True, bc)
31 assert repr(ext) == (
32 "<Extension(oid=<ObjectIdentifier(oid=2.5.29.19, name=basicConst"
33 "raints)>, critical=True, value=<BasicConstraints(ca=False, path"
34 "_length=None)>)>"
35 )
36
37
Paul Kehrercecbbba2015-03-30 14:58:38 -050038class TestKeyUsage(object):
39 def test_key_agreement_false_encipher_decipher_true(self):
40 with pytest.raises(ValueError):
41 x509.KeyUsage(
42 digital_signature=False,
43 content_commitment=False,
44 key_encipherment=False,
45 data_encipherment=False,
46 key_agreement=False,
47 key_cert_sign=False,
48 crl_sign=False,
49 encipher_only=True,
50 decipher_only=False
51 )
52
53 with pytest.raises(ValueError):
54 x509.KeyUsage(
55 digital_signature=False,
56 content_commitment=False,
57 key_encipherment=False,
58 data_encipherment=False,
59 key_agreement=False,
60 key_cert_sign=False,
61 crl_sign=False,
62 encipher_only=True,
63 decipher_only=True
64 )
65
66 with pytest.raises(ValueError):
67 x509.KeyUsage(
68 digital_signature=False,
69 content_commitment=False,
70 key_encipherment=False,
71 data_encipherment=False,
72 key_agreement=False,
73 key_cert_sign=False,
74 crl_sign=False,
75 encipher_only=False,
76 decipher_only=True
77 )
78
79 def test_properties_key_agreement_true(self):
80 ku = x509.KeyUsage(
81 digital_signature=True,
82 content_commitment=True,
83 key_encipherment=False,
84 data_encipherment=False,
85 key_agreement=False,
86 key_cert_sign=True,
87 crl_sign=False,
88 encipher_only=False,
89 decipher_only=False
90 )
91 assert ku.digital_signature is True
92 assert ku.content_commitment is True
93 assert ku.key_encipherment is False
94 assert ku.data_encipherment is False
95 assert ku.key_agreement is False
96 assert ku.key_cert_sign is True
97 assert ku.crl_sign is False
98
99 def test_key_agreement_true_properties(self):
100 ku = x509.KeyUsage(
101 digital_signature=False,
102 content_commitment=False,
103 key_encipherment=False,
104 data_encipherment=False,
105 key_agreement=True,
106 key_cert_sign=False,
107 crl_sign=False,
108 encipher_only=False,
109 decipher_only=True
110 )
111 assert ku.key_agreement is True
112 assert ku.encipher_only is False
113 assert ku.decipher_only is True
114
115 def test_key_agreement_false_properties(self):
116 ku = x509.KeyUsage(
117 digital_signature=False,
118 content_commitment=False,
119 key_encipherment=False,
120 data_encipherment=False,
121 key_agreement=False,
122 key_cert_sign=False,
123 crl_sign=False,
124 encipher_only=False,
125 decipher_only=False
126 )
127 assert ku.key_agreement is False
128 with pytest.raises(ValueError):
129 ku.encipher_only
130
131 with pytest.raises(ValueError):
132 ku.decipher_only
133
134
Paul Kehrer8cf26422015-03-21 09:50:24 -0500135class TestBasicConstraints(object):
136 def test_ca_not_boolean(self):
137 with pytest.raises(TypeError):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500138 x509.BasicConstraints(ca="notbool", path_length=None)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500139
140 def test_path_length_not_ca(self):
141 with pytest.raises(ValueError):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500142 x509.BasicConstraints(ca=False, path_length=0)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500143
144 def test_path_length_not_int(self):
145 with pytest.raises(TypeError):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500146 x509.BasicConstraints(ca=True, path_length=1.1)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500147
148 with pytest.raises(TypeError):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500149 x509.BasicConstraints(ca=True, path_length="notint")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500150
151 def test_path_length_negative(self):
152 with pytest.raises(TypeError):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500153 x509.BasicConstraints(ca=True, path_length=-1)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500154
155 def test_repr(self):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500156 na = x509.BasicConstraints(ca=True, path_length=None)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500157 assert repr(na) == (
Paul Kehrer85894662015-03-22 13:19:31 -0500158 "<BasicConstraints(ca=True, path_length=None)>"
Paul Kehrer8cf26422015-03-21 09:50:24 -0500159 )
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500160
161
Paul Kehrerffa2a152015-03-31 08:18:25 -0500162class TestExtendedKeyUsage(object):
163 def test_not_all_oids(self):
164 with pytest.raises(TypeError):
165 x509.ExtendedKeyUsage(["notoid"])
166
167 def test_iter_len(self):
168 eku = x509.ExtendedKeyUsage([
169 x509.ObjectIdentifier("1.3.6.1.5.5.7.3.1"),
170 x509.ObjectIdentifier("1.3.6.1.5.5.7.3.2"),
171 ])
172 assert len(eku) == 2
173 assert list(eku) == [
174 x509.OID_SERVER_AUTH,
175 x509.OID_CLIENT_AUTH
176 ]
177
Paul Kehrer23d10c32015-04-02 23:12:32 -0500178 def test_repr(self):
179 eku = x509.ExtendedKeyUsage([
180 x509.ObjectIdentifier("1.3.6.1.5.5.7.3.1"),
181 x509.ObjectIdentifier("1.3.6.1.5.5.7.3.2"),
182 ])
183 assert repr(eku) == (
184 "<ExtendedKeyUsage([<ObjectIdentifier(oid=1.3.6.1.5.5.7.3.1, name="
185 "serverAuth)>, <ObjectIdentifier(oid=1.3.6.1.5.5.7.3.2, name=clien"
186 "tAuth)>])>"
187 )
188
Paul Kehrerffa2a152015-03-31 08:18:25 -0500189
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500190@pytest.mark.requires_backend_interface(interface=RSABackend)
191@pytest.mark.requires_backend_interface(interface=X509Backend)
192class TestExtensions(object):
193 def test_no_extensions(self, backend):
194 cert = _load_cert(
195 os.path.join("x509", "verisign_md2_root.pem"),
196 x509.load_pem_x509_certificate,
197 backend
198 )
199 ext = cert.extensions
200 assert len(ext) == 0
201 assert list(ext) == []
Paul Kehrerfa56a232015-03-17 13:14:03 -0500202 with pytest.raises(x509.ExtensionNotFound) as exc:
203 ext.get_extension_for_oid(x509.OID_BASIC_CONSTRAINTS)
204
205 assert exc.value.oid == x509.OID_BASIC_CONSTRAINTS
206
207 def test_one_extension(self, backend):
208 cert = _load_cert(
209 os.path.join(
210 "x509", "custom", "basic_constraints_not_critical.pem"
211 ),
212 x509.load_pem_x509_certificate,
213 backend
214 )
215 extensions = cert.extensions
216 ext = extensions.get_extension_for_oid(x509.OID_BASIC_CONSTRAINTS)
217 assert ext is not None
218 assert ext.value.ca is False
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500219
220 def test_duplicate_extension(self, backend):
221 cert = _load_cert(
222 os.path.join(
223 "x509", "custom", "two_basic_constraints.pem"
224 ),
225 x509.load_pem_x509_certificate,
226 backend
227 )
228 with pytest.raises(x509.DuplicateExtension) as exc:
229 cert.extensions
230
231 assert exc.value.oid == x509.OID_BASIC_CONSTRAINTS
232
233 def test_unsupported_critical_extension(self, backend):
234 cert = _load_cert(
235 os.path.join(
236 "x509", "custom", "unsupported_extension_critical.pem"
237 ),
238 x509.load_pem_x509_certificate,
239 backend
240 )
241 with pytest.raises(x509.UnsupportedExtension) as exc:
242 cert.extensions
243
244 assert exc.value.oid == x509.ObjectIdentifier("1.2.3.4")
245
246 def test_unsupported_extension(self, backend):
247 # TODO: this will raise an exception when all extensions are complete
248 cert = _load_cert(
249 os.path.join(
250 "x509", "custom", "unsupported_extension.pem"
251 ),
252 x509.load_pem_x509_certificate,
253 backend
254 )
255 extensions = cert.extensions
256 assert len(extensions) == 0
Paul Kehrerfa56a232015-03-17 13:14:03 -0500257
258
259@pytest.mark.requires_backend_interface(interface=RSABackend)
260@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrerde813ea2015-03-28 12:44:34 -0500261class TestBasicConstraintsExtension(object):
Paul Kehrerfa56a232015-03-17 13:14:03 -0500262 def test_ca_true_pathlen_6(self, backend):
263 cert = _load_cert(
264 os.path.join(
265 "x509", "PKITS_data", "certs", "pathLenConstraint6CACert.crt"
266 ),
267 x509.load_der_x509_certificate,
268 backend
269 )
270 ext = cert.extensions.get_extension_for_oid(
271 x509.OID_BASIC_CONSTRAINTS
272 )
273 assert ext is not None
274 assert ext.critical is True
275 assert ext.value.ca is True
276 assert ext.value.path_length == 6
277
278 def test_path_length_zero(self, backend):
279 cert = _load_cert(
280 os.path.join("x509", "custom", "bc_path_length_zero.pem"),
281 x509.load_pem_x509_certificate,
282 backend
283 )
284 ext = cert.extensions.get_extension_for_oid(
285 x509.OID_BASIC_CONSTRAINTS
286 )
287 assert ext is not None
288 assert ext.critical is True
289 assert ext.value.ca is True
290 assert ext.value.path_length == 0
291
292 def test_ca_true_no_pathlen(self, backend):
293 cert = _load_cert(
294 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
295 x509.load_der_x509_certificate,
296 backend
297 )
298 ext = cert.extensions.get_extension_for_oid(
299 x509.OID_BASIC_CONSTRAINTS
300 )
301 assert ext is not None
302 assert ext.critical is True
303 assert ext.value.ca is True
304 assert ext.value.path_length is None
305
306 def test_ca_false(self, backend):
307 cert = _load_cert(
308 os.path.join("x509", "cryptography.io.pem"),
309 x509.load_pem_x509_certificate,
310 backend
311 )
312 ext = cert.extensions.get_extension_for_oid(
313 x509.OID_BASIC_CONSTRAINTS
314 )
315 assert ext is not None
316 assert ext.critical is True
317 assert ext.value.ca is False
318 assert ext.value.path_length is None
319
320 def test_no_basic_constraints(self, backend):
321 cert = _load_cert(
322 os.path.join(
323 "x509",
324 "PKITS_data",
325 "certs",
326 "ValidCertificatePathTest1EE.crt"
327 ),
328 x509.load_der_x509_certificate,
329 backend
330 )
331 with pytest.raises(x509.ExtensionNotFound):
332 cert.extensions.get_extension_for_oid(x509.OID_BASIC_CONSTRAINTS)
333
334 def test_basic_constraint_not_critical(self, backend):
335 cert = _load_cert(
336 os.path.join(
337 "x509", "custom", "basic_constraints_not_critical.pem"
338 ),
339 x509.load_pem_x509_certificate,
340 backend
341 )
342 ext = cert.extensions.get_extension_for_oid(
343 x509.OID_BASIC_CONSTRAINTS
344 )
345 assert ext is not None
346 assert ext.critical is False
347 assert ext.value.ca is False