blob: 61e7a7d02540a40c6aefd3ae2b7b750d63067206 [file] [log] [blame]
Paul Kehrer016e08a2014-11-26 09:41:18 -10001# 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 Kehrer0307c372014-11-27 09:49:31 -10007import binascii
Paul Kehrer016e08a2014-11-26 09:41:18 -10008import datetime
Paul Kehrer235e5a12015-07-10 19:45:47 -05009import ipaddress
Paul Kehrer016e08a2014-11-26 09:41:18 -100010import os
Paul Kehrer016e08a2014-11-26 09:41:18 -100011
12import pytest
13
Ian Cordascoa908d692015-06-16 21:35:24 -050014import six
15
Paul Kehrer474a6472015-07-11 12:29:52 -050016from cryptography import utils, x509
Paul Kehrer8802a5b2015-02-13 12:06:57 -060017from cryptography.exceptions import UnsupportedAlgorithm
Paul Kehrerf1ef3512014-11-26 17:36:05 -100018from cryptography.hazmat.backends.interfaces import (
19 DSABackend, EllipticCurveBackend, RSABackend, X509Backend
20)
Andre Caron476c5df2015-05-18 10:23:28 -040021from cryptography.hazmat.primitives import hashes, serialization
Alex Gaynor32c57df2015-02-23 21:51:27 -080022from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
Paul Kehrer9e102db2015-08-10 21:53:09 -050023from cryptography.x509.oid import (
24 AuthorityInformationAccessOID, ExtendedKeyUsageOID, ExtensionOID, NameOID
25)
Paul Kehrer016e08a2014-11-26 09:41:18 -100026
Ian Cordasco8ed8edc2015-06-22 20:11:17 -050027from .hazmat.primitives.fixtures_dsa import DSA_KEY_2048
Ian Cordasco85fc4d52015-08-01 20:29:31 -050028from .hazmat.primitives.fixtures_rsa import RSA_KEY_2048, RSA_KEY_512
Ian Cordasco4d46eb72015-06-17 12:08:27 -050029from .hazmat.primitives.test_ec import _skip_curve_unsupported
Paul Kehrera9d78c12014-11-26 10:59:03 -100030from .utils import load_vectors_from_file
Paul Kehrer016e08a2014-11-26 09:41:18 -100031
32
Paul Kehrer69b64e42015-08-09 00:00:44 -050033@utils.register_interface(x509.ExtensionType)
34class DummyExtension(object):
35 oid = x509.ObjectIdentifier("1.2.3.4")
36
37
Paul Kehrer474a6472015-07-11 12:29:52 -050038@utils.register_interface(x509.GeneralName)
39class FakeGeneralName(object):
40 def __init__(self, value):
41 self._value = value
42
43 value = utils.read_only_property("_value")
44
45
Paul Kehrer41120322014-12-02 18:31:14 -100046def _load_cert(filename, loader, backend):
Paul Kehrer016e08a2014-11-26 09:41:18 -100047 cert = load_vectors_from_file(
Paul Kehrera693cfd2014-11-27 07:47:58 -100048 filename=filename,
49 loader=lambda pemfile: loader(pemfile.read(), backend),
50 mode="rb"
Paul Kehrer016e08a2014-11-26 09:41:18 -100051 )
52 return cert
53
54
Erik Trauschkedc570402015-09-24 20:24:28 -070055@pytest.mark.requires_backend_interface(interface=X509Backend)
56class TestCertificateRevocationList(object):
57 def test_load_pem_crl(self, backend):
58 crl = _load_cert(
59 os.path.join("x509", "custom", "crl_all_reasons.pem"),
60 x509.load_pem_x509_crl,
61 backend
62 )
63
64 assert isinstance(crl, x509.CertificateRevocationList)
65 fingerprint = binascii.hexlify(crl.fingerprint(hashes.SHA1()))
66 assert fingerprint == b"3234b0cb4c0cedf6423724b736729dcfc9e441ef"
67 assert isinstance(crl.signature_hash_algorithm, hashes.SHA256)
68
69 def test_load_der_crl(self, backend):
70 crl = _load_cert(
71 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
72 x509.load_der_x509_crl,
73 backend
74 )
75
76 assert isinstance(crl, x509.CertificateRevocationList)
77 fingerprint = binascii.hexlify(crl.fingerprint(hashes.SHA1()))
78 assert fingerprint == b"dd3db63c50f4c4a13e090f14053227cb1011a5ad"
79 assert isinstance(crl.signature_hash_algorithm, hashes.SHA256)
80
81 def test_invalid_pem(self, backend):
82 with pytest.raises(ValueError):
83 x509.load_pem_x509_crl(b"notacrl", backend)
84
85 def test_invalid_der(self, backend):
86 with pytest.raises(ValueError):
87 x509.load_der_x509_crl(b"notacrl", backend)
88
89 def test_unknown_signature_algorithm(self, backend):
90 crl = _load_cert(
91 os.path.join(
92 "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
93 ),
94 x509.load_pem_x509_crl,
95 backend
96 )
97
98 with pytest.raises(UnsupportedAlgorithm):
99 crl.signature_hash_algorithm()
100
101 def test_issuer(self, backend):
102 crl = _load_cert(
103 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
104 x509.load_der_x509_crl,
105 backend
106 )
107
108 assert isinstance(crl.issuer, x509.Name)
109 assert list(crl.issuer) == [
110 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
111 x509.NameAttribute(
112 x509.OID_ORGANIZATION_NAME, u'Test Certificates 2011'
113 ),
114 x509.NameAttribute(x509.OID_COMMON_NAME, u'Good CA')
115 ]
116 assert crl.issuer.get_attributes_for_oid(x509.OID_COMMON_NAME) == [
117 x509.NameAttribute(x509.OID_COMMON_NAME, u'Good CA')
118 ]
119
120 def test_equality(self, backend):
121 crl1 = _load_cert(
122 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
123 x509.load_der_x509_crl,
124 backend
125 )
126
127 crl2 = _load_cert(
128 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
129 x509.load_der_x509_crl,
130 backend
131 )
132
133 crl3 = _load_cert(
134 os.path.join("x509", "custom", "crl_all_reasons.pem"),
135 x509.load_pem_x509_crl,
136 backend
137 )
138
139 assert crl1 == crl2
140 assert crl1 != crl3
141 assert crl1 != object()
142
143 def test_update_dates(self, backend):
144 crl = _load_cert(
145 os.path.join("x509", "custom", "crl_all_reasons.pem"),
146 x509.load_pem_x509_crl,
147 backend
148 )
149
150 assert isinstance(crl.next_update, datetime.datetime)
151 assert isinstance(crl.last_update, datetime.datetime)
152
153 assert crl.next_update.isoformat() == "2016-01-01T00:00:00"
154 assert crl.last_update.isoformat() == "2015-01-01T00:00:00"
155
156 def test_revoked_certs(self, backend):
157 crl = _load_cert(
158 os.path.join("x509", "custom", "crl_all_reasons.pem"),
159 x509.load_pem_x509_crl,
160 backend
161 )
162
163 assert isinstance(crl.revoked_certificates, list)
164 for r in crl.revoked_certificates:
165 assert isinstance(r, x509.RevokedCertificate)
166
167 def test_extensions(self, backend):
168 crl = _load_cert(
169 os.path.join("x509", "custom", "crl_all_reasons.pem"),
170 x509.load_pem_x509_crl,
171 backend
172 )
173
174 # CRL extensions are currently not supported in the OpenSSL backend.
175 with pytest.raises(NotImplementedError):
176 crl.extensions
177
178
179@pytest.mark.requires_backend_interface(interface=X509Backend)
180class TestRevokedCertificate(object):
181
182 def test_revoked_basics(self, backend):
183 crl = _load_cert(
184 os.path.join("x509", "custom", "crl_all_reasons.pem"),
185 x509.load_pem_x509_crl,
186 backend
187 )
188
189 for i, rev in enumerate(crl.revoked_certificates):
190 assert isinstance(rev, x509.RevokedCertificate)
191 assert isinstance(rev.serial_number, int)
192 assert isinstance(rev.revocation_date, datetime.datetime)
193 assert isinstance(rev.extensions, x509.Extensions)
194
195 assert rev.serial_number == i
196 assert rev.revocation_date.isoformat() == "2015-01-01T00:00:00"
197
198 def test_revoked_extensions(self, backend):
199 crl = _load_cert(
200 os.path.join("x509", "custom", "crl_all_reasons.pem"),
201 x509.load_pem_x509_crl,
202 backend
203 )
204
205 # First revoked cert doesn't have extensions, test if it is handled
206 # correctly.
207 rev0 = crl.revoked_certificates[0]
208 # It should return an empty Extensions object.
209 assert isinstance(rev0.extensions, x509.Extensions)
210 assert len(rev0.extensions) == 0
211 with pytest.raises(x509.ExtensionNotFound):
212 rev0.extensions.get_extension_for_oid(x509.OID_CRL_REASON)
213
214 assert rev0.get_invalidity_date() is None
215 assert rev0.get_certificate_issuer() is None
216 assert rev0.get_reason() is None
217
218 # Test manual retrieval of extension values.
219 rev1 = crl.revoked_certificates[1]
220 assert isinstance(rev1.extensions, x509.Extensions)
221
222 reason = rev1.extensions.get_extension_for_oid(
223 x509.OID_CRL_REASON).value
224 assert reason == x509.ReasonFlags.unspecified
225
226 date = rev1.extensions.get_extension_for_oid(
227 x509.OID_INVALIDITY_DATE).value
228 assert isinstance(date, datetime.datetime)
229 assert date.isoformat() == "2015-01-01T00:00:00"
230
231 # Test convenience function.
232 assert rev1.get_invalidity_date().isoformat() == "2015-01-01T00:00:00"
233
234 # Check if all reason flags can be found in the CRL.
Erik Trauschke396a2822015-09-28 08:56:18 -0700235 # Also test if CRL as iterator works.
Erik Trauschkedc570402015-09-24 20:24:28 -0700236 flags = set(x509.ReasonFlags)
Erik Trauschke396a2822015-09-28 08:56:18 -0700237 for r in crl:
Erik Trauschkedc570402015-09-24 20:24:28 -0700238 flags.discard(r.get_reason())
239 assert len(flags) == 0
240
Erik Trauschke396a2822015-09-28 08:56:18 -0700241 # Check that len() works for CRLs.
242 assert len(crl) == 12
243
Erik Trauschke3cdabaf2015-10-13 09:42:53 -0700244 # Check that direct access to revoked cert in CRL works
245 assert isinstance(crl[0], x509.RevokedCertificate)
246
Erik Trauschkedc570402015-09-24 20:24:28 -0700247 def test_duplicate_entry_ext(self, backend):
248 crl = _load_cert(
249 os.path.join("x509", "custom", "crl_dup_entry_ext.pem"),
250 x509.load_pem_x509_crl,
251 backend
252 )
253
254 with pytest.raises(x509.DuplicateExtension):
255 crl.revoked_certificates[0].extensions
256
257 def test_unsupported_crit_entry_ext(self, backend):
258 crl = _load_cert(
259 os.path.join(
260 "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
261 ),
262 x509.load_pem_x509_crl,
263 backend
264 )
265
266 with pytest.raises(x509.UnsupportedExtension):
267 crl.revoked_certificates[0].extensions
268
269 def test_unsupported_reason(self, backend):
270 crl = _load_cert(
271 os.path.join(
272 "x509", "custom", "crl_unsupported_reason.pem"
273 ),
274 x509.load_pem_x509_crl,
275 backend
276 )
277
278 with pytest.raises(ValueError):
279 crl.revoked_certificates[0].extensions
280
281 def test_cert_issuer_ext(self, backend):
282 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10000000:
283 pytest.skip("Requires a newer OpenSSL. Must be at least 1.0.0")
284
285 crl = _load_cert(
286 os.path.join("x509", "custom", "crl_all_reasons.pem"),
287 x509.load_pem_x509_crl,
288 backend
289 )
290
291 exp_issuer = x509.GeneralNames([
292 x509.DirectoryName(x509.Name([
293 x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
294 x509.NameAttribute(x509.OID_COMMON_NAME, u"cryptography.io"),
295 ]))
296 ])
297
298 rev = crl.revoked_certificates[1]
299 issuer = rev.extensions.get_extension_for_oid(
300 x509.OID_CERTIFICATE_ISSUER).value
301 assert issuer == exp_issuer
302
303 # Test convenience function.
304 assert rev.get_certificate_issuer() == exp_issuer
305
306
Paul Kehrer016e08a2014-11-26 09:41:18 -1000307@pytest.mark.requires_backend_interface(interface=RSABackend)
308@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -0600309class TestRSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000310 def test_load_pem_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000311 cert = _load_cert(
312 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000313 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000314 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000315 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600316 assert isinstance(cert, x509.Certificate)
317 assert cert.serial == 11559813051657483483
318 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
319 assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8"
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600320 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000321
322 def test_load_der_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000323 cert = _load_cert(
324 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000325 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000326 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000327 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600328 assert isinstance(cert, x509.Certificate)
329 assert cert.serial == 2
330 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
331 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600332 assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000333
Paul Kehrer719d5362015-01-01 20:03:52 -0600334 def test_issuer(self, backend):
335 cert = _load_cert(
336 os.path.join(
337 "x509", "PKITS_data", "certs",
338 "Validpre2000UTCnotBeforeDateTest3EE.crt"
339 ),
340 x509.load_der_x509_certificate,
341 backend
342 )
343 issuer = cert.issuer
344 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600345 assert list(issuer) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500346 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600347 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500348 NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -0600349 ),
Paul Kehrereba19e62015-08-10 18:44:24 -0500350 x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -0600351 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500352 assert issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
353 x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -0600354 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600355
356 def test_all_issuer_name_types(self, backend):
357 cert = _load_cert(
358 os.path.join(
359 "x509", "custom",
360 "all_supported_names.pem"
361 ),
362 x509.load_pem_x509_certificate,
363 backend
364 )
365 issuer = cert.issuer
366
367 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600368 assert list(issuer) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500369 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
370 x509.NameAttribute(NameOID.COUNTRY_NAME, u'CA'),
371 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
372 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Illinois'),
373 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Chicago'),
374 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
375 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Zero, LLC'),
376 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'One, LLC'),
377 x509.NameAttribute(NameOID.COMMON_NAME, u'common name 0'),
378 x509.NameAttribute(NameOID.COMMON_NAME, u'common name 1'),
379 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 0'),
380 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 1'),
381 x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier0'),
382 x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier1'),
383 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'123'),
384 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'456'),
385 x509.NameAttribute(NameOID.TITLE, u'Title 0'),
386 x509.NameAttribute(NameOID.TITLE, u'Title 1'),
387 x509.NameAttribute(NameOID.SURNAME, u'Surname 0'),
388 x509.NameAttribute(NameOID.SURNAME, u'Surname 1'),
389 x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 0'),
390 x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 1'),
391 x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 0'),
392 x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 1'),
393 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Last Gen'),
394 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Next Gen'),
395 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc0'),
396 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc1'),
397 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test0@test.local'),
398 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test1@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600399 ]
400
Paul Kehrer719d5362015-01-01 20:03:52 -0600401 def test_subject(self, backend):
402 cert = _load_cert(
403 os.path.join(
404 "x509", "PKITS_data", "certs",
405 "Validpre2000UTCnotBeforeDateTest3EE.crt"
406 ),
407 x509.load_der_x509_certificate,
408 backend
409 )
410 subject = cert.subject
411 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600412 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500413 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600414 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500415 NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -0600416 ),
417 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500418 NameOID.COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500419 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600420 )
421 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500422 assert subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600423 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500424 NameOID.COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500425 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600426 )
427 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600428
429 def test_unicode_name(self, backend):
430 cert = _load_cert(
431 os.path.join(
432 "x509", "custom",
433 "utf8_common_name.pem"
434 ),
435 x509.load_pem_x509_certificate,
436 backend
437 )
Paul Kehrereba19e62015-08-10 18:44:24 -0500438 assert cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600439 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500440 NameOID.COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530441 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600442 )
443 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500444 assert cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600445 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500446 NameOID.COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530447 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600448 )
449 ]
450
451 def test_all_subject_name_types(self, backend):
452 cert = _load_cert(
453 os.path.join(
454 "x509", "custom",
455 "all_supported_names.pem"
456 ),
457 x509.load_pem_x509_certificate,
458 backend
459 )
460 subject = cert.subject
461 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600462 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500463 x509.NameAttribute(NameOID.COUNTRY_NAME, u'AU'),
464 x509.NameAttribute(NameOID.COUNTRY_NAME, u'DE'),
465 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'California'),
466 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'New York'),
467 x509.NameAttribute(NameOID.LOCALITY_NAME, u'San Francisco'),
468 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Ithaca'),
469 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org Zero, LLC'),
470 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org One, LLC'),
471 x509.NameAttribute(NameOID.COMMON_NAME, u'CN 0'),
472 x509.NameAttribute(NameOID.COMMON_NAME, u'CN 1'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600473 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500474 NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 0'
Paul Kehrer719d5362015-01-01 20:03:52 -0600475 ),
476 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500477 NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 1'
Paul Kehrer719d5362015-01-01 20:03:52 -0600478 ),
Paul Kehrereba19e62015-08-10 18:44:24 -0500479 x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified0'),
480 x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified1'),
481 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'789'),
482 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'012'),
483 x509.NameAttribute(NameOID.TITLE, u'Title IX'),
484 x509.NameAttribute(NameOID.TITLE, u'Title X'),
485 x509.NameAttribute(NameOID.SURNAME, u'Last 0'),
486 x509.NameAttribute(NameOID.SURNAME, u'Last 1'),
487 x509.NameAttribute(NameOID.GIVEN_NAME, u'First 0'),
488 x509.NameAttribute(NameOID.GIVEN_NAME, u'First 1'),
489 x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 0'),
490 x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 1'),
491 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'32X'),
492 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Dreamcast'),
493 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc2'),
494 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc3'),
495 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test2@test.local'),
496 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test3@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600497 ]
498
Paul Kehrer016e08a2014-11-26 09:41:18 -1000499 def test_load_good_ca_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000500 cert = _load_cert(
501 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000502 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000503 backend
504 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000505
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600506 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
507 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrer016e08a2014-11-26 09:41:18 -1000508 assert cert.serial == 2
509 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -0800510 assert isinstance(public_key, rsa.RSAPublicKey)
Paul Kehrere76cd272014-12-14 19:00:51 -0600511 assert cert.version is x509.Version.v3
Paul Kehrer0307c372014-11-27 09:49:31 -1000512 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
Paul Kehrer4e1db792014-11-27 10:50:55 -1000513 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer016e08a2014-11-26 09:41:18 -1000514
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000515 def test_utc_pre_2000_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000516 cert = _load_cert(
517 os.path.join(
518 "x509", "PKITS_data", "certs",
519 "Validpre2000UTCnotBeforeDateTest3EE.crt"
520 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000521 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000522 backend
523 )
524
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600525 assert cert.not_valid_before == datetime.datetime(1950, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000526
527 def test_pre_2000_utc_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000528 cert = _load_cert(
529 os.path.join(
530 "x509", "PKITS_data", "certs",
531 "Invalidpre2000UTCEEnotAfterDateTest7EE.crt"
532 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000533 x509.load_der_x509_certificate,
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000534 backend
535 )
536
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600537 assert cert.not_valid_after == datetime.datetime(1999, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000538
539 def test_post_2000_utc_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000540 cert = _load_cert(
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000541 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000542 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000543 backend
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000544 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600545 assert cert.not_valid_before == datetime.datetime(
546 2014, 11, 26, 21, 41, 20
547 )
548 assert cert.not_valid_after == datetime.datetime(
549 2014, 12, 26, 21, 41, 20
550 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000551
552 def test_generalized_time_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000553 cert = _load_cert(
554 os.path.join(
555 "x509", "PKITS_data", "certs",
556 "ValidGeneralizedTimenotBeforeDateTest4EE.crt"
557 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000558 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000559 backend
560 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600561 assert cert.not_valid_before == datetime.datetime(2002, 1, 1, 12, 1)
562 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrere76cd272014-12-14 19:00:51 -0600563 assert cert.version is x509.Version.v3
Paul Kehrer016e08a2014-11-26 09:41:18 -1000564
565 def test_generalized_time_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000566 cert = _load_cert(
567 os.path.join(
568 "x509", "PKITS_data", "certs",
569 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
570 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000571 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000572 backend
573 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600574 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
575 assert cert.not_valid_after == datetime.datetime(2050, 1, 1, 12, 1)
Paul Kehrere76cd272014-12-14 19:00:51 -0600576 assert cert.version is x509.Version.v3
Paul Kehrera9d78c12014-11-26 10:59:03 -1000577
578 def test_invalid_version_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000579 cert = _load_cert(
Paul Kehrera9d78c12014-11-26 10:59:03 -1000580 os.path.join("x509", "custom", "invalid_version.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000581 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000582 backend
Paul Kehrera9d78c12014-11-26 10:59:03 -1000583 )
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600584 with pytest.raises(x509.InvalidVersion) as exc:
Paul Kehrera9d78c12014-11-26 10:59:03 -1000585 cert.version
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000586
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600587 assert exc.value.parsed_version == 7
588
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -0500589 def test_eq(self, backend):
590 cert = _load_cert(
591 os.path.join("x509", "custom", "post2000utctime.pem"),
592 x509.load_pem_x509_certificate,
593 backend
594 )
595 cert2 = _load_cert(
596 os.path.join("x509", "custom", "post2000utctime.pem"),
597 x509.load_pem_x509_certificate,
598 backend
599 )
600 assert cert == cert2
601
602 def test_ne(self, backend):
603 cert = _load_cert(
604 os.path.join("x509", "custom", "post2000utctime.pem"),
605 x509.load_pem_x509_certificate,
606 backend
607 )
608 cert2 = _load_cert(
609 os.path.join(
610 "x509", "PKITS_data", "certs",
611 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
612 ),
613 x509.load_der_x509_certificate,
614 backend
615 )
616 assert cert != cert2
617 assert cert != object()
618
Alex Gaynor969f3a52015-07-06 18:52:41 -0400619 def test_hash(self, backend):
620 cert1 = _load_cert(
621 os.path.join("x509", "custom", "post2000utctime.pem"),
622 x509.load_pem_x509_certificate,
623 backend
624 )
625 cert2 = _load_cert(
626 os.path.join("x509", "custom", "post2000utctime.pem"),
627 x509.load_pem_x509_certificate,
628 backend
629 )
630 cert3 = _load_cert(
631 os.path.join(
632 "x509", "PKITS_data", "certs",
633 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
634 ),
635 x509.load_der_x509_certificate,
636 backend
637 )
638
639 assert hash(cert1) == hash(cert2)
640 assert hash(cert1) != hash(cert3)
641
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000642 def test_version_1_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000643 cert = _load_cert(
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000644 os.path.join("x509", "v1_cert.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000645 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000646 backend
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000647 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600648 assert cert.version is x509.Version.v1
Paul Kehrer7638c312014-11-26 11:13:31 -1000649
650 def test_invalid_pem(self, backend):
651 with pytest.raises(ValueError):
652 x509.load_pem_x509_certificate(b"notacert", backend)
653
654 def test_invalid_der(self, backend):
655 with pytest.raises(ValueError):
656 x509.load_der_x509_certificate(b"notacert", backend)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000657
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600658 def test_unsupported_signature_hash_algorithm_cert(self, backend):
659 cert = _load_cert(
660 os.path.join("x509", "verisign_md2_root.pem"),
661 x509.load_pem_x509_certificate,
662 backend
663 )
664 with pytest.raises(UnsupportedAlgorithm):
665 cert.signature_hash_algorithm
666
Andre Carona8aded62015-05-19 20:11:57 -0400667 def test_public_bytes_pem(self, backend):
668 # Load an existing certificate.
669 cert = _load_cert(
670 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
671 x509.load_der_x509_certificate,
672 backend
673 )
674
675 # Encode it to PEM and load it back.
676 cert = x509.load_pem_x509_certificate(cert.public_bytes(
677 encoding=serialization.Encoding.PEM,
678 ), backend)
679
680 # We should recover what we had to start with.
681 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
682 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
683 assert cert.serial == 2
684 public_key = cert.public_key()
685 assert isinstance(public_key, rsa.RSAPublicKey)
686 assert cert.version is x509.Version.v3
687 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
688 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
689
690 def test_public_bytes_der(self, backend):
691 # Load an existing certificate.
692 cert = _load_cert(
693 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
694 x509.load_der_x509_certificate,
695 backend
696 )
697
698 # Encode it to DER and load it back.
699 cert = x509.load_der_x509_certificate(cert.public_bytes(
700 encoding=serialization.Encoding.DER,
701 ), backend)
702
703 # We should recover what we had to start with.
704 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
705 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
706 assert cert.serial == 2
707 public_key = cert.public_key()
708 assert isinstance(public_key, rsa.RSAPublicKey)
709 assert cert.version is x509.Version.v3
710 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
711 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
712
713 def test_public_bytes_invalid_encoding(self, backend):
714 cert = _load_cert(
715 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
716 x509.load_der_x509_certificate,
717 backend
718 )
719
720 with pytest.raises(TypeError):
721 cert.public_bytes('NotAnEncoding')
722
723 @pytest.mark.parametrize(
724 ("cert_path", "loader_func", "encoding"),
725 [
726 (
727 os.path.join("x509", "v1_cert.pem"),
728 x509.load_pem_x509_certificate,
729 serialization.Encoding.PEM,
730 ),
731 (
732 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
733 x509.load_der_x509_certificate,
734 serialization.Encoding.DER,
735 ),
736 ]
737 )
738 def test_public_bytes_match(self, cert_path, loader_func, encoding,
739 backend):
740 cert_bytes = load_vectors_from_file(
741 cert_path, lambda pemfile: pemfile.read(), mode="rb"
742 )
743 cert = loader_func(cert_bytes, backend)
744 serialized = cert.public_bytes(encoding)
745 assert serialized == cert_bytes
746
Major Haydenf315af22015-06-17 14:02:26 -0500747 def test_certificate_repr(self, backend):
748 cert = _load_cert(
749 os.path.join(
750 "x509", "cryptography.io.pem"
751 ),
752 x509.load_pem_x509_certificate,
753 backend
754 )
755 if six.PY3:
756 assert repr(cert) == (
757 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
758 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value='GT487"
759 "42965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11, "
760 "name=organizationalUnitName)>, value='See www.rapidssl.com/re"
761 "sources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier(oi"
762 "d=2.5.4.11, name=organizationalUnitName)>, value='Domain Cont"
763 "rol Validated - RapidSSL(R)')>, <NameAttribute(oid=<ObjectIde"
764 "ntifier(oid=2.5.4.3, name=commonName)>, value='www.cryptograp"
765 "hy.io')>])>, ...)>"
766 )
767 else:
768 assert repr(cert) == (
769 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
770 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value=u'GT48"
771 "742965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11,"
772 " name=organizationalUnitName)>, value=u'See www.rapidssl.com/"
773 "resources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier("
774 "oid=2.5.4.11, name=organizationalUnitName)>, value=u'Domain C"
775 "ontrol Validated - RapidSSL(R)')>, <NameAttribute(oid=<Object"
776 "Identifier(oid=2.5.4.3, name=commonName)>, value=u'www.crypto"
777 "graphy.io')>])>, ...)>"
778 )
779
Andre Carona8aded62015-05-19 20:11:57 -0400780
781@pytest.mark.requires_backend_interface(interface=RSABackend)
782@pytest.mark.requires_backend_interface(interface=X509Backend)
783class TestRSACertificateRequest(object):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500784 @pytest.mark.parametrize(
785 ("path", "loader_func"),
786 [
787 [
788 os.path.join("x509", "requests", "rsa_sha1.pem"),
789 x509.load_pem_x509_csr
790 ],
791 [
792 os.path.join("x509", "requests", "rsa_sha1.der"),
793 x509.load_der_x509_csr
794 ],
795 ]
796 )
797 def test_load_rsa_certificate_request(self, path, loader_func, backend):
798 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600799 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
800 public_key = request.public_key()
801 assert isinstance(public_key, rsa.RSAPublicKey)
802 subject = request.subject
803 assert isinstance(subject, x509.Name)
804 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500805 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
806 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
807 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
808 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
809 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600810 ]
Andre Caron6e721a92015-05-17 15:08:48 -0400811 extensions = request.extensions
812 assert isinstance(extensions, x509.Extensions)
813 assert list(extensions) == []
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600814
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500815 @pytest.mark.parametrize(
816 "loader_func",
817 [x509.load_pem_x509_csr, x509.load_der_x509_csr]
818 )
819 def test_invalid_certificate_request(self, loader_func, backend):
Paul Kehrerb759e292015-03-17 07:34:41 -0500820 with pytest.raises(ValueError):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500821 loader_func(b"notacsr", backend)
Paul Kehrerb759e292015-03-17 07:34:41 -0500822
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600823 def test_unsupported_signature_hash_algorithm_request(self, backend):
824 request = _load_cert(
825 os.path.join("x509", "requests", "rsa_md4.pem"),
Paul Kehrer31e39882015-03-11 11:37:04 -0500826 x509.load_pem_x509_csr,
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600827 backend
828 )
829 with pytest.raises(UnsupportedAlgorithm):
830 request.signature_hash_algorithm
831
Andre Caron6e721a92015-05-17 15:08:48 -0400832 def test_duplicate_extension(self, backend):
833 request = _load_cert(
834 os.path.join(
835 "x509", "requests", "two_basic_constraints.pem"
836 ),
837 x509.load_pem_x509_csr,
838 backend
839 )
840 with pytest.raises(x509.DuplicateExtension) as exc:
841 request.extensions
842
Paul Kehrerd44e4132015-08-10 19:13:13 -0500843 assert exc.value.oid == ExtensionOID.BASIC_CONSTRAINTS
Andre Caron6e721a92015-05-17 15:08:48 -0400844
845 def test_unsupported_critical_extension(self, backend):
846 request = _load_cert(
847 os.path.join(
848 "x509", "requests", "unsupported_extension_critical.pem"
849 ),
850 x509.load_pem_x509_csr,
851 backend
852 )
853 with pytest.raises(x509.UnsupportedExtension) as exc:
854 request.extensions
855
856 assert exc.value.oid == x509.ObjectIdentifier('1.2.3.4')
857
858 def test_unsupported_extension(self, backend):
859 request = _load_cert(
860 os.path.join(
861 "x509", "requests", "unsupported_extension.pem"
862 ),
863 x509.load_pem_x509_csr,
864 backend
865 )
866 extensions = request.extensions
867 assert len(extensions) == 0
868
869 def test_request_basic_constraints(self, backend):
870 request = _load_cert(
871 os.path.join(
872 "x509", "requests", "basic_constraints.pem"
873 ),
874 x509.load_pem_x509_csr,
875 backend
876 )
877 extensions = request.extensions
878 assert isinstance(extensions, x509.Extensions)
879 assert list(extensions) == [
880 x509.Extension(
Paul Kehrerd44e4132015-08-10 19:13:13 -0500881 ExtensionOID.BASIC_CONSTRAINTS,
Andre Caron6e721a92015-05-17 15:08:48 -0400882 True,
Ian Cordasco0112b022015-06-16 17:51:18 -0500883 x509.BasicConstraints(ca=True, path_length=1),
Andre Caron6e721a92015-05-17 15:08:48 -0400884 ),
885 ]
886
Alex Gaynor37b82df2015-07-03 10:26:37 -0400887 def test_subject_alt_name(self, backend):
888 request = _load_cert(
889 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
890 x509.load_pem_x509_csr,
891 backend,
892 )
893 ext = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -0500894 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynor37b82df2015-07-03 10:26:37 -0400895 )
896 assert list(ext.value) == [
897 x509.DNSName(u"cryptography.io"),
898 x509.DNSName(u"sub.cryptography.io"),
899 ]
900
Andre Caronf27e4f42015-05-18 17:54:59 -0400901 def test_public_bytes_pem(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400902 # Load an existing CSR.
903 request = _load_cert(
904 os.path.join("x509", "requests", "rsa_sha1.pem"),
905 x509.load_pem_x509_csr,
906 backend
907 )
908
909 # Encode it to PEM and load it back.
910 request = x509.load_pem_x509_csr(request.public_bytes(
911 encoding=serialization.Encoding.PEM,
912 ), backend)
913
914 # We should recover what we had to start with.
915 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
916 public_key = request.public_key()
917 assert isinstance(public_key, rsa.RSAPublicKey)
918 subject = request.subject
919 assert isinstance(subject, x509.Name)
920 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500921 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
922 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
923 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
924 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
925 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400926 ]
927
Andre Caronf27e4f42015-05-18 17:54:59 -0400928 def test_public_bytes_der(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400929 # Load an existing CSR.
930 request = _load_cert(
931 os.path.join("x509", "requests", "rsa_sha1.pem"),
932 x509.load_pem_x509_csr,
933 backend
934 )
935
936 # Encode it to DER and load it back.
937 request = x509.load_der_x509_csr(request.public_bytes(
938 encoding=serialization.Encoding.DER,
939 ), backend)
940
941 # We should recover what we had to start with.
942 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
943 public_key = request.public_key()
944 assert isinstance(public_key, rsa.RSAPublicKey)
945 subject = request.subject
946 assert isinstance(subject, x509.Name)
947 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500948 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
949 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
950 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
951 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
952 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400953 ]
954
Andre Caronf27e4f42015-05-18 17:54:59 -0400955 def test_public_bytes_invalid_encoding(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400956 request = _load_cert(
957 os.path.join("x509", "requests", "rsa_sha1.pem"),
958 x509.load_pem_x509_csr,
959 backend
960 )
961
962 with pytest.raises(TypeError):
963 request.public_bytes('NotAnEncoding')
964
Andre Caronacb18972015-05-18 21:04:15 -0400965 @pytest.mark.parametrize(
966 ("request_path", "loader_func", "encoding"),
967 [
968 (
969 os.path.join("x509", "requests", "rsa_sha1.pem"),
970 x509.load_pem_x509_csr,
971 serialization.Encoding.PEM,
972 ),
973 (
974 os.path.join("x509", "requests", "rsa_sha1.der"),
975 x509.load_der_x509_csr,
976 serialization.Encoding.DER,
977 ),
978 ]
979 )
980 def test_public_bytes_match(self, request_path, loader_func, encoding,
981 backend):
982 request_bytes = load_vectors_from_file(
983 request_path, lambda pemfile: pemfile.read(), mode="rb"
984 )
985 request = loader_func(request_bytes, backend)
986 serialized = request.public_bytes(encoding)
987 assert serialized == request_bytes
988
Alex Gaynor70c8f8b2015-07-06 21:02:54 -0400989 def test_eq(self, backend):
990 request1 = _load_cert(
991 os.path.join("x509", "requests", "rsa_sha1.pem"),
992 x509.load_pem_x509_csr,
993 backend
994 )
995 request2 = _load_cert(
996 os.path.join("x509", "requests", "rsa_sha1.pem"),
997 x509.load_pem_x509_csr,
998 backend
999 )
1000
1001 assert request1 == request2
1002
1003 def test_ne(self, backend):
1004 request1 = _load_cert(
1005 os.path.join("x509", "requests", "rsa_sha1.pem"),
1006 x509.load_pem_x509_csr,
1007 backend
1008 )
1009 request2 = _load_cert(
Alex Gaynoreb2df542015-07-06 21:50:15 -04001010 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001011 x509.load_pem_x509_csr,
1012 backend
1013 )
1014
1015 assert request1 != request2
1016 assert request1 != object()
1017
Alex Gaynor978137d2015-07-08 20:59:16 -04001018 def test_hash(self, backend):
1019 request1 = _load_cert(
1020 os.path.join("x509", "requests", "rsa_sha1.pem"),
1021 x509.load_pem_x509_csr,
1022 backend
1023 )
1024 request2 = _load_cert(
1025 os.path.join("x509", "requests", "rsa_sha1.pem"),
1026 x509.load_pem_x509_csr,
1027 backend
1028 )
1029 request3 = _load_cert(
1030 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
1031 x509.load_pem_x509_csr,
1032 backend
1033 )
1034
1035 assert hash(request1) == hash(request2)
1036 assert hash(request1) != hash(request3)
1037
Andre Caron9bbfcea2015-05-18 20:55:29 -04001038 def test_build_cert(self, backend):
Ian Cordascoe4e52a42015-07-19 10:15:37 -05001039 issuer_private_key = RSA_KEY_2048.private_key(backend)
1040 subject_private_key = RSA_KEY_2048.private_key(backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001041
Andre Caron9bbfcea2015-05-18 20:55:29 -04001042 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1043 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
Ian Cordascob3ed4842015-07-01 22:46:03 -05001044
Ian Cordasco893246f2015-07-24 14:52:18 -05001045 builder = x509.CertificateBuilder().serial_number(
Ian Cordascob3ed4842015-07-01 22:46:03 -05001046 777
1047 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001048 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1049 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1050 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1051 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1052 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -05001053 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001054 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1055 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1056 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1057 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1058 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -05001059 ])).public_key(
1060 subject_private_key.public_key()
1061 ).add_extension(
Ian Cordasco8887a572015-07-19 10:26:59 -05001062 x509.BasicConstraints(ca=False, path_length=None), True,
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001063 ).add_extension(
1064 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1065 critical=False,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001066 ).not_valid_before(
1067 not_valid_before
1068 ).not_valid_after(
1069 not_valid_after
1070 )
1071
Paul Kehrer9add80e2015-08-03 17:53:14 +01001072 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001073
1074 assert cert.version is x509.Version.v3
1075 assert cert.not_valid_before == not_valid_before
1076 assert cert.not_valid_after == not_valid_after
1077 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001078 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron9bbfcea2015-05-18 20:55:29 -04001079 )
1080 assert basic_constraints.value.ca is False
1081 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001082 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001083 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001084 )
1085 assert list(subject_alternative_name.value) == [
1086 x509.DNSName(u"cryptography.io"),
1087 ]
Andre Caron9bbfcea2015-05-18 20:55:29 -04001088
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001089
Ian Cordasco747a2172015-07-19 11:00:14 -05001090class TestCertificateBuilder(object):
Paul Kehrer25f19222015-08-04 23:05:09 +01001091 @pytest.mark.requires_backend_interface(interface=RSABackend)
1092 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrera03c3252015-08-09 10:59:29 -05001093 def test_checks_for_unsupported_extensions(self, backend):
1094 private_key = RSA_KEY_2048.private_key(backend)
1095 builder = x509.CertificateBuilder().subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001096 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera03c3252015-08-09 10:59:29 -05001097 ])).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001098 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera03c3252015-08-09 10:59:29 -05001099 ])).public_key(
1100 private_key.public_key()
1101 ).serial_number(
1102 777
1103 ).not_valid_before(
1104 datetime.datetime(1999, 1, 1)
1105 ).not_valid_after(
1106 datetime.datetime(2020, 1, 1)
1107 ).add_extension(
1108 DummyExtension(), False
1109 )
1110
1111 with pytest.raises(NotImplementedError):
1112 builder.sign(private_key, hashes.SHA1(), backend)
1113
1114 @pytest.mark.requires_backend_interface(interface=RSABackend)
1115 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer25f19222015-08-04 23:05:09 +01001116 def test_no_subject_name(self, backend):
1117 subject_private_key = RSA_KEY_2048.private_key(backend)
1118 builder = x509.CertificateBuilder().serial_number(
1119 777
1120 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001121 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001122 ])).public_key(
1123 subject_private_key.public_key()
1124 ).not_valid_before(
1125 datetime.datetime(2002, 1, 1, 12, 1)
1126 ).not_valid_after(
1127 datetime.datetime(2030, 12, 31, 8, 30)
1128 )
1129 with pytest.raises(ValueError):
1130 builder.sign(subject_private_key, hashes.SHA256(), backend)
1131
1132 @pytest.mark.requires_backend_interface(interface=RSABackend)
1133 @pytest.mark.requires_backend_interface(interface=X509Backend)
1134 def test_no_issuer_name(self, backend):
1135 subject_private_key = RSA_KEY_2048.private_key(backend)
1136 builder = x509.CertificateBuilder().serial_number(
1137 777
1138 ).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001139 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001140 ])).public_key(
1141 subject_private_key.public_key()
1142 ).not_valid_before(
1143 datetime.datetime(2002, 1, 1, 12, 1)
1144 ).not_valid_after(
1145 datetime.datetime(2030, 12, 31, 8, 30)
1146 )
1147 with pytest.raises(ValueError):
1148 builder.sign(subject_private_key, hashes.SHA256(), backend)
1149
1150 @pytest.mark.requires_backend_interface(interface=RSABackend)
1151 @pytest.mark.requires_backend_interface(interface=X509Backend)
1152 def test_no_public_key(self, backend):
1153 subject_private_key = RSA_KEY_2048.private_key(backend)
1154 builder = x509.CertificateBuilder().serial_number(
1155 777
1156 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001157 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001158 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001159 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001160 ])).not_valid_before(
1161 datetime.datetime(2002, 1, 1, 12, 1)
1162 ).not_valid_after(
1163 datetime.datetime(2030, 12, 31, 8, 30)
1164 )
1165 with pytest.raises(ValueError):
1166 builder.sign(subject_private_key, hashes.SHA256(), backend)
1167
1168 @pytest.mark.requires_backend_interface(interface=RSABackend)
1169 @pytest.mark.requires_backend_interface(interface=X509Backend)
1170 def test_no_not_valid_before(self, backend):
1171 subject_private_key = RSA_KEY_2048.private_key(backend)
1172 builder = x509.CertificateBuilder().serial_number(
1173 777
1174 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001175 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001176 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001177 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001178 ])).public_key(
1179 subject_private_key.public_key()
1180 ).not_valid_after(
1181 datetime.datetime(2030, 12, 31, 8, 30)
1182 )
1183 with pytest.raises(ValueError):
1184 builder.sign(subject_private_key, hashes.SHA256(), backend)
1185
1186 @pytest.mark.requires_backend_interface(interface=RSABackend)
1187 @pytest.mark.requires_backend_interface(interface=X509Backend)
1188 def test_no_not_valid_after(self, backend):
1189 subject_private_key = RSA_KEY_2048.private_key(backend)
1190 builder = x509.CertificateBuilder().serial_number(
1191 777
1192 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001193 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001194 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001195 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001196 ])).public_key(
1197 subject_private_key.public_key()
1198 ).not_valid_before(
1199 datetime.datetime(2002, 1, 1, 12, 1)
1200 )
1201 with pytest.raises(ValueError):
1202 builder.sign(subject_private_key, hashes.SHA256(), backend)
1203
1204 @pytest.mark.requires_backend_interface(interface=RSABackend)
1205 @pytest.mark.requires_backend_interface(interface=X509Backend)
1206 def test_no_serial_number(self, backend):
1207 subject_private_key = RSA_KEY_2048.private_key(backend)
1208 builder = x509.CertificateBuilder().issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001209 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001210 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001211 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001212 ])).public_key(
1213 subject_private_key.public_key()
1214 ).not_valid_before(
1215 datetime.datetime(2002, 1, 1, 12, 1)
1216 ).not_valid_after(
1217 datetime.datetime(2030, 12, 31, 8, 30)
1218 )
1219 with pytest.raises(ValueError):
1220 builder.sign(subject_private_key, hashes.SHA256(), backend)
1221
Ian Cordasco747a2172015-07-19 11:00:14 -05001222 def test_issuer_name_must_be_a_name_type(self):
1223 builder = x509.CertificateBuilder()
1224
1225 with pytest.raises(TypeError):
1226 builder.issuer_name("subject")
1227
1228 with pytest.raises(TypeError):
1229 builder.issuer_name(object)
1230
1231 def test_issuer_name_may_only_be_set_once(self):
1232 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001233 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -05001234 ])
1235 builder = x509.CertificateBuilder().issuer_name(name)
1236
1237 with pytest.raises(ValueError):
1238 builder.issuer_name(name)
1239
1240 def test_subject_name_must_be_a_name_type(self):
1241 builder = x509.CertificateBuilder()
1242
1243 with pytest.raises(TypeError):
1244 builder.subject_name("subject")
1245
1246 with pytest.raises(TypeError):
1247 builder.subject_name(object)
1248
1249 def test_subject_name_may_only_be_set_once(self):
1250 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001251 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -05001252 ])
1253 builder = x509.CertificateBuilder().subject_name(name)
1254
1255 with pytest.raises(ValueError):
1256 builder.subject_name(name)
1257
1258 @pytest.mark.requires_backend_interface(interface=RSABackend)
1259 @pytest.mark.requires_backend_interface(interface=X509Backend)
1260 def test_public_key_must_be_public_key(self, backend):
1261 private_key = RSA_KEY_2048.private_key(backend)
1262 builder = x509.CertificateBuilder()
1263
1264 with pytest.raises(TypeError):
1265 builder.public_key(private_key)
1266
1267 @pytest.mark.requires_backend_interface(interface=RSABackend)
1268 @pytest.mark.requires_backend_interface(interface=X509Backend)
1269 def test_public_key_may_only_be_set_once(self, backend):
1270 private_key = RSA_KEY_2048.private_key(backend)
1271 public_key = private_key.public_key()
1272 builder = x509.CertificateBuilder().public_key(public_key)
1273
1274 with pytest.raises(ValueError):
1275 builder.public_key(public_key)
1276
1277 def test_serial_number_must_be_an_integer_type(self):
1278 with pytest.raises(TypeError):
1279 x509.CertificateBuilder().serial_number(10.0)
1280
Ian Cordascob4a155d2015-08-01 23:07:19 -05001281 def test_serial_number_must_be_non_negative(self):
1282 with pytest.raises(ValueError):
1283 x509.CertificateBuilder().serial_number(-10)
1284
1285 def test_serial_number_must_be_less_than_160_bits_long(self):
1286 with pytest.raises(ValueError):
1287 # 2 raised to the 160th power is actually 161 bits
1288 x509.CertificateBuilder().serial_number(2 ** 160)
1289
Ian Cordasco747a2172015-07-19 11:00:14 -05001290 def test_serial_number_may_only_be_set_once(self):
1291 builder = x509.CertificateBuilder().serial_number(10)
1292
1293 with pytest.raises(ValueError):
1294 builder.serial_number(20)
1295
1296 def test_invalid_not_valid_after(self):
1297 with pytest.raises(TypeError):
1298 x509.CertificateBuilder().not_valid_after(104204304504)
1299
1300 with pytest.raises(TypeError):
1301 x509.CertificateBuilder().not_valid_after(datetime.time())
1302
Ian Cordascob4a155d2015-08-01 23:07:19 -05001303 with pytest.raises(ValueError):
1304 x509.CertificateBuilder().not_valid_after(
1305 datetime.datetime(1960, 8, 10)
1306 )
1307
Ian Cordasco747a2172015-07-19 11:00:14 -05001308 def test_not_valid_after_may_only_be_set_once(self):
1309 builder = x509.CertificateBuilder().not_valid_after(
1310 datetime.datetime.now()
1311 )
1312
1313 with pytest.raises(ValueError):
1314 builder.not_valid_after(
1315 datetime.datetime.now()
1316 )
1317
1318 def test_invalid_not_valid_before(self):
1319 with pytest.raises(TypeError):
1320 x509.CertificateBuilder().not_valid_before(104204304504)
1321
1322 with pytest.raises(TypeError):
1323 x509.CertificateBuilder().not_valid_before(datetime.time())
1324
Ian Cordascob4a155d2015-08-01 23:07:19 -05001325 with pytest.raises(ValueError):
1326 x509.CertificateBuilder().not_valid_before(
1327 datetime.datetime(1960, 8, 10)
1328 )
1329
Ian Cordasco747a2172015-07-19 11:00:14 -05001330 def test_not_valid_before_may_only_be_set_once(self):
1331 builder = x509.CertificateBuilder().not_valid_before(
1332 datetime.datetime.now()
1333 )
1334
1335 with pytest.raises(ValueError):
1336 builder.not_valid_before(
1337 datetime.datetime.now()
1338 )
1339
1340 def test_add_extension_checks_for_duplicates(self):
1341 builder = x509.CertificateBuilder().add_extension(
1342 x509.BasicConstraints(ca=False, path_length=None), True,
1343 )
1344
1345 with pytest.raises(ValueError):
1346 builder.add_extension(
1347 x509.BasicConstraints(ca=False, path_length=None), True,
1348 )
1349
Paul Kehrer08f950e2015-08-08 22:14:42 -05001350 def test_add_invalid_extension_type(self):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001351 builder = x509.CertificateBuilder()
1352
Paul Kehrer08f950e2015-08-08 22:14:42 -05001353 with pytest.raises(TypeError):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001354 builder.add_extension(object(), False)
1355
Ian Cordascob77c7162015-07-20 21:22:33 -05001356 @pytest.mark.requires_backend_interface(interface=RSABackend)
1357 @pytest.mark.requires_backend_interface(interface=X509Backend)
1358 def test_sign_with_unsupported_hash(self, backend):
1359 private_key = RSA_KEY_2048.private_key(backend)
1360 builder = x509.CertificateBuilder()
Paul Kehrer25f19222015-08-04 23:05:09 +01001361 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001362 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer25f19222015-08-04 23:05:09 +01001363 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001364 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer25f19222015-08-04 23:05:09 +01001365 ).serial_number(
1366 1
1367 ).public_key(
1368 private_key.public_key()
1369 ).not_valid_before(
1370 datetime.datetime(2002, 1, 1, 12, 1)
1371 ).not_valid_after(
1372 datetime.datetime(2032, 1, 1, 12, 1)
1373 )
Ian Cordascob77c7162015-07-20 21:22:33 -05001374
1375 with pytest.raises(TypeError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001376 builder.sign(private_key, object(), backend)
Ian Cordascob77c7162015-07-20 21:22:33 -05001377
Ian Cordasco56561b12015-07-24 16:38:50 -05001378 @pytest.mark.requires_backend_interface(interface=DSABackend)
1379 @pytest.mark.requires_backend_interface(interface=X509Backend)
1380 def test_sign_with_dsa_private_key_is_unsupported(self, backend):
1381 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1382 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1383
1384 private_key = DSA_KEY_2048.private_key(backend)
1385 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001386 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001387 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001388 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001389 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001390 ).serial_number(
1391 1
1392 ).public_key(
1393 private_key.public_key()
1394 ).not_valid_before(
1395 datetime.datetime(2002, 1, 1, 12, 1)
1396 ).not_valid_after(
1397 datetime.datetime(2032, 1, 1, 12, 1)
1398 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001399
1400 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001401 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001402
1403 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1404 @pytest.mark.requires_backend_interface(interface=X509Backend)
1405 def test_sign_with_ec_private_key_is_unsupported(self, backend):
1406 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1407 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1408
1409 _skip_curve_unsupported(backend, ec.SECP256R1())
1410 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1411 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001412 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001413 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001414 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001415 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001416 ).serial_number(
1417 1
1418 ).public_key(
1419 private_key.public_key()
1420 ).not_valid_before(
1421 datetime.datetime(2002, 1, 1, 12, 1)
1422 ).not_valid_after(
1423 datetime.datetime(2032, 1, 1, 12, 1)
1424 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001425
1426 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001427 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001428
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001429 @pytest.mark.parametrize(
1430 "cdp",
1431 [
1432 x509.CRLDistributionPoints([
1433 x509.DistributionPoint(
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001434 full_name=None,
1435 relative_name=x509.Name([
1436 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001437 NameOID.COMMON_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001438 u"indirect CRL for indirectCRL CA3"
1439 ),
1440 ]),
1441 reasons=None,
1442 crl_issuer=[x509.DirectoryName(
1443 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001444 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001445 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001446 NameOID.ORGANIZATION_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001447 u"Test Certificates 2011"
1448 ),
1449 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001450 NameOID.ORGANIZATIONAL_UNIT_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001451 u"indirectCRL CA3 cRLIssuer"
1452 ),
1453 ])
1454 )],
1455 )
1456 ]),
1457 x509.CRLDistributionPoints([
1458 x509.DistributionPoint(
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001459 full_name=[x509.DirectoryName(
1460 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001461 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001462 ])
1463 )],
1464 relative_name=None,
1465 reasons=None,
1466 crl_issuer=[x509.DirectoryName(
1467 x509.Name([
1468 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001469 NameOID.ORGANIZATION_NAME,
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001470 u"cryptography Testing"
1471 ),
1472 ])
1473 )],
1474 )
1475 ]),
1476 x509.CRLDistributionPoints([
1477 x509.DistributionPoint(
Paul Kehrerc6cf8f32015-08-08 09:47:44 -05001478 full_name=[
1479 x509.UniformResourceIdentifier(
1480 u"http://myhost.com/myca.crl"
1481 ),
1482 x509.UniformResourceIdentifier(
1483 u"http://backup.myhost.com/myca.crl"
1484 )
1485 ],
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001486 relative_name=None,
1487 reasons=frozenset([
1488 x509.ReasonFlags.key_compromise,
1489 x509.ReasonFlags.ca_compromise
1490 ]),
1491 crl_issuer=[x509.DirectoryName(
1492 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001493 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001494 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001495 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001496 ),
1497 ])
1498 )],
1499 )
1500 ]),
1501 x509.CRLDistributionPoints([
1502 x509.DistributionPoint(
1503 full_name=[x509.UniformResourceIdentifier(
1504 u"http://domain.com/some.crl"
1505 )],
1506 relative_name=None,
1507 reasons=frozenset([
1508 x509.ReasonFlags.key_compromise,
1509 x509.ReasonFlags.ca_compromise,
1510 x509.ReasonFlags.affiliation_changed,
1511 x509.ReasonFlags.superseded,
1512 x509.ReasonFlags.privilege_withdrawn,
1513 x509.ReasonFlags.cessation_of_operation,
1514 x509.ReasonFlags.aa_compromise,
1515 x509.ReasonFlags.certificate_hold,
1516 ]),
1517 crl_issuer=None
1518 )
1519 ]),
1520 x509.CRLDistributionPoints([
1521 x509.DistributionPoint(
1522 full_name=None,
1523 relative_name=None,
1524 reasons=None,
1525 crl_issuer=[x509.DirectoryName(
1526 x509.Name([
1527 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001528 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001529 ),
1530 ])
1531 )],
1532 )
1533 ]),
1534 x509.CRLDistributionPoints([
1535 x509.DistributionPoint(
1536 full_name=[x509.UniformResourceIdentifier(
1537 u"http://domain.com/some.crl"
1538 )],
1539 relative_name=None,
1540 reasons=frozenset([x509.ReasonFlags.aa_compromise]),
1541 crl_issuer=None
1542 )
1543 ])
1544 ]
1545 )
1546 @pytest.mark.requires_backend_interface(interface=RSABackend)
1547 @pytest.mark.requires_backend_interface(interface=X509Backend)
1548 def test_crl_distribution_points(self, backend, cdp):
1549 issuer_private_key = RSA_KEY_2048.private_key(backend)
1550 subject_private_key = RSA_KEY_2048.private_key(backend)
1551
1552 builder = x509.CertificateBuilder().serial_number(
1553 4444444
1554 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001555 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001556 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001557 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001558 ])).public_key(
1559 subject_private_key.public_key()
1560 ).add_extension(
1561 cdp,
1562 critical=False,
1563 ).not_valid_before(
1564 datetime.datetime(2002, 1, 1, 12, 1)
1565 ).not_valid_after(
1566 datetime.datetime(2030, 12, 31, 8, 30)
1567 )
1568
1569 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
1570
1571 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001572 ExtensionOID.CRL_DISTRIBUTION_POINTS
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001573 )
1574 assert ext.critical is False
1575 assert ext.value == cdp
1576
Ian Cordasco56561b12015-07-24 16:38:50 -05001577 @pytest.mark.requires_backend_interface(interface=DSABackend)
1578 @pytest.mark.requires_backend_interface(interface=X509Backend)
1579 def test_build_cert_with_dsa_private_key(self, backend):
1580 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1581 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1582
1583 issuer_private_key = DSA_KEY_2048.private_key(backend)
1584 subject_private_key = DSA_KEY_2048.private_key(backend)
1585
1586 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1587 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1588
1589 builder = x509.CertificateBuilder().serial_number(
1590 777
1591 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001592 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001593 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001594 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001595 ])).public_key(
1596 subject_private_key.public_key()
1597 ).add_extension(
1598 x509.BasicConstraints(ca=False, path_length=None), True,
1599 ).add_extension(
1600 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1601 critical=False,
1602 ).not_valid_before(
1603 not_valid_before
1604 ).not_valid_after(
1605 not_valid_after
1606 )
1607
Paul Kehrer9add80e2015-08-03 17:53:14 +01001608 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001609
1610 assert cert.version is x509.Version.v3
1611 assert cert.not_valid_before == not_valid_before
1612 assert cert.not_valid_after == not_valid_after
1613 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001614 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco56561b12015-07-24 16:38:50 -05001615 )
1616 assert basic_constraints.value.ca is False
1617 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001618 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001619 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001620 )
1621 assert list(subject_alternative_name.value) == [
1622 x509.DNSName(u"cryptography.io"),
1623 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001624
1625 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1626 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco85fc4d52015-08-01 20:29:31 -05001627 def test_build_cert_with_ec_private_key(self, backend):
Ian Cordasco56561b12015-07-24 16:38:50 -05001628 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1629 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1630
1631 _skip_curve_unsupported(backend, ec.SECP256R1())
1632 issuer_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1633 subject_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1634
1635 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1636 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1637
1638 builder = x509.CertificateBuilder().serial_number(
1639 777
1640 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001641 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001642 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001643 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001644 ])).public_key(
1645 subject_private_key.public_key()
1646 ).add_extension(
1647 x509.BasicConstraints(ca=False, path_length=None), True,
1648 ).add_extension(
1649 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1650 critical=False,
1651 ).not_valid_before(
1652 not_valid_before
1653 ).not_valid_after(
1654 not_valid_after
1655 )
1656
Paul Kehrer9add80e2015-08-03 17:53:14 +01001657 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001658
1659 assert cert.version is x509.Version.v3
1660 assert cert.not_valid_before == not_valid_before
1661 assert cert.not_valid_after == not_valid_after
1662 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001663 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco56561b12015-07-24 16:38:50 -05001664 )
1665 assert basic_constraints.value.ca is False
1666 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001667 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001668 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001669 )
1670 assert list(subject_alternative_name.value) == [
1671 x509.DNSName(u"cryptography.io"),
1672 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001673
Ian Cordasco8690eff2015-07-24 16:42:58 -05001674 @pytest.mark.requires_backend_interface(interface=RSABackend)
1675 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco19f5a492015-08-01 11:06:17 -05001676 def test_build_cert_with_rsa_key_too_small(self, backend):
Ian Cordasco8690eff2015-07-24 16:42:58 -05001677 issuer_private_key = RSA_KEY_512.private_key(backend)
1678 subject_private_key = RSA_KEY_512.private_key(backend)
1679
1680 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1681 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1682
1683 builder = x509.CertificateBuilder().serial_number(
1684 777
1685 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001686 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001687 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001688 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001689 ])).public_key(
1690 subject_private_key.public_key()
Ian Cordasco8690eff2015-07-24 16:42:58 -05001691 ).not_valid_before(
1692 not_valid_before
1693 ).not_valid_after(
1694 not_valid_after
1695 )
1696
Ian Cordasco19f5a492015-08-01 11:06:17 -05001697 with pytest.raises(ValueError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001698 builder.sign(issuer_private_key, hashes.SHA512(), backend)
Ian Cordasco8690eff2015-07-24 16:42:58 -05001699
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001700 @pytest.mark.requires_backend_interface(interface=RSABackend)
1701 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer69b64e42015-08-09 00:00:44 -05001702 def test_issuer_alt_name(self, backend):
1703 issuer_private_key = RSA_KEY_2048.private_key(backend)
1704 subject_private_key = RSA_KEY_2048.private_key(backend)
1705
1706 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1707 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1708
1709 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001710 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer69b64e42015-08-09 00:00:44 -05001711 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001712 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer69b64e42015-08-09 00:00:44 -05001713 ).not_valid_before(
1714 not_valid_before
1715 ).not_valid_after(
1716 not_valid_after
1717 ).public_key(
1718 subject_private_key.public_key()
1719 ).serial_number(
1720 123
1721 ).add_extension(
1722 x509.IssuerAlternativeName([
1723 x509.DNSName(u"myissuer"),
1724 x509.RFC822Name(u"email@domain.com"),
1725 ]), critical=False
1726 ).sign(issuer_private_key, hashes.SHA256(), backend)
1727
1728 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001729 ExtensionOID.ISSUER_ALTERNATIVE_NAME
Paul Kehrer69b64e42015-08-09 00:00:44 -05001730 )
1731 assert ext.critical is False
1732 assert ext.value == x509.IssuerAlternativeName([
1733 x509.DNSName(u"myissuer"),
1734 x509.RFC822Name(u"email@domain.com"),
1735 ])
1736
1737 @pytest.mark.requires_backend_interface(interface=RSABackend)
1738 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001739 def test_extended_key_usage(self, backend):
1740 issuer_private_key = RSA_KEY_2048.private_key(backend)
1741 subject_private_key = RSA_KEY_2048.private_key(backend)
1742
1743 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1744 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1745
1746 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001747 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001748 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001749 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001750 ).not_valid_before(
1751 not_valid_before
1752 ).not_valid_after(
1753 not_valid_after
1754 ).public_key(
1755 subject_private_key.public_key()
1756 ).serial_number(
1757 123
1758 ).add_extension(
1759 x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05001760 ExtendedKeyUsageOID.CLIENT_AUTH,
1761 ExtendedKeyUsageOID.SERVER_AUTH,
1762 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001763 ]), critical=False
1764 ).sign(issuer_private_key, hashes.SHA256(), backend)
1765
1766 eku = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001767 ExtensionOID.EXTENDED_KEY_USAGE
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001768 )
1769 assert eku.critical is False
1770 assert eku.value == x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05001771 ExtendedKeyUsageOID.CLIENT_AUTH,
1772 ExtendedKeyUsageOID.SERVER_AUTH,
1773 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001774 ])
1775
1776 @pytest.mark.requires_backend_interface(interface=RSABackend)
1777 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer683d4d82015-08-06 23:13:45 +01001778 def test_inhibit_any_policy(self, backend):
1779 issuer_private_key = RSA_KEY_2048.private_key(backend)
1780 subject_private_key = RSA_KEY_2048.private_key(backend)
1781
1782 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1783 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1784
1785 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001786 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer683d4d82015-08-06 23:13:45 +01001787 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001788 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer683d4d82015-08-06 23:13:45 +01001789 ).not_valid_before(
1790 not_valid_before
1791 ).not_valid_after(
1792 not_valid_after
1793 ).public_key(
1794 subject_private_key.public_key()
1795 ).serial_number(
1796 123
1797 ).add_extension(
1798 x509.InhibitAnyPolicy(3), critical=False
1799 ).sign(issuer_private_key, hashes.SHA256(), backend)
1800
1801 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001802 ExtensionOID.INHIBIT_ANY_POLICY
Paul Kehrer683d4d82015-08-06 23:13:45 +01001803 )
1804 assert ext.value == x509.InhibitAnyPolicy(3)
1805
1806 @pytest.mark.requires_backend_interface(interface=RSABackend)
1807 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001808 def test_key_usage(self, backend):
1809 issuer_private_key = RSA_KEY_2048.private_key(backend)
1810 subject_private_key = RSA_KEY_2048.private_key(backend)
1811
1812 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1813 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1814
1815 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001816 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001817 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001818 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001819 ).not_valid_before(
1820 not_valid_before
1821 ).not_valid_after(
1822 not_valid_after
1823 ).public_key(
1824 subject_private_key.public_key()
1825 ).serial_number(
1826 123
1827 ).add_extension(
1828 x509.KeyUsage(
1829 digital_signature=True,
1830 content_commitment=True,
1831 key_encipherment=False,
1832 data_encipherment=False,
1833 key_agreement=False,
1834 key_cert_sign=True,
1835 crl_sign=False,
1836 encipher_only=False,
1837 decipher_only=False
1838 ),
1839 critical=False
1840 ).sign(issuer_private_key, hashes.SHA256(), backend)
1841
Paul Kehrerd44e4132015-08-10 19:13:13 -05001842 ext = cert.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001843 assert ext.critical is False
1844 assert ext.value == x509.KeyUsage(
1845 digital_signature=True,
1846 content_commitment=True,
1847 key_encipherment=False,
1848 data_encipherment=False,
1849 key_agreement=False,
1850 key_cert_sign=True,
1851 crl_sign=False,
1852 encipher_only=False,
1853 decipher_only=False
1854 )
1855
Ian Cordasco747a2172015-07-19 11:00:14 -05001856
Andre Caron0ef595f2015-05-18 13:53:43 -04001857@pytest.mark.requires_backend_interface(interface=X509Backend)
1858class TestCertificateSigningRequestBuilder(object):
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001859 @pytest.mark.requires_backend_interface(interface=RSABackend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001860 def test_sign_invalid_hash_algorithm(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001861 private_key = RSA_KEY_2048.private_key(backend)
1862
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001863 builder = x509.CertificateSigningRequestBuilder().subject_name(
1864 x509.Name([])
1865 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001866 with pytest.raises(TypeError):
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001867 builder.sign(private_key, 'NotAHash', backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001868
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001869 @pytest.mark.requires_backend_interface(interface=RSABackend)
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001870 def test_no_subject_name(self, backend):
1871 private_key = RSA_KEY_2048.private_key(backend)
1872
1873 builder = x509.CertificateSigningRequestBuilder()
1874 with pytest.raises(ValueError):
1875 builder.sign(private_key, hashes.SHA256(), backend)
1876
1877 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001878 def test_build_ca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001879 private_key = RSA_KEY_2048.private_key(backend)
1880
Andre Carona9a51172015-06-06 20:18:44 -04001881 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04001882 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001883 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Andre Caron99d0f902015-06-01 08:36:59 -04001884 ])
Andre Caron472fd692015-06-06 20:04:44 -04001885 ).add_extension(
Ian Cordasco41f51ce2015-06-17 11:49:11 -05001886 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001887 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001888
1889 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1890 public_key = request.public_key()
1891 assert isinstance(public_key, rsa.RSAPublicKey)
1892 subject = request.subject
1893 assert isinstance(subject, x509.Name)
1894 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001895 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Andre Caron0ef595f2015-05-18 13:53:43 -04001896 ]
1897 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001898 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron0ef595f2015-05-18 13:53:43 -04001899 )
1900 assert basic_constraints.value.ca is True
1901 assert basic_constraints.value.path_length == 2
1902
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001903 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001904 def test_build_ca_request_with_unicode(self, backend):
1905 private_key = RSA_KEY_2048.private_key(backend)
1906
1907 request = x509.CertificateSigningRequestBuilder().subject_name(
1908 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001909 x509.NameAttribute(NameOID.ORGANIZATION_NAME,
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001910 u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001911 ])
1912 ).add_extension(
1913 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001914 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001915
1916 loaded_request = x509.load_pem_x509_csr(
1917 request.public_bytes(encoding=serialization.Encoding.PEM), backend
1918 )
1919 subject = loaded_request.subject
1920 assert isinstance(subject, x509.Name)
1921 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001922 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001923 ]
1924
1925 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001926 def test_build_nonca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001927 private_key = RSA_KEY_2048.private_key(backend)
1928
Andre Carona9a51172015-06-06 20:18:44 -04001929 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04001930 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001931 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Andre Caron99d0f902015-06-01 08:36:59 -04001932 ])
Andre Caron472fd692015-06-06 20:04:44 -04001933 ).add_extension(
Ian Cordasco0112b022015-06-16 17:51:18 -05001934 x509.BasicConstraints(ca=False, path_length=None), critical=True,
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001935 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001936
1937 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1938 public_key = request.public_key()
1939 assert isinstance(public_key, rsa.RSAPublicKey)
1940 subject = request.subject
1941 assert isinstance(subject, x509.Name)
1942 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001943 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Andre Caron0ef595f2015-05-18 13:53:43 -04001944 ]
1945 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001946 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron0ef595f2015-05-18 13:53:43 -04001947 )
1948 assert basic_constraints.value.ca is False
1949 assert basic_constraints.value.path_length is None
1950
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001951 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1952 def test_build_ca_request_with_ec(self, backend):
1953 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1954 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1955
Ian Cordasco8cdcdfc2015-06-24 22:00:26 -05001956 _skip_curve_unsupported(backend, ec.SECP256R1())
1957 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001958
1959 request = x509.CertificateSigningRequestBuilder().subject_name(
1960 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001961 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001962 ])
1963 ).add_extension(
1964 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001965 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001966
1967 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1968 public_key = request.public_key()
1969 assert isinstance(public_key, ec.EllipticCurvePublicKey)
1970 subject = request.subject
1971 assert isinstance(subject, x509.Name)
1972 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001973 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001974 ]
1975 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001976 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001977 )
1978 assert basic_constraints.value.ca is True
1979 assert basic_constraints.value.path_length == 2
1980
1981 @pytest.mark.requires_backend_interface(interface=DSABackend)
1982 def test_build_ca_request_with_dsa(self, backend):
1983 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1984 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1985
1986 private_key = DSA_KEY_2048.private_key(backend)
1987
1988 request = x509.CertificateSigningRequestBuilder().subject_name(
1989 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001990 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001991 ])
1992 ).add_extension(
1993 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001994 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001995
1996 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1997 public_key = request.public_key()
1998 assert isinstance(public_key, dsa.DSAPublicKey)
1999 subject = request.subject
2000 assert isinstance(subject, x509.Name)
2001 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002002 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002003 ]
2004 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002005 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002006 )
2007 assert basic_constraints.value.ca is True
2008 assert basic_constraints.value.path_length == 2
2009
Paul Kehrerff917802015-06-26 17:29:04 -05002010 def test_add_duplicate_extension(self):
Andre Caronfc164c52015-05-31 17:36:18 -04002011 builder = x509.CertificateSigningRequestBuilder().add_extension(
Andre Caron472fd692015-06-06 20:04:44 -04002012 x509.BasicConstraints(True, 2), critical=True,
Andre Caronfc164c52015-05-31 17:36:18 -04002013 )
Andre Caron0ef595f2015-05-18 13:53:43 -04002014 with pytest.raises(ValueError):
Andre Caron472fd692015-06-06 20:04:44 -04002015 builder.add_extension(
2016 x509.BasicConstraints(True, 2), critical=True,
2017 )
Andre Caron0ef595f2015-05-18 13:53:43 -04002018
Paul Kehrerff917802015-06-26 17:29:04 -05002019 def test_set_invalid_subject(self):
Andre Caron0ef595f2015-05-18 13:53:43 -04002020 builder = x509.CertificateSigningRequestBuilder()
2021 with pytest.raises(TypeError):
Andre Carona9a51172015-06-06 20:18:44 -04002022 builder.subject_name('NotAName')
Andre Caron0ef595f2015-05-18 13:53:43 -04002023
Paul Kehrere59fd222015-08-08 22:50:19 -05002024 def test_add_invalid_extension_type(self):
Ian Cordasco34853f32015-06-21 10:50:53 -05002025 builder = x509.CertificateSigningRequestBuilder()
Andre Caron0ef595f2015-05-18 13:53:43 -04002026
Paul Kehrere59fd222015-08-08 22:50:19 -05002027 with pytest.raises(TypeError):
2028 builder.add_extension(object(), False)
2029
2030 def test_add_unsupported_extension(self, backend):
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002031 private_key = RSA_KEY_2048.private_key(backend)
2032 builder = x509.CertificateSigningRequestBuilder()
2033 builder = builder.subject_name(
2034 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002035 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002036 ])
2037 ).add_extension(
Alex Gaynor7583f7f2015-07-03 10:56:49 -04002038 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
2039 critical=False,
2040 ).add_extension(
Paul Kehrer69b64e42015-08-09 00:00:44 -05002041 DummyExtension(), False
Paul Kehrerdce91f02015-07-23 20:31:12 +01002042 )
2043 with pytest.raises(NotImplementedError):
2044 builder.sign(private_key, hashes.SHA256(), backend)
2045
2046 def test_key_usage(self, backend):
2047 private_key = RSA_KEY_2048.private_key(backend)
2048 builder = x509.CertificateSigningRequestBuilder()
2049 request = builder.subject_name(
2050 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002051 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerdce91f02015-07-23 20:31:12 +01002052 ])
2053 ).add_extension(
Alex Gaynorac7f70a2015-06-28 11:07:52 -04002054 x509.KeyUsage(
2055 digital_signature=True,
2056 content_commitment=True,
2057 key_encipherment=False,
2058 data_encipherment=False,
2059 key_agreement=False,
2060 key_cert_sign=True,
2061 crl_sign=False,
2062 encipher_only=False,
2063 decipher_only=False
2064 ),
Alex Gaynor887a4082015-07-03 04:29:03 -04002065 critical=False
Paul Kehrerdce91f02015-07-23 20:31:12 +01002066 ).sign(private_key, hashes.SHA256(), backend)
2067 assert len(request.extensions) == 1
Paul Kehrerd44e4132015-08-10 19:13:13 -05002068 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrerdce91f02015-07-23 20:31:12 +01002069 assert ext.critical is False
2070 assert ext.value == x509.KeyUsage(
2071 digital_signature=True,
2072 content_commitment=True,
2073 key_encipherment=False,
2074 data_encipherment=False,
2075 key_agreement=False,
2076 key_cert_sign=True,
2077 crl_sign=False,
2078 encipher_only=False,
2079 decipher_only=False
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002080 )
Paul Kehrerdce91f02015-07-23 20:31:12 +01002081
2082 def test_key_usage_key_agreement_bit(self, backend):
2083 private_key = RSA_KEY_2048.private_key(backend)
2084 builder = x509.CertificateSigningRequestBuilder()
2085 request = builder.subject_name(
2086 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002087 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerdce91f02015-07-23 20:31:12 +01002088 ])
2089 ).add_extension(
2090 x509.KeyUsage(
2091 digital_signature=False,
2092 content_commitment=False,
2093 key_encipherment=False,
2094 data_encipherment=False,
2095 key_agreement=True,
2096 key_cert_sign=True,
2097 crl_sign=False,
2098 encipher_only=False,
2099 decipher_only=True
2100 ),
2101 critical=False
2102 ).sign(private_key, hashes.SHA256(), backend)
2103 assert len(request.extensions) == 1
Paul Kehrerd44e4132015-08-10 19:13:13 -05002104 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrerdce91f02015-07-23 20:31:12 +01002105 assert ext.critical is False
2106 assert ext.value == x509.KeyUsage(
2107 digital_signature=False,
2108 content_commitment=False,
2109 key_encipherment=False,
2110 data_encipherment=False,
2111 key_agreement=True,
2112 key_cert_sign=True,
2113 crl_sign=False,
2114 encipher_only=False,
2115 decipher_only=True
2116 )
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002117
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002118 def test_add_two_extensions(self, backend):
2119 private_key = RSA_KEY_2048.private_key(backend)
2120 builder = x509.CertificateSigningRequestBuilder()
2121 request = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002122 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002123 ).add_extension(
2124 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
2125 critical=False,
2126 ).add_extension(
2127 x509.BasicConstraints(ca=True, path_length=2), critical=True
2128 ).sign(private_key, hashes.SHA1(), backend)
2129
2130 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2131 public_key = request.public_key()
2132 assert isinstance(public_key, rsa.RSAPublicKey)
2133 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002134 ExtensionOID.BASIC_CONSTRAINTS
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002135 )
2136 assert basic_constraints.value.ca is True
2137 assert basic_constraints.value.path_length == 2
2138 ext = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002139 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002140 )
2141 assert list(ext.value) == [x509.DNSName(u"cryptography.io")]
Paul Kehrerff917802015-06-26 17:29:04 -05002142
Andre Caron0ef595f2015-05-18 13:53:43 -04002143 def test_set_subject_twice(self):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002144 builder = x509.CertificateSigningRequestBuilder()
2145 builder = builder.subject_name(
Paul Kehrere76cd272014-12-14 19:00:51 -06002146 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002147 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera693cfd2014-11-27 07:47:58 -10002148 ])
Paul Kehrer4903adc2014-12-13 16:57:50 -06002149 )
Paul Kehrer41120322014-12-02 18:31:14 -10002150 with pytest.raises(ValueError):
Paul Kehrera693cfd2014-11-27 07:47:58 -10002151 builder.subject_name(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002152 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002153 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002154 ])
Alex Gaynor32c57df2015-02-23 21:51:27 -08002155 )
Alex Gaynorfcadda62015-03-10 10:01:18 -04002156
Alex Gaynord3e84162015-06-28 10:14:55 -04002157 def test_subject_alt_names(self, backend):
2158 private_key = RSA_KEY_2048.private_key(backend)
2159
2160 csr = x509.CertificateSigningRequestBuilder().subject_name(
2161 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002162 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Alex Gaynord3e84162015-06-28 10:14:55 -04002163 ])
2164 ).add_extension(
2165 x509.SubjectAlternativeName([
Alex Gaynor6431d502015-07-05 12:28:46 -04002166 x509.DNSName(u"example.com"),
2167 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05002168 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002169 x509.DirectoryName(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002170 x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002171 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002172 NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002173 )
2174 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05002175 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
2176 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05002177 x509.OtherName(
2178 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2179 value=b"0\x03\x02\x01\x05"
2180 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05002181 x509.RFC822Name(u"test@example.com"),
2182 x509.RFC822Name(u"email"),
2183 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05002184 x509.UniformResourceIdentifier(
2185 u"https://\u043f\u044b\u043a\u0430.cryptography"
2186 ),
2187 x509.UniformResourceIdentifier(
2188 u"gopher://cryptography:70/some/path"
2189 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04002190 ]),
2191 critical=False,
2192 ).sign(private_key, hashes.SHA256(), backend)
2193
2194 assert len(csr.extensions) == 1
2195 ext = csr.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002196 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynord3e84162015-06-28 10:14:55 -04002197 )
2198 assert not ext.critical
Paul Kehrerd44e4132015-08-10 19:13:13 -05002199 assert ext.oid == ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynord3e84162015-06-28 10:14:55 -04002200 assert list(ext.value) == [
Alex Gaynor6431d502015-07-05 12:28:46 -04002201 x509.DNSName(u"example.com"),
2202 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05002203 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002204 x509.DirectoryName(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002205 x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002206 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002207 NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002208 ),
2209 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05002210 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
2211 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05002212 x509.OtherName(
2213 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2214 value=b"0\x03\x02\x01\x05"
2215 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05002216 x509.RFC822Name(u"test@example.com"),
2217 x509.RFC822Name(u"email"),
2218 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05002219 x509.UniformResourceIdentifier(
2220 u"https://\u043f\u044b\u043a\u0430.cryptography"
2221 ),
2222 x509.UniformResourceIdentifier(
2223 u"gopher://cryptography:70/some/path"
2224 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04002225 ]
2226
Paul Kehrer500ed9d2015-07-10 20:51:36 -05002227 def test_invalid_asn1_othername(self, backend):
2228 private_key = RSA_KEY_2048.private_key(backend)
2229
2230 builder = x509.CertificateSigningRequestBuilder().subject_name(
2231 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002232 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Paul Kehrer500ed9d2015-07-10 20:51:36 -05002233 ])
2234 ).add_extension(
2235 x509.SubjectAlternativeName([
2236 x509.OtherName(
2237 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2238 value=b"\x01\x02\x01\x05"
2239 ),
2240 ]),
2241 critical=False,
2242 )
2243 with pytest.raises(ValueError):
2244 builder.sign(private_key, hashes.SHA256(), backend)
2245
Alex Gaynord5f718c2015-07-05 11:19:38 -04002246 def test_subject_alt_name_unsupported_general_name(self, backend):
2247 private_key = RSA_KEY_2048.private_key(backend)
2248
2249 builder = x509.CertificateSigningRequestBuilder().subject_name(
2250 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002251 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Alex Gaynord5f718c2015-07-05 11:19:38 -04002252 ])
2253 ).add_extension(
Paul Kehrer474a6472015-07-11 12:29:52 -05002254 x509.SubjectAlternativeName([FakeGeneralName("")]),
Alex Gaynord5f718c2015-07-05 11:19:38 -04002255 critical=False,
2256 )
2257
Paul Kehrer474a6472015-07-11 12:29:52 -05002258 with pytest.raises(ValueError):
Alex Gaynord5f718c2015-07-05 11:19:38 -04002259 builder.sign(private_key, hashes.SHA256(), backend)
2260
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002261 def test_extended_key_usage(self, backend):
2262 private_key = RSA_KEY_2048.private_key(backend)
2263 builder = x509.CertificateSigningRequestBuilder()
2264 request = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002265 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002266 ).add_extension(
2267 x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05002268 ExtendedKeyUsageOID.CLIENT_AUTH,
2269 ExtendedKeyUsageOID.SERVER_AUTH,
2270 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002271 ]), critical=False
2272 ).sign(private_key, hashes.SHA256(), backend)
2273
2274 eku = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002275 ExtensionOID.EXTENDED_KEY_USAGE
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002276 )
2277 assert eku.critical is False
2278 assert eku.value == x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05002279 ExtendedKeyUsageOID.CLIENT_AUTH,
2280 ExtendedKeyUsageOID.SERVER_AUTH,
2281 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002282 ])
2283
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002284 @pytest.mark.requires_backend_interface(interface=RSABackend)
2285 def test_rsa_key_too_small(self, backend):
2286 private_key = rsa.generate_private_key(65537, 512, backend)
2287 builder = x509.CertificateSigningRequestBuilder()
2288 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002289 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002290 )
2291
2292 with pytest.raises(ValueError) as exc:
2293 builder.sign(private_key, hashes.SHA512(), backend)
2294
Paul Kehrer6a71f8d2015-07-25 19:15:59 +01002295 assert str(exc.value) == "Digest too big for RSA key"
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002296
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002297 @pytest.mark.requires_backend_interface(interface=RSABackend)
2298 @pytest.mark.requires_backend_interface(interface=X509Backend)
2299 def test_build_cert_with_aia(self, backend):
2300 issuer_private_key = RSA_KEY_2048.private_key(backend)
2301 subject_private_key = RSA_KEY_2048.private_key(backend)
2302
2303 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2304 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2305
2306 aia = x509.AuthorityInformationAccess([
2307 x509.AccessDescription(
Paul Kehrer9e102db2015-08-10 21:53:09 -05002308 AuthorityInformationAccessOID.OCSP,
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002309 x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
2310 ),
2311 x509.AccessDescription(
Paul Kehrer9e102db2015-08-10 21:53:09 -05002312 AuthorityInformationAccessOID.CA_ISSUERS,
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002313 x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
2314 )
2315 ])
2316
2317 builder = x509.CertificateBuilder().serial_number(
2318 777
2319 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002320 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002321 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002322 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002323 ])).public_key(
2324 subject_private_key.public_key()
2325 ).add_extension(
2326 aia, critical=False
2327 ).not_valid_before(
2328 not_valid_before
2329 ).not_valid_after(
2330 not_valid_after
2331 )
2332
2333 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2334
2335 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002336 ExtensionOID.AUTHORITY_INFORMATION_ACCESS
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002337 )
2338 assert ext.value == aia
2339
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002340 @pytest.mark.requires_backend_interface(interface=RSABackend)
2341 @pytest.mark.requires_backend_interface(interface=X509Backend)
2342 def test_build_cert_with_ski(self, backend):
2343 issuer_private_key = RSA_KEY_2048.private_key(backend)
2344 subject_private_key = RSA_KEY_2048.private_key(backend)
2345
2346 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2347 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2348
2349 ski = x509.SubjectKeyIdentifier.from_public_key(
2350 subject_private_key.public_key()
2351 )
2352
2353 builder = x509.CertificateBuilder().serial_number(
2354 777
2355 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002356 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002357 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002358 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002359 ])).public_key(
2360 subject_private_key.public_key()
2361 ).add_extension(
2362 ski, critical=False
2363 ).not_valid_before(
2364 not_valid_before
2365 ).not_valid_after(
2366 not_valid_after
2367 )
2368
2369 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2370
2371 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002372 ExtensionOID.SUBJECT_KEY_IDENTIFIER
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002373 )
2374 assert ext.value == ski
2375
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002376 @pytest.mark.parametrize(
2377 "aki",
2378 [
2379 x509.AuthorityKeyIdentifier(
2380 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2381 b"\xcbY",
2382 None,
2383 None
2384 ),
2385 x509.AuthorityKeyIdentifier(
2386 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2387 b"\xcbY",
2388 [
2389 x509.DirectoryName(
2390 x509.Name([
2391 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002392 NameOID.ORGANIZATION_NAME, u"PyCA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002393 ),
2394 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002395 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002396 )
2397 ])
2398 )
2399 ],
2400 333
2401 ),
2402 x509.AuthorityKeyIdentifier(
2403 None,
2404 [
2405 x509.DirectoryName(
2406 x509.Name([
2407 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002408 NameOID.ORGANIZATION_NAME, u"PyCA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002409 ),
2410 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002411 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002412 )
2413 ])
2414 )
2415 ],
2416 333
2417 ),
2418 ]
2419 )
2420 @pytest.mark.requires_backend_interface(interface=RSABackend)
2421 @pytest.mark.requires_backend_interface(interface=X509Backend)
2422 def test_build_cert_with_aki(self, aki, backend):
2423 issuer_private_key = RSA_KEY_2048.private_key(backend)
2424 subject_private_key = RSA_KEY_2048.private_key(backend)
2425
2426 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2427 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2428
2429 builder = x509.CertificateBuilder().serial_number(
2430 777
2431 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002432 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002433 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002434 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002435 ])).public_key(
2436 subject_private_key.public_key()
2437 ).add_extension(
2438 aki, critical=False
2439 ).not_valid_before(
2440 not_valid_before
2441 ).not_valid_after(
2442 not_valid_after
2443 )
2444
2445 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2446
2447 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002448 ExtensionOID.AUTHORITY_KEY_IDENTIFIER
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002449 )
2450 assert ext.value == aki
2451
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002452 def test_ocsp_nocheck(self, backend):
2453 issuer_private_key = RSA_KEY_2048.private_key(backend)
2454 subject_private_key = RSA_KEY_2048.private_key(backend)
2455
2456 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2457 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2458
2459 builder = x509.CertificateBuilder().serial_number(
2460 777
2461 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002462 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002463 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002464 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002465 ])).public_key(
2466 subject_private_key.public_key()
2467 ).add_extension(
2468 x509.OCSPNoCheck(), critical=False
2469 ).not_valid_before(
2470 not_valid_before
2471 ).not_valid_after(
2472 not_valid_after
2473 )
2474
2475 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2476
2477 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002478 ExtensionOID.OCSP_NO_CHECK
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002479 )
2480 assert isinstance(ext.value, x509.OCSPNoCheck)
2481
Alex Gaynord5f718c2015-07-05 11:19:38 -04002482
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002483@pytest.mark.requires_backend_interface(interface=DSABackend)
2484@pytest.mark.requires_backend_interface(interface=X509Backend)
2485class TestDSACertificate(object):
2486 def test_load_dsa_cert(self, backend):
2487 cert = _load_cert(
2488 os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
2489 x509.load_pem_x509_certificate,
2490 backend
2491 )
2492 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
2493 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002494 assert isinstance(public_key, dsa.DSAPublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002495 num = public_key.public_numbers()
2496 assert num.y == int(
2497 "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94"
2498 "53b6656f13e543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2"
2499 "dea559f0b584c97a2b235b9b69b46bc6de1aed422a6f341832618bcaae2"
2500 "198aba388099dafb05ff0b5efecb3b0ae169a62e1c72022af50ae68af3b"
2501 "033c18e6eec1f7df4692c456ccafb79cc7e08da0a5786e9816ceda651d6"
2502 "1b4bb7b81c2783da97cea62df67af5e85991fdc13aff10fc60e06586386"
2503 "b96bb78d65750f542f86951e05a6d81baadbcd35a2e5cad4119923ae6a2"
2504 "002091a3d17017f93c52970113cdc119970b9074ca506eac91c3dd37632"
2505 "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c", 16
2506 )
2507 assert num.parameter_numbers.g == int(
2508 "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67"
2509 "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b"
2510 "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2"
2511 "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa"
2512 "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f"
2513 "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a"
2514 "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0"
2515 "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76"
2516 "fa6247676a6d3ac945844a083509c6a1b436baca", 16
2517 )
2518 assert num.parameter_numbers.p == int(
2519 "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3"
2520 "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330"
2521 "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e"
2522 "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a"
2523 "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4"
2524 "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2"
2525 "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93"
2526 "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d"
2527 "833e36468f3907cfca788a3cb790f0341c8a31bf", 16
2528 )
2529 assert num.parameter_numbers.q == int(
2530 "822ff5d234e073b901cf5941f58e1f538e71d40d", 16
2531 )
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002532
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002533 @pytest.mark.parametrize(
2534 ("path", "loader_func"),
2535 [
2536 [
2537 os.path.join("x509", "requests", "dsa_sha1.pem"),
2538 x509.load_pem_x509_csr
2539 ],
2540 [
2541 os.path.join("x509", "requests", "dsa_sha1.der"),
2542 x509.load_der_x509_csr
2543 ],
2544 ]
2545 )
2546 def test_load_dsa_request(self, path, loader_func, backend):
2547 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002548 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2549 public_key = request.public_key()
2550 assert isinstance(public_key, dsa.DSAPublicKey)
2551 subject = request.subject
2552 assert isinstance(subject, x509.Name)
2553 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002554 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2555 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2556 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2557 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2558 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002559 ]
2560
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002561
2562@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2563@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -06002564class TestECDSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002565 def test_load_ecdsa_cert(self, backend):
2566 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrera693cfd2014-11-27 07:47:58 -10002567 cert = _load_cert(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002568 os.path.join("x509", "ecdsa_root.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -10002569 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -10002570 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002571 )
Paul Kehrer8802a5b2015-02-13 12:06:57 -06002572 assert isinstance(cert.signature_hash_algorithm, hashes.SHA384)
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002573 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002574 assert isinstance(public_key, ec.EllipticCurvePublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002575 num = public_key.public_numbers()
2576 assert num.x == int(
2577 "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f"
2578 "6f0ccd00bba615b51467e9e2d9fee8e630c17", 16
2579 )
2580 assert num.y == int(
2581 "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7"
2582 "2deae88a7a16bb543ce67dc23ff031ca3e23e", 16
2583 )
2584 assert isinstance(num.curve, ec.SECP384R1)
Paul Kehrer6c660a82014-12-12 11:50:44 -06002585
2586 def test_load_ecdsa_no_named_curve(self, backend):
2587 _skip_curve_unsupported(backend, ec.SECP256R1())
2588 cert = _load_cert(
2589 os.path.join("x509", "custom", "ec_no_named_curve.pem"),
2590 x509.load_pem_x509_certificate,
2591 backend
2592 )
2593 with pytest.raises(NotImplementedError):
2594 cert.public_key()
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002595
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002596 @pytest.mark.parametrize(
2597 ("path", "loader_func"),
2598 [
2599 [
2600 os.path.join("x509", "requests", "ec_sha256.pem"),
2601 x509.load_pem_x509_csr
2602 ],
2603 [
2604 os.path.join("x509", "requests", "ec_sha256.der"),
2605 x509.load_der_x509_csr
2606 ],
2607 ]
2608 )
2609 def test_load_ecdsa_certificate_request(self, path, loader_func, backend):
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002610 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002611 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002612 assert isinstance(request.signature_hash_algorithm, hashes.SHA256)
2613 public_key = request.public_key()
2614 assert isinstance(public_key, ec.EllipticCurvePublicKey)
2615 subject = request.subject
2616 assert isinstance(subject, x509.Name)
2617 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002618 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2619 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2620 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2621 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2622 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002623 ]
2624
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002625
Paul Kehrer806bfb22015-02-02 17:05:24 -06002626class TestNameAttribute(object):
Alex Gaynora56ff412015-02-10 17:26:32 -05002627 def test_init_bad_oid(self):
2628 with pytest.raises(TypeError):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002629 x509.NameAttribute(None, u'value')
Alex Gaynora56ff412015-02-10 17:26:32 -05002630
Ian Cordasco7618fbe2015-06-16 19:12:17 -05002631 def test_init_bad_value(self):
2632 with pytest.raises(TypeError):
2633 x509.NameAttribute(
2634 x509.ObjectIdentifier('oid'),
2635 b'bytes'
2636 )
2637
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002638 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002639 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002640 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002641 ) == x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002642 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002643 )
2644
2645 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002646 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002647 x509.ObjectIdentifier('2.5.4.3'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002648 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002649 x509.ObjectIdentifier('2.5.4.5'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002650 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002651 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002652 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002653 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002654 x509.ObjectIdentifier('oid'), u'value2'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002655 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002656 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002657 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002658 ) != object()
2659
Paul Kehrera498be82015-02-12 15:00:56 -06002660 def test_repr(self):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002661 na = x509.NameAttribute(x509.ObjectIdentifier('2.5.4.3'), u'value')
Ian Cordascoa908d692015-06-16 21:35:24 -05002662 if six.PY3:
2663 assert repr(na) == (
2664 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2665 "nName)>, value='value')>"
2666 )
2667 else:
2668 assert repr(na) == (
2669 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2670 "nName)>, value=u'value')>"
2671 )
Paul Kehrera498be82015-02-12 15:00:56 -06002672
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002673
2674class TestObjectIdentifier(object):
2675 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002676 oid1 = x509.ObjectIdentifier('oid')
2677 oid2 = x509.ObjectIdentifier('oid')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002678 assert oid1 == oid2
2679
2680 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002681 oid1 = x509.ObjectIdentifier('oid')
2682 assert oid1 != x509.ObjectIdentifier('oid1')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002683 assert oid1 != object()
2684
2685 def test_repr(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002686 oid = x509.ObjectIdentifier("2.5.4.3")
2687 assert repr(oid) == "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>"
2688 oid = x509.ObjectIdentifier("oid1")
2689 assert repr(oid) == "<ObjectIdentifier(oid=oid1, name=Unknown OID)>"
Paul Kehrer719d5362015-01-01 20:03:52 -06002690
Brendan McCollam1b3b3ce2015-08-25 10:55:44 -05002691 def test_name_property(self):
2692 oid = x509.ObjectIdentifier("2.5.4.3")
2693 assert oid._name == 'commonName'
2694 oid = x509.ObjectIdentifier("oid1")
2695 assert oid._name == 'Unknown OID'
2696
Paul Kehrer719d5362015-01-01 20:03:52 -06002697
2698class TestName(object):
2699 def test_eq(self):
2700 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002701 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2702 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002703 ])
2704 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002705 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2706 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002707 ])
2708 assert name1 == name2
2709
2710 def test_ne(self):
2711 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002712 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2713 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002714 ])
2715 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002716 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
2717 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002718 ])
2719 assert name1 != name2
2720 assert name1 != object()
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002721
2722 def test_repr(self):
2723 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002724 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2725 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002726 ])
2727
Ian Cordascoa908d692015-06-16 21:35:24 -05002728 if six.PY3:
2729 assert repr(name) == (
2730 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2731 "=commonName)>, value='cryptography.io')>, <NameAttribute(oid="
2732 "<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, valu"
2733 "e='PyCA')>])>"
2734 )
2735 else:
2736 assert repr(name) == (
2737 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2738 "=commonName)>, value=u'cryptography.io')>, <NameAttribute(oid"
2739 "=<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, val"
2740 "ue=u'PyCA')>])>"
2741 )