blob: 05734b42cd9f03dcd703b800b78a5927fd7e83da [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 Kehrer1eb82a62015-03-31 20:00:33 -05007import binascii
Paul Kehrer31bdf792015-03-25 14:11:00 -05008import ipaddress
Paul Kehrerfbb7ac82015-03-16 19:26:29 -05009import os
10
Paul Kehrer8cf26422015-03-21 09:50:24 -050011import pytest
12
Paul Kehrercbfb1012015-04-10 20:57:20 -040013import six
14
Paul Kehrer8cf26422015-03-21 09:50:24 -050015from cryptography import x509
Paul Kehrerfbb7ac82015-03-16 19:26:29 -050016from cryptography.hazmat.backends.interfaces import RSABackend, X509Backend
17
18from .test_x509 import _load_cert
Paul Kehrer8cf26422015-03-21 09:50:24 -050019
20
Paul Kehrer85894662015-03-22 13:19:31 -050021class TestExtension(object):
22 def test_not_an_oid(self):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -050023 bc = x509.BasicConstraints(ca=False, path_length=None)
Paul Kehrer85894662015-03-22 13:19:31 -050024 with pytest.raises(TypeError):
25 x509.Extension("notanoid", True, bc)
26
27 def test_critical_not_a_bool(self):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -050028 bc = x509.BasicConstraints(ca=False, path_length=None)
Paul Kehrer85894662015-03-22 13:19:31 -050029 with pytest.raises(TypeError):
30 x509.Extension(x509.OID_BASIC_CONSTRAINTS, "notabool", bc)
31
32 def test_repr(self):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -050033 bc = x509.BasicConstraints(ca=False, path_length=None)
Paul Kehrer85894662015-03-22 13:19:31 -050034 ext = x509.Extension(x509.OID_BASIC_CONSTRAINTS, True, bc)
35 assert repr(ext) == (
36 "<Extension(oid=<ObjectIdentifier(oid=2.5.29.19, name=basicConst"
37 "raints)>, critical=True, value=<BasicConstraints(ca=False, path"
38 "_length=None)>)>"
39 )
40
41
Paul Kehrercecbbba2015-03-30 14:58:38 -050042class TestKeyUsage(object):
43 def test_key_agreement_false_encipher_decipher_true(self):
44 with pytest.raises(ValueError):
45 x509.KeyUsage(
46 digital_signature=False,
47 content_commitment=False,
48 key_encipherment=False,
49 data_encipherment=False,
50 key_agreement=False,
51 key_cert_sign=False,
52 crl_sign=False,
53 encipher_only=True,
54 decipher_only=False
55 )
56
57 with pytest.raises(ValueError):
58 x509.KeyUsage(
59 digital_signature=False,
60 content_commitment=False,
61 key_encipherment=False,
62 data_encipherment=False,
63 key_agreement=False,
64 key_cert_sign=False,
65 crl_sign=False,
66 encipher_only=True,
67 decipher_only=True
68 )
69
70 with pytest.raises(ValueError):
71 x509.KeyUsage(
72 digital_signature=False,
73 content_commitment=False,
74 key_encipherment=False,
75 data_encipherment=False,
76 key_agreement=False,
77 key_cert_sign=False,
78 crl_sign=False,
79 encipher_only=False,
80 decipher_only=True
81 )
82
83 def test_properties_key_agreement_true(self):
84 ku = x509.KeyUsage(
85 digital_signature=True,
86 content_commitment=True,
87 key_encipherment=False,
88 data_encipherment=False,
89 key_agreement=False,
90 key_cert_sign=True,
91 crl_sign=False,
92 encipher_only=False,
93 decipher_only=False
94 )
95 assert ku.digital_signature is True
96 assert ku.content_commitment is True
97 assert ku.key_encipherment is False
98 assert ku.data_encipherment is False
99 assert ku.key_agreement is False
100 assert ku.key_cert_sign is True
101 assert ku.crl_sign is False
102
103 def test_key_agreement_true_properties(self):
104 ku = x509.KeyUsage(
105 digital_signature=False,
106 content_commitment=False,
107 key_encipherment=False,
108 data_encipherment=False,
109 key_agreement=True,
110 key_cert_sign=False,
111 crl_sign=False,
112 encipher_only=False,
113 decipher_only=True
114 )
115 assert ku.key_agreement is True
116 assert ku.encipher_only is False
117 assert ku.decipher_only is True
118
119 def test_key_agreement_false_properties(self):
120 ku = x509.KeyUsage(
121 digital_signature=False,
122 content_commitment=False,
123 key_encipherment=False,
124 data_encipherment=False,
125 key_agreement=False,
126 key_cert_sign=False,
127 crl_sign=False,
128 encipher_only=False,
129 decipher_only=False
130 )
131 assert ku.key_agreement is False
132 with pytest.raises(ValueError):
133 ku.encipher_only
134
135 with pytest.raises(ValueError):
136 ku.decipher_only
137
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500138 def test_repr_key_agreement_false(self):
139 ku = x509.KeyUsage(
140 digital_signature=True,
141 content_commitment=True,
142 key_encipherment=False,
143 data_encipherment=False,
144 key_agreement=False,
145 key_cert_sign=True,
146 crl_sign=False,
147 encipher_only=False,
148 decipher_only=False
149 )
150 assert repr(ku) == (
151 "<KeyUsage(digital_signature=True, content_commitment=True, key_en"
152 "cipherment=False, data_encipherment=False, key_agreement=False, k"
Paul Kehrerb372e672015-04-15 11:05:24 -0400153 "ey_cert_sign=True, crl_sign=False, encipher_only=None, decipher_o"
154 "nly=None)>"
Paul Kehrerac3e5bb2015-04-02 23:07:10 -0500155 )
156
157 def test_repr_key_agreement_true(self):
158 ku = x509.KeyUsage(
159 digital_signature=True,
160 content_commitment=True,
161 key_encipherment=False,
162 data_encipherment=False,
163 key_agreement=True,
164 key_cert_sign=True,
165 crl_sign=False,
166 encipher_only=False,
167 decipher_only=False
168 )
169 assert repr(ku) == (
170 "<KeyUsage(digital_signature=True, content_commitment=True, key_en"
171 "cipherment=False, data_encipherment=False, key_agreement=True, k"
172 "ey_cert_sign=True, crl_sign=False, encipher_only=False, decipher_"
173 "only=False)>"
174 )
175
Paul Kehrercecbbba2015-03-30 14:58:38 -0500176
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500177class TestSubjectKeyIdentifier(object):
178 def test_properties(self):
Paul Kehrercbfb1012015-04-10 20:57:20 -0400179 value = binascii.unhexlify(b"092384932230498bc980aa8098456f6ff7ff3ac9")
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500180 ski = x509.SubjectKeyIdentifier(value)
181 assert ski.digest == value
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500182
183 def test_repr(self):
184 ski = x509.SubjectKeyIdentifier(
Paul Kehreree997262015-04-04 12:20:28 -0500185 binascii.unhexlify(b"092384932230498bc980aa8098456f6ff7ff3ac9")
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500186 )
187 ext = x509.Extension(x509.OID_SUBJECT_KEY_IDENTIFIER, False, ski)
Paul Kehrercbfb1012015-04-10 20:57:20 -0400188 if six.PY3:
189 assert repr(ext) == (
190 "<Extension(oid=<ObjectIdentifier(oid=2.5.29.14, name=subjectK"
191 "eyIdentifier)>, critical=False, value=<SubjectKeyIdentifier(d"
192 "igest=b\'\\t#\\x84\\x93\"0I\\x8b\\xc9\\x80\\xaa\\x80\\x98Eoo"
193 "\\xf7\\xff:\\xc9\')>)>"
194 )
195 else:
196 assert repr(ext) == (
197 "<Extension(oid=<ObjectIdentifier(oid=2.5.29.14, name=subjectK"
198 "eyIdentifier)>, critical=False, value=<SubjectKeyIdentifier(d"
199 "igest=\'\\t#\\x84\\x93\"0I\\x8b\\xc9\\x80\\xaa\\x80\\x98Eoo"
200 "\\xf7\\xff:\\xc9\')>)>"
201 )
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500202
203 def test_eq(self):
204 ski = x509.SubjectKeyIdentifier(
Paul Kehreree997262015-04-04 12:20:28 -0500205 binascii.unhexlify(b"092384932230498bc980aa8098456f6ff7ff3ac9")
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500206 )
207 ski2 = x509.SubjectKeyIdentifier(
Paul Kehreree997262015-04-04 12:20:28 -0500208 binascii.unhexlify(b"092384932230498bc980aa8098456f6ff7ff3ac9")
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500209 )
210 assert ski == ski2
211
212 def test_ne(self):
213 ski = x509.SubjectKeyIdentifier(
Paul Kehreree997262015-04-04 12:20:28 -0500214 binascii.unhexlify(b"092384932230498bc980aa8098456f6ff7ff3ac9")
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500215 )
216 ski2 = x509.SubjectKeyIdentifier(
Paul Kehreree997262015-04-04 12:20:28 -0500217 binascii.unhexlify(b"aa8098456f6ff7ff3ac9092384932230498bc980")
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500218 )
219 assert ski != ski2
220 assert ski != object()
221
222
Paul Kehrer2eb4ed92015-04-11 15:33:45 -0400223class TestAuthorityKeyIdentifier(object):
224 def test_authority_cert_issuer_not_name(self):
225 with pytest.raises(TypeError):
226 x509.AuthorityKeyIdentifier(b"identifier", "notname", 3)
227
228 def test_authority_cert_serial_number_not_integer(self):
229 name = x509.Name([
230 x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'),
231 x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'),
232 ])
233 with pytest.raises(TypeError):
234 x509.AuthorityKeyIdentifier(b"identifier", name, "notanint")
235
236 def test_authority_issuer_none_serial_not_none(self):
237 with pytest.raises(ValueError):
238 x509.AuthorityKeyIdentifier(b"identifier", None, 3)
239
240 def test_authority_issuer_not_none_serial_none(self):
241 name = x509.Name([
242 x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1'),
243 x509.NameAttribute(x509.ObjectIdentifier('oid2'), 'value2'),
244 ])
245 with pytest.raises(ValueError):
246 x509.AuthorityKeyIdentifier(b"identifier", name, None)
247
248 def test_authority_cert_serial_and_issuer_none(self):
249 aki = x509.AuthorityKeyIdentifier(b"id", None, None)
250 assert aki.key_identifier == b"id"
251 assert aki.authority_cert_issuer is None
252 assert aki.authority_cert_serial_number is None
253
254 def test_repr(self):
255 name = x509.Name([x509.NameAttribute(x509.OID_COMMON_NAME, 'myCN')])
256 aki = x509.AuthorityKeyIdentifier(b"digest", name, 1234)
257
258 if six.PY3:
259 assert repr(aki) == (
260 "<AuthorityKeyIdentifier(key_identifier=b'digest', authority_"
261 "cert_issuer=<Name([<NameAttribute(oid=<ObjectIdentifier(oid="
262 "2.5.4.3, name=commonName)>, value='myCN')>])>, authority_cer"
263 "t_serial_number=1234)>"
264 )
265 else:
266 assert repr(aki) == (
267 "<AuthorityKeyIdentifier(key_identifier='digest', authority_ce"
268 "rt_issuer=<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5"
269 ".4.3, name=commonName)>, value='myCN')>])>, authority_cert_se"
270 "rial_number=1234)>"
271 )
272
273
Paul Kehrer8cf26422015-03-21 09:50:24 -0500274class TestBasicConstraints(object):
275 def test_ca_not_boolean(self):
276 with pytest.raises(TypeError):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500277 x509.BasicConstraints(ca="notbool", path_length=None)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500278
279 def test_path_length_not_ca(self):
280 with pytest.raises(ValueError):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500281 x509.BasicConstraints(ca=False, path_length=0)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500282
283 def test_path_length_not_int(self):
284 with pytest.raises(TypeError):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500285 x509.BasicConstraints(ca=True, path_length=1.1)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500286
287 with pytest.raises(TypeError):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500288 x509.BasicConstraints(ca=True, path_length="notint")
Paul Kehrer8cf26422015-03-21 09:50:24 -0500289
290 def test_path_length_negative(self):
291 with pytest.raises(TypeError):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500292 x509.BasicConstraints(ca=True, path_length=-1)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500293
294 def test_repr(self):
Paul Kehrera5c6e9a2015-03-23 19:23:43 -0500295 na = x509.BasicConstraints(ca=True, path_length=None)
Paul Kehrer8cf26422015-03-21 09:50:24 -0500296 assert repr(na) == (
Paul Kehrer85894662015-03-22 13:19:31 -0500297 "<BasicConstraints(ca=True, path_length=None)>"
Paul Kehrer8cf26422015-03-21 09:50:24 -0500298 )
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500299
300
Paul Kehrerffa2a152015-03-31 08:18:25 -0500301class TestExtendedKeyUsage(object):
302 def test_not_all_oids(self):
303 with pytest.raises(TypeError):
304 x509.ExtendedKeyUsage(["notoid"])
305
306 def test_iter_len(self):
307 eku = x509.ExtendedKeyUsage([
308 x509.ObjectIdentifier("1.3.6.1.5.5.7.3.1"),
309 x509.ObjectIdentifier("1.3.6.1.5.5.7.3.2"),
310 ])
311 assert len(eku) == 2
312 assert list(eku) == [
313 x509.OID_SERVER_AUTH,
314 x509.OID_CLIENT_AUTH
315 ]
316
Paul Kehrer23d10c32015-04-02 23:12:32 -0500317 def test_repr(self):
318 eku = x509.ExtendedKeyUsage([
319 x509.ObjectIdentifier("1.3.6.1.5.5.7.3.1"),
320 x509.ObjectIdentifier("1.3.6.1.5.5.7.3.2"),
321 ])
322 assert repr(eku) == (
323 "<ExtendedKeyUsage([<ObjectIdentifier(oid=1.3.6.1.5.5.7.3.1, name="
324 "serverAuth)>, <ObjectIdentifier(oid=1.3.6.1.5.5.7.3.2, name=clien"
325 "tAuth)>])>"
326 )
327
Paul Kehrerb0476172015-05-02 19:34:51 -0500328 def test_eq(self):
329 eku = x509.ExtendedKeyUsage([
330 x509.ObjectIdentifier("1.3.6"), x509.ObjectIdentifier("1.3.7")
331 ])
332 eku2 = x509.ExtendedKeyUsage([
333 x509.ObjectIdentifier("1.3.6"), x509.ObjectIdentifier("1.3.7")
334 ])
335 assert eku == eku2
336
337 def test_ne(self):
338 eku = x509.ExtendedKeyUsage([x509.ObjectIdentifier("1.3.6")])
339 eku2 = x509.ExtendedKeyUsage([x509.ObjectIdentifier("1.3.6.1")])
340 assert eku != eku2
341 assert eku != object()
342
Paul Kehrerffa2a152015-03-31 08:18:25 -0500343
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500344@pytest.mark.requires_backend_interface(interface=RSABackend)
345@pytest.mark.requires_backend_interface(interface=X509Backend)
346class TestExtensions(object):
347 def test_no_extensions(self, backend):
348 cert = _load_cert(
349 os.path.join("x509", "verisign_md2_root.pem"),
350 x509.load_pem_x509_certificate,
351 backend
352 )
353 ext = cert.extensions
354 assert len(ext) == 0
355 assert list(ext) == []
Paul Kehrerfa56a232015-03-17 13:14:03 -0500356 with pytest.raises(x509.ExtensionNotFound) as exc:
357 ext.get_extension_for_oid(x509.OID_BASIC_CONSTRAINTS)
358
359 assert exc.value.oid == x509.OID_BASIC_CONSTRAINTS
360
361 def test_one_extension(self, backend):
362 cert = _load_cert(
363 os.path.join(
364 "x509", "custom", "basic_constraints_not_critical.pem"
365 ),
366 x509.load_pem_x509_certificate,
367 backend
368 )
369 extensions = cert.extensions
370 ext = extensions.get_extension_for_oid(x509.OID_BASIC_CONSTRAINTS)
371 assert ext is not None
372 assert ext.value.ca is False
Paul Kehrerfbb7ac82015-03-16 19:26:29 -0500373
374 def test_duplicate_extension(self, backend):
375 cert = _load_cert(
376 os.path.join(
377 "x509", "custom", "two_basic_constraints.pem"
378 ),
379 x509.load_pem_x509_certificate,
380 backend
381 )
382 with pytest.raises(x509.DuplicateExtension) as exc:
383 cert.extensions
384
385 assert exc.value.oid == x509.OID_BASIC_CONSTRAINTS
386
387 def test_unsupported_critical_extension(self, backend):
388 cert = _load_cert(
389 os.path.join(
390 "x509", "custom", "unsupported_extension_critical.pem"
391 ),
392 x509.load_pem_x509_certificate,
393 backend
394 )
395 with pytest.raises(x509.UnsupportedExtension) as exc:
396 cert.extensions
397
398 assert exc.value.oid == x509.ObjectIdentifier("1.2.3.4")
399
400 def test_unsupported_extension(self, backend):
401 # TODO: this will raise an exception when all extensions are complete
402 cert = _load_cert(
403 os.path.join(
404 "x509", "custom", "unsupported_extension.pem"
405 ),
406 x509.load_pem_x509_certificate,
407 backend
408 )
409 extensions = cert.extensions
410 assert len(extensions) == 0
Paul Kehrerfa56a232015-03-17 13:14:03 -0500411
412
413@pytest.mark.requires_backend_interface(interface=RSABackend)
414@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrerde813ea2015-03-28 12:44:34 -0500415class TestBasicConstraintsExtension(object):
Paul Kehrerfa56a232015-03-17 13:14:03 -0500416 def test_ca_true_pathlen_6(self, backend):
417 cert = _load_cert(
418 os.path.join(
419 "x509", "PKITS_data", "certs", "pathLenConstraint6CACert.crt"
420 ),
421 x509.load_der_x509_certificate,
422 backend
423 )
424 ext = cert.extensions.get_extension_for_oid(
425 x509.OID_BASIC_CONSTRAINTS
426 )
427 assert ext is not None
428 assert ext.critical is True
429 assert ext.value.ca is True
430 assert ext.value.path_length == 6
431
432 def test_path_length_zero(self, backend):
433 cert = _load_cert(
434 os.path.join("x509", "custom", "bc_path_length_zero.pem"),
435 x509.load_pem_x509_certificate,
436 backend
437 )
438 ext = cert.extensions.get_extension_for_oid(
439 x509.OID_BASIC_CONSTRAINTS
440 )
441 assert ext is not None
442 assert ext.critical is True
443 assert ext.value.ca is True
444 assert ext.value.path_length == 0
445
446 def test_ca_true_no_pathlen(self, backend):
447 cert = _load_cert(
448 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
449 x509.load_der_x509_certificate,
450 backend
451 )
452 ext = cert.extensions.get_extension_for_oid(
453 x509.OID_BASIC_CONSTRAINTS
454 )
455 assert ext is not None
456 assert ext.critical is True
457 assert ext.value.ca is True
458 assert ext.value.path_length is None
459
460 def test_ca_false(self, backend):
461 cert = _load_cert(
462 os.path.join("x509", "cryptography.io.pem"),
463 x509.load_pem_x509_certificate,
464 backend
465 )
466 ext = cert.extensions.get_extension_for_oid(
467 x509.OID_BASIC_CONSTRAINTS
468 )
469 assert ext is not None
470 assert ext.critical is True
471 assert ext.value.ca is False
472 assert ext.value.path_length is None
473
474 def test_no_basic_constraints(self, backend):
475 cert = _load_cert(
476 os.path.join(
477 "x509",
478 "PKITS_data",
479 "certs",
480 "ValidCertificatePathTest1EE.crt"
481 ),
482 x509.load_der_x509_certificate,
483 backend
484 )
485 with pytest.raises(x509.ExtensionNotFound):
486 cert.extensions.get_extension_for_oid(x509.OID_BASIC_CONSTRAINTS)
487
488 def test_basic_constraint_not_critical(self, backend):
489 cert = _load_cert(
490 os.path.join(
491 "x509", "custom", "basic_constraints_not_critical.pem"
492 ),
493 x509.load_pem_x509_certificate,
494 backend
495 )
496 ext = cert.extensions.get_extension_for_oid(
497 x509.OID_BASIC_CONSTRAINTS
498 )
499 assert ext is not None
500 assert ext.critical is False
501 assert ext.value.ca is False
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500502
503
504@pytest.mark.requires_backend_interface(interface=RSABackend)
505@pytest.mark.requires_backend_interface(interface=X509Backend)
506class TestSubjectKeyIdentifierExtension(object):
507 def test_subject_key_identifier(self, backend):
508 cert = _load_cert(
509 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
510 x509.load_der_x509_certificate,
511 backend
512 )
513 ext = cert.extensions.get_extension_for_oid(
514 x509.OID_SUBJECT_KEY_IDENTIFIER
515 )
516 ski = ext.value
517 assert ext is not None
518 assert ext.critical is False
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500519 assert ski.digest == binascii.unhexlify(
Paul Kehreree997262015-04-04 12:20:28 -0500520 b"580184241bbc2b52944a3da510721451f5af3ac9"
Paul Kehrer1eb82a62015-03-31 20:00:33 -0500521 )
522
523 def test_no_subject_key_identifier(self, backend):
524 cert = _load_cert(
525 os.path.join("x509", "custom", "bc_path_length_zero.pem"),
526 x509.load_pem_x509_certificate,
527 backend
528 )
529 with pytest.raises(x509.ExtensionNotFound):
530 cert.extensions.get_extension_for_oid(
531 x509.OID_SUBJECT_KEY_IDENTIFIER
532 )
Paul Kehrer5508ee22015-04-02 19:31:03 -0500533
534
535@pytest.mark.requires_backend_interface(interface=RSABackend)
536@pytest.mark.requires_backend_interface(interface=X509Backend)
537class TestKeyUsageExtension(object):
538 def test_no_key_usage(self, backend):
539 cert = _load_cert(
540 os.path.join("x509", "verisign_md2_root.pem"),
541 x509.load_pem_x509_certificate,
542 backend
543 )
544 ext = cert.extensions
545 with pytest.raises(x509.ExtensionNotFound) as exc:
546 ext.get_extension_for_oid(x509.OID_KEY_USAGE)
547
548 assert exc.value.oid == x509.OID_KEY_USAGE
549
550 def test_all_purposes(self, backend):
551 cert = _load_cert(
552 os.path.join(
553 "x509", "custom", "all_key_usages.pem"
554 ),
555 x509.load_pem_x509_certificate,
556 backend
557 )
558 extensions = cert.extensions
559 ext = extensions.get_extension_for_oid(x509.OID_KEY_USAGE)
560 assert ext is not None
561
562 ku = ext.value
563 assert ku.digital_signature is True
564 assert ku.content_commitment is True
565 assert ku.key_encipherment is True
566 assert ku.data_encipherment is True
567 assert ku.key_agreement is True
568 assert ku.key_cert_sign is True
569 assert ku.crl_sign is True
570 assert ku.encipher_only is True
571 assert ku.decipher_only is True
572
573 def test_key_cert_sign_crl_sign(self, backend):
574 cert = _load_cert(
575 os.path.join(
576 "x509", "PKITS_data", "certs", "pathLenConstraint6CACert.crt"
577 ),
578 x509.load_der_x509_certificate,
579 backend
580 )
581 ext = cert.extensions.get_extension_for_oid(x509.OID_KEY_USAGE)
582 assert ext is not None
583 assert ext.critical is True
584
585 ku = ext.value
586 assert ku.digital_signature is False
587 assert ku.content_commitment is False
588 assert ku.key_encipherment is False
589 assert ku.data_encipherment is False
590 assert ku.key_agreement is False
591 assert ku.key_cert_sign is True
592 assert ku.crl_sign is True
Paul Kehrer31bdf792015-03-25 14:11:00 -0500593
594
595@pytest.mark.parametrize(
596 "name", [
597 x509.RFC822Name,
598 x509.DNSName,
599 x509.UniformResourceIdentifier
600 ]
601)
602class TestTextGeneralNames(object):
603 def test_not_text(self, name):
604 with pytest.raises(TypeError):
605 name(b"notaunicodestring")
606
607 with pytest.raises(TypeError):
608 name(1.3)
609
610 def test_repr(self, name):
Eeshan Gargf1234152015-04-29 18:41:00 +0530611 gn = name(u"string")
Paul Kehrer31bdf792015-03-25 14:11:00 -0500612 assert repr(gn) == "<{0}(value=string)>".format(name.__name__)
613
614 def test_eq(self, name):
Eeshan Gargf1234152015-04-29 18:41:00 +0530615 gn = name(u"string")
616 gn2 = name(u"string")
Paul Kehrer31bdf792015-03-25 14:11:00 -0500617 assert gn == gn2
618
619 def test_ne(self, name):
Eeshan Gargf1234152015-04-29 18:41:00 +0530620 gn = name(u"string")
621 gn2 = name(u"string2")
Paul Kehrer31bdf792015-03-25 14:11:00 -0500622 assert gn != gn2
623 assert gn != object()
624
625
626class TestDirectoryName(object):
627 def test_not_name(self):
628 with pytest.raises(TypeError):
629 x509.DirectoryName(b"notaname")
630
631 with pytest.raises(TypeError):
632 x509.DirectoryName(1.3)
633
634 def test_repr(self):
635 name = x509.Name([x509.NameAttribute(x509.OID_COMMON_NAME, 'value1')])
636 gn = x509.DirectoryName(x509.Name([name]))
637 assert repr(gn) == (
638 "<DirectoryName(value=<Name([<Name([<NameAttribute(oid=<ObjectIden"
639 "tifier(oid=2.5.4.3, name=commonName)>, value='value1')>])>])>)>"
640 )
641
642 def test_eq(self):
643 name = x509.Name([
644 x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1')
645 ])
646 name2 = x509.Name([
647 x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1')
648 ])
649 gn = x509.DirectoryName(x509.Name([name]))
650 gn2 = x509.DirectoryName(x509.Name([name2]))
651 assert gn == gn2
652
653 def test_ne(self):
654 name = x509.Name([
655 x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value1')
656 ])
657 name2 = x509.Name([
658 x509.NameAttribute(x509.ObjectIdentifier('oid'), 'value2')
659 ])
660 gn = x509.DirectoryName(x509.Name([name]))
661 gn2 = x509.DirectoryName(x509.Name([name2]))
662 assert gn != gn2
663 assert gn != object()
664
665
666class TestRegisteredID(object):
667 def test_not_oid(self):
668 with pytest.raises(TypeError):
669 x509.RegisteredID(b"notanoid")
670
671 with pytest.raises(TypeError):
672 x509.RegisteredID(1.3)
673
674 def test_repr(self):
675 gn = x509.RegisteredID(x509.OID_COMMON_NAME)
676 assert repr(gn) == (
677 "<RegisteredID(value=<ObjectIdentifier(oid=2.5.4.3, name=commonNam"
678 "e)>)>"
679 )
680
681 def test_eq(self):
682 gn = x509.RegisteredID(x509.OID_COMMON_NAME)
683 gn2 = x509.RegisteredID(x509.OID_COMMON_NAME)
684 assert gn == gn2
685
686 def test_ne(self):
687 gn = x509.RegisteredID(x509.OID_COMMON_NAME)
688 gn2 = x509.RegisteredID(x509.OID_BASIC_CONSTRAINTS)
689 assert gn != gn2
690 assert gn != object()
691
692
693class TestIPAddress(object):
694 def test_not_ipaddress(self):
695 with pytest.raises(TypeError):
696 x509.IPAddress(b"notanipaddress")
697
698 with pytest.raises(TypeError):
699 x509.IPAddress(1.3)
700
701 def test_repr(self):
Eeshan Gargf1234152015-04-29 18:41:00 +0530702 gn = x509.IPAddress(ipaddress.IPv4Address(u"127.0.0.1"))
Paul Kehrer31bdf792015-03-25 14:11:00 -0500703 assert repr(gn) == "<IPAddress(value=127.0.0.1)>"
704
Eeshan Gargf1234152015-04-29 18:41:00 +0530705 gn2 = x509.IPAddress(ipaddress.IPv6Address(u"ff::"))
Paul Kehrer31bdf792015-03-25 14:11:00 -0500706 assert repr(gn2) == "<IPAddress(value=ff::)>"
707
708 def test_eq(self):
Eeshan Gargf1234152015-04-29 18:41:00 +0530709 gn = x509.IPAddress(ipaddress.IPv4Address(u"127.0.0.1"))
710 gn2 = x509.IPAddress(ipaddress.IPv4Address(u"127.0.0.1"))
Paul Kehrer31bdf792015-03-25 14:11:00 -0500711 assert gn == gn2
712
713 def test_ne(self):
Eeshan Gargf1234152015-04-29 18:41:00 +0530714 gn = x509.IPAddress(ipaddress.IPv4Address(u"127.0.0.1"))
715 gn2 = x509.IPAddress(ipaddress.IPv4Address(u"127.0.0.2"))
Paul Kehrer31bdf792015-03-25 14:11:00 -0500716 assert gn != gn2
717 assert gn != object()
718
719
720class TestSubjectAlternativeName(object):
721 def test_get_values_for_type(self):
722 san = x509.SubjectAlternativeName(
Eeshan Gargf1234152015-04-29 18:41:00 +0530723 [x509.DNSName(u"cryptography.io")]
Paul Kehrer31bdf792015-03-25 14:11:00 -0500724 )
725 names = san.get_values_for_type(x509.DNSName)
Eeshan Gargf1234152015-04-29 18:41:00 +0530726 assert names == [u"cryptography.io"]
Paul Kehrer31bdf792015-03-25 14:11:00 -0500727
728 def test_iter_names(self):
729 san = x509.SubjectAlternativeName([
Eeshan Gargf1234152015-04-29 18:41:00 +0530730 x509.DNSName(u"cryptography.io"),
731 x509.DNSName(u"crypto.local"),
Paul Kehrer31bdf792015-03-25 14:11:00 -0500732 ])
733 assert len(san) == 2
734 assert list(san) == [
Eeshan Gargf1234152015-04-29 18:41:00 +0530735 x509.DNSName(u"cryptography.io"),
736 x509.DNSName(u"crypto.local"),
Paul Kehrer31bdf792015-03-25 14:11:00 -0500737 ]
738
Paul Kehrerd04b39b2015-04-21 08:44:17 -0500739 def test_invalid_general_names(self):
740 with pytest.raises(TypeError):
741 x509.SubjectAlternativeName(
Eeshan Gargf1234152015-04-29 18:41:00 +0530742 [x509.DNSName(u"cryptography.io"), "invalid"]
Paul Kehrerd04b39b2015-04-21 08:44:17 -0500743 )
744
Paul Kehrer31bdf792015-03-25 14:11:00 -0500745 def test_repr(self):
746 san = x509.SubjectAlternativeName(
747 [
Eeshan Gargf1234152015-04-29 18:41:00 +0530748 x509.DNSName(u"cryptography.io")
Paul Kehrer31bdf792015-03-25 14:11:00 -0500749 ]
750 )
751 assert repr(san) == (
752 "<SubjectAlternativeName([<DNSName(value=cryptography.io)>])>"
753 )
Paul Kehrer40f83382015-04-20 15:00:16 -0500754
755
756@pytest.mark.requires_backend_interface(interface=RSABackend)
757@pytest.mark.requires_backend_interface(interface=X509Backend)
758class TestRSASubjectAlternativeNameExtension(object):
759 def test_dns_name(self, backend):
760 cert = _load_cert(
761 os.path.join("x509", "cryptography.io.pem"),
762 x509.load_pem_x509_certificate,
763 backend
764 )
765 ext = cert.extensions.get_extension_for_oid(
766 x509.OID_SUBJECT_ALTERNATIVE_NAME
767 )
768 assert ext is not None
769 assert ext.critical is False
770
771 san = ext.value
772
773 dns = san.get_values_for_type(x509.DNSName)
774 assert dns == [u"www.cryptography.io", u"cryptography.io"]
Paul Kehrer9089c912015-04-20 22:15:20 -0500775
776 def test_unsupported_other_name(self, backend):
777 cert = _load_cert(
778 os.path.join(
779 "x509", "custom", "san_other_name.pem"
780 ),
781 x509.load_pem_x509_certificate,
782 backend
783 )
Paul Kehrerbed07352015-04-21 08:31:10 -0500784 with pytest.raises(x509.UnsupportedGeneralNameType) as exc:
Paul Kehrer9089c912015-04-20 22:15:20 -0500785 cert.extensions
Paul Kehrerbed07352015-04-21 08:31:10 -0500786
Paul Kehrer0a621bf2015-04-22 09:22:56 -0500787 assert exc.value.type == 0
Paul Kehrer4db96622015-04-20 22:17:39 -0500788
789 def test_registered_id(self, backend):
790 cert = _load_cert(
791 os.path.join(
792 "x509", "custom", "san_registered_id.pem"
793 ),
794 x509.load_pem_x509_certificate,
795 backend
796 )
797 ext = cert.extensions.get_extension_for_oid(
798 x509.OID_SUBJECT_ALTERNATIVE_NAME
799 )
800 assert ext is not None
801 assert ext.critical is False
802
803 san = ext.value
804 rid = san.get_values_for_type(x509.RegisteredID)
805 assert rid == [x509.ObjectIdentifier("1.2.3.4")]
Paul Kehrerb8ef82e2015-04-22 16:04:24 -0500806
807 def test_uri(self, backend):
808 cert = _load_cert(
809 os.path.join(
810 "x509", "custom", "san_uri_with_port.pem"
811 ),
812 x509.load_pem_x509_certificate,
813 backend
814 )
815 ext = cert.extensions.get_extension_for_oid(
816 x509.OID_SUBJECT_ALTERNATIVE_NAME
817 )
818 assert ext is not None
819 uri = ext.value.get_values_for_type(
820 x509.UniformResourceIdentifier
821 )
822 assert uri == [
823 u"gopher://\u043f\u044b\u043a\u0430.cryptography:70/path?q=s#hel"
824 u"lo",
825 u"http://someregulardomain.com",
826 ]
Paul Kehrera5f030c2015-04-28 08:33:18 -0500827
828 def test_ipaddress(self, backend):
829 cert = _load_cert(
830 os.path.join(
831 "x509", "custom", "san_ipaddr.pem"
832 ),
833 x509.load_pem_x509_certificate,
834 backend
835 )
836 ext = cert.extensions.get_extension_for_oid(
837 x509.OID_SUBJECT_ALTERNATIVE_NAME
838 )
839 assert ext is not None
840 assert ext.critical is False
841
842 san = ext.value
843
844 ip = san.get_values_for_type(x509.IPAddress)
845 assert [
846 ipaddress.ip_address(u"127.0.0.1"),
847 ipaddress.ip_address(u"ff::")
848 ] == ip
Paul Kehrer2187a052015-04-30 08:22:07 -0500849
850 def test_dirname(self, backend):
851 cert = _load_cert(
852 os.path.join(
853 "x509", "custom", "san_dirname.pem"
854 ),
855 x509.load_pem_x509_certificate,
856 backend
857 )
858 ext = cert.extensions.get_extension_for_oid(
859 x509.OID_SUBJECT_ALTERNATIVE_NAME
860 )
861 assert ext is not None
862 assert ext.critical is False
863
864 san = ext.value
865
866 dirname = san.get_values_for_type(x509.DirectoryName)
867 assert [
868 x509.Name([
869 x509.NameAttribute(x509.OID_COMMON_NAME, 'test'),
870 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, 'Org'),
871 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, 'Texas'),
872 ])
873 ] == dirname
Paul Kehrere06cab42015-04-30 10:23:33 -0500874
875 def test_rfc822name(self, backend):
876 cert = _load_cert(
877 os.path.join(
878 "x509", "custom", "san_rfc822_idna.pem"
879 ),
880 x509.load_pem_x509_certificate,
881 backend
882 )
883 ext = cert.extensions.get_extension_for_oid(
884 x509.OID_SUBJECT_ALTERNATIVE_NAME
885 )
886 assert ext is not None
887 assert ext.critical is False
888
889 san = ext.value
890
891 rfc822name = san.get_values_for_type(x509.RFC822Name)
892 assert [u"email@em\xe5\xefl.com"] == rfc822name
893
894 def test_unicode_rfc822_name_dns_name_uri(self, backend):
895 cert = _load_cert(
896 os.path.join(
897 "x509", "custom", "san_idna_names.pem"
898 ),
899 x509.load_pem_x509_certificate,
900 backend
901 )
902 ext = cert.extensions.get_extension_for_oid(
903 x509.OID_SUBJECT_ALTERNATIVE_NAME
904 )
905 assert ext is not None
906 rfc822_name = ext.value.get_values_for_type(x509.RFC822Name)
907 dns_name = ext.value.get_values_for_type(x509.DNSName)
908 uri = ext.value.get_values_for_type(x509.UniformResourceIdentifier)
909 assert rfc822_name == [u"email@\u043f\u044b\u043a\u0430.cryptography"]
910 assert dns_name == [u"\u043f\u044b\u043a\u0430.cryptography"]
911 assert uri == [u"https://www.\u043f\u044b\u043a\u0430.cryptography"]
912
913 def test_rfc822name_dnsname_ipaddress_directoryname_uri(self, backend):
914 cert = _load_cert(
915 os.path.join(
916 "x509", "custom", "san_email_dns_ip_dirname_uri.pem"
917 ),
918 x509.load_pem_x509_certificate,
919 backend
920 )
921 ext = cert.extensions.get_extension_for_oid(
922 x509.OID_SUBJECT_ALTERNATIVE_NAME
923 )
924 assert ext is not None
925 assert ext.critical is False
926
927 san = ext.value
928
929 rfc822_name = san.get_values_for_type(x509.RFC822Name)
930 uri = san.get_values_for_type(x509.UniformResourceIdentifier)
931 dns = san.get_values_for_type(x509.DNSName)
932 ip = san.get_values_for_type(x509.IPAddress)
933 dirname = san.get_values_for_type(x509.DirectoryName)
934 assert [u"user@cryptography.io"] == rfc822_name
Paul Kehrere3a330c2015-05-02 16:42:52 -0500935 assert [u"https://cryptography.io"] == uri
Paul Kehrere06cab42015-04-30 10:23:33 -0500936 assert [u"cryptography.io"] == dns
937 assert [
938 x509.Name([
939 x509.NameAttribute(x509.OID_COMMON_NAME, 'dirCN'),
940 x509.NameAttribute(
941 x509.OID_ORGANIZATION_NAME, 'Cryptographic Authority'
942 ),
943 ])
944 ] == dirname
945 assert [
946 ipaddress.ip_address(u"127.0.0.1"),
947 ipaddress.ip_address(u"ff::")
948 ] == ip
949
950 def test_invalid_rfc822name(self, backend):
951 cert = _load_cert(
952 os.path.join(
953 "x509", "custom", "san_rfc822_names.pem"
954 ),
955 x509.load_pem_x509_certificate,
956 backend
957 )
958 with pytest.raises(ValueError) as exc:
959 cert.extensions
960
961 assert 'Invalid rfc822name value' in str(exc.value)