blob: f5fead539dc5ba921da8b814efb37b0de53305d2 [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.
235 flags = set(x509.ReasonFlags)
236 # The first revoked cert doesn't have a reason.
237 for r in crl.revoked_certificates[1:]:
238 flags.discard(r.get_reason())
239 assert len(flags) == 0
240
241 def test_duplicate_entry_ext(self, backend):
242 crl = _load_cert(
243 os.path.join("x509", "custom", "crl_dup_entry_ext.pem"),
244 x509.load_pem_x509_crl,
245 backend
246 )
247
248 with pytest.raises(x509.DuplicateExtension):
249 crl.revoked_certificates[0].extensions
250
251 def test_unsupported_crit_entry_ext(self, backend):
252 crl = _load_cert(
253 os.path.join(
254 "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
255 ),
256 x509.load_pem_x509_crl,
257 backend
258 )
259
260 with pytest.raises(x509.UnsupportedExtension):
261 crl.revoked_certificates[0].extensions
262
263 def test_unsupported_reason(self, backend):
264 crl = _load_cert(
265 os.path.join(
266 "x509", "custom", "crl_unsupported_reason.pem"
267 ),
268 x509.load_pem_x509_crl,
269 backend
270 )
271
272 with pytest.raises(ValueError):
273 crl.revoked_certificates[0].extensions
274
275 def test_cert_issuer_ext(self, backend):
276 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10000000:
277 pytest.skip("Requires a newer OpenSSL. Must be at least 1.0.0")
278
279 crl = _load_cert(
280 os.path.join("x509", "custom", "crl_all_reasons.pem"),
281 x509.load_pem_x509_crl,
282 backend
283 )
284
285 exp_issuer = x509.GeneralNames([
286 x509.DirectoryName(x509.Name([
287 x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
288 x509.NameAttribute(x509.OID_COMMON_NAME, u"cryptography.io"),
289 ]))
290 ])
291
292 rev = crl.revoked_certificates[1]
293 issuer = rev.extensions.get_extension_for_oid(
294 x509.OID_CERTIFICATE_ISSUER).value
295 assert issuer == exp_issuer
296
297 # Test convenience function.
298 assert rev.get_certificate_issuer() == exp_issuer
299
300
Paul Kehrer016e08a2014-11-26 09:41:18 -1000301@pytest.mark.requires_backend_interface(interface=RSABackend)
302@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -0600303class TestRSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000304 def test_load_pem_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000305 cert = _load_cert(
306 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000307 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000308 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000309 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600310 assert isinstance(cert, x509.Certificate)
311 assert cert.serial == 11559813051657483483
312 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
313 assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8"
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600314 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000315
316 def test_load_der_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000317 cert = _load_cert(
318 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000319 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000320 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000321 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600322 assert isinstance(cert, x509.Certificate)
323 assert cert.serial == 2
324 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
325 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600326 assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000327
Paul Kehrer719d5362015-01-01 20:03:52 -0600328 def test_issuer(self, backend):
329 cert = _load_cert(
330 os.path.join(
331 "x509", "PKITS_data", "certs",
332 "Validpre2000UTCnotBeforeDateTest3EE.crt"
333 ),
334 x509.load_der_x509_certificate,
335 backend
336 )
337 issuer = cert.issuer
338 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600339 assert list(issuer) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500340 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600341 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500342 NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -0600343 ),
Paul Kehrereba19e62015-08-10 18:44:24 -0500344 x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -0600345 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500346 assert issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
347 x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -0600348 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600349
350 def test_all_issuer_name_types(self, backend):
351 cert = _load_cert(
352 os.path.join(
353 "x509", "custom",
354 "all_supported_names.pem"
355 ),
356 x509.load_pem_x509_certificate,
357 backend
358 )
359 issuer = cert.issuer
360
361 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600362 assert list(issuer) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500363 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
364 x509.NameAttribute(NameOID.COUNTRY_NAME, u'CA'),
365 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
366 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Illinois'),
367 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Chicago'),
368 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
369 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Zero, LLC'),
370 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'One, LLC'),
371 x509.NameAttribute(NameOID.COMMON_NAME, u'common name 0'),
372 x509.NameAttribute(NameOID.COMMON_NAME, u'common name 1'),
373 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 0'),
374 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 1'),
375 x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier0'),
376 x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier1'),
377 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'123'),
378 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'456'),
379 x509.NameAttribute(NameOID.TITLE, u'Title 0'),
380 x509.NameAttribute(NameOID.TITLE, u'Title 1'),
381 x509.NameAttribute(NameOID.SURNAME, u'Surname 0'),
382 x509.NameAttribute(NameOID.SURNAME, u'Surname 1'),
383 x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 0'),
384 x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 1'),
385 x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 0'),
386 x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 1'),
387 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Last Gen'),
388 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Next Gen'),
389 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc0'),
390 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc1'),
391 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test0@test.local'),
392 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test1@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600393 ]
394
Paul Kehrer719d5362015-01-01 20:03:52 -0600395 def test_subject(self, backend):
396 cert = _load_cert(
397 os.path.join(
398 "x509", "PKITS_data", "certs",
399 "Validpre2000UTCnotBeforeDateTest3EE.crt"
400 ),
401 x509.load_der_x509_certificate,
402 backend
403 )
404 subject = cert.subject
405 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600406 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500407 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600408 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500409 NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -0600410 ),
411 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500412 NameOID.COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500413 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600414 )
415 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500416 assert subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600417 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 Kehrer719d5362015-01-01 20:03:52 -0600422
423 def test_unicode_name(self, backend):
424 cert = _load_cert(
425 os.path.join(
426 "x509", "custom",
427 "utf8_common_name.pem"
428 ),
429 x509.load_pem_x509_certificate,
430 backend
431 )
Paul Kehrereba19e62015-08-10 18:44:24 -0500432 assert cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600433 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500434 NameOID.COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530435 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600436 )
437 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500438 assert cert.issuer.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 ]
444
445 def test_all_subject_name_types(self, backend):
446 cert = _load_cert(
447 os.path.join(
448 "x509", "custom",
449 "all_supported_names.pem"
450 ),
451 x509.load_pem_x509_certificate,
452 backend
453 )
454 subject = cert.subject
455 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600456 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500457 x509.NameAttribute(NameOID.COUNTRY_NAME, u'AU'),
458 x509.NameAttribute(NameOID.COUNTRY_NAME, u'DE'),
459 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'California'),
460 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'New York'),
461 x509.NameAttribute(NameOID.LOCALITY_NAME, u'San Francisco'),
462 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Ithaca'),
463 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org Zero, LLC'),
464 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org One, LLC'),
465 x509.NameAttribute(NameOID.COMMON_NAME, u'CN 0'),
466 x509.NameAttribute(NameOID.COMMON_NAME, u'CN 1'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600467 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500468 NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 0'
Paul Kehrer719d5362015-01-01 20:03:52 -0600469 ),
470 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500471 NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 1'
Paul Kehrer719d5362015-01-01 20:03:52 -0600472 ),
Paul Kehrereba19e62015-08-10 18:44:24 -0500473 x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified0'),
474 x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified1'),
475 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'789'),
476 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'012'),
477 x509.NameAttribute(NameOID.TITLE, u'Title IX'),
478 x509.NameAttribute(NameOID.TITLE, u'Title X'),
479 x509.NameAttribute(NameOID.SURNAME, u'Last 0'),
480 x509.NameAttribute(NameOID.SURNAME, u'Last 1'),
481 x509.NameAttribute(NameOID.GIVEN_NAME, u'First 0'),
482 x509.NameAttribute(NameOID.GIVEN_NAME, u'First 1'),
483 x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 0'),
484 x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 1'),
485 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'32X'),
486 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Dreamcast'),
487 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc2'),
488 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc3'),
489 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test2@test.local'),
490 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test3@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600491 ]
492
Paul Kehrer016e08a2014-11-26 09:41:18 -1000493 def test_load_good_ca_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000494 cert = _load_cert(
495 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000496 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000497 backend
498 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000499
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600500 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
501 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrer016e08a2014-11-26 09:41:18 -1000502 assert cert.serial == 2
503 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -0800504 assert isinstance(public_key, rsa.RSAPublicKey)
Paul Kehrere76cd272014-12-14 19:00:51 -0600505 assert cert.version is x509.Version.v3
Paul Kehrer0307c372014-11-27 09:49:31 -1000506 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
Paul Kehrer4e1db792014-11-27 10:50:55 -1000507 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer016e08a2014-11-26 09:41:18 -1000508
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000509 def test_utc_pre_2000_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000510 cert = _load_cert(
511 os.path.join(
512 "x509", "PKITS_data", "certs",
513 "Validpre2000UTCnotBeforeDateTest3EE.crt"
514 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000515 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000516 backend
517 )
518
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600519 assert cert.not_valid_before == datetime.datetime(1950, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000520
521 def test_pre_2000_utc_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000522 cert = _load_cert(
523 os.path.join(
524 "x509", "PKITS_data", "certs",
525 "Invalidpre2000UTCEEnotAfterDateTest7EE.crt"
526 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000527 x509.load_der_x509_certificate,
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000528 backend
529 )
530
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600531 assert cert.not_valid_after == datetime.datetime(1999, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000532
533 def test_post_2000_utc_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000534 cert = _load_cert(
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000535 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000536 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000537 backend
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000538 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600539 assert cert.not_valid_before == datetime.datetime(
540 2014, 11, 26, 21, 41, 20
541 )
542 assert cert.not_valid_after == datetime.datetime(
543 2014, 12, 26, 21, 41, 20
544 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000545
546 def test_generalized_time_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000547 cert = _load_cert(
548 os.path.join(
549 "x509", "PKITS_data", "certs",
550 "ValidGeneralizedTimenotBeforeDateTest4EE.crt"
551 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000552 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000553 backend
554 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600555 assert cert.not_valid_before == datetime.datetime(2002, 1, 1, 12, 1)
556 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrere76cd272014-12-14 19:00:51 -0600557 assert cert.version is x509.Version.v3
Paul Kehrer016e08a2014-11-26 09:41:18 -1000558
559 def test_generalized_time_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000560 cert = _load_cert(
561 os.path.join(
562 "x509", "PKITS_data", "certs",
563 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
564 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000565 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000566 backend
567 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600568 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
569 assert cert.not_valid_after == datetime.datetime(2050, 1, 1, 12, 1)
Paul Kehrere76cd272014-12-14 19:00:51 -0600570 assert cert.version is x509.Version.v3
Paul Kehrera9d78c12014-11-26 10:59:03 -1000571
572 def test_invalid_version_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000573 cert = _load_cert(
Paul Kehrera9d78c12014-11-26 10:59:03 -1000574 os.path.join("x509", "custom", "invalid_version.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000575 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000576 backend
Paul Kehrera9d78c12014-11-26 10:59:03 -1000577 )
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600578 with pytest.raises(x509.InvalidVersion) as exc:
Paul Kehrera9d78c12014-11-26 10:59:03 -1000579 cert.version
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000580
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600581 assert exc.value.parsed_version == 7
582
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -0500583 def test_eq(self, backend):
584 cert = _load_cert(
585 os.path.join("x509", "custom", "post2000utctime.pem"),
586 x509.load_pem_x509_certificate,
587 backend
588 )
589 cert2 = _load_cert(
590 os.path.join("x509", "custom", "post2000utctime.pem"),
591 x509.load_pem_x509_certificate,
592 backend
593 )
594 assert cert == cert2
595
596 def test_ne(self, backend):
597 cert = _load_cert(
598 os.path.join("x509", "custom", "post2000utctime.pem"),
599 x509.load_pem_x509_certificate,
600 backend
601 )
602 cert2 = _load_cert(
603 os.path.join(
604 "x509", "PKITS_data", "certs",
605 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
606 ),
607 x509.load_der_x509_certificate,
608 backend
609 )
610 assert cert != cert2
611 assert cert != object()
612
Alex Gaynor969f3a52015-07-06 18:52:41 -0400613 def test_hash(self, backend):
614 cert1 = _load_cert(
615 os.path.join("x509", "custom", "post2000utctime.pem"),
616 x509.load_pem_x509_certificate,
617 backend
618 )
619 cert2 = _load_cert(
620 os.path.join("x509", "custom", "post2000utctime.pem"),
621 x509.load_pem_x509_certificate,
622 backend
623 )
624 cert3 = _load_cert(
625 os.path.join(
626 "x509", "PKITS_data", "certs",
627 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
628 ),
629 x509.load_der_x509_certificate,
630 backend
631 )
632
633 assert hash(cert1) == hash(cert2)
634 assert hash(cert1) != hash(cert3)
635
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000636 def test_version_1_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000637 cert = _load_cert(
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000638 os.path.join("x509", "v1_cert.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000639 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000640 backend
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000641 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600642 assert cert.version is x509.Version.v1
Paul Kehrer7638c312014-11-26 11:13:31 -1000643
644 def test_invalid_pem(self, backend):
645 with pytest.raises(ValueError):
646 x509.load_pem_x509_certificate(b"notacert", backend)
647
648 def test_invalid_der(self, backend):
649 with pytest.raises(ValueError):
650 x509.load_der_x509_certificate(b"notacert", backend)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000651
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600652 def test_unsupported_signature_hash_algorithm_cert(self, backend):
653 cert = _load_cert(
654 os.path.join("x509", "verisign_md2_root.pem"),
655 x509.load_pem_x509_certificate,
656 backend
657 )
658 with pytest.raises(UnsupportedAlgorithm):
659 cert.signature_hash_algorithm
660
Andre Carona8aded62015-05-19 20:11:57 -0400661 def test_public_bytes_pem(self, backend):
662 # Load an existing certificate.
663 cert = _load_cert(
664 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
665 x509.load_der_x509_certificate,
666 backend
667 )
668
669 # Encode it to PEM and load it back.
670 cert = x509.load_pem_x509_certificate(cert.public_bytes(
671 encoding=serialization.Encoding.PEM,
672 ), backend)
673
674 # We should recover what we had to start with.
675 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
676 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
677 assert cert.serial == 2
678 public_key = cert.public_key()
679 assert isinstance(public_key, rsa.RSAPublicKey)
680 assert cert.version is x509.Version.v3
681 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
682 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
683
684 def test_public_bytes_der(self, backend):
685 # Load an existing certificate.
686 cert = _load_cert(
687 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
688 x509.load_der_x509_certificate,
689 backend
690 )
691
692 # Encode it to DER and load it back.
693 cert = x509.load_der_x509_certificate(cert.public_bytes(
694 encoding=serialization.Encoding.DER,
695 ), backend)
696
697 # We should recover what we had to start with.
698 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
699 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
700 assert cert.serial == 2
701 public_key = cert.public_key()
702 assert isinstance(public_key, rsa.RSAPublicKey)
703 assert cert.version is x509.Version.v3
704 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
705 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
706
707 def test_public_bytes_invalid_encoding(self, backend):
708 cert = _load_cert(
709 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
710 x509.load_der_x509_certificate,
711 backend
712 )
713
714 with pytest.raises(TypeError):
715 cert.public_bytes('NotAnEncoding')
716
717 @pytest.mark.parametrize(
718 ("cert_path", "loader_func", "encoding"),
719 [
720 (
721 os.path.join("x509", "v1_cert.pem"),
722 x509.load_pem_x509_certificate,
723 serialization.Encoding.PEM,
724 ),
725 (
726 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
727 x509.load_der_x509_certificate,
728 serialization.Encoding.DER,
729 ),
730 ]
731 )
732 def test_public_bytes_match(self, cert_path, loader_func, encoding,
733 backend):
734 cert_bytes = load_vectors_from_file(
735 cert_path, lambda pemfile: pemfile.read(), mode="rb"
736 )
737 cert = loader_func(cert_bytes, backend)
738 serialized = cert.public_bytes(encoding)
739 assert serialized == cert_bytes
740
Major Haydenf315af22015-06-17 14:02:26 -0500741 def test_certificate_repr(self, backend):
742 cert = _load_cert(
743 os.path.join(
744 "x509", "cryptography.io.pem"
745 ),
746 x509.load_pem_x509_certificate,
747 backend
748 )
749 if six.PY3:
750 assert repr(cert) == (
751 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
752 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value='GT487"
753 "42965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11, "
754 "name=organizationalUnitName)>, value='See www.rapidssl.com/re"
755 "sources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier(oi"
756 "d=2.5.4.11, name=organizationalUnitName)>, value='Domain Cont"
757 "rol Validated - RapidSSL(R)')>, <NameAttribute(oid=<ObjectIde"
758 "ntifier(oid=2.5.4.3, name=commonName)>, value='www.cryptograp"
759 "hy.io')>])>, ...)>"
760 )
761 else:
762 assert repr(cert) == (
763 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
764 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value=u'GT48"
765 "742965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11,"
766 " name=organizationalUnitName)>, value=u'See www.rapidssl.com/"
767 "resources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier("
768 "oid=2.5.4.11, name=organizationalUnitName)>, value=u'Domain C"
769 "ontrol Validated - RapidSSL(R)')>, <NameAttribute(oid=<Object"
770 "Identifier(oid=2.5.4.3, name=commonName)>, value=u'www.crypto"
771 "graphy.io')>])>, ...)>"
772 )
773
Andre Carona8aded62015-05-19 20:11:57 -0400774
775@pytest.mark.requires_backend_interface(interface=RSABackend)
776@pytest.mark.requires_backend_interface(interface=X509Backend)
777class TestRSACertificateRequest(object):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500778 @pytest.mark.parametrize(
779 ("path", "loader_func"),
780 [
781 [
782 os.path.join("x509", "requests", "rsa_sha1.pem"),
783 x509.load_pem_x509_csr
784 ],
785 [
786 os.path.join("x509", "requests", "rsa_sha1.der"),
787 x509.load_der_x509_csr
788 ],
789 ]
790 )
791 def test_load_rsa_certificate_request(self, path, loader_func, backend):
792 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600793 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
794 public_key = request.public_key()
795 assert isinstance(public_key, rsa.RSAPublicKey)
796 subject = request.subject
797 assert isinstance(subject, x509.Name)
798 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500799 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
800 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
801 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
802 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
803 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600804 ]
Andre Caron6e721a92015-05-17 15:08:48 -0400805 extensions = request.extensions
806 assert isinstance(extensions, x509.Extensions)
807 assert list(extensions) == []
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600808
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500809 @pytest.mark.parametrize(
810 "loader_func",
811 [x509.load_pem_x509_csr, x509.load_der_x509_csr]
812 )
813 def test_invalid_certificate_request(self, loader_func, backend):
Paul Kehrerb759e292015-03-17 07:34:41 -0500814 with pytest.raises(ValueError):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500815 loader_func(b"notacsr", backend)
Paul Kehrerb759e292015-03-17 07:34:41 -0500816
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600817 def test_unsupported_signature_hash_algorithm_request(self, backend):
818 request = _load_cert(
819 os.path.join("x509", "requests", "rsa_md4.pem"),
Paul Kehrer31e39882015-03-11 11:37:04 -0500820 x509.load_pem_x509_csr,
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600821 backend
822 )
823 with pytest.raises(UnsupportedAlgorithm):
824 request.signature_hash_algorithm
825
Andre Caron6e721a92015-05-17 15:08:48 -0400826 def test_duplicate_extension(self, backend):
827 request = _load_cert(
828 os.path.join(
829 "x509", "requests", "two_basic_constraints.pem"
830 ),
831 x509.load_pem_x509_csr,
832 backend
833 )
834 with pytest.raises(x509.DuplicateExtension) as exc:
835 request.extensions
836
Paul Kehrerd44e4132015-08-10 19:13:13 -0500837 assert exc.value.oid == ExtensionOID.BASIC_CONSTRAINTS
Andre Caron6e721a92015-05-17 15:08:48 -0400838
839 def test_unsupported_critical_extension(self, backend):
840 request = _load_cert(
841 os.path.join(
842 "x509", "requests", "unsupported_extension_critical.pem"
843 ),
844 x509.load_pem_x509_csr,
845 backend
846 )
847 with pytest.raises(x509.UnsupportedExtension) as exc:
848 request.extensions
849
850 assert exc.value.oid == x509.ObjectIdentifier('1.2.3.4')
851
852 def test_unsupported_extension(self, backend):
853 request = _load_cert(
854 os.path.join(
855 "x509", "requests", "unsupported_extension.pem"
856 ),
857 x509.load_pem_x509_csr,
858 backend
859 )
860 extensions = request.extensions
861 assert len(extensions) == 0
862
863 def test_request_basic_constraints(self, backend):
864 request = _load_cert(
865 os.path.join(
866 "x509", "requests", "basic_constraints.pem"
867 ),
868 x509.load_pem_x509_csr,
869 backend
870 )
871 extensions = request.extensions
872 assert isinstance(extensions, x509.Extensions)
873 assert list(extensions) == [
874 x509.Extension(
Paul Kehrerd44e4132015-08-10 19:13:13 -0500875 ExtensionOID.BASIC_CONSTRAINTS,
Andre Caron6e721a92015-05-17 15:08:48 -0400876 True,
Ian Cordasco0112b022015-06-16 17:51:18 -0500877 x509.BasicConstraints(ca=True, path_length=1),
Andre Caron6e721a92015-05-17 15:08:48 -0400878 ),
879 ]
880
Alex Gaynor37b82df2015-07-03 10:26:37 -0400881 def test_subject_alt_name(self, backend):
882 request = _load_cert(
883 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
884 x509.load_pem_x509_csr,
885 backend,
886 )
887 ext = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -0500888 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynor37b82df2015-07-03 10:26:37 -0400889 )
890 assert list(ext.value) == [
891 x509.DNSName(u"cryptography.io"),
892 x509.DNSName(u"sub.cryptography.io"),
893 ]
894
Andre Caronf27e4f42015-05-18 17:54:59 -0400895 def test_public_bytes_pem(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400896 # Load an existing CSR.
897 request = _load_cert(
898 os.path.join("x509", "requests", "rsa_sha1.pem"),
899 x509.load_pem_x509_csr,
900 backend
901 )
902
903 # Encode it to PEM and load it back.
904 request = x509.load_pem_x509_csr(request.public_bytes(
905 encoding=serialization.Encoding.PEM,
906 ), backend)
907
908 # We should recover what we had to start with.
909 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
910 public_key = request.public_key()
911 assert isinstance(public_key, rsa.RSAPublicKey)
912 subject = request.subject
913 assert isinstance(subject, x509.Name)
914 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500915 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
916 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
917 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
918 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
919 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400920 ]
921
Andre Caronf27e4f42015-05-18 17:54:59 -0400922 def test_public_bytes_der(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400923 # Load an existing CSR.
924 request = _load_cert(
925 os.path.join("x509", "requests", "rsa_sha1.pem"),
926 x509.load_pem_x509_csr,
927 backend
928 )
929
930 # Encode it to DER and load it back.
931 request = x509.load_der_x509_csr(request.public_bytes(
932 encoding=serialization.Encoding.DER,
933 ), backend)
934
935 # We should recover what we had to start with.
936 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
937 public_key = request.public_key()
938 assert isinstance(public_key, rsa.RSAPublicKey)
939 subject = request.subject
940 assert isinstance(subject, x509.Name)
941 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500942 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
943 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
944 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
945 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
946 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400947 ]
948
Andre Caronf27e4f42015-05-18 17:54:59 -0400949 def test_public_bytes_invalid_encoding(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400950 request = _load_cert(
951 os.path.join("x509", "requests", "rsa_sha1.pem"),
952 x509.load_pem_x509_csr,
953 backend
954 )
955
956 with pytest.raises(TypeError):
957 request.public_bytes('NotAnEncoding')
958
Andre Caronacb18972015-05-18 21:04:15 -0400959 @pytest.mark.parametrize(
960 ("request_path", "loader_func", "encoding"),
961 [
962 (
963 os.path.join("x509", "requests", "rsa_sha1.pem"),
964 x509.load_pem_x509_csr,
965 serialization.Encoding.PEM,
966 ),
967 (
968 os.path.join("x509", "requests", "rsa_sha1.der"),
969 x509.load_der_x509_csr,
970 serialization.Encoding.DER,
971 ),
972 ]
973 )
974 def test_public_bytes_match(self, request_path, loader_func, encoding,
975 backend):
976 request_bytes = load_vectors_from_file(
977 request_path, lambda pemfile: pemfile.read(), mode="rb"
978 )
979 request = loader_func(request_bytes, backend)
980 serialized = request.public_bytes(encoding)
981 assert serialized == request_bytes
982
Alex Gaynor70c8f8b2015-07-06 21:02:54 -0400983 def test_eq(self, backend):
984 request1 = _load_cert(
985 os.path.join("x509", "requests", "rsa_sha1.pem"),
986 x509.load_pem_x509_csr,
987 backend
988 )
989 request2 = _load_cert(
990 os.path.join("x509", "requests", "rsa_sha1.pem"),
991 x509.load_pem_x509_csr,
992 backend
993 )
994
995 assert request1 == request2
996
997 def test_ne(self, backend):
998 request1 = _load_cert(
999 os.path.join("x509", "requests", "rsa_sha1.pem"),
1000 x509.load_pem_x509_csr,
1001 backend
1002 )
1003 request2 = _load_cert(
Alex Gaynoreb2df542015-07-06 21:50:15 -04001004 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001005 x509.load_pem_x509_csr,
1006 backend
1007 )
1008
1009 assert request1 != request2
1010 assert request1 != object()
1011
Alex Gaynor978137d2015-07-08 20:59:16 -04001012 def test_hash(self, backend):
1013 request1 = _load_cert(
1014 os.path.join("x509", "requests", "rsa_sha1.pem"),
1015 x509.load_pem_x509_csr,
1016 backend
1017 )
1018 request2 = _load_cert(
1019 os.path.join("x509", "requests", "rsa_sha1.pem"),
1020 x509.load_pem_x509_csr,
1021 backend
1022 )
1023 request3 = _load_cert(
1024 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
1025 x509.load_pem_x509_csr,
1026 backend
1027 )
1028
1029 assert hash(request1) == hash(request2)
1030 assert hash(request1) != hash(request3)
1031
Andre Caron9bbfcea2015-05-18 20:55:29 -04001032 def test_build_cert(self, backend):
Ian Cordascoe4e52a42015-07-19 10:15:37 -05001033 issuer_private_key = RSA_KEY_2048.private_key(backend)
1034 subject_private_key = RSA_KEY_2048.private_key(backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001035
Andre Caron9bbfcea2015-05-18 20:55:29 -04001036 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1037 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
Ian Cordascob3ed4842015-07-01 22:46:03 -05001038
Ian Cordasco893246f2015-07-24 14:52:18 -05001039 builder = x509.CertificateBuilder().serial_number(
Ian Cordascob3ed4842015-07-01 22:46:03 -05001040 777
1041 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001042 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1043 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1044 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1045 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1046 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -05001047 ])).subject_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 ])).public_key(
1054 subject_private_key.public_key()
1055 ).add_extension(
Ian Cordasco8887a572015-07-19 10:26:59 -05001056 x509.BasicConstraints(ca=False, path_length=None), True,
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001057 ).add_extension(
1058 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1059 critical=False,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001060 ).not_valid_before(
1061 not_valid_before
1062 ).not_valid_after(
1063 not_valid_after
1064 )
1065
Paul Kehrer9add80e2015-08-03 17:53:14 +01001066 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001067
1068 assert cert.version is x509.Version.v3
1069 assert cert.not_valid_before == not_valid_before
1070 assert cert.not_valid_after == not_valid_after
1071 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001072 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron9bbfcea2015-05-18 20:55:29 -04001073 )
1074 assert basic_constraints.value.ca is False
1075 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001076 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001077 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001078 )
1079 assert list(subject_alternative_name.value) == [
1080 x509.DNSName(u"cryptography.io"),
1081 ]
Andre Caron9bbfcea2015-05-18 20:55:29 -04001082
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001083
Ian Cordasco747a2172015-07-19 11:00:14 -05001084class TestCertificateBuilder(object):
Paul Kehrer25f19222015-08-04 23:05:09 +01001085 @pytest.mark.requires_backend_interface(interface=RSABackend)
1086 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrera03c3252015-08-09 10:59:29 -05001087 def test_checks_for_unsupported_extensions(self, backend):
1088 private_key = RSA_KEY_2048.private_key(backend)
1089 builder = x509.CertificateBuilder().subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001090 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera03c3252015-08-09 10:59:29 -05001091 ])).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001092 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera03c3252015-08-09 10:59:29 -05001093 ])).public_key(
1094 private_key.public_key()
1095 ).serial_number(
1096 777
1097 ).not_valid_before(
1098 datetime.datetime(1999, 1, 1)
1099 ).not_valid_after(
1100 datetime.datetime(2020, 1, 1)
1101 ).add_extension(
1102 DummyExtension(), False
1103 )
1104
1105 with pytest.raises(NotImplementedError):
1106 builder.sign(private_key, hashes.SHA1(), backend)
1107
1108 @pytest.mark.requires_backend_interface(interface=RSABackend)
1109 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer25f19222015-08-04 23:05:09 +01001110 def test_no_subject_name(self, backend):
1111 subject_private_key = RSA_KEY_2048.private_key(backend)
1112 builder = x509.CertificateBuilder().serial_number(
1113 777
1114 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001115 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001116 ])).public_key(
1117 subject_private_key.public_key()
1118 ).not_valid_before(
1119 datetime.datetime(2002, 1, 1, 12, 1)
1120 ).not_valid_after(
1121 datetime.datetime(2030, 12, 31, 8, 30)
1122 )
1123 with pytest.raises(ValueError):
1124 builder.sign(subject_private_key, hashes.SHA256(), backend)
1125
1126 @pytest.mark.requires_backend_interface(interface=RSABackend)
1127 @pytest.mark.requires_backend_interface(interface=X509Backend)
1128 def test_no_issuer_name(self, backend):
1129 subject_private_key = RSA_KEY_2048.private_key(backend)
1130 builder = x509.CertificateBuilder().serial_number(
1131 777
1132 ).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001133 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001134 ])).public_key(
1135 subject_private_key.public_key()
1136 ).not_valid_before(
1137 datetime.datetime(2002, 1, 1, 12, 1)
1138 ).not_valid_after(
1139 datetime.datetime(2030, 12, 31, 8, 30)
1140 )
1141 with pytest.raises(ValueError):
1142 builder.sign(subject_private_key, hashes.SHA256(), backend)
1143
1144 @pytest.mark.requires_backend_interface(interface=RSABackend)
1145 @pytest.mark.requires_backend_interface(interface=X509Backend)
1146 def test_no_public_key(self, backend):
1147 subject_private_key = RSA_KEY_2048.private_key(backend)
1148 builder = x509.CertificateBuilder().serial_number(
1149 777
1150 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001151 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001152 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001153 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001154 ])).not_valid_before(
1155 datetime.datetime(2002, 1, 1, 12, 1)
1156 ).not_valid_after(
1157 datetime.datetime(2030, 12, 31, 8, 30)
1158 )
1159 with pytest.raises(ValueError):
1160 builder.sign(subject_private_key, hashes.SHA256(), backend)
1161
1162 @pytest.mark.requires_backend_interface(interface=RSABackend)
1163 @pytest.mark.requires_backend_interface(interface=X509Backend)
1164 def test_no_not_valid_before(self, backend):
1165 subject_private_key = RSA_KEY_2048.private_key(backend)
1166 builder = x509.CertificateBuilder().serial_number(
1167 777
1168 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001169 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001170 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001171 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001172 ])).public_key(
1173 subject_private_key.public_key()
1174 ).not_valid_after(
1175 datetime.datetime(2030, 12, 31, 8, 30)
1176 )
1177 with pytest.raises(ValueError):
1178 builder.sign(subject_private_key, hashes.SHA256(), backend)
1179
1180 @pytest.mark.requires_backend_interface(interface=RSABackend)
1181 @pytest.mark.requires_backend_interface(interface=X509Backend)
1182 def test_no_not_valid_after(self, backend):
1183 subject_private_key = RSA_KEY_2048.private_key(backend)
1184 builder = x509.CertificateBuilder().serial_number(
1185 777
1186 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001187 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001188 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001189 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001190 ])).public_key(
1191 subject_private_key.public_key()
1192 ).not_valid_before(
1193 datetime.datetime(2002, 1, 1, 12, 1)
1194 )
1195 with pytest.raises(ValueError):
1196 builder.sign(subject_private_key, hashes.SHA256(), backend)
1197
1198 @pytest.mark.requires_backend_interface(interface=RSABackend)
1199 @pytest.mark.requires_backend_interface(interface=X509Backend)
1200 def test_no_serial_number(self, backend):
1201 subject_private_key = RSA_KEY_2048.private_key(backend)
1202 builder = x509.CertificateBuilder().issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001203 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001204 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001205 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001206 ])).public_key(
1207 subject_private_key.public_key()
1208 ).not_valid_before(
1209 datetime.datetime(2002, 1, 1, 12, 1)
1210 ).not_valid_after(
1211 datetime.datetime(2030, 12, 31, 8, 30)
1212 )
1213 with pytest.raises(ValueError):
1214 builder.sign(subject_private_key, hashes.SHA256(), backend)
1215
Ian Cordasco747a2172015-07-19 11:00:14 -05001216 def test_issuer_name_must_be_a_name_type(self):
1217 builder = x509.CertificateBuilder()
1218
1219 with pytest.raises(TypeError):
1220 builder.issuer_name("subject")
1221
1222 with pytest.raises(TypeError):
1223 builder.issuer_name(object)
1224
1225 def test_issuer_name_may_only_be_set_once(self):
1226 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001227 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -05001228 ])
1229 builder = x509.CertificateBuilder().issuer_name(name)
1230
1231 with pytest.raises(ValueError):
1232 builder.issuer_name(name)
1233
1234 def test_subject_name_must_be_a_name_type(self):
1235 builder = x509.CertificateBuilder()
1236
1237 with pytest.raises(TypeError):
1238 builder.subject_name("subject")
1239
1240 with pytest.raises(TypeError):
1241 builder.subject_name(object)
1242
1243 def test_subject_name_may_only_be_set_once(self):
1244 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001245 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -05001246 ])
1247 builder = x509.CertificateBuilder().subject_name(name)
1248
1249 with pytest.raises(ValueError):
1250 builder.subject_name(name)
1251
1252 @pytest.mark.requires_backend_interface(interface=RSABackend)
1253 @pytest.mark.requires_backend_interface(interface=X509Backend)
1254 def test_public_key_must_be_public_key(self, backend):
1255 private_key = RSA_KEY_2048.private_key(backend)
1256 builder = x509.CertificateBuilder()
1257
1258 with pytest.raises(TypeError):
1259 builder.public_key(private_key)
1260
1261 @pytest.mark.requires_backend_interface(interface=RSABackend)
1262 @pytest.mark.requires_backend_interface(interface=X509Backend)
1263 def test_public_key_may_only_be_set_once(self, backend):
1264 private_key = RSA_KEY_2048.private_key(backend)
1265 public_key = private_key.public_key()
1266 builder = x509.CertificateBuilder().public_key(public_key)
1267
1268 with pytest.raises(ValueError):
1269 builder.public_key(public_key)
1270
1271 def test_serial_number_must_be_an_integer_type(self):
1272 with pytest.raises(TypeError):
1273 x509.CertificateBuilder().serial_number(10.0)
1274
Ian Cordascob4a155d2015-08-01 23:07:19 -05001275 def test_serial_number_must_be_non_negative(self):
1276 with pytest.raises(ValueError):
1277 x509.CertificateBuilder().serial_number(-10)
1278
1279 def test_serial_number_must_be_less_than_160_bits_long(self):
1280 with pytest.raises(ValueError):
1281 # 2 raised to the 160th power is actually 161 bits
1282 x509.CertificateBuilder().serial_number(2 ** 160)
1283
Ian Cordasco747a2172015-07-19 11:00:14 -05001284 def test_serial_number_may_only_be_set_once(self):
1285 builder = x509.CertificateBuilder().serial_number(10)
1286
1287 with pytest.raises(ValueError):
1288 builder.serial_number(20)
1289
1290 def test_invalid_not_valid_after(self):
1291 with pytest.raises(TypeError):
1292 x509.CertificateBuilder().not_valid_after(104204304504)
1293
1294 with pytest.raises(TypeError):
1295 x509.CertificateBuilder().not_valid_after(datetime.time())
1296
Ian Cordascob4a155d2015-08-01 23:07:19 -05001297 with pytest.raises(ValueError):
1298 x509.CertificateBuilder().not_valid_after(
1299 datetime.datetime(1960, 8, 10)
1300 )
1301
Ian Cordasco747a2172015-07-19 11:00:14 -05001302 def test_not_valid_after_may_only_be_set_once(self):
1303 builder = x509.CertificateBuilder().not_valid_after(
1304 datetime.datetime.now()
1305 )
1306
1307 with pytest.raises(ValueError):
1308 builder.not_valid_after(
1309 datetime.datetime.now()
1310 )
1311
1312 def test_invalid_not_valid_before(self):
1313 with pytest.raises(TypeError):
1314 x509.CertificateBuilder().not_valid_before(104204304504)
1315
1316 with pytest.raises(TypeError):
1317 x509.CertificateBuilder().not_valid_before(datetime.time())
1318
Ian Cordascob4a155d2015-08-01 23:07:19 -05001319 with pytest.raises(ValueError):
1320 x509.CertificateBuilder().not_valid_before(
1321 datetime.datetime(1960, 8, 10)
1322 )
1323
Ian Cordasco747a2172015-07-19 11:00:14 -05001324 def test_not_valid_before_may_only_be_set_once(self):
1325 builder = x509.CertificateBuilder().not_valid_before(
1326 datetime.datetime.now()
1327 )
1328
1329 with pytest.raises(ValueError):
1330 builder.not_valid_before(
1331 datetime.datetime.now()
1332 )
1333
1334 def test_add_extension_checks_for_duplicates(self):
1335 builder = x509.CertificateBuilder().add_extension(
1336 x509.BasicConstraints(ca=False, path_length=None), True,
1337 )
1338
1339 with pytest.raises(ValueError):
1340 builder.add_extension(
1341 x509.BasicConstraints(ca=False, path_length=None), True,
1342 )
1343
Paul Kehrer08f950e2015-08-08 22:14:42 -05001344 def test_add_invalid_extension_type(self):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001345 builder = x509.CertificateBuilder()
1346
Paul Kehrer08f950e2015-08-08 22:14:42 -05001347 with pytest.raises(TypeError):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001348 builder.add_extension(object(), False)
1349
Ian Cordascob77c7162015-07-20 21:22:33 -05001350 @pytest.mark.requires_backend_interface(interface=RSABackend)
1351 @pytest.mark.requires_backend_interface(interface=X509Backend)
1352 def test_sign_with_unsupported_hash(self, backend):
1353 private_key = RSA_KEY_2048.private_key(backend)
1354 builder = x509.CertificateBuilder()
Paul Kehrer25f19222015-08-04 23:05:09 +01001355 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001356 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer25f19222015-08-04 23:05:09 +01001357 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001358 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer25f19222015-08-04 23:05:09 +01001359 ).serial_number(
1360 1
1361 ).public_key(
1362 private_key.public_key()
1363 ).not_valid_before(
1364 datetime.datetime(2002, 1, 1, 12, 1)
1365 ).not_valid_after(
1366 datetime.datetime(2032, 1, 1, 12, 1)
1367 )
Ian Cordascob77c7162015-07-20 21:22:33 -05001368
1369 with pytest.raises(TypeError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001370 builder.sign(private_key, object(), backend)
Ian Cordascob77c7162015-07-20 21:22:33 -05001371
Ian Cordasco56561b12015-07-24 16:38:50 -05001372 @pytest.mark.requires_backend_interface(interface=DSABackend)
1373 @pytest.mark.requires_backend_interface(interface=X509Backend)
1374 def test_sign_with_dsa_private_key_is_unsupported(self, backend):
1375 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1376 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1377
1378 private_key = DSA_KEY_2048.private_key(backend)
1379 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001380 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001381 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001382 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001383 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001384 ).serial_number(
1385 1
1386 ).public_key(
1387 private_key.public_key()
1388 ).not_valid_before(
1389 datetime.datetime(2002, 1, 1, 12, 1)
1390 ).not_valid_after(
1391 datetime.datetime(2032, 1, 1, 12, 1)
1392 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001393
1394 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001395 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001396
1397 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1398 @pytest.mark.requires_backend_interface(interface=X509Backend)
1399 def test_sign_with_ec_private_key_is_unsupported(self, backend):
1400 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1401 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1402
1403 _skip_curve_unsupported(backend, ec.SECP256R1())
1404 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1405 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001406 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001407 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001408 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001409 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001410 ).serial_number(
1411 1
1412 ).public_key(
1413 private_key.public_key()
1414 ).not_valid_before(
1415 datetime.datetime(2002, 1, 1, 12, 1)
1416 ).not_valid_after(
1417 datetime.datetime(2032, 1, 1, 12, 1)
1418 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001419
1420 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001421 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001422
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001423 @pytest.mark.parametrize(
1424 "cdp",
1425 [
1426 x509.CRLDistributionPoints([
1427 x509.DistributionPoint(
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001428 full_name=None,
1429 relative_name=x509.Name([
1430 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001431 NameOID.COMMON_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001432 u"indirect CRL for indirectCRL CA3"
1433 ),
1434 ]),
1435 reasons=None,
1436 crl_issuer=[x509.DirectoryName(
1437 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001438 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001439 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001440 NameOID.ORGANIZATION_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001441 u"Test Certificates 2011"
1442 ),
1443 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001444 NameOID.ORGANIZATIONAL_UNIT_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001445 u"indirectCRL CA3 cRLIssuer"
1446 ),
1447 ])
1448 )],
1449 )
1450 ]),
1451 x509.CRLDistributionPoints([
1452 x509.DistributionPoint(
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001453 full_name=[x509.DirectoryName(
1454 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001455 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001456 ])
1457 )],
1458 relative_name=None,
1459 reasons=None,
1460 crl_issuer=[x509.DirectoryName(
1461 x509.Name([
1462 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001463 NameOID.ORGANIZATION_NAME,
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001464 u"cryptography Testing"
1465 ),
1466 ])
1467 )],
1468 )
1469 ]),
1470 x509.CRLDistributionPoints([
1471 x509.DistributionPoint(
Paul Kehrerc6cf8f32015-08-08 09:47:44 -05001472 full_name=[
1473 x509.UniformResourceIdentifier(
1474 u"http://myhost.com/myca.crl"
1475 ),
1476 x509.UniformResourceIdentifier(
1477 u"http://backup.myhost.com/myca.crl"
1478 )
1479 ],
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001480 relative_name=None,
1481 reasons=frozenset([
1482 x509.ReasonFlags.key_compromise,
1483 x509.ReasonFlags.ca_compromise
1484 ]),
1485 crl_issuer=[x509.DirectoryName(
1486 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001487 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001488 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001489 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001490 ),
1491 ])
1492 )],
1493 )
1494 ]),
1495 x509.CRLDistributionPoints([
1496 x509.DistributionPoint(
1497 full_name=[x509.UniformResourceIdentifier(
1498 u"http://domain.com/some.crl"
1499 )],
1500 relative_name=None,
1501 reasons=frozenset([
1502 x509.ReasonFlags.key_compromise,
1503 x509.ReasonFlags.ca_compromise,
1504 x509.ReasonFlags.affiliation_changed,
1505 x509.ReasonFlags.superseded,
1506 x509.ReasonFlags.privilege_withdrawn,
1507 x509.ReasonFlags.cessation_of_operation,
1508 x509.ReasonFlags.aa_compromise,
1509 x509.ReasonFlags.certificate_hold,
1510 ]),
1511 crl_issuer=None
1512 )
1513 ]),
1514 x509.CRLDistributionPoints([
1515 x509.DistributionPoint(
1516 full_name=None,
1517 relative_name=None,
1518 reasons=None,
1519 crl_issuer=[x509.DirectoryName(
1520 x509.Name([
1521 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001522 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001523 ),
1524 ])
1525 )],
1526 )
1527 ]),
1528 x509.CRLDistributionPoints([
1529 x509.DistributionPoint(
1530 full_name=[x509.UniformResourceIdentifier(
1531 u"http://domain.com/some.crl"
1532 )],
1533 relative_name=None,
1534 reasons=frozenset([x509.ReasonFlags.aa_compromise]),
1535 crl_issuer=None
1536 )
1537 ])
1538 ]
1539 )
1540 @pytest.mark.requires_backend_interface(interface=RSABackend)
1541 @pytest.mark.requires_backend_interface(interface=X509Backend)
1542 def test_crl_distribution_points(self, backend, cdp):
1543 issuer_private_key = RSA_KEY_2048.private_key(backend)
1544 subject_private_key = RSA_KEY_2048.private_key(backend)
1545
1546 builder = x509.CertificateBuilder().serial_number(
1547 4444444
1548 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001549 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001550 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001551 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001552 ])).public_key(
1553 subject_private_key.public_key()
1554 ).add_extension(
1555 cdp,
1556 critical=False,
1557 ).not_valid_before(
1558 datetime.datetime(2002, 1, 1, 12, 1)
1559 ).not_valid_after(
1560 datetime.datetime(2030, 12, 31, 8, 30)
1561 )
1562
1563 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
1564
1565 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001566 ExtensionOID.CRL_DISTRIBUTION_POINTS
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001567 )
1568 assert ext.critical is False
1569 assert ext.value == cdp
1570
Ian Cordasco56561b12015-07-24 16:38:50 -05001571 @pytest.mark.requires_backend_interface(interface=DSABackend)
1572 @pytest.mark.requires_backend_interface(interface=X509Backend)
1573 def test_build_cert_with_dsa_private_key(self, backend):
1574 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1575 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1576
1577 issuer_private_key = DSA_KEY_2048.private_key(backend)
1578 subject_private_key = DSA_KEY_2048.private_key(backend)
1579
1580 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1581 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1582
1583 builder = x509.CertificateBuilder().serial_number(
1584 777
1585 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001586 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001587 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001588 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001589 ])).public_key(
1590 subject_private_key.public_key()
1591 ).add_extension(
1592 x509.BasicConstraints(ca=False, path_length=None), True,
1593 ).add_extension(
1594 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1595 critical=False,
1596 ).not_valid_before(
1597 not_valid_before
1598 ).not_valid_after(
1599 not_valid_after
1600 )
1601
Paul Kehrer9add80e2015-08-03 17:53:14 +01001602 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001603
1604 assert cert.version is x509.Version.v3
1605 assert cert.not_valid_before == not_valid_before
1606 assert cert.not_valid_after == not_valid_after
1607 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001608 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco56561b12015-07-24 16:38:50 -05001609 )
1610 assert basic_constraints.value.ca is False
1611 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001612 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001613 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001614 )
1615 assert list(subject_alternative_name.value) == [
1616 x509.DNSName(u"cryptography.io"),
1617 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001618
1619 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1620 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco85fc4d52015-08-01 20:29:31 -05001621 def test_build_cert_with_ec_private_key(self, backend):
Ian Cordasco56561b12015-07-24 16:38:50 -05001622 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1623 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1624
1625 _skip_curve_unsupported(backend, ec.SECP256R1())
1626 issuer_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1627 subject_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1628
1629 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1630 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1631
1632 builder = x509.CertificateBuilder().serial_number(
1633 777
1634 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001635 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001636 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001637 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001638 ])).public_key(
1639 subject_private_key.public_key()
1640 ).add_extension(
1641 x509.BasicConstraints(ca=False, path_length=None), True,
1642 ).add_extension(
1643 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1644 critical=False,
1645 ).not_valid_before(
1646 not_valid_before
1647 ).not_valid_after(
1648 not_valid_after
1649 )
1650
Paul Kehrer9add80e2015-08-03 17:53:14 +01001651 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001652
1653 assert cert.version is x509.Version.v3
1654 assert cert.not_valid_before == not_valid_before
1655 assert cert.not_valid_after == not_valid_after
1656 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001657 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco56561b12015-07-24 16:38:50 -05001658 )
1659 assert basic_constraints.value.ca is False
1660 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001661 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001662 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001663 )
1664 assert list(subject_alternative_name.value) == [
1665 x509.DNSName(u"cryptography.io"),
1666 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001667
Ian Cordasco8690eff2015-07-24 16:42:58 -05001668 @pytest.mark.requires_backend_interface(interface=RSABackend)
1669 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco19f5a492015-08-01 11:06:17 -05001670 def test_build_cert_with_rsa_key_too_small(self, backend):
Ian Cordasco8690eff2015-07-24 16:42:58 -05001671 issuer_private_key = RSA_KEY_512.private_key(backend)
1672 subject_private_key = RSA_KEY_512.private_key(backend)
1673
1674 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1675 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1676
1677 builder = x509.CertificateBuilder().serial_number(
1678 777
1679 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001680 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001681 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001682 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001683 ])).public_key(
1684 subject_private_key.public_key()
Ian Cordasco8690eff2015-07-24 16:42:58 -05001685 ).not_valid_before(
1686 not_valid_before
1687 ).not_valid_after(
1688 not_valid_after
1689 )
1690
Ian Cordasco19f5a492015-08-01 11:06:17 -05001691 with pytest.raises(ValueError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001692 builder.sign(issuer_private_key, hashes.SHA512(), backend)
Ian Cordasco8690eff2015-07-24 16:42:58 -05001693
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001694 @pytest.mark.requires_backend_interface(interface=RSABackend)
1695 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer69b64e42015-08-09 00:00:44 -05001696 def test_issuer_alt_name(self, backend):
1697 issuer_private_key = RSA_KEY_2048.private_key(backend)
1698 subject_private_key = RSA_KEY_2048.private_key(backend)
1699
1700 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1701 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1702
1703 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001704 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer69b64e42015-08-09 00:00:44 -05001705 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001706 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer69b64e42015-08-09 00:00:44 -05001707 ).not_valid_before(
1708 not_valid_before
1709 ).not_valid_after(
1710 not_valid_after
1711 ).public_key(
1712 subject_private_key.public_key()
1713 ).serial_number(
1714 123
1715 ).add_extension(
1716 x509.IssuerAlternativeName([
1717 x509.DNSName(u"myissuer"),
1718 x509.RFC822Name(u"email@domain.com"),
1719 ]), critical=False
1720 ).sign(issuer_private_key, hashes.SHA256(), backend)
1721
1722 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001723 ExtensionOID.ISSUER_ALTERNATIVE_NAME
Paul Kehrer69b64e42015-08-09 00:00:44 -05001724 )
1725 assert ext.critical is False
1726 assert ext.value == x509.IssuerAlternativeName([
1727 x509.DNSName(u"myissuer"),
1728 x509.RFC822Name(u"email@domain.com"),
1729 ])
1730
1731 @pytest.mark.requires_backend_interface(interface=RSABackend)
1732 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001733 def test_extended_key_usage(self, backend):
1734 issuer_private_key = RSA_KEY_2048.private_key(backend)
1735 subject_private_key = RSA_KEY_2048.private_key(backend)
1736
1737 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1738 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1739
1740 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001741 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001742 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001743 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001744 ).not_valid_before(
1745 not_valid_before
1746 ).not_valid_after(
1747 not_valid_after
1748 ).public_key(
1749 subject_private_key.public_key()
1750 ).serial_number(
1751 123
1752 ).add_extension(
1753 x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05001754 ExtendedKeyUsageOID.CLIENT_AUTH,
1755 ExtendedKeyUsageOID.SERVER_AUTH,
1756 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001757 ]), critical=False
1758 ).sign(issuer_private_key, hashes.SHA256(), backend)
1759
1760 eku = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001761 ExtensionOID.EXTENDED_KEY_USAGE
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001762 )
1763 assert eku.critical is False
1764 assert eku.value == x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05001765 ExtendedKeyUsageOID.CLIENT_AUTH,
1766 ExtendedKeyUsageOID.SERVER_AUTH,
1767 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001768 ])
1769
1770 @pytest.mark.requires_backend_interface(interface=RSABackend)
1771 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer683d4d82015-08-06 23:13:45 +01001772 def test_inhibit_any_policy(self, backend):
1773 issuer_private_key = RSA_KEY_2048.private_key(backend)
1774 subject_private_key = RSA_KEY_2048.private_key(backend)
1775
1776 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1777 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1778
1779 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001780 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer683d4d82015-08-06 23:13:45 +01001781 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001782 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer683d4d82015-08-06 23:13:45 +01001783 ).not_valid_before(
1784 not_valid_before
1785 ).not_valid_after(
1786 not_valid_after
1787 ).public_key(
1788 subject_private_key.public_key()
1789 ).serial_number(
1790 123
1791 ).add_extension(
1792 x509.InhibitAnyPolicy(3), critical=False
1793 ).sign(issuer_private_key, hashes.SHA256(), backend)
1794
1795 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001796 ExtensionOID.INHIBIT_ANY_POLICY
Paul Kehrer683d4d82015-08-06 23:13:45 +01001797 )
1798 assert ext.value == x509.InhibitAnyPolicy(3)
1799
1800 @pytest.mark.requires_backend_interface(interface=RSABackend)
1801 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001802 def test_key_usage(self, backend):
1803 issuer_private_key = RSA_KEY_2048.private_key(backend)
1804 subject_private_key = RSA_KEY_2048.private_key(backend)
1805
1806 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1807 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1808
1809 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001810 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001811 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001812 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001813 ).not_valid_before(
1814 not_valid_before
1815 ).not_valid_after(
1816 not_valid_after
1817 ).public_key(
1818 subject_private_key.public_key()
1819 ).serial_number(
1820 123
1821 ).add_extension(
1822 x509.KeyUsage(
1823 digital_signature=True,
1824 content_commitment=True,
1825 key_encipherment=False,
1826 data_encipherment=False,
1827 key_agreement=False,
1828 key_cert_sign=True,
1829 crl_sign=False,
1830 encipher_only=False,
1831 decipher_only=False
1832 ),
1833 critical=False
1834 ).sign(issuer_private_key, hashes.SHA256(), backend)
1835
Paul Kehrerd44e4132015-08-10 19:13:13 -05001836 ext = cert.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001837 assert ext.critical is False
1838 assert ext.value == x509.KeyUsage(
1839 digital_signature=True,
1840 content_commitment=True,
1841 key_encipherment=False,
1842 data_encipherment=False,
1843 key_agreement=False,
1844 key_cert_sign=True,
1845 crl_sign=False,
1846 encipher_only=False,
1847 decipher_only=False
1848 )
1849
Ian Cordasco747a2172015-07-19 11:00:14 -05001850
Andre Caron0ef595f2015-05-18 13:53:43 -04001851@pytest.mark.requires_backend_interface(interface=X509Backend)
1852class TestCertificateSigningRequestBuilder(object):
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001853 @pytest.mark.requires_backend_interface(interface=RSABackend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001854 def test_sign_invalid_hash_algorithm(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001855 private_key = RSA_KEY_2048.private_key(backend)
1856
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001857 builder = x509.CertificateSigningRequestBuilder().subject_name(
1858 x509.Name([])
1859 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001860 with pytest.raises(TypeError):
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001861 builder.sign(private_key, 'NotAHash', backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001862
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001863 @pytest.mark.requires_backend_interface(interface=RSABackend)
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001864 def test_no_subject_name(self, backend):
1865 private_key = RSA_KEY_2048.private_key(backend)
1866
1867 builder = x509.CertificateSigningRequestBuilder()
1868 with pytest.raises(ValueError):
1869 builder.sign(private_key, hashes.SHA256(), backend)
1870
1871 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001872 def test_build_ca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001873 private_key = RSA_KEY_2048.private_key(backend)
1874
Andre Carona9a51172015-06-06 20:18:44 -04001875 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04001876 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001877 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Andre Caron99d0f902015-06-01 08:36:59 -04001878 ])
Andre Caron472fd692015-06-06 20:04:44 -04001879 ).add_extension(
Ian Cordasco41f51ce2015-06-17 11:49:11 -05001880 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001881 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001882
1883 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1884 public_key = request.public_key()
1885 assert isinstance(public_key, rsa.RSAPublicKey)
1886 subject = request.subject
1887 assert isinstance(subject, x509.Name)
1888 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001889 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Andre Caron0ef595f2015-05-18 13:53:43 -04001890 ]
1891 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001892 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron0ef595f2015-05-18 13:53:43 -04001893 )
1894 assert basic_constraints.value.ca is True
1895 assert basic_constraints.value.path_length == 2
1896
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001897 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001898 def test_build_ca_request_with_unicode(self, backend):
1899 private_key = RSA_KEY_2048.private_key(backend)
1900
1901 request = x509.CertificateSigningRequestBuilder().subject_name(
1902 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001903 x509.NameAttribute(NameOID.ORGANIZATION_NAME,
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001904 u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001905 ])
1906 ).add_extension(
1907 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001908 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001909
1910 loaded_request = x509.load_pem_x509_csr(
1911 request.public_bytes(encoding=serialization.Encoding.PEM), backend
1912 )
1913 subject = loaded_request.subject
1914 assert isinstance(subject, x509.Name)
1915 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001916 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001917 ]
1918
1919 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001920 def test_build_nonca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001921 private_key = RSA_KEY_2048.private_key(backend)
1922
Andre Carona9a51172015-06-06 20:18:44 -04001923 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04001924 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001925 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Andre Caron99d0f902015-06-01 08:36:59 -04001926 ])
Andre Caron472fd692015-06-06 20:04:44 -04001927 ).add_extension(
Ian Cordasco0112b022015-06-16 17:51:18 -05001928 x509.BasicConstraints(ca=False, path_length=None), critical=True,
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001929 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001930
1931 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1932 public_key = request.public_key()
1933 assert isinstance(public_key, rsa.RSAPublicKey)
1934 subject = request.subject
1935 assert isinstance(subject, x509.Name)
1936 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001937 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Andre Caron0ef595f2015-05-18 13:53:43 -04001938 ]
1939 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001940 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron0ef595f2015-05-18 13:53:43 -04001941 )
1942 assert basic_constraints.value.ca is False
1943 assert basic_constraints.value.path_length is None
1944
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001945 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1946 def test_build_ca_request_with_ec(self, backend):
1947 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1948 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1949
Ian Cordasco8cdcdfc2015-06-24 22:00:26 -05001950 _skip_curve_unsupported(backend, ec.SECP256R1())
1951 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001952
1953 request = x509.CertificateSigningRequestBuilder().subject_name(
1954 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001955 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001956 ])
1957 ).add_extension(
1958 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001959 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001960
1961 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1962 public_key = request.public_key()
1963 assert isinstance(public_key, ec.EllipticCurvePublicKey)
1964 subject = request.subject
1965 assert isinstance(subject, x509.Name)
1966 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001967 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001968 ]
1969 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001970 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001971 )
1972 assert basic_constraints.value.ca is True
1973 assert basic_constraints.value.path_length == 2
1974
1975 @pytest.mark.requires_backend_interface(interface=DSABackend)
1976 def test_build_ca_request_with_dsa(self, backend):
1977 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1978 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1979
1980 private_key = DSA_KEY_2048.private_key(backend)
1981
1982 request = x509.CertificateSigningRequestBuilder().subject_name(
1983 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001984 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001985 ])
1986 ).add_extension(
1987 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001988 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001989
1990 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1991 public_key = request.public_key()
1992 assert isinstance(public_key, dsa.DSAPublicKey)
1993 subject = request.subject
1994 assert isinstance(subject, x509.Name)
1995 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001996 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001997 ]
1998 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001999 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002000 )
2001 assert basic_constraints.value.ca is True
2002 assert basic_constraints.value.path_length == 2
2003
Paul Kehrerff917802015-06-26 17:29:04 -05002004 def test_add_duplicate_extension(self):
Andre Caronfc164c52015-05-31 17:36:18 -04002005 builder = x509.CertificateSigningRequestBuilder().add_extension(
Andre Caron472fd692015-06-06 20:04:44 -04002006 x509.BasicConstraints(True, 2), critical=True,
Andre Caronfc164c52015-05-31 17:36:18 -04002007 )
Andre Caron0ef595f2015-05-18 13:53:43 -04002008 with pytest.raises(ValueError):
Andre Caron472fd692015-06-06 20:04:44 -04002009 builder.add_extension(
2010 x509.BasicConstraints(True, 2), critical=True,
2011 )
Andre Caron0ef595f2015-05-18 13:53:43 -04002012
Paul Kehrerff917802015-06-26 17:29:04 -05002013 def test_set_invalid_subject(self):
Andre Caron0ef595f2015-05-18 13:53:43 -04002014 builder = x509.CertificateSigningRequestBuilder()
2015 with pytest.raises(TypeError):
Andre Carona9a51172015-06-06 20:18:44 -04002016 builder.subject_name('NotAName')
Andre Caron0ef595f2015-05-18 13:53:43 -04002017
Paul Kehrere59fd222015-08-08 22:50:19 -05002018 def test_add_invalid_extension_type(self):
Ian Cordasco34853f32015-06-21 10:50:53 -05002019 builder = x509.CertificateSigningRequestBuilder()
Andre Caron0ef595f2015-05-18 13:53:43 -04002020
Paul Kehrere59fd222015-08-08 22:50:19 -05002021 with pytest.raises(TypeError):
2022 builder.add_extension(object(), False)
2023
2024 def test_add_unsupported_extension(self, backend):
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002025 private_key = RSA_KEY_2048.private_key(backend)
2026 builder = x509.CertificateSigningRequestBuilder()
2027 builder = builder.subject_name(
2028 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002029 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002030 ])
2031 ).add_extension(
Alex Gaynor7583f7f2015-07-03 10:56:49 -04002032 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
2033 critical=False,
2034 ).add_extension(
Paul Kehrer69b64e42015-08-09 00:00:44 -05002035 DummyExtension(), False
Paul Kehrerdce91f02015-07-23 20:31:12 +01002036 )
2037 with pytest.raises(NotImplementedError):
2038 builder.sign(private_key, hashes.SHA256(), backend)
2039
2040 def test_key_usage(self, backend):
2041 private_key = RSA_KEY_2048.private_key(backend)
2042 builder = x509.CertificateSigningRequestBuilder()
2043 request = builder.subject_name(
2044 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002045 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerdce91f02015-07-23 20:31:12 +01002046 ])
2047 ).add_extension(
Alex Gaynorac7f70a2015-06-28 11:07:52 -04002048 x509.KeyUsage(
2049 digital_signature=True,
2050 content_commitment=True,
2051 key_encipherment=False,
2052 data_encipherment=False,
2053 key_agreement=False,
2054 key_cert_sign=True,
2055 crl_sign=False,
2056 encipher_only=False,
2057 decipher_only=False
2058 ),
Alex Gaynor887a4082015-07-03 04:29:03 -04002059 critical=False
Paul Kehrerdce91f02015-07-23 20:31:12 +01002060 ).sign(private_key, hashes.SHA256(), backend)
2061 assert len(request.extensions) == 1
Paul Kehrerd44e4132015-08-10 19:13:13 -05002062 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrerdce91f02015-07-23 20:31:12 +01002063 assert ext.critical is False
2064 assert ext.value == x509.KeyUsage(
2065 digital_signature=True,
2066 content_commitment=True,
2067 key_encipherment=False,
2068 data_encipherment=False,
2069 key_agreement=False,
2070 key_cert_sign=True,
2071 crl_sign=False,
2072 encipher_only=False,
2073 decipher_only=False
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002074 )
Paul Kehrerdce91f02015-07-23 20:31:12 +01002075
2076 def test_key_usage_key_agreement_bit(self, backend):
2077 private_key = RSA_KEY_2048.private_key(backend)
2078 builder = x509.CertificateSigningRequestBuilder()
2079 request = builder.subject_name(
2080 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002081 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerdce91f02015-07-23 20:31:12 +01002082 ])
2083 ).add_extension(
2084 x509.KeyUsage(
2085 digital_signature=False,
2086 content_commitment=False,
2087 key_encipherment=False,
2088 data_encipherment=False,
2089 key_agreement=True,
2090 key_cert_sign=True,
2091 crl_sign=False,
2092 encipher_only=False,
2093 decipher_only=True
2094 ),
2095 critical=False
2096 ).sign(private_key, hashes.SHA256(), backend)
2097 assert len(request.extensions) == 1
Paul Kehrerd44e4132015-08-10 19:13:13 -05002098 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrerdce91f02015-07-23 20:31:12 +01002099 assert ext.critical is False
2100 assert ext.value == x509.KeyUsage(
2101 digital_signature=False,
2102 content_commitment=False,
2103 key_encipherment=False,
2104 data_encipherment=False,
2105 key_agreement=True,
2106 key_cert_sign=True,
2107 crl_sign=False,
2108 encipher_only=False,
2109 decipher_only=True
2110 )
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002111
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002112 def test_add_two_extensions(self, backend):
2113 private_key = RSA_KEY_2048.private_key(backend)
2114 builder = x509.CertificateSigningRequestBuilder()
2115 request = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002116 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002117 ).add_extension(
2118 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
2119 critical=False,
2120 ).add_extension(
2121 x509.BasicConstraints(ca=True, path_length=2), critical=True
2122 ).sign(private_key, hashes.SHA1(), backend)
2123
2124 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2125 public_key = request.public_key()
2126 assert isinstance(public_key, rsa.RSAPublicKey)
2127 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002128 ExtensionOID.BASIC_CONSTRAINTS
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002129 )
2130 assert basic_constraints.value.ca is True
2131 assert basic_constraints.value.path_length == 2
2132 ext = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002133 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002134 )
2135 assert list(ext.value) == [x509.DNSName(u"cryptography.io")]
Paul Kehrerff917802015-06-26 17:29:04 -05002136
Andre Caron0ef595f2015-05-18 13:53:43 -04002137 def test_set_subject_twice(self):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002138 builder = x509.CertificateSigningRequestBuilder()
2139 builder = builder.subject_name(
Paul Kehrere76cd272014-12-14 19:00:51 -06002140 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002141 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera693cfd2014-11-27 07:47:58 -10002142 ])
Paul Kehrer4903adc2014-12-13 16:57:50 -06002143 )
Paul Kehrer41120322014-12-02 18:31:14 -10002144 with pytest.raises(ValueError):
Paul Kehrera693cfd2014-11-27 07:47:58 -10002145 builder.subject_name(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002146 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002147 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002148 ])
Alex Gaynor32c57df2015-02-23 21:51:27 -08002149 )
Alex Gaynorfcadda62015-03-10 10:01:18 -04002150
Alex Gaynord3e84162015-06-28 10:14:55 -04002151 def test_subject_alt_names(self, backend):
2152 private_key = RSA_KEY_2048.private_key(backend)
2153
2154 csr = x509.CertificateSigningRequestBuilder().subject_name(
2155 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002156 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Alex Gaynord3e84162015-06-28 10:14:55 -04002157 ])
2158 ).add_extension(
2159 x509.SubjectAlternativeName([
Alex Gaynor6431d502015-07-05 12:28:46 -04002160 x509.DNSName(u"example.com"),
2161 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05002162 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002163 x509.DirectoryName(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002164 x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002165 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002166 NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002167 )
2168 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05002169 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
2170 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05002171 x509.OtherName(
2172 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2173 value=b"0\x03\x02\x01\x05"
2174 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05002175 x509.RFC822Name(u"test@example.com"),
2176 x509.RFC822Name(u"email"),
2177 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05002178 x509.UniformResourceIdentifier(
2179 u"https://\u043f\u044b\u043a\u0430.cryptography"
2180 ),
2181 x509.UniformResourceIdentifier(
2182 u"gopher://cryptography:70/some/path"
2183 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04002184 ]),
2185 critical=False,
2186 ).sign(private_key, hashes.SHA256(), backend)
2187
2188 assert len(csr.extensions) == 1
2189 ext = csr.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002190 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynord3e84162015-06-28 10:14:55 -04002191 )
2192 assert not ext.critical
Paul Kehrerd44e4132015-08-10 19:13:13 -05002193 assert ext.oid == ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynord3e84162015-06-28 10:14:55 -04002194 assert list(ext.value) == [
Alex Gaynor6431d502015-07-05 12:28:46 -04002195 x509.DNSName(u"example.com"),
2196 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05002197 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002198 x509.DirectoryName(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002199 x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002200 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002201 NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002202 ),
2203 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05002204 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
2205 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05002206 x509.OtherName(
2207 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2208 value=b"0\x03\x02\x01\x05"
2209 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05002210 x509.RFC822Name(u"test@example.com"),
2211 x509.RFC822Name(u"email"),
2212 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05002213 x509.UniformResourceIdentifier(
2214 u"https://\u043f\u044b\u043a\u0430.cryptography"
2215 ),
2216 x509.UniformResourceIdentifier(
2217 u"gopher://cryptography:70/some/path"
2218 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04002219 ]
2220
Paul Kehrer500ed9d2015-07-10 20:51:36 -05002221 def test_invalid_asn1_othername(self, backend):
2222 private_key = RSA_KEY_2048.private_key(backend)
2223
2224 builder = x509.CertificateSigningRequestBuilder().subject_name(
2225 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002226 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Paul Kehrer500ed9d2015-07-10 20:51:36 -05002227 ])
2228 ).add_extension(
2229 x509.SubjectAlternativeName([
2230 x509.OtherName(
2231 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2232 value=b"\x01\x02\x01\x05"
2233 ),
2234 ]),
2235 critical=False,
2236 )
2237 with pytest.raises(ValueError):
2238 builder.sign(private_key, hashes.SHA256(), backend)
2239
Alex Gaynord5f718c2015-07-05 11:19:38 -04002240 def test_subject_alt_name_unsupported_general_name(self, backend):
2241 private_key = RSA_KEY_2048.private_key(backend)
2242
2243 builder = x509.CertificateSigningRequestBuilder().subject_name(
2244 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002245 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Alex Gaynord5f718c2015-07-05 11:19:38 -04002246 ])
2247 ).add_extension(
Paul Kehrer474a6472015-07-11 12:29:52 -05002248 x509.SubjectAlternativeName([FakeGeneralName("")]),
Alex Gaynord5f718c2015-07-05 11:19:38 -04002249 critical=False,
2250 )
2251
Paul Kehrer474a6472015-07-11 12:29:52 -05002252 with pytest.raises(ValueError):
Alex Gaynord5f718c2015-07-05 11:19:38 -04002253 builder.sign(private_key, hashes.SHA256(), backend)
2254
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002255 def test_extended_key_usage(self, backend):
2256 private_key = RSA_KEY_2048.private_key(backend)
2257 builder = x509.CertificateSigningRequestBuilder()
2258 request = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002259 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002260 ).add_extension(
2261 x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05002262 ExtendedKeyUsageOID.CLIENT_AUTH,
2263 ExtendedKeyUsageOID.SERVER_AUTH,
2264 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002265 ]), critical=False
2266 ).sign(private_key, hashes.SHA256(), backend)
2267
2268 eku = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002269 ExtensionOID.EXTENDED_KEY_USAGE
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002270 )
2271 assert eku.critical is False
2272 assert eku.value == x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05002273 ExtendedKeyUsageOID.CLIENT_AUTH,
2274 ExtendedKeyUsageOID.SERVER_AUTH,
2275 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002276 ])
2277
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002278 @pytest.mark.requires_backend_interface(interface=RSABackend)
2279 def test_rsa_key_too_small(self, backend):
2280 private_key = rsa.generate_private_key(65537, 512, backend)
2281 builder = x509.CertificateSigningRequestBuilder()
2282 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002283 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002284 )
2285
2286 with pytest.raises(ValueError) as exc:
2287 builder.sign(private_key, hashes.SHA512(), backend)
2288
Paul Kehrer6a71f8d2015-07-25 19:15:59 +01002289 assert str(exc.value) == "Digest too big for RSA key"
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002290
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002291 @pytest.mark.requires_backend_interface(interface=RSABackend)
2292 @pytest.mark.requires_backend_interface(interface=X509Backend)
2293 def test_build_cert_with_aia(self, backend):
2294 issuer_private_key = RSA_KEY_2048.private_key(backend)
2295 subject_private_key = RSA_KEY_2048.private_key(backend)
2296
2297 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2298 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2299
2300 aia = x509.AuthorityInformationAccess([
2301 x509.AccessDescription(
Paul Kehrer9e102db2015-08-10 21:53:09 -05002302 AuthorityInformationAccessOID.OCSP,
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002303 x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
2304 ),
2305 x509.AccessDescription(
Paul Kehrer9e102db2015-08-10 21:53:09 -05002306 AuthorityInformationAccessOID.CA_ISSUERS,
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002307 x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
2308 )
2309 ])
2310
2311 builder = x509.CertificateBuilder().serial_number(
2312 777
2313 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002314 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002315 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002316 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002317 ])).public_key(
2318 subject_private_key.public_key()
2319 ).add_extension(
2320 aia, critical=False
2321 ).not_valid_before(
2322 not_valid_before
2323 ).not_valid_after(
2324 not_valid_after
2325 )
2326
2327 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2328
2329 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002330 ExtensionOID.AUTHORITY_INFORMATION_ACCESS
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002331 )
2332 assert ext.value == aia
2333
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002334 @pytest.mark.requires_backend_interface(interface=RSABackend)
2335 @pytest.mark.requires_backend_interface(interface=X509Backend)
2336 def test_build_cert_with_ski(self, backend):
2337 issuer_private_key = RSA_KEY_2048.private_key(backend)
2338 subject_private_key = RSA_KEY_2048.private_key(backend)
2339
2340 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2341 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2342
2343 ski = x509.SubjectKeyIdentifier.from_public_key(
2344 subject_private_key.public_key()
2345 )
2346
2347 builder = x509.CertificateBuilder().serial_number(
2348 777
2349 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002350 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002351 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002352 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002353 ])).public_key(
2354 subject_private_key.public_key()
2355 ).add_extension(
2356 ski, critical=False
2357 ).not_valid_before(
2358 not_valid_before
2359 ).not_valid_after(
2360 not_valid_after
2361 )
2362
2363 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2364
2365 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002366 ExtensionOID.SUBJECT_KEY_IDENTIFIER
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002367 )
2368 assert ext.value == ski
2369
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002370 @pytest.mark.parametrize(
2371 "aki",
2372 [
2373 x509.AuthorityKeyIdentifier(
2374 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2375 b"\xcbY",
2376 None,
2377 None
2378 ),
2379 x509.AuthorityKeyIdentifier(
2380 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2381 b"\xcbY",
2382 [
2383 x509.DirectoryName(
2384 x509.Name([
2385 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002386 NameOID.ORGANIZATION_NAME, u"PyCA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002387 ),
2388 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002389 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002390 )
2391 ])
2392 )
2393 ],
2394 333
2395 ),
2396 x509.AuthorityKeyIdentifier(
2397 None,
2398 [
2399 x509.DirectoryName(
2400 x509.Name([
2401 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002402 NameOID.ORGANIZATION_NAME, u"PyCA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002403 ),
2404 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002405 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002406 )
2407 ])
2408 )
2409 ],
2410 333
2411 ),
2412 ]
2413 )
2414 @pytest.mark.requires_backend_interface(interface=RSABackend)
2415 @pytest.mark.requires_backend_interface(interface=X509Backend)
2416 def test_build_cert_with_aki(self, aki, backend):
2417 issuer_private_key = RSA_KEY_2048.private_key(backend)
2418 subject_private_key = RSA_KEY_2048.private_key(backend)
2419
2420 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2421 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2422
2423 builder = x509.CertificateBuilder().serial_number(
2424 777
2425 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002426 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002427 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002428 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002429 ])).public_key(
2430 subject_private_key.public_key()
2431 ).add_extension(
2432 aki, critical=False
2433 ).not_valid_before(
2434 not_valid_before
2435 ).not_valid_after(
2436 not_valid_after
2437 )
2438
2439 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2440
2441 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002442 ExtensionOID.AUTHORITY_KEY_IDENTIFIER
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002443 )
2444 assert ext.value == aki
2445
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002446 def test_ocsp_nocheck(self, backend):
2447 issuer_private_key = RSA_KEY_2048.private_key(backend)
2448 subject_private_key = RSA_KEY_2048.private_key(backend)
2449
2450 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2451 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2452
2453 builder = x509.CertificateBuilder().serial_number(
2454 777
2455 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002456 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002457 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002458 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002459 ])).public_key(
2460 subject_private_key.public_key()
2461 ).add_extension(
2462 x509.OCSPNoCheck(), critical=False
2463 ).not_valid_before(
2464 not_valid_before
2465 ).not_valid_after(
2466 not_valid_after
2467 )
2468
2469 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2470
2471 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002472 ExtensionOID.OCSP_NO_CHECK
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002473 )
2474 assert isinstance(ext.value, x509.OCSPNoCheck)
2475
Alex Gaynord5f718c2015-07-05 11:19:38 -04002476
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002477@pytest.mark.requires_backend_interface(interface=DSABackend)
2478@pytest.mark.requires_backend_interface(interface=X509Backend)
2479class TestDSACertificate(object):
2480 def test_load_dsa_cert(self, backend):
2481 cert = _load_cert(
2482 os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
2483 x509.load_pem_x509_certificate,
2484 backend
2485 )
2486 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
2487 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002488 assert isinstance(public_key, dsa.DSAPublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002489 num = public_key.public_numbers()
2490 assert num.y == int(
2491 "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94"
2492 "53b6656f13e543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2"
2493 "dea559f0b584c97a2b235b9b69b46bc6de1aed422a6f341832618bcaae2"
2494 "198aba388099dafb05ff0b5efecb3b0ae169a62e1c72022af50ae68af3b"
2495 "033c18e6eec1f7df4692c456ccafb79cc7e08da0a5786e9816ceda651d6"
2496 "1b4bb7b81c2783da97cea62df67af5e85991fdc13aff10fc60e06586386"
2497 "b96bb78d65750f542f86951e05a6d81baadbcd35a2e5cad4119923ae6a2"
2498 "002091a3d17017f93c52970113cdc119970b9074ca506eac91c3dd37632"
2499 "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c", 16
2500 )
2501 assert num.parameter_numbers.g == int(
2502 "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67"
2503 "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b"
2504 "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2"
2505 "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa"
2506 "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f"
2507 "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a"
2508 "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0"
2509 "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76"
2510 "fa6247676a6d3ac945844a083509c6a1b436baca", 16
2511 )
2512 assert num.parameter_numbers.p == int(
2513 "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3"
2514 "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330"
2515 "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e"
2516 "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a"
2517 "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4"
2518 "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2"
2519 "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93"
2520 "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d"
2521 "833e36468f3907cfca788a3cb790f0341c8a31bf", 16
2522 )
2523 assert num.parameter_numbers.q == int(
2524 "822ff5d234e073b901cf5941f58e1f538e71d40d", 16
2525 )
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002526
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002527 @pytest.mark.parametrize(
2528 ("path", "loader_func"),
2529 [
2530 [
2531 os.path.join("x509", "requests", "dsa_sha1.pem"),
2532 x509.load_pem_x509_csr
2533 ],
2534 [
2535 os.path.join("x509", "requests", "dsa_sha1.der"),
2536 x509.load_der_x509_csr
2537 ],
2538 ]
2539 )
2540 def test_load_dsa_request(self, path, loader_func, backend):
2541 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002542 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2543 public_key = request.public_key()
2544 assert isinstance(public_key, dsa.DSAPublicKey)
2545 subject = request.subject
2546 assert isinstance(subject, x509.Name)
2547 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002548 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2549 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2550 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2551 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2552 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002553 ]
2554
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002555
2556@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2557@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -06002558class TestECDSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002559 def test_load_ecdsa_cert(self, backend):
2560 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrera693cfd2014-11-27 07:47:58 -10002561 cert = _load_cert(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002562 os.path.join("x509", "ecdsa_root.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -10002563 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -10002564 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002565 )
Paul Kehrer8802a5b2015-02-13 12:06:57 -06002566 assert isinstance(cert.signature_hash_algorithm, hashes.SHA384)
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002567 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002568 assert isinstance(public_key, ec.EllipticCurvePublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002569 num = public_key.public_numbers()
2570 assert num.x == int(
2571 "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f"
2572 "6f0ccd00bba615b51467e9e2d9fee8e630c17", 16
2573 )
2574 assert num.y == int(
2575 "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7"
2576 "2deae88a7a16bb543ce67dc23ff031ca3e23e", 16
2577 )
2578 assert isinstance(num.curve, ec.SECP384R1)
Paul Kehrer6c660a82014-12-12 11:50:44 -06002579
2580 def test_load_ecdsa_no_named_curve(self, backend):
2581 _skip_curve_unsupported(backend, ec.SECP256R1())
2582 cert = _load_cert(
2583 os.path.join("x509", "custom", "ec_no_named_curve.pem"),
2584 x509.load_pem_x509_certificate,
2585 backend
2586 )
2587 with pytest.raises(NotImplementedError):
2588 cert.public_key()
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002589
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002590 @pytest.mark.parametrize(
2591 ("path", "loader_func"),
2592 [
2593 [
2594 os.path.join("x509", "requests", "ec_sha256.pem"),
2595 x509.load_pem_x509_csr
2596 ],
2597 [
2598 os.path.join("x509", "requests", "ec_sha256.der"),
2599 x509.load_der_x509_csr
2600 ],
2601 ]
2602 )
2603 def test_load_ecdsa_certificate_request(self, path, loader_func, backend):
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002604 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002605 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002606 assert isinstance(request.signature_hash_algorithm, hashes.SHA256)
2607 public_key = request.public_key()
2608 assert isinstance(public_key, ec.EllipticCurvePublicKey)
2609 subject = request.subject
2610 assert isinstance(subject, x509.Name)
2611 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002612 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2613 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2614 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2615 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2616 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002617 ]
2618
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002619
Paul Kehrer806bfb22015-02-02 17:05:24 -06002620class TestNameAttribute(object):
Alex Gaynora56ff412015-02-10 17:26:32 -05002621 def test_init_bad_oid(self):
2622 with pytest.raises(TypeError):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002623 x509.NameAttribute(None, u'value')
Alex Gaynora56ff412015-02-10 17:26:32 -05002624
Ian Cordasco7618fbe2015-06-16 19:12:17 -05002625 def test_init_bad_value(self):
2626 with pytest.raises(TypeError):
2627 x509.NameAttribute(
2628 x509.ObjectIdentifier('oid'),
2629 b'bytes'
2630 )
2631
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002632 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002633 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002634 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002635 ) == x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002636 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002637 )
2638
2639 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002640 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002641 x509.ObjectIdentifier('2.5.4.3'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002642 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002643 x509.ObjectIdentifier('2.5.4.5'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002644 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002645 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002646 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002647 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002648 x509.ObjectIdentifier('oid'), u'value2'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002649 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002650 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002651 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002652 ) != object()
2653
Paul Kehrera498be82015-02-12 15:00:56 -06002654 def test_repr(self):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002655 na = x509.NameAttribute(x509.ObjectIdentifier('2.5.4.3'), u'value')
Ian Cordascoa908d692015-06-16 21:35:24 -05002656 if six.PY3:
2657 assert repr(na) == (
2658 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2659 "nName)>, value='value')>"
2660 )
2661 else:
2662 assert repr(na) == (
2663 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2664 "nName)>, value=u'value')>"
2665 )
Paul Kehrera498be82015-02-12 15:00:56 -06002666
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002667
2668class TestObjectIdentifier(object):
2669 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002670 oid1 = x509.ObjectIdentifier('oid')
2671 oid2 = x509.ObjectIdentifier('oid')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002672 assert oid1 == oid2
2673
2674 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002675 oid1 = x509.ObjectIdentifier('oid')
2676 assert oid1 != x509.ObjectIdentifier('oid1')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002677 assert oid1 != object()
2678
2679 def test_repr(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002680 oid = x509.ObjectIdentifier("2.5.4.3")
2681 assert repr(oid) == "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>"
2682 oid = x509.ObjectIdentifier("oid1")
2683 assert repr(oid) == "<ObjectIdentifier(oid=oid1, name=Unknown OID)>"
Paul Kehrer719d5362015-01-01 20:03:52 -06002684
Brendan McCollam1b3b3ce2015-08-25 10:55:44 -05002685 def test_name_property(self):
2686 oid = x509.ObjectIdentifier("2.5.4.3")
2687 assert oid._name == 'commonName'
2688 oid = x509.ObjectIdentifier("oid1")
2689 assert oid._name == 'Unknown OID'
2690
Paul Kehrer719d5362015-01-01 20:03:52 -06002691
2692class TestName(object):
2693 def test_eq(self):
2694 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002695 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2696 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002697 ])
2698 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002699 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2700 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002701 ])
2702 assert name1 == name2
2703
2704 def test_ne(self):
2705 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002706 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2707 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002708 ])
2709 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002710 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
2711 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002712 ])
2713 assert name1 != name2
2714 assert name1 != object()
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002715
2716 def test_repr(self):
2717 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002718 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2719 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002720 ])
2721
Ian Cordascoa908d692015-06-16 21:35:24 -05002722 if six.PY3:
2723 assert repr(name) == (
2724 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2725 "=commonName)>, value='cryptography.io')>, <NameAttribute(oid="
2726 "<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, valu"
2727 "e='PyCA')>])>"
2728 )
2729 else:
2730 assert repr(name) == (
2731 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2732 "=commonName)>, value=u'cryptography.io')>, <NameAttribute(oid"
2733 "=<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, val"
2734 "ue=u'PyCA')>])>"
2735 )