blob: c380b86018c64ff3962005823498efc38be1ac79 [file] [log] [blame]
Paul Kehrer016e08a2014-11-26 09:41:18 -10001# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import absolute_import, division, print_function
6
Paul Kehrer0307c372014-11-27 09:49:31 -10007import binascii
Paul Kehrer016e08a2014-11-26 09:41:18 -10008import datetime
Paul Kehrer235e5a12015-07-10 19:45:47 -05009import ipaddress
Paul Kehrer016e08a2014-11-26 09:41:18 -100010import os
Paul Kehrer016e08a2014-11-26 09:41:18 -100011
12import pytest
13
Ian Cordascoa908d692015-06-16 21:35:24 -050014import six
15
Paul Kehrer474a6472015-07-11 12:29:52 -050016from cryptography import utils, x509
Paul Kehrer8802a5b2015-02-13 12:06:57 -060017from cryptography.exceptions import UnsupportedAlgorithm
Paul Kehrerf1ef3512014-11-26 17:36:05 -100018from cryptography.hazmat.backends.interfaces import (
19 DSABackend, EllipticCurveBackend, RSABackend, X509Backend
20)
Andre Caron476c5df2015-05-18 10:23:28 -040021from cryptography.hazmat.primitives import hashes, serialization
Alex Gaynor32c57df2015-02-23 21:51:27 -080022from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
Paul Kehrer9e102db2015-08-10 21:53:09 -050023from cryptography.x509.oid import (
24 AuthorityInformationAccessOID, ExtendedKeyUsageOID, ExtensionOID, NameOID
25)
Paul Kehrer016e08a2014-11-26 09:41:18 -100026
Ian Cordasco8ed8edc2015-06-22 20:11:17 -050027from .hazmat.primitives.fixtures_dsa import DSA_KEY_2048
Ian Cordasco85fc4d52015-08-01 20:29:31 -050028from .hazmat.primitives.fixtures_rsa import RSA_KEY_2048, RSA_KEY_512
Ian Cordasco4d46eb72015-06-17 12:08:27 -050029from .hazmat.primitives.test_ec import _skip_curve_unsupported
Paul Kehrera9d78c12014-11-26 10:59:03 -100030from .utils import load_vectors_from_file
Paul Kehrer016e08a2014-11-26 09:41:18 -100031
32
Paul Kehrer69b64e42015-08-09 00:00:44 -050033@utils.register_interface(x509.ExtensionType)
34class DummyExtension(object):
35 oid = x509.ObjectIdentifier("1.2.3.4")
36
37
Paul Kehrer474a6472015-07-11 12:29:52 -050038@utils.register_interface(x509.GeneralName)
39class FakeGeneralName(object):
40 def __init__(self, value):
41 self._value = value
42
43 value = utils.read_only_property("_value")
44
45
Paul Kehrer41120322014-12-02 18:31:14 -100046def _load_cert(filename, loader, backend):
Paul Kehrer016e08a2014-11-26 09:41:18 -100047 cert = load_vectors_from_file(
Paul Kehrera693cfd2014-11-27 07:47:58 -100048 filename=filename,
49 loader=lambda pemfile: loader(pemfile.read(), backend),
50 mode="rb"
Paul Kehrer016e08a2014-11-26 09:41:18 -100051 )
52 return cert
53
54
Erik Trauschkedc570402015-09-24 20:24:28 -070055@pytest.mark.requires_backend_interface(interface=X509Backend)
56class TestCertificateRevocationList(object):
57 def test_load_pem_crl(self, backend):
58 crl = _load_cert(
59 os.path.join("x509", "custom", "crl_all_reasons.pem"),
60 x509.load_pem_x509_crl,
61 backend
62 )
63
64 assert isinstance(crl, x509.CertificateRevocationList)
65 fingerprint = binascii.hexlify(crl.fingerprint(hashes.SHA1()))
66 assert fingerprint == b"3234b0cb4c0cedf6423724b736729dcfc9e441ef"
67 assert isinstance(crl.signature_hash_algorithm, hashes.SHA256)
68
69 def test_load_der_crl(self, backend):
70 crl = _load_cert(
71 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
72 x509.load_der_x509_crl,
73 backend
74 )
75
76 assert isinstance(crl, x509.CertificateRevocationList)
77 fingerprint = binascii.hexlify(crl.fingerprint(hashes.SHA1()))
78 assert fingerprint == b"dd3db63c50f4c4a13e090f14053227cb1011a5ad"
79 assert isinstance(crl.signature_hash_algorithm, hashes.SHA256)
80
81 def test_invalid_pem(self, backend):
82 with pytest.raises(ValueError):
83 x509.load_pem_x509_crl(b"notacrl", backend)
84
85 def test_invalid_der(self, backend):
86 with pytest.raises(ValueError):
87 x509.load_der_x509_crl(b"notacrl", backend)
88
89 def test_unknown_signature_algorithm(self, backend):
90 crl = _load_cert(
91 os.path.join(
92 "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
93 ),
94 x509.load_pem_x509_crl,
95 backend
96 )
97
98 with pytest.raises(UnsupportedAlgorithm):
99 crl.signature_hash_algorithm()
100
101 def test_issuer(self, backend):
102 crl = _load_cert(
103 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
104 x509.load_der_x509_crl,
105 backend
106 )
107
108 assert isinstance(crl.issuer, x509.Name)
109 assert list(crl.issuer) == [
110 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
111 x509.NameAttribute(
112 x509.OID_ORGANIZATION_NAME, u'Test Certificates 2011'
113 ),
114 x509.NameAttribute(x509.OID_COMMON_NAME, u'Good CA')
115 ]
116 assert crl.issuer.get_attributes_for_oid(x509.OID_COMMON_NAME) == [
117 x509.NameAttribute(x509.OID_COMMON_NAME, u'Good CA')
118 ]
119
120 def test_equality(self, backend):
121 crl1 = _load_cert(
122 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
123 x509.load_der_x509_crl,
124 backend
125 )
126
127 crl2 = _load_cert(
128 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
129 x509.load_der_x509_crl,
130 backend
131 )
132
133 crl3 = _load_cert(
134 os.path.join("x509", "custom", "crl_all_reasons.pem"),
135 x509.load_pem_x509_crl,
136 backend
137 )
138
139 assert crl1 == crl2
140 assert crl1 != crl3
141 assert crl1 != object()
142
143 def test_update_dates(self, backend):
144 crl = _load_cert(
145 os.path.join("x509", "custom", "crl_all_reasons.pem"),
146 x509.load_pem_x509_crl,
147 backend
148 )
149
150 assert isinstance(crl.next_update, datetime.datetime)
151 assert isinstance(crl.last_update, datetime.datetime)
152
153 assert crl.next_update.isoformat() == "2016-01-01T00:00:00"
154 assert crl.last_update.isoformat() == "2015-01-01T00:00:00"
155
156 def test_revoked_certs(self, backend):
157 crl = _load_cert(
158 os.path.join("x509", "custom", "crl_all_reasons.pem"),
159 x509.load_pem_x509_crl,
160 backend
161 )
162
163 assert isinstance(crl.revoked_certificates, list)
164 for r in crl.revoked_certificates:
165 assert isinstance(r, x509.RevokedCertificate)
166
167 def test_extensions(self, backend):
168 crl = _load_cert(
169 os.path.join("x509", "custom", "crl_all_reasons.pem"),
170 x509.load_pem_x509_crl,
171 backend
172 )
173
174 # CRL extensions are currently not supported in the OpenSSL backend.
175 with pytest.raises(NotImplementedError):
176 crl.extensions
177
178
179@pytest.mark.requires_backend_interface(interface=X509Backend)
180class TestRevokedCertificate(object):
181
182 def test_revoked_basics(self, backend):
183 crl = _load_cert(
184 os.path.join("x509", "custom", "crl_all_reasons.pem"),
185 x509.load_pem_x509_crl,
186 backend
187 )
188
189 for i, rev in enumerate(crl.revoked_certificates):
190 assert isinstance(rev, x509.RevokedCertificate)
191 assert isinstance(rev.serial_number, int)
192 assert isinstance(rev.revocation_date, datetime.datetime)
193 assert isinstance(rev.extensions, x509.Extensions)
194
195 assert rev.serial_number == i
196 assert rev.revocation_date.isoformat() == "2015-01-01T00:00:00"
197
198 def test_revoked_extensions(self, backend):
199 crl = _load_cert(
200 os.path.join("x509", "custom", "crl_all_reasons.pem"),
201 x509.load_pem_x509_crl,
202 backend
203 )
204
205 # First revoked cert doesn't have extensions, test if it is handled
206 # correctly.
207 rev0 = crl.revoked_certificates[0]
208 # It should return an empty Extensions object.
209 assert isinstance(rev0.extensions, x509.Extensions)
210 assert len(rev0.extensions) == 0
211 with pytest.raises(x509.ExtensionNotFound):
212 rev0.extensions.get_extension_for_oid(x509.OID_CRL_REASON)
213
214 assert rev0.get_invalidity_date() is None
215 assert rev0.get_certificate_issuer() is None
216 assert rev0.get_reason() is None
217
218 # Test manual retrieval of extension values.
219 rev1 = crl.revoked_certificates[1]
220 assert isinstance(rev1.extensions, x509.Extensions)
221
222 reason = rev1.extensions.get_extension_for_oid(
223 x509.OID_CRL_REASON).value
224 assert reason == x509.ReasonFlags.unspecified
225
226 date = rev1.extensions.get_extension_for_oid(
227 x509.OID_INVALIDITY_DATE).value
228 assert isinstance(date, datetime.datetime)
229 assert date.isoformat() == "2015-01-01T00:00:00"
230
231 # Test convenience function.
232 assert rev1.get_invalidity_date().isoformat() == "2015-01-01T00:00:00"
233
234 # Check if all reason flags can be found in the CRL.
Erik Trauschke396a2822015-09-28 08:56:18 -0700235 # Also test if CRL as iterator works.
Erik Trauschkedc570402015-09-24 20:24:28 -0700236 flags = set(x509.ReasonFlags)
Erik Trauschke396a2822015-09-28 08:56:18 -0700237 for r in crl:
Erik Trauschkedc570402015-09-24 20:24:28 -0700238 flags.discard(r.get_reason())
239 assert len(flags) == 0
240
Erik Trauschke396a2822015-09-28 08:56:18 -0700241 # Check that len() works for CRLs.
242 assert len(crl) == 12
243
Erik Trauschkedc570402015-09-24 20:24:28 -0700244 def test_duplicate_entry_ext(self, backend):
245 crl = _load_cert(
246 os.path.join("x509", "custom", "crl_dup_entry_ext.pem"),
247 x509.load_pem_x509_crl,
248 backend
249 )
250
251 with pytest.raises(x509.DuplicateExtension):
252 crl.revoked_certificates[0].extensions
253
254 def test_unsupported_crit_entry_ext(self, backend):
255 crl = _load_cert(
256 os.path.join(
257 "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
258 ),
259 x509.load_pem_x509_crl,
260 backend
261 )
262
263 with pytest.raises(x509.UnsupportedExtension):
264 crl.revoked_certificates[0].extensions
265
266 def test_unsupported_reason(self, backend):
267 crl = _load_cert(
268 os.path.join(
269 "x509", "custom", "crl_unsupported_reason.pem"
270 ),
271 x509.load_pem_x509_crl,
272 backend
273 )
274
275 with pytest.raises(ValueError):
276 crl.revoked_certificates[0].extensions
277
278 def test_cert_issuer_ext(self, backend):
279 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10000000:
280 pytest.skip("Requires a newer OpenSSL. Must be at least 1.0.0")
281
282 crl = _load_cert(
283 os.path.join("x509", "custom", "crl_all_reasons.pem"),
284 x509.load_pem_x509_crl,
285 backend
286 )
287
288 exp_issuer = x509.GeneralNames([
289 x509.DirectoryName(x509.Name([
290 x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
291 x509.NameAttribute(x509.OID_COMMON_NAME, u"cryptography.io"),
292 ]))
293 ])
294
295 rev = crl.revoked_certificates[1]
296 issuer = rev.extensions.get_extension_for_oid(
297 x509.OID_CERTIFICATE_ISSUER).value
298 assert issuer == exp_issuer
299
300 # Test convenience function.
301 assert rev.get_certificate_issuer() == exp_issuer
302
303
Paul Kehrer016e08a2014-11-26 09:41:18 -1000304@pytest.mark.requires_backend_interface(interface=RSABackend)
305@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -0600306class TestRSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000307 def test_load_pem_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000308 cert = _load_cert(
309 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000310 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000311 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000312 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600313 assert isinstance(cert, x509.Certificate)
314 assert cert.serial == 11559813051657483483
315 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
316 assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8"
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600317 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000318
319 def test_load_der_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000320 cert = _load_cert(
321 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000322 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000323 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000324 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600325 assert isinstance(cert, x509.Certificate)
326 assert cert.serial == 2
327 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
328 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600329 assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000330
Paul Kehrer719d5362015-01-01 20:03:52 -0600331 def test_issuer(self, backend):
332 cert = _load_cert(
333 os.path.join(
334 "x509", "PKITS_data", "certs",
335 "Validpre2000UTCnotBeforeDateTest3EE.crt"
336 ),
337 x509.load_der_x509_certificate,
338 backend
339 )
340 issuer = cert.issuer
341 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600342 assert list(issuer) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500343 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600344 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500345 NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -0600346 ),
Paul Kehrereba19e62015-08-10 18:44:24 -0500347 x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -0600348 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500349 assert issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
350 x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -0600351 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600352
353 def test_all_issuer_name_types(self, backend):
354 cert = _load_cert(
355 os.path.join(
356 "x509", "custom",
357 "all_supported_names.pem"
358 ),
359 x509.load_pem_x509_certificate,
360 backend
361 )
362 issuer = cert.issuer
363
364 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600365 assert list(issuer) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500366 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
367 x509.NameAttribute(NameOID.COUNTRY_NAME, u'CA'),
368 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
369 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Illinois'),
370 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Chicago'),
371 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
372 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Zero, LLC'),
373 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'One, LLC'),
374 x509.NameAttribute(NameOID.COMMON_NAME, u'common name 0'),
375 x509.NameAttribute(NameOID.COMMON_NAME, u'common name 1'),
376 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 0'),
377 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 1'),
378 x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier0'),
379 x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier1'),
380 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'123'),
381 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'456'),
382 x509.NameAttribute(NameOID.TITLE, u'Title 0'),
383 x509.NameAttribute(NameOID.TITLE, u'Title 1'),
384 x509.NameAttribute(NameOID.SURNAME, u'Surname 0'),
385 x509.NameAttribute(NameOID.SURNAME, u'Surname 1'),
386 x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 0'),
387 x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 1'),
388 x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 0'),
389 x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 1'),
390 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Last Gen'),
391 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Next Gen'),
392 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc0'),
393 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc1'),
394 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test0@test.local'),
395 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test1@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600396 ]
397
Paul Kehrer719d5362015-01-01 20:03:52 -0600398 def test_subject(self, backend):
399 cert = _load_cert(
400 os.path.join(
401 "x509", "PKITS_data", "certs",
402 "Validpre2000UTCnotBeforeDateTest3EE.crt"
403 ),
404 x509.load_der_x509_certificate,
405 backend
406 )
407 subject = cert.subject
408 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600409 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500410 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600411 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500412 NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -0600413 ),
414 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500415 NameOID.COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500416 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600417 )
418 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500419 assert subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600420 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500421 NameOID.COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500422 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600423 )
424 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600425
426 def test_unicode_name(self, backend):
427 cert = _load_cert(
428 os.path.join(
429 "x509", "custom",
430 "utf8_common_name.pem"
431 ),
432 x509.load_pem_x509_certificate,
433 backend
434 )
Paul Kehrereba19e62015-08-10 18:44:24 -0500435 assert cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600436 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500437 NameOID.COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530438 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600439 )
440 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500441 assert cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600442 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500443 NameOID.COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530444 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600445 )
446 ]
447
448 def test_all_subject_name_types(self, backend):
449 cert = _load_cert(
450 os.path.join(
451 "x509", "custom",
452 "all_supported_names.pem"
453 ),
454 x509.load_pem_x509_certificate,
455 backend
456 )
457 subject = cert.subject
458 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600459 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500460 x509.NameAttribute(NameOID.COUNTRY_NAME, u'AU'),
461 x509.NameAttribute(NameOID.COUNTRY_NAME, u'DE'),
462 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'California'),
463 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'New York'),
464 x509.NameAttribute(NameOID.LOCALITY_NAME, u'San Francisco'),
465 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Ithaca'),
466 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org Zero, LLC'),
467 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org One, LLC'),
468 x509.NameAttribute(NameOID.COMMON_NAME, u'CN 0'),
469 x509.NameAttribute(NameOID.COMMON_NAME, u'CN 1'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600470 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500471 NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 0'
Paul Kehrer719d5362015-01-01 20:03:52 -0600472 ),
473 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500474 NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 1'
Paul Kehrer719d5362015-01-01 20:03:52 -0600475 ),
Paul Kehrereba19e62015-08-10 18:44:24 -0500476 x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified0'),
477 x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified1'),
478 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'789'),
479 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'012'),
480 x509.NameAttribute(NameOID.TITLE, u'Title IX'),
481 x509.NameAttribute(NameOID.TITLE, u'Title X'),
482 x509.NameAttribute(NameOID.SURNAME, u'Last 0'),
483 x509.NameAttribute(NameOID.SURNAME, u'Last 1'),
484 x509.NameAttribute(NameOID.GIVEN_NAME, u'First 0'),
485 x509.NameAttribute(NameOID.GIVEN_NAME, u'First 1'),
486 x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 0'),
487 x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 1'),
488 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'32X'),
489 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Dreamcast'),
490 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc2'),
491 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc3'),
492 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test2@test.local'),
493 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test3@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600494 ]
495
Paul Kehrer016e08a2014-11-26 09:41:18 -1000496 def test_load_good_ca_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000497 cert = _load_cert(
498 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000499 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000500 backend
501 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000502
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600503 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
504 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrer016e08a2014-11-26 09:41:18 -1000505 assert cert.serial == 2
506 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -0800507 assert isinstance(public_key, rsa.RSAPublicKey)
Paul Kehrere76cd272014-12-14 19:00:51 -0600508 assert cert.version is x509.Version.v3
Paul Kehrer0307c372014-11-27 09:49:31 -1000509 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
Paul Kehrer4e1db792014-11-27 10:50:55 -1000510 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer016e08a2014-11-26 09:41:18 -1000511
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000512 def test_utc_pre_2000_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000513 cert = _load_cert(
514 os.path.join(
515 "x509", "PKITS_data", "certs",
516 "Validpre2000UTCnotBeforeDateTest3EE.crt"
517 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000518 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000519 backend
520 )
521
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600522 assert cert.not_valid_before == datetime.datetime(1950, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000523
524 def test_pre_2000_utc_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000525 cert = _load_cert(
526 os.path.join(
527 "x509", "PKITS_data", "certs",
528 "Invalidpre2000UTCEEnotAfterDateTest7EE.crt"
529 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000530 x509.load_der_x509_certificate,
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000531 backend
532 )
533
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600534 assert cert.not_valid_after == datetime.datetime(1999, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000535
536 def test_post_2000_utc_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000537 cert = _load_cert(
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000538 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000539 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000540 backend
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000541 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600542 assert cert.not_valid_before == datetime.datetime(
543 2014, 11, 26, 21, 41, 20
544 )
545 assert cert.not_valid_after == datetime.datetime(
546 2014, 12, 26, 21, 41, 20
547 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000548
549 def test_generalized_time_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000550 cert = _load_cert(
551 os.path.join(
552 "x509", "PKITS_data", "certs",
553 "ValidGeneralizedTimenotBeforeDateTest4EE.crt"
554 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000555 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000556 backend
557 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600558 assert cert.not_valid_before == datetime.datetime(2002, 1, 1, 12, 1)
559 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrere76cd272014-12-14 19:00:51 -0600560 assert cert.version is x509.Version.v3
Paul Kehrer016e08a2014-11-26 09:41:18 -1000561
562 def test_generalized_time_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000563 cert = _load_cert(
564 os.path.join(
565 "x509", "PKITS_data", "certs",
566 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
567 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000568 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000569 backend
570 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600571 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
572 assert cert.not_valid_after == datetime.datetime(2050, 1, 1, 12, 1)
Paul Kehrere76cd272014-12-14 19:00:51 -0600573 assert cert.version is x509.Version.v3
Paul Kehrera9d78c12014-11-26 10:59:03 -1000574
575 def test_invalid_version_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000576 cert = _load_cert(
Paul Kehrera9d78c12014-11-26 10:59:03 -1000577 os.path.join("x509", "custom", "invalid_version.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000578 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000579 backend
Paul Kehrera9d78c12014-11-26 10:59:03 -1000580 )
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600581 with pytest.raises(x509.InvalidVersion) as exc:
Paul Kehrera9d78c12014-11-26 10:59:03 -1000582 cert.version
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000583
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600584 assert exc.value.parsed_version == 7
585
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -0500586 def test_eq(self, backend):
587 cert = _load_cert(
588 os.path.join("x509", "custom", "post2000utctime.pem"),
589 x509.load_pem_x509_certificate,
590 backend
591 )
592 cert2 = _load_cert(
593 os.path.join("x509", "custom", "post2000utctime.pem"),
594 x509.load_pem_x509_certificate,
595 backend
596 )
597 assert cert == cert2
598
599 def test_ne(self, backend):
600 cert = _load_cert(
601 os.path.join("x509", "custom", "post2000utctime.pem"),
602 x509.load_pem_x509_certificate,
603 backend
604 )
605 cert2 = _load_cert(
606 os.path.join(
607 "x509", "PKITS_data", "certs",
608 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
609 ),
610 x509.load_der_x509_certificate,
611 backend
612 )
613 assert cert != cert2
614 assert cert != object()
615
Alex Gaynor969f3a52015-07-06 18:52:41 -0400616 def test_hash(self, backend):
617 cert1 = _load_cert(
618 os.path.join("x509", "custom", "post2000utctime.pem"),
619 x509.load_pem_x509_certificate,
620 backend
621 )
622 cert2 = _load_cert(
623 os.path.join("x509", "custom", "post2000utctime.pem"),
624 x509.load_pem_x509_certificate,
625 backend
626 )
627 cert3 = _load_cert(
628 os.path.join(
629 "x509", "PKITS_data", "certs",
630 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
631 ),
632 x509.load_der_x509_certificate,
633 backend
634 )
635
636 assert hash(cert1) == hash(cert2)
637 assert hash(cert1) != hash(cert3)
638
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000639 def test_version_1_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000640 cert = _load_cert(
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000641 os.path.join("x509", "v1_cert.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000642 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000643 backend
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000644 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600645 assert cert.version is x509.Version.v1
Paul Kehrer7638c312014-11-26 11:13:31 -1000646
647 def test_invalid_pem(self, backend):
648 with pytest.raises(ValueError):
649 x509.load_pem_x509_certificate(b"notacert", backend)
650
651 def test_invalid_der(self, backend):
652 with pytest.raises(ValueError):
653 x509.load_der_x509_certificate(b"notacert", backend)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000654
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600655 def test_unsupported_signature_hash_algorithm_cert(self, backend):
656 cert = _load_cert(
657 os.path.join("x509", "verisign_md2_root.pem"),
658 x509.load_pem_x509_certificate,
659 backend
660 )
661 with pytest.raises(UnsupportedAlgorithm):
662 cert.signature_hash_algorithm
663
Andre Carona8aded62015-05-19 20:11:57 -0400664 def test_public_bytes_pem(self, backend):
665 # Load an existing certificate.
666 cert = _load_cert(
667 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
668 x509.load_der_x509_certificate,
669 backend
670 )
671
672 # Encode it to PEM and load it back.
673 cert = x509.load_pem_x509_certificate(cert.public_bytes(
674 encoding=serialization.Encoding.PEM,
675 ), backend)
676
677 # We should recover what we had to start with.
678 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
679 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
680 assert cert.serial == 2
681 public_key = cert.public_key()
682 assert isinstance(public_key, rsa.RSAPublicKey)
683 assert cert.version is x509.Version.v3
684 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
685 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
686
687 def test_public_bytes_der(self, backend):
688 # Load an existing certificate.
689 cert = _load_cert(
690 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
691 x509.load_der_x509_certificate,
692 backend
693 )
694
695 # Encode it to DER and load it back.
696 cert = x509.load_der_x509_certificate(cert.public_bytes(
697 encoding=serialization.Encoding.DER,
698 ), backend)
699
700 # We should recover what we had to start with.
701 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
702 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
703 assert cert.serial == 2
704 public_key = cert.public_key()
705 assert isinstance(public_key, rsa.RSAPublicKey)
706 assert cert.version is x509.Version.v3
707 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
708 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
709
710 def test_public_bytes_invalid_encoding(self, backend):
711 cert = _load_cert(
712 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
713 x509.load_der_x509_certificate,
714 backend
715 )
716
717 with pytest.raises(TypeError):
718 cert.public_bytes('NotAnEncoding')
719
720 @pytest.mark.parametrize(
721 ("cert_path", "loader_func", "encoding"),
722 [
723 (
724 os.path.join("x509", "v1_cert.pem"),
725 x509.load_pem_x509_certificate,
726 serialization.Encoding.PEM,
727 ),
728 (
729 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
730 x509.load_der_x509_certificate,
731 serialization.Encoding.DER,
732 ),
733 ]
734 )
735 def test_public_bytes_match(self, cert_path, loader_func, encoding,
736 backend):
737 cert_bytes = load_vectors_from_file(
738 cert_path, lambda pemfile: pemfile.read(), mode="rb"
739 )
740 cert = loader_func(cert_bytes, backend)
741 serialized = cert.public_bytes(encoding)
742 assert serialized == cert_bytes
743
Major Haydenf315af22015-06-17 14:02:26 -0500744 def test_certificate_repr(self, backend):
745 cert = _load_cert(
746 os.path.join(
747 "x509", "cryptography.io.pem"
748 ),
749 x509.load_pem_x509_certificate,
750 backend
751 )
752 if six.PY3:
753 assert repr(cert) == (
754 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
755 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value='GT487"
756 "42965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11, "
757 "name=organizationalUnitName)>, value='See www.rapidssl.com/re"
758 "sources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier(oi"
759 "d=2.5.4.11, name=organizationalUnitName)>, value='Domain Cont"
760 "rol Validated - RapidSSL(R)')>, <NameAttribute(oid=<ObjectIde"
761 "ntifier(oid=2.5.4.3, name=commonName)>, value='www.cryptograp"
762 "hy.io')>])>, ...)>"
763 )
764 else:
765 assert repr(cert) == (
766 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
767 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value=u'GT48"
768 "742965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11,"
769 " name=organizationalUnitName)>, value=u'See www.rapidssl.com/"
770 "resources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier("
771 "oid=2.5.4.11, name=organizationalUnitName)>, value=u'Domain C"
772 "ontrol Validated - RapidSSL(R)')>, <NameAttribute(oid=<Object"
773 "Identifier(oid=2.5.4.3, name=commonName)>, value=u'www.crypto"
774 "graphy.io')>])>, ...)>"
775 )
776
Andre Carona8aded62015-05-19 20:11:57 -0400777
778@pytest.mark.requires_backend_interface(interface=RSABackend)
779@pytest.mark.requires_backend_interface(interface=X509Backend)
780class TestRSACertificateRequest(object):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500781 @pytest.mark.parametrize(
782 ("path", "loader_func"),
783 [
784 [
785 os.path.join("x509", "requests", "rsa_sha1.pem"),
786 x509.load_pem_x509_csr
787 ],
788 [
789 os.path.join("x509", "requests", "rsa_sha1.der"),
790 x509.load_der_x509_csr
791 ],
792 ]
793 )
794 def test_load_rsa_certificate_request(self, path, loader_func, backend):
795 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600796 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
797 public_key = request.public_key()
798 assert isinstance(public_key, rsa.RSAPublicKey)
799 subject = request.subject
800 assert isinstance(subject, x509.Name)
801 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500802 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
803 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
804 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
805 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
806 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600807 ]
Andre Caron6e721a92015-05-17 15:08:48 -0400808 extensions = request.extensions
809 assert isinstance(extensions, x509.Extensions)
810 assert list(extensions) == []
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600811
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500812 @pytest.mark.parametrize(
813 "loader_func",
814 [x509.load_pem_x509_csr, x509.load_der_x509_csr]
815 )
816 def test_invalid_certificate_request(self, loader_func, backend):
Paul Kehrerb759e292015-03-17 07:34:41 -0500817 with pytest.raises(ValueError):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500818 loader_func(b"notacsr", backend)
Paul Kehrerb759e292015-03-17 07:34:41 -0500819
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600820 def test_unsupported_signature_hash_algorithm_request(self, backend):
821 request = _load_cert(
822 os.path.join("x509", "requests", "rsa_md4.pem"),
Paul Kehrer31e39882015-03-11 11:37:04 -0500823 x509.load_pem_x509_csr,
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600824 backend
825 )
826 with pytest.raises(UnsupportedAlgorithm):
827 request.signature_hash_algorithm
828
Andre Caron6e721a92015-05-17 15:08:48 -0400829 def test_duplicate_extension(self, backend):
830 request = _load_cert(
831 os.path.join(
832 "x509", "requests", "two_basic_constraints.pem"
833 ),
834 x509.load_pem_x509_csr,
835 backend
836 )
837 with pytest.raises(x509.DuplicateExtension) as exc:
838 request.extensions
839
Paul Kehrerd44e4132015-08-10 19:13:13 -0500840 assert exc.value.oid == ExtensionOID.BASIC_CONSTRAINTS
Andre Caron6e721a92015-05-17 15:08:48 -0400841
842 def test_unsupported_critical_extension(self, backend):
843 request = _load_cert(
844 os.path.join(
845 "x509", "requests", "unsupported_extension_critical.pem"
846 ),
847 x509.load_pem_x509_csr,
848 backend
849 )
850 with pytest.raises(x509.UnsupportedExtension) as exc:
851 request.extensions
852
853 assert exc.value.oid == x509.ObjectIdentifier('1.2.3.4')
854
855 def test_unsupported_extension(self, backend):
856 request = _load_cert(
857 os.path.join(
858 "x509", "requests", "unsupported_extension.pem"
859 ),
860 x509.load_pem_x509_csr,
861 backend
862 )
863 extensions = request.extensions
864 assert len(extensions) == 0
865
866 def test_request_basic_constraints(self, backend):
867 request = _load_cert(
868 os.path.join(
869 "x509", "requests", "basic_constraints.pem"
870 ),
871 x509.load_pem_x509_csr,
872 backend
873 )
874 extensions = request.extensions
875 assert isinstance(extensions, x509.Extensions)
876 assert list(extensions) == [
877 x509.Extension(
Paul Kehrerd44e4132015-08-10 19:13:13 -0500878 ExtensionOID.BASIC_CONSTRAINTS,
Andre Caron6e721a92015-05-17 15:08:48 -0400879 True,
Ian Cordasco0112b022015-06-16 17:51:18 -0500880 x509.BasicConstraints(ca=True, path_length=1),
Andre Caron6e721a92015-05-17 15:08:48 -0400881 ),
882 ]
883
Alex Gaynor37b82df2015-07-03 10:26:37 -0400884 def test_subject_alt_name(self, backend):
885 request = _load_cert(
886 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
887 x509.load_pem_x509_csr,
888 backend,
889 )
890 ext = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -0500891 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynor37b82df2015-07-03 10:26:37 -0400892 )
893 assert list(ext.value) == [
894 x509.DNSName(u"cryptography.io"),
895 x509.DNSName(u"sub.cryptography.io"),
896 ]
897
Andre Caronf27e4f42015-05-18 17:54:59 -0400898 def test_public_bytes_pem(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400899 # Load an existing CSR.
900 request = _load_cert(
901 os.path.join("x509", "requests", "rsa_sha1.pem"),
902 x509.load_pem_x509_csr,
903 backend
904 )
905
906 # Encode it to PEM and load it back.
907 request = x509.load_pem_x509_csr(request.public_bytes(
908 encoding=serialization.Encoding.PEM,
909 ), backend)
910
911 # We should recover what we had to start with.
912 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
913 public_key = request.public_key()
914 assert isinstance(public_key, rsa.RSAPublicKey)
915 subject = request.subject
916 assert isinstance(subject, x509.Name)
917 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500918 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
919 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
920 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
921 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
922 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400923 ]
924
Andre Caronf27e4f42015-05-18 17:54:59 -0400925 def test_public_bytes_der(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400926 # Load an existing CSR.
927 request = _load_cert(
928 os.path.join("x509", "requests", "rsa_sha1.pem"),
929 x509.load_pem_x509_csr,
930 backend
931 )
932
933 # Encode it to DER and load it back.
934 request = x509.load_der_x509_csr(request.public_bytes(
935 encoding=serialization.Encoding.DER,
936 ), backend)
937
938 # We should recover what we had to start with.
939 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
940 public_key = request.public_key()
941 assert isinstance(public_key, rsa.RSAPublicKey)
942 subject = request.subject
943 assert isinstance(subject, x509.Name)
944 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500945 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
946 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
947 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
948 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
949 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400950 ]
951
Andre Caronf27e4f42015-05-18 17:54:59 -0400952 def test_public_bytes_invalid_encoding(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400953 request = _load_cert(
954 os.path.join("x509", "requests", "rsa_sha1.pem"),
955 x509.load_pem_x509_csr,
956 backend
957 )
958
959 with pytest.raises(TypeError):
960 request.public_bytes('NotAnEncoding')
961
Andre Caronacb18972015-05-18 21:04:15 -0400962 @pytest.mark.parametrize(
963 ("request_path", "loader_func", "encoding"),
964 [
965 (
966 os.path.join("x509", "requests", "rsa_sha1.pem"),
967 x509.load_pem_x509_csr,
968 serialization.Encoding.PEM,
969 ),
970 (
971 os.path.join("x509", "requests", "rsa_sha1.der"),
972 x509.load_der_x509_csr,
973 serialization.Encoding.DER,
974 ),
975 ]
976 )
977 def test_public_bytes_match(self, request_path, loader_func, encoding,
978 backend):
979 request_bytes = load_vectors_from_file(
980 request_path, lambda pemfile: pemfile.read(), mode="rb"
981 )
982 request = loader_func(request_bytes, backend)
983 serialized = request.public_bytes(encoding)
984 assert serialized == request_bytes
985
Alex Gaynor70c8f8b2015-07-06 21:02:54 -0400986 def test_eq(self, backend):
987 request1 = _load_cert(
988 os.path.join("x509", "requests", "rsa_sha1.pem"),
989 x509.load_pem_x509_csr,
990 backend
991 )
992 request2 = _load_cert(
993 os.path.join("x509", "requests", "rsa_sha1.pem"),
994 x509.load_pem_x509_csr,
995 backend
996 )
997
998 assert request1 == request2
999
1000 def test_ne(self, backend):
1001 request1 = _load_cert(
1002 os.path.join("x509", "requests", "rsa_sha1.pem"),
1003 x509.load_pem_x509_csr,
1004 backend
1005 )
1006 request2 = _load_cert(
Alex Gaynoreb2df542015-07-06 21:50:15 -04001007 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001008 x509.load_pem_x509_csr,
1009 backend
1010 )
1011
1012 assert request1 != request2
1013 assert request1 != object()
1014
Alex Gaynor978137d2015-07-08 20:59:16 -04001015 def test_hash(self, backend):
1016 request1 = _load_cert(
1017 os.path.join("x509", "requests", "rsa_sha1.pem"),
1018 x509.load_pem_x509_csr,
1019 backend
1020 )
1021 request2 = _load_cert(
1022 os.path.join("x509", "requests", "rsa_sha1.pem"),
1023 x509.load_pem_x509_csr,
1024 backend
1025 )
1026 request3 = _load_cert(
1027 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
1028 x509.load_pem_x509_csr,
1029 backend
1030 )
1031
1032 assert hash(request1) == hash(request2)
1033 assert hash(request1) != hash(request3)
1034
Andre Caron9bbfcea2015-05-18 20:55:29 -04001035 def test_build_cert(self, backend):
Ian Cordascoe4e52a42015-07-19 10:15:37 -05001036 issuer_private_key = RSA_KEY_2048.private_key(backend)
1037 subject_private_key = RSA_KEY_2048.private_key(backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001038
Andre Caron9bbfcea2015-05-18 20:55:29 -04001039 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1040 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
Ian Cordascob3ed4842015-07-01 22:46:03 -05001041
Ian Cordasco893246f2015-07-24 14:52:18 -05001042 builder = x509.CertificateBuilder().serial_number(
Ian Cordascob3ed4842015-07-01 22:46:03 -05001043 777
1044 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001045 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1046 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1047 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1048 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1049 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -05001050 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001051 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1052 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1053 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1054 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1055 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -05001056 ])).public_key(
1057 subject_private_key.public_key()
1058 ).add_extension(
Ian Cordasco8887a572015-07-19 10:26:59 -05001059 x509.BasicConstraints(ca=False, path_length=None), True,
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001060 ).add_extension(
1061 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1062 critical=False,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001063 ).not_valid_before(
1064 not_valid_before
1065 ).not_valid_after(
1066 not_valid_after
1067 )
1068
Paul Kehrer9add80e2015-08-03 17:53:14 +01001069 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001070
1071 assert cert.version is x509.Version.v3
1072 assert cert.not_valid_before == not_valid_before
1073 assert cert.not_valid_after == not_valid_after
1074 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001075 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron9bbfcea2015-05-18 20:55:29 -04001076 )
1077 assert basic_constraints.value.ca is False
1078 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001079 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001080 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001081 )
1082 assert list(subject_alternative_name.value) == [
1083 x509.DNSName(u"cryptography.io"),
1084 ]
Andre Caron9bbfcea2015-05-18 20:55:29 -04001085
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001086
Ian Cordasco747a2172015-07-19 11:00:14 -05001087class TestCertificateBuilder(object):
Paul Kehrer25f19222015-08-04 23:05:09 +01001088 @pytest.mark.requires_backend_interface(interface=RSABackend)
1089 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrera03c3252015-08-09 10:59:29 -05001090 def test_checks_for_unsupported_extensions(self, backend):
1091 private_key = RSA_KEY_2048.private_key(backend)
1092 builder = x509.CertificateBuilder().subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001093 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera03c3252015-08-09 10:59:29 -05001094 ])).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001095 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera03c3252015-08-09 10:59:29 -05001096 ])).public_key(
1097 private_key.public_key()
1098 ).serial_number(
1099 777
1100 ).not_valid_before(
1101 datetime.datetime(1999, 1, 1)
1102 ).not_valid_after(
1103 datetime.datetime(2020, 1, 1)
1104 ).add_extension(
1105 DummyExtension(), False
1106 )
1107
1108 with pytest.raises(NotImplementedError):
1109 builder.sign(private_key, hashes.SHA1(), backend)
1110
1111 @pytest.mark.requires_backend_interface(interface=RSABackend)
1112 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer25f19222015-08-04 23:05:09 +01001113 def test_no_subject_name(self, backend):
1114 subject_private_key = RSA_KEY_2048.private_key(backend)
1115 builder = x509.CertificateBuilder().serial_number(
1116 777
1117 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001118 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001119 ])).public_key(
1120 subject_private_key.public_key()
1121 ).not_valid_before(
1122 datetime.datetime(2002, 1, 1, 12, 1)
1123 ).not_valid_after(
1124 datetime.datetime(2030, 12, 31, 8, 30)
1125 )
1126 with pytest.raises(ValueError):
1127 builder.sign(subject_private_key, hashes.SHA256(), backend)
1128
1129 @pytest.mark.requires_backend_interface(interface=RSABackend)
1130 @pytest.mark.requires_backend_interface(interface=X509Backend)
1131 def test_no_issuer_name(self, backend):
1132 subject_private_key = RSA_KEY_2048.private_key(backend)
1133 builder = x509.CertificateBuilder().serial_number(
1134 777
1135 ).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001136 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001137 ])).public_key(
1138 subject_private_key.public_key()
1139 ).not_valid_before(
1140 datetime.datetime(2002, 1, 1, 12, 1)
1141 ).not_valid_after(
1142 datetime.datetime(2030, 12, 31, 8, 30)
1143 )
1144 with pytest.raises(ValueError):
1145 builder.sign(subject_private_key, hashes.SHA256(), backend)
1146
1147 @pytest.mark.requires_backend_interface(interface=RSABackend)
1148 @pytest.mark.requires_backend_interface(interface=X509Backend)
1149 def test_no_public_key(self, backend):
1150 subject_private_key = RSA_KEY_2048.private_key(backend)
1151 builder = x509.CertificateBuilder().serial_number(
1152 777
1153 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001154 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001155 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001156 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001157 ])).not_valid_before(
1158 datetime.datetime(2002, 1, 1, 12, 1)
1159 ).not_valid_after(
1160 datetime.datetime(2030, 12, 31, 8, 30)
1161 )
1162 with pytest.raises(ValueError):
1163 builder.sign(subject_private_key, hashes.SHA256(), backend)
1164
1165 @pytest.mark.requires_backend_interface(interface=RSABackend)
1166 @pytest.mark.requires_backend_interface(interface=X509Backend)
1167 def test_no_not_valid_before(self, backend):
1168 subject_private_key = RSA_KEY_2048.private_key(backend)
1169 builder = x509.CertificateBuilder().serial_number(
1170 777
1171 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001172 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001173 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001174 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001175 ])).public_key(
1176 subject_private_key.public_key()
1177 ).not_valid_after(
1178 datetime.datetime(2030, 12, 31, 8, 30)
1179 )
1180 with pytest.raises(ValueError):
1181 builder.sign(subject_private_key, hashes.SHA256(), backend)
1182
1183 @pytest.mark.requires_backend_interface(interface=RSABackend)
1184 @pytest.mark.requires_backend_interface(interface=X509Backend)
1185 def test_no_not_valid_after(self, backend):
1186 subject_private_key = RSA_KEY_2048.private_key(backend)
1187 builder = x509.CertificateBuilder().serial_number(
1188 777
1189 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001190 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001191 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001192 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001193 ])).public_key(
1194 subject_private_key.public_key()
1195 ).not_valid_before(
1196 datetime.datetime(2002, 1, 1, 12, 1)
1197 )
1198 with pytest.raises(ValueError):
1199 builder.sign(subject_private_key, hashes.SHA256(), backend)
1200
1201 @pytest.mark.requires_backend_interface(interface=RSABackend)
1202 @pytest.mark.requires_backend_interface(interface=X509Backend)
1203 def test_no_serial_number(self, backend):
1204 subject_private_key = RSA_KEY_2048.private_key(backend)
1205 builder = x509.CertificateBuilder().issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001206 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001207 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001208 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001209 ])).public_key(
1210 subject_private_key.public_key()
1211 ).not_valid_before(
1212 datetime.datetime(2002, 1, 1, 12, 1)
1213 ).not_valid_after(
1214 datetime.datetime(2030, 12, 31, 8, 30)
1215 )
1216 with pytest.raises(ValueError):
1217 builder.sign(subject_private_key, hashes.SHA256(), backend)
1218
Ian Cordasco747a2172015-07-19 11:00:14 -05001219 def test_issuer_name_must_be_a_name_type(self):
1220 builder = x509.CertificateBuilder()
1221
1222 with pytest.raises(TypeError):
1223 builder.issuer_name("subject")
1224
1225 with pytest.raises(TypeError):
1226 builder.issuer_name(object)
1227
1228 def test_issuer_name_may_only_be_set_once(self):
1229 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001230 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -05001231 ])
1232 builder = x509.CertificateBuilder().issuer_name(name)
1233
1234 with pytest.raises(ValueError):
1235 builder.issuer_name(name)
1236
1237 def test_subject_name_must_be_a_name_type(self):
1238 builder = x509.CertificateBuilder()
1239
1240 with pytest.raises(TypeError):
1241 builder.subject_name("subject")
1242
1243 with pytest.raises(TypeError):
1244 builder.subject_name(object)
1245
1246 def test_subject_name_may_only_be_set_once(self):
1247 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001248 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -05001249 ])
1250 builder = x509.CertificateBuilder().subject_name(name)
1251
1252 with pytest.raises(ValueError):
1253 builder.subject_name(name)
1254
1255 @pytest.mark.requires_backend_interface(interface=RSABackend)
1256 @pytest.mark.requires_backend_interface(interface=X509Backend)
1257 def test_public_key_must_be_public_key(self, backend):
1258 private_key = RSA_KEY_2048.private_key(backend)
1259 builder = x509.CertificateBuilder()
1260
1261 with pytest.raises(TypeError):
1262 builder.public_key(private_key)
1263
1264 @pytest.mark.requires_backend_interface(interface=RSABackend)
1265 @pytest.mark.requires_backend_interface(interface=X509Backend)
1266 def test_public_key_may_only_be_set_once(self, backend):
1267 private_key = RSA_KEY_2048.private_key(backend)
1268 public_key = private_key.public_key()
1269 builder = x509.CertificateBuilder().public_key(public_key)
1270
1271 with pytest.raises(ValueError):
1272 builder.public_key(public_key)
1273
1274 def test_serial_number_must_be_an_integer_type(self):
1275 with pytest.raises(TypeError):
1276 x509.CertificateBuilder().serial_number(10.0)
1277
Ian Cordascob4a155d2015-08-01 23:07:19 -05001278 def test_serial_number_must_be_non_negative(self):
1279 with pytest.raises(ValueError):
1280 x509.CertificateBuilder().serial_number(-10)
1281
1282 def test_serial_number_must_be_less_than_160_bits_long(self):
1283 with pytest.raises(ValueError):
1284 # 2 raised to the 160th power is actually 161 bits
1285 x509.CertificateBuilder().serial_number(2 ** 160)
1286
Ian Cordasco747a2172015-07-19 11:00:14 -05001287 def test_serial_number_may_only_be_set_once(self):
1288 builder = x509.CertificateBuilder().serial_number(10)
1289
1290 with pytest.raises(ValueError):
1291 builder.serial_number(20)
1292
1293 def test_invalid_not_valid_after(self):
1294 with pytest.raises(TypeError):
1295 x509.CertificateBuilder().not_valid_after(104204304504)
1296
1297 with pytest.raises(TypeError):
1298 x509.CertificateBuilder().not_valid_after(datetime.time())
1299
Ian Cordascob4a155d2015-08-01 23:07:19 -05001300 with pytest.raises(ValueError):
1301 x509.CertificateBuilder().not_valid_after(
1302 datetime.datetime(1960, 8, 10)
1303 )
1304
Ian Cordasco747a2172015-07-19 11:00:14 -05001305 def test_not_valid_after_may_only_be_set_once(self):
1306 builder = x509.CertificateBuilder().not_valid_after(
1307 datetime.datetime.now()
1308 )
1309
1310 with pytest.raises(ValueError):
1311 builder.not_valid_after(
1312 datetime.datetime.now()
1313 )
1314
1315 def test_invalid_not_valid_before(self):
1316 with pytest.raises(TypeError):
1317 x509.CertificateBuilder().not_valid_before(104204304504)
1318
1319 with pytest.raises(TypeError):
1320 x509.CertificateBuilder().not_valid_before(datetime.time())
1321
Ian Cordascob4a155d2015-08-01 23:07:19 -05001322 with pytest.raises(ValueError):
1323 x509.CertificateBuilder().not_valid_before(
1324 datetime.datetime(1960, 8, 10)
1325 )
1326
Ian Cordasco747a2172015-07-19 11:00:14 -05001327 def test_not_valid_before_may_only_be_set_once(self):
1328 builder = x509.CertificateBuilder().not_valid_before(
1329 datetime.datetime.now()
1330 )
1331
1332 with pytest.raises(ValueError):
1333 builder.not_valid_before(
1334 datetime.datetime.now()
1335 )
1336
1337 def test_add_extension_checks_for_duplicates(self):
1338 builder = x509.CertificateBuilder().add_extension(
1339 x509.BasicConstraints(ca=False, path_length=None), True,
1340 )
1341
1342 with pytest.raises(ValueError):
1343 builder.add_extension(
1344 x509.BasicConstraints(ca=False, path_length=None), True,
1345 )
1346
Paul Kehrer08f950e2015-08-08 22:14:42 -05001347 def test_add_invalid_extension_type(self):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001348 builder = x509.CertificateBuilder()
1349
Paul Kehrer08f950e2015-08-08 22:14:42 -05001350 with pytest.raises(TypeError):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001351 builder.add_extension(object(), False)
1352
Ian Cordascob77c7162015-07-20 21:22:33 -05001353 @pytest.mark.requires_backend_interface(interface=RSABackend)
1354 @pytest.mark.requires_backend_interface(interface=X509Backend)
1355 def test_sign_with_unsupported_hash(self, backend):
1356 private_key = RSA_KEY_2048.private_key(backend)
1357 builder = x509.CertificateBuilder()
Paul Kehrer25f19222015-08-04 23:05:09 +01001358 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001359 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer25f19222015-08-04 23:05:09 +01001360 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001361 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer25f19222015-08-04 23:05:09 +01001362 ).serial_number(
1363 1
1364 ).public_key(
1365 private_key.public_key()
1366 ).not_valid_before(
1367 datetime.datetime(2002, 1, 1, 12, 1)
1368 ).not_valid_after(
1369 datetime.datetime(2032, 1, 1, 12, 1)
1370 )
Ian Cordascob77c7162015-07-20 21:22:33 -05001371
1372 with pytest.raises(TypeError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001373 builder.sign(private_key, object(), backend)
Ian Cordascob77c7162015-07-20 21:22:33 -05001374
Ian Cordasco56561b12015-07-24 16:38:50 -05001375 @pytest.mark.requires_backend_interface(interface=DSABackend)
1376 @pytest.mark.requires_backend_interface(interface=X509Backend)
1377 def test_sign_with_dsa_private_key_is_unsupported(self, backend):
1378 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1379 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1380
1381 private_key = DSA_KEY_2048.private_key(backend)
1382 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001383 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001384 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001385 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001386 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001387 ).serial_number(
1388 1
1389 ).public_key(
1390 private_key.public_key()
1391 ).not_valid_before(
1392 datetime.datetime(2002, 1, 1, 12, 1)
1393 ).not_valid_after(
1394 datetime.datetime(2032, 1, 1, 12, 1)
1395 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001396
1397 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001398 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001399
1400 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1401 @pytest.mark.requires_backend_interface(interface=X509Backend)
1402 def test_sign_with_ec_private_key_is_unsupported(self, backend):
1403 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1404 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1405
1406 _skip_curve_unsupported(backend, ec.SECP256R1())
1407 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1408 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001409 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001410 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001411 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001412 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001413 ).serial_number(
1414 1
1415 ).public_key(
1416 private_key.public_key()
1417 ).not_valid_before(
1418 datetime.datetime(2002, 1, 1, 12, 1)
1419 ).not_valid_after(
1420 datetime.datetime(2032, 1, 1, 12, 1)
1421 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001422
1423 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001424 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001425
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001426 @pytest.mark.parametrize(
1427 "cdp",
1428 [
1429 x509.CRLDistributionPoints([
1430 x509.DistributionPoint(
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001431 full_name=None,
1432 relative_name=x509.Name([
1433 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001434 NameOID.COMMON_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001435 u"indirect CRL for indirectCRL CA3"
1436 ),
1437 ]),
1438 reasons=None,
1439 crl_issuer=[x509.DirectoryName(
1440 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001441 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001442 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001443 NameOID.ORGANIZATION_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001444 u"Test Certificates 2011"
1445 ),
1446 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001447 NameOID.ORGANIZATIONAL_UNIT_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001448 u"indirectCRL CA3 cRLIssuer"
1449 ),
1450 ])
1451 )],
1452 )
1453 ]),
1454 x509.CRLDistributionPoints([
1455 x509.DistributionPoint(
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001456 full_name=[x509.DirectoryName(
1457 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001458 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001459 ])
1460 )],
1461 relative_name=None,
1462 reasons=None,
1463 crl_issuer=[x509.DirectoryName(
1464 x509.Name([
1465 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001466 NameOID.ORGANIZATION_NAME,
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001467 u"cryptography Testing"
1468 ),
1469 ])
1470 )],
1471 )
1472 ]),
1473 x509.CRLDistributionPoints([
1474 x509.DistributionPoint(
Paul Kehrerc6cf8f32015-08-08 09:47:44 -05001475 full_name=[
1476 x509.UniformResourceIdentifier(
1477 u"http://myhost.com/myca.crl"
1478 ),
1479 x509.UniformResourceIdentifier(
1480 u"http://backup.myhost.com/myca.crl"
1481 )
1482 ],
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001483 relative_name=None,
1484 reasons=frozenset([
1485 x509.ReasonFlags.key_compromise,
1486 x509.ReasonFlags.ca_compromise
1487 ]),
1488 crl_issuer=[x509.DirectoryName(
1489 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001490 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001491 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001492 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001493 ),
1494 ])
1495 )],
1496 )
1497 ]),
1498 x509.CRLDistributionPoints([
1499 x509.DistributionPoint(
1500 full_name=[x509.UniformResourceIdentifier(
1501 u"http://domain.com/some.crl"
1502 )],
1503 relative_name=None,
1504 reasons=frozenset([
1505 x509.ReasonFlags.key_compromise,
1506 x509.ReasonFlags.ca_compromise,
1507 x509.ReasonFlags.affiliation_changed,
1508 x509.ReasonFlags.superseded,
1509 x509.ReasonFlags.privilege_withdrawn,
1510 x509.ReasonFlags.cessation_of_operation,
1511 x509.ReasonFlags.aa_compromise,
1512 x509.ReasonFlags.certificate_hold,
1513 ]),
1514 crl_issuer=None
1515 )
1516 ]),
1517 x509.CRLDistributionPoints([
1518 x509.DistributionPoint(
1519 full_name=None,
1520 relative_name=None,
1521 reasons=None,
1522 crl_issuer=[x509.DirectoryName(
1523 x509.Name([
1524 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001525 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001526 ),
1527 ])
1528 )],
1529 )
1530 ]),
1531 x509.CRLDistributionPoints([
1532 x509.DistributionPoint(
1533 full_name=[x509.UniformResourceIdentifier(
1534 u"http://domain.com/some.crl"
1535 )],
1536 relative_name=None,
1537 reasons=frozenset([x509.ReasonFlags.aa_compromise]),
1538 crl_issuer=None
1539 )
1540 ])
1541 ]
1542 )
1543 @pytest.mark.requires_backend_interface(interface=RSABackend)
1544 @pytest.mark.requires_backend_interface(interface=X509Backend)
1545 def test_crl_distribution_points(self, backend, cdp):
1546 issuer_private_key = RSA_KEY_2048.private_key(backend)
1547 subject_private_key = RSA_KEY_2048.private_key(backend)
1548
1549 builder = x509.CertificateBuilder().serial_number(
1550 4444444
1551 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001552 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001553 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001554 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001555 ])).public_key(
1556 subject_private_key.public_key()
1557 ).add_extension(
1558 cdp,
1559 critical=False,
1560 ).not_valid_before(
1561 datetime.datetime(2002, 1, 1, 12, 1)
1562 ).not_valid_after(
1563 datetime.datetime(2030, 12, 31, 8, 30)
1564 )
1565
1566 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
1567
1568 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001569 ExtensionOID.CRL_DISTRIBUTION_POINTS
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001570 )
1571 assert ext.critical is False
1572 assert ext.value == cdp
1573
Ian Cordasco56561b12015-07-24 16:38:50 -05001574 @pytest.mark.requires_backend_interface(interface=DSABackend)
1575 @pytest.mark.requires_backend_interface(interface=X509Backend)
1576 def test_build_cert_with_dsa_private_key(self, backend):
1577 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1578 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1579
1580 issuer_private_key = DSA_KEY_2048.private_key(backend)
1581 subject_private_key = DSA_KEY_2048.private_key(backend)
1582
1583 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1584 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1585
1586 builder = x509.CertificateBuilder().serial_number(
1587 777
1588 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001589 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001590 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001591 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001592 ])).public_key(
1593 subject_private_key.public_key()
1594 ).add_extension(
1595 x509.BasicConstraints(ca=False, path_length=None), True,
1596 ).add_extension(
1597 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1598 critical=False,
1599 ).not_valid_before(
1600 not_valid_before
1601 ).not_valid_after(
1602 not_valid_after
1603 )
1604
Paul Kehrer9add80e2015-08-03 17:53:14 +01001605 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001606
1607 assert cert.version is x509.Version.v3
1608 assert cert.not_valid_before == not_valid_before
1609 assert cert.not_valid_after == not_valid_after
1610 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001611 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco56561b12015-07-24 16:38:50 -05001612 )
1613 assert basic_constraints.value.ca is False
1614 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001615 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001616 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001617 )
1618 assert list(subject_alternative_name.value) == [
1619 x509.DNSName(u"cryptography.io"),
1620 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001621
1622 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1623 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco85fc4d52015-08-01 20:29:31 -05001624 def test_build_cert_with_ec_private_key(self, backend):
Ian Cordasco56561b12015-07-24 16:38:50 -05001625 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1626 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1627
1628 _skip_curve_unsupported(backend, ec.SECP256R1())
1629 issuer_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1630 subject_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1631
1632 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1633 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1634
1635 builder = x509.CertificateBuilder().serial_number(
1636 777
1637 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001638 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001639 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001640 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001641 ])).public_key(
1642 subject_private_key.public_key()
1643 ).add_extension(
1644 x509.BasicConstraints(ca=False, path_length=None), True,
1645 ).add_extension(
1646 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1647 critical=False,
1648 ).not_valid_before(
1649 not_valid_before
1650 ).not_valid_after(
1651 not_valid_after
1652 )
1653
Paul Kehrer9add80e2015-08-03 17:53:14 +01001654 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001655
1656 assert cert.version is x509.Version.v3
1657 assert cert.not_valid_before == not_valid_before
1658 assert cert.not_valid_after == not_valid_after
1659 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001660 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco56561b12015-07-24 16:38:50 -05001661 )
1662 assert basic_constraints.value.ca is False
1663 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001664 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001665 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001666 )
1667 assert list(subject_alternative_name.value) == [
1668 x509.DNSName(u"cryptography.io"),
1669 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001670
Ian Cordasco8690eff2015-07-24 16:42:58 -05001671 @pytest.mark.requires_backend_interface(interface=RSABackend)
1672 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco19f5a492015-08-01 11:06:17 -05001673 def test_build_cert_with_rsa_key_too_small(self, backend):
Ian Cordasco8690eff2015-07-24 16:42:58 -05001674 issuer_private_key = RSA_KEY_512.private_key(backend)
1675 subject_private_key = RSA_KEY_512.private_key(backend)
1676
1677 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1678 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1679
1680 builder = x509.CertificateBuilder().serial_number(
1681 777
1682 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001683 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001684 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001685 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001686 ])).public_key(
1687 subject_private_key.public_key()
Ian Cordasco8690eff2015-07-24 16:42:58 -05001688 ).not_valid_before(
1689 not_valid_before
1690 ).not_valid_after(
1691 not_valid_after
1692 )
1693
Ian Cordasco19f5a492015-08-01 11:06:17 -05001694 with pytest.raises(ValueError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001695 builder.sign(issuer_private_key, hashes.SHA512(), backend)
Ian Cordasco8690eff2015-07-24 16:42:58 -05001696
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001697 @pytest.mark.requires_backend_interface(interface=RSABackend)
1698 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer69b64e42015-08-09 00:00:44 -05001699 def test_issuer_alt_name(self, backend):
1700 issuer_private_key = RSA_KEY_2048.private_key(backend)
1701 subject_private_key = RSA_KEY_2048.private_key(backend)
1702
1703 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1704 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1705
1706 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001707 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer69b64e42015-08-09 00:00:44 -05001708 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001709 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer69b64e42015-08-09 00:00:44 -05001710 ).not_valid_before(
1711 not_valid_before
1712 ).not_valid_after(
1713 not_valid_after
1714 ).public_key(
1715 subject_private_key.public_key()
1716 ).serial_number(
1717 123
1718 ).add_extension(
1719 x509.IssuerAlternativeName([
1720 x509.DNSName(u"myissuer"),
1721 x509.RFC822Name(u"email@domain.com"),
1722 ]), critical=False
1723 ).sign(issuer_private_key, hashes.SHA256(), backend)
1724
1725 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001726 ExtensionOID.ISSUER_ALTERNATIVE_NAME
Paul Kehrer69b64e42015-08-09 00:00:44 -05001727 )
1728 assert ext.critical is False
1729 assert ext.value == x509.IssuerAlternativeName([
1730 x509.DNSName(u"myissuer"),
1731 x509.RFC822Name(u"email@domain.com"),
1732 ])
1733
1734 @pytest.mark.requires_backend_interface(interface=RSABackend)
1735 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001736 def test_extended_key_usage(self, backend):
1737 issuer_private_key = RSA_KEY_2048.private_key(backend)
1738 subject_private_key = RSA_KEY_2048.private_key(backend)
1739
1740 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1741 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1742
1743 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001744 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001745 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001746 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001747 ).not_valid_before(
1748 not_valid_before
1749 ).not_valid_after(
1750 not_valid_after
1751 ).public_key(
1752 subject_private_key.public_key()
1753 ).serial_number(
1754 123
1755 ).add_extension(
1756 x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05001757 ExtendedKeyUsageOID.CLIENT_AUTH,
1758 ExtendedKeyUsageOID.SERVER_AUTH,
1759 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001760 ]), critical=False
1761 ).sign(issuer_private_key, hashes.SHA256(), backend)
1762
1763 eku = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001764 ExtensionOID.EXTENDED_KEY_USAGE
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001765 )
1766 assert eku.critical is False
1767 assert eku.value == x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05001768 ExtendedKeyUsageOID.CLIENT_AUTH,
1769 ExtendedKeyUsageOID.SERVER_AUTH,
1770 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001771 ])
1772
1773 @pytest.mark.requires_backend_interface(interface=RSABackend)
1774 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer683d4d82015-08-06 23:13:45 +01001775 def test_inhibit_any_policy(self, backend):
1776 issuer_private_key = RSA_KEY_2048.private_key(backend)
1777 subject_private_key = RSA_KEY_2048.private_key(backend)
1778
1779 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1780 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1781
1782 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001783 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer683d4d82015-08-06 23:13:45 +01001784 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001785 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer683d4d82015-08-06 23:13:45 +01001786 ).not_valid_before(
1787 not_valid_before
1788 ).not_valid_after(
1789 not_valid_after
1790 ).public_key(
1791 subject_private_key.public_key()
1792 ).serial_number(
1793 123
1794 ).add_extension(
1795 x509.InhibitAnyPolicy(3), critical=False
1796 ).sign(issuer_private_key, hashes.SHA256(), backend)
1797
1798 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001799 ExtensionOID.INHIBIT_ANY_POLICY
Paul Kehrer683d4d82015-08-06 23:13:45 +01001800 )
1801 assert ext.value == x509.InhibitAnyPolicy(3)
1802
1803 @pytest.mark.requires_backend_interface(interface=RSABackend)
1804 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001805 def test_key_usage(self, backend):
1806 issuer_private_key = RSA_KEY_2048.private_key(backend)
1807 subject_private_key = RSA_KEY_2048.private_key(backend)
1808
1809 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1810 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1811
1812 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001813 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001814 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001815 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001816 ).not_valid_before(
1817 not_valid_before
1818 ).not_valid_after(
1819 not_valid_after
1820 ).public_key(
1821 subject_private_key.public_key()
1822 ).serial_number(
1823 123
1824 ).add_extension(
1825 x509.KeyUsage(
1826 digital_signature=True,
1827 content_commitment=True,
1828 key_encipherment=False,
1829 data_encipherment=False,
1830 key_agreement=False,
1831 key_cert_sign=True,
1832 crl_sign=False,
1833 encipher_only=False,
1834 decipher_only=False
1835 ),
1836 critical=False
1837 ).sign(issuer_private_key, hashes.SHA256(), backend)
1838
Paul Kehrerd44e4132015-08-10 19:13:13 -05001839 ext = cert.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001840 assert ext.critical is False
1841 assert ext.value == x509.KeyUsage(
1842 digital_signature=True,
1843 content_commitment=True,
1844 key_encipherment=False,
1845 data_encipherment=False,
1846 key_agreement=False,
1847 key_cert_sign=True,
1848 crl_sign=False,
1849 encipher_only=False,
1850 decipher_only=False
1851 )
1852
Ian Cordasco747a2172015-07-19 11:00:14 -05001853
Andre Caron0ef595f2015-05-18 13:53:43 -04001854@pytest.mark.requires_backend_interface(interface=X509Backend)
1855class TestCertificateSigningRequestBuilder(object):
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001856 @pytest.mark.requires_backend_interface(interface=RSABackend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001857 def test_sign_invalid_hash_algorithm(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001858 private_key = RSA_KEY_2048.private_key(backend)
1859
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001860 builder = x509.CertificateSigningRequestBuilder().subject_name(
1861 x509.Name([])
1862 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001863 with pytest.raises(TypeError):
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001864 builder.sign(private_key, 'NotAHash', backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001865
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001866 @pytest.mark.requires_backend_interface(interface=RSABackend)
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001867 def test_no_subject_name(self, backend):
1868 private_key = RSA_KEY_2048.private_key(backend)
1869
1870 builder = x509.CertificateSigningRequestBuilder()
1871 with pytest.raises(ValueError):
1872 builder.sign(private_key, hashes.SHA256(), backend)
1873
1874 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001875 def test_build_ca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001876 private_key = RSA_KEY_2048.private_key(backend)
1877
Andre Carona9a51172015-06-06 20:18:44 -04001878 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04001879 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001880 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Andre Caron99d0f902015-06-01 08:36:59 -04001881 ])
Andre Caron472fd692015-06-06 20:04:44 -04001882 ).add_extension(
Ian Cordasco41f51ce2015-06-17 11:49:11 -05001883 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001884 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001885
1886 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1887 public_key = request.public_key()
1888 assert isinstance(public_key, rsa.RSAPublicKey)
1889 subject = request.subject
1890 assert isinstance(subject, x509.Name)
1891 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001892 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Andre Caron0ef595f2015-05-18 13:53:43 -04001893 ]
1894 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001895 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron0ef595f2015-05-18 13:53:43 -04001896 )
1897 assert basic_constraints.value.ca is True
1898 assert basic_constraints.value.path_length == 2
1899
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001900 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001901 def test_build_ca_request_with_unicode(self, backend):
1902 private_key = RSA_KEY_2048.private_key(backend)
1903
1904 request = x509.CertificateSigningRequestBuilder().subject_name(
1905 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001906 x509.NameAttribute(NameOID.ORGANIZATION_NAME,
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001907 u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001908 ])
1909 ).add_extension(
1910 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001911 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001912
1913 loaded_request = x509.load_pem_x509_csr(
1914 request.public_bytes(encoding=serialization.Encoding.PEM), backend
1915 )
1916 subject = loaded_request.subject
1917 assert isinstance(subject, x509.Name)
1918 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001919 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001920 ]
1921
1922 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001923 def test_build_nonca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001924 private_key = RSA_KEY_2048.private_key(backend)
1925
Andre Carona9a51172015-06-06 20:18:44 -04001926 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04001927 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001928 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Andre Caron99d0f902015-06-01 08:36:59 -04001929 ])
Andre Caron472fd692015-06-06 20:04:44 -04001930 ).add_extension(
Ian Cordasco0112b022015-06-16 17:51:18 -05001931 x509.BasicConstraints(ca=False, path_length=None), critical=True,
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001932 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001933
1934 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1935 public_key = request.public_key()
1936 assert isinstance(public_key, rsa.RSAPublicKey)
1937 subject = request.subject
1938 assert isinstance(subject, x509.Name)
1939 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001940 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Andre Caron0ef595f2015-05-18 13:53:43 -04001941 ]
1942 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001943 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron0ef595f2015-05-18 13:53:43 -04001944 )
1945 assert basic_constraints.value.ca is False
1946 assert basic_constraints.value.path_length is None
1947
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001948 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1949 def test_build_ca_request_with_ec(self, backend):
1950 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1951 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1952
Ian Cordasco8cdcdfc2015-06-24 22:00:26 -05001953 _skip_curve_unsupported(backend, ec.SECP256R1())
1954 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001955
1956 request = x509.CertificateSigningRequestBuilder().subject_name(
1957 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001958 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001959 ])
1960 ).add_extension(
1961 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001962 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001963
1964 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1965 public_key = request.public_key()
1966 assert isinstance(public_key, ec.EllipticCurvePublicKey)
1967 subject = request.subject
1968 assert isinstance(subject, x509.Name)
1969 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001970 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001971 ]
1972 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001973 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001974 )
1975 assert basic_constraints.value.ca is True
1976 assert basic_constraints.value.path_length == 2
1977
1978 @pytest.mark.requires_backend_interface(interface=DSABackend)
1979 def test_build_ca_request_with_dsa(self, backend):
1980 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1981 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1982
1983 private_key = DSA_KEY_2048.private_key(backend)
1984
1985 request = x509.CertificateSigningRequestBuilder().subject_name(
1986 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001987 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001988 ])
1989 ).add_extension(
1990 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001991 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001992
1993 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1994 public_key = request.public_key()
1995 assert isinstance(public_key, dsa.DSAPublicKey)
1996 subject = request.subject
1997 assert isinstance(subject, x509.Name)
1998 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001999 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002000 ]
2001 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002002 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002003 )
2004 assert basic_constraints.value.ca is True
2005 assert basic_constraints.value.path_length == 2
2006
Paul Kehrerff917802015-06-26 17:29:04 -05002007 def test_add_duplicate_extension(self):
Andre Caronfc164c52015-05-31 17:36:18 -04002008 builder = x509.CertificateSigningRequestBuilder().add_extension(
Andre Caron472fd692015-06-06 20:04:44 -04002009 x509.BasicConstraints(True, 2), critical=True,
Andre Caronfc164c52015-05-31 17:36:18 -04002010 )
Andre Caron0ef595f2015-05-18 13:53:43 -04002011 with pytest.raises(ValueError):
Andre Caron472fd692015-06-06 20:04:44 -04002012 builder.add_extension(
2013 x509.BasicConstraints(True, 2), critical=True,
2014 )
Andre Caron0ef595f2015-05-18 13:53:43 -04002015
Paul Kehrerff917802015-06-26 17:29:04 -05002016 def test_set_invalid_subject(self):
Andre Caron0ef595f2015-05-18 13:53:43 -04002017 builder = x509.CertificateSigningRequestBuilder()
2018 with pytest.raises(TypeError):
Andre Carona9a51172015-06-06 20:18:44 -04002019 builder.subject_name('NotAName')
Andre Caron0ef595f2015-05-18 13:53:43 -04002020
Paul Kehrere59fd222015-08-08 22:50:19 -05002021 def test_add_invalid_extension_type(self):
Ian Cordasco34853f32015-06-21 10:50:53 -05002022 builder = x509.CertificateSigningRequestBuilder()
Andre Caron0ef595f2015-05-18 13:53:43 -04002023
Paul Kehrere59fd222015-08-08 22:50:19 -05002024 with pytest.raises(TypeError):
2025 builder.add_extension(object(), False)
2026
2027 def test_add_unsupported_extension(self, backend):
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002028 private_key = RSA_KEY_2048.private_key(backend)
2029 builder = x509.CertificateSigningRequestBuilder()
2030 builder = builder.subject_name(
2031 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002032 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002033 ])
2034 ).add_extension(
Alex Gaynor7583f7f2015-07-03 10:56:49 -04002035 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
2036 critical=False,
2037 ).add_extension(
Paul Kehrer69b64e42015-08-09 00:00:44 -05002038 DummyExtension(), False
Paul Kehrerdce91f02015-07-23 20:31:12 +01002039 )
2040 with pytest.raises(NotImplementedError):
2041 builder.sign(private_key, hashes.SHA256(), backend)
2042
2043 def test_key_usage(self, backend):
2044 private_key = RSA_KEY_2048.private_key(backend)
2045 builder = x509.CertificateSigningRequestBuilder()
2046 request = builder.subject_name(
2047 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002048 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerdce91f02015-07-23 20:31:12 +01002049 ])
2050 ).add_extension(
Alex Gaynorac7f70a2015-06-28 11:07:52 -04002051 x509.KeyUsage(
2052 digital_signature=True,
2053 content_commitment=True,
2054 key_encipherment=False,
2055 data_encipherment=False,
2056 key_agreement=False,
2057 key_cert_sign=True,
2058 crl_sign=False,
2059 encipher_only=False,
2060 decipher_only=False
2061 ),
Alex Gaynor887a4082015-07-03 04:29:03 -04002062 critical=False
Paul Kehrerdce91f02015-07-23 20:31:12 +01002063 ).sign(private_key, hashes.SHA256(), backend)
2064 assert len(request.extensions) == 1
Paul Kehrerd44e4132015-08-10 19:13:13 -05002065 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrerdce91f02015-07-23 20:31:12 +01002066 assert ext.critical is False
2067 assert ext.value == x509.KeyUsage(
2068 digital_signature=True,
2069 content_commitment=True,
2070 key_encipherment=False,
2071 data_encipherment=False,
2072 key_agreement=False,
2073 key_cert_sign=True,
2074 crl_sign=False,
2075 encipher_only=False,
2076 decipher_only=False
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002077 )
Paul Kehrerdce91f02015-07-23 20:31:12 +01002078
2079 def test_key_usage_key_agreement_bit(self, backend):
2080 private_key = RSA_KEY_2048.private_key(backend)
2081 builder = x509.CertificateSigningRequestBuilder()
2082 request = builder.subject_name(
2083 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002084 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerdce91f02015-07-23 20:31:12 +01002085 ])
2086 ).add_extension(
2087 x509.KeyUsage(
2088 digital_signature=False,
2089 content_commitment=False,
2090 key_encipherment=False,
2091 data_encipherment=False,
2092 key_agreement=True,
2093 key_cert_sign=True,
2094 crl_sign=False,
2095 encipher_only=False,
2096 decipher_only=True
2097 ),
2098 critical=False
2099 ).sign(private_key, hashes.SHA256(), backend)
2100 assert len(request.extensions) == 1
Paul Kehrerd44e4132015-08-10 19:13:13 -05002101 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrerdce91f02015-07-23 20:31:12 +01002102 assert ext.critical is False
2103 assert ext.value == x509.KeyUsage(
2104 digital_signature=False,
2105 content_commitment=False,
2106 key_encipherment=False,
2107 data_encipherment=False,
2108 key_agreement=True,
2109 key_cert_sign=True,
2110 crl_sign=False,
2111 encipher_only=False,
2112 decipher_only=True
2113 )
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002114
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002115 def test_add_two_extensions(self, backend):
2116 private_key = RSA_KEY_2048.private_key(backend)
2117 builder = x509.CertificateSigningRequestBuilder()
2118 request = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002119 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002120 ).add_extension(
2121 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
2122 critical=False,
2123 ).add_extension(
2124 x509.BasicConstraints(ca=True, path_length=2), critical=True
2125 ).sign(private_key, hashes.SHA1(), backend)
2126
2127 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2128 public_key = request.public_key()
2129 assert isinstance(public_key, rsa.RSAPublicKey)
2130 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002131 ExtensionOID.BASIC_CONSTRAINTS
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002132 )
2133 assert basic_constraints.value.ca is True
2134 assert basic_constraints.value.path_length == 2
2135 ext = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002136 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002137 )
2138 assert list(ext.value) == [x509.DNSName(u"cryptography.io")]
Paul Kehrerff917802015-06-26 17:29:04 -05002139
Andre Caron0ef595f2015-05-18 13:53:43 -04002140 def test_set_subject_twice(self):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002141 builder = x509.CertificateSigningRequestBuilder()
2142 builder = builder.subject_name(
Paul Kehrere76cd272014-12-14 19:00:51 -06002143 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002144 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera693cfd2014-11-27 07:47:58 -10002145 ])
Paul Kehrer4903adc2014-12-13 16:57:50 -06002146 )
Paul Kehrer41120322014-12-02 18:31:14 -10002147 with pytest.raises(ValueError):
Paul Kehrera693cfd2014-11-27 07:47:58 -10002148 builder.subject_name(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002149 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002150 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002151 ])
Alex Gaynor32c57df2015-02-23 21:51:27 -08002152 )
Alex Gaynorfcadda62015-03-10 10:01:18 -04002153
Alex Gaynord3e84162015-06-28 10:14:55 -04002154 def test_subject_alt_names(self, backend):
2155 private_key = RSA_KEY_2048.private_key(backend)
2156
2157 csr = x509.CertificateSigningRequestBuilder().subject_name(
2158 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002159 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Alex Gaynord3e84162015-06-28 10:14:55 -04002160 ])
2161 ).add_extension(
2162 x509.SubjectAlternativeName([
Alex Gaynor6431d502015-07-05 12:28:46 -04002163 x509.DNSName(u"example.com"),
2164 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05002165 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002166 x509.DirectoryName(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002167 x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002168 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002169 NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002170 )
2171 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05002172 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
2173 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05002174 x509.OtherName(
2175 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2176 value=b"0\x03\x02\x01\x05"
2177 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05002178 x509.RFC822Name(u"test@example.com"),
2179 x509.RFC822Name(u"email"),
2180 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05002181 x509.UniformResourceIdentifier(
2182 u"https://\u043f\u044b\u043a\u0430.cryptography"
2183 ),
2184 x509.UniformResourceIdentifier(
2185 u"gopher://cryptography:70/some/path"
2186 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04002187 ]),
2188 critical=False,
2189 ).sign(private_key, hashes.SHA256(), backend)
2190
2191 assert len(csr.extensions) == 1
2192 ext = csr.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002193 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynord3e84162015-06-28 10:14:55 -04002194 )
2195 assert not ext.critical
Paul Kehrerd44e4132015-08-10 19:13:13 -05002196 assert ext.oid == ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynord3e84162015-06-28 10:14:55 -04002197 assert list(ext.value) == [
Alex Gaynor6431d502015-07-05 12:28:46 -04002198 x509.DNSName(u"example.com"),
2199 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05002200 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002201 x509.DirectoryName(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002202 x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002203 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002204 NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002205 ),
2206 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05002207 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
2208 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05002209 x509.OtherName(
2210 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2211 value=b"0\x03\x02\x01\x05"
2212 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05002213 x509.RFC822Name(u"test@example.com"),
2214 x509.RFC822Name(u"email"),
2215 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05002216 x509.UniformResourceIdentifier(
2217 u"https://\u043f\u044b\u043a\u0430.cryptography"
2218 ),
2219 x509.UniformResourceIdentifier(
2220 u"gopher://cryptography:70/some/path"
2221 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04002222 ]
2223
Paul Kehrer500ed9d2015-07-10 20:51:36 -05002224 def test_invalid_asn1_othername(self, backend):
2225 private_key = RSA_KEY_2048.private_key(backend)
2226
2227 builder = x509.CertificateSigningRequestBuilder().subject_name(
2228 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002229 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Paul Kehrer500ed9d2015-07-10 20:51:36 -05002230 ])
2231 ).add_extension(
2232 x509.SubjectAlternativeName([
2233 x509.OtherName(
2234 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2235 value=b"\x01\x02\x01\x05"
2236 ),
2237 ]),
2238 critical=False,
2239 )
2240 with pytest.raises(ValueError):
2241 builder.sign(private_key, hashes.SHA256(), backend)
2242
Alex Gaynord5f718c2015-07-05 11:19:38 -04002243 def test_subject_alt_name_unsupported_general_name(self, backend):
2244 private_key = RSA_KEY_2048.private_key(backend)
2245
2246 builder = x509.CertificateSigningRequestBuilder().subject_name(
2247 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002248 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Alex Gaynord5f718c2015-07-05 11:19:38 -04002249 ])
2250 ).add_extension(
Paul Kehrer474a6472015-07-11 12:29:52 -05002251 x509.SubjectAlternativeName([FakeGeneralName("")]),
Alex Gaynord5f718c2015-07-05 11:19:38 -04002252 critical=False,
2253 )
2254
Paul Kehrer474a6472015-07-11 12:29:52 -05002255 with pytest.raises(ValueError):
Alex Gaynord5f718c2015-07-05 11:19:38 -04002256 builder.sign(private_key, hashes.SHA256(), backend)
2257
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002258 def test_extended_key_usage(self, backend):
2259 private_key = RSA_KEY_2048.private_key(backend)
2260 builder = x509.CertificateSigningRequestBuilder()
2261 request = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002262 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002263 ).add_extension(
2264 x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05002265 ExtendedKeyUsageOID.CLIENT_AUTH,
2266 ExtendedKeyUsageOID.SERVER_AUTH,
2267 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002268 ]), critical=False
2269 ).sign(private_key, hashes.SHA256(), backend)
2270
2271 eku = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002272 ExtensionOID.EXTENDED_KEY_USAGE
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002273 )
2274 assert eku.critical is False
2275 assert eku.value == x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05002276 ExtendedKeyUsageOID.CLIENT_AUTH,
2277 ExtendedKeyUsageOID.SERVER_AUTH,
2278 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002279 ])
2280
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002281 @pytest.mark.requires_backend_interface(interface=RSABackend)
2282 def test_rsa_key_too_small(self, backend):
2283 private_key = rsa.generate_private_key(65537, 512, backend)
2284 builder = x509.CertificateSigningRequestBuilder()
2285 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002286 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002287 )
2288
2289 with pytest.raises(ValueError) as exc:
2290 builder.sign(private_key, hashes.SHA512(), backend)
2291
Paul Kehrer6a71f8d2015-07-25 19:15:59 +01002292 assert str(exc.value) == "Digest too big for RSA key"
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002293
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002294 @pytest.mark.requires_backend_interface(interface=RSABackend)
2295 @pytest.mark.requires_backend_interface(interface=X509Backend)
2296 def test_build_cert_with_aia(self, backend):
2297 issuer_private_key = RSA_KEY_2048.private_key(backend)
2298 subject_private_key = RSA_KEY_2048.private_key(backend)
2299
2300 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2301 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2302
2303 aia = x509.AuthorityInformationAccess([
2304 x509.AccessDescription(
Paul Kehrer9e102db2015-08-10 21:53:09 -05002305 AuthorityInformationAccessOID.OCSP,
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002306 x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
2307 ),
2308 x509.AccessDescription(
Paul Kehrer9e102db2015-08-10 21:53:09 -05002309 AuthorityInformationAccessOID.CA_ISSUERS,
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002310 x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
2311 )
2312 ])
2313
2314 builder = x509.CertificateBuilder().serial_number(
2315 777
2316 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002317 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002318 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002319 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002320 ])).public_key(
2321 subject_private_key.public_key()
2322 ).add_extension(
2323 aia, critical=False
2324 ).not_valid_before(
2325 not_valid_before
2326 ).not_valid_after(
2327 not_valid_after
2328 )
2329
2330 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2331
2332 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002333 ExtensionOID.AUTHORITY_INFORMATION_ACCESS
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002334 )
2335 assert ext.value == aia
2336
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002337 @pytest.mark.requires_backend_interface(interface=RSABackend)
2338 @pytest.mark.requires_backend_interface(interface=X509Backend)
2339 def test_build_cert_with_ski(self, backend):
2340 issuer_private_key = RSA_KEY_2048.private_key(backend)
2341 subject_private_key = RSA_KEY_2048.private_key(backend)
2342
2343 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2344 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2345
2346 ski = x509.SubjectKeyIdentifier.from_public_key(
2347 subject_private_key.public_key()
2348 )
2349
2350 builder = x509.CertificateBuilder().serial_number(
2351 777
2352 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002353 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002354 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002355 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002356 ])).public_key(
2357 subject_private_key.public_key()
2358 ).add_extension(
2359 ski, critical=False
2360 ).not_valid_before(
2361 not_valid_before
2362 ).not_valid_after(
2363 not_valid_after
2364 )
2365
2366 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2367
2368 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002369 ExtensionOID.SUBJECT_KEY_IDENTIFIER
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002370 )
2371 assert ext.value == ski
2372
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002373 @pytest.mark.parametrize(
2374 "aki",
2375 [
2376 x509.AuthorityKeyIdentifier(
2377 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2378 b"\xcbY",
2379 None,
2380 None
2381 ),
2382 x509.AuthorityKeyIdentifier(
2383 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2384 b"\xcbY",
2385 [
2386 x509.DirectoryName(
2387 x509.Name([
2388 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002389 NameOID.ORGANIZATION_NAME, u"PyCA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002390 ),
2391 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002392 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002393 )
2394 ])
2395 )
2396 ],
2397 333
2398 ),
2399 x509.AuthorityKeyIdentifier(
2400 None,
2401 [
2402 x509.DirectoryName(
2403 x509.Name([
2404 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002405 NameOID.ORGANIZATION_NAME, u"PyCA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002406 ),
2407 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002408 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002409 )
2410 ])
2411 )
2412 ],
2413 333
2414 ),
2415 ]
2416 )
2417 @pytest.mark.requires_backend_interface(interface=RSABackend)
2418 @pytest.mark.requires_backend_interface(interface=X509Backend)
2419 def test_build_cert_with_aki(self, aki, backend):
2420 issuer_private_key = RSA_KEY_2048.private_key(backend)
2421 subject_private_key = RSA_KEY_2048.private_key(backend)
2422
2423 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2424 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2425
2426 builder = x509.CertificateBuilder().serial_number(
2427 777
2428 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002429 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002430 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002431 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002432 ])).public_key(
2433 subject_private_key.public_key()
2434 ).add_extension(
2435 aki, critical=False
2436 ).not_valid_before(
2437 not_valid_before
2438 ).not_valid_after(
2439 not_valid_after
2440 )
2441
2442 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2443
2444 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002445 ExtensionOID.AUTHORITY_KEY_IDENTIFIER
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002446 )
2447 assert ext.value == aki
2448
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002449 def test_ocsp_nocheck(self, backend):
2450 issuer_private_key = RSA_KEY_2048.private_key(backend)
2451 subject_private_key = RSA_KEY_2048.private_key(backend)
2452
2453 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2454 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2455
2456 builder = x509.CertificateBuilder().serial_number(
2457 777
2458 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002459 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002460 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002461 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002462 ])).public_key(
2463 subject_private_key.public_key()
2464 ).add_extension(
2465 x509.OCSPNoCheck(), critical=False
2466 ).not_valid_before(
2467 not_valid_before
2468 ).not_valid_after(
2469 not_valid_after
2470 )
2471
2472 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2473
2474 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002475 ExtensionOID.OCSP_NO_CHECK
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002476 )
2477 assert isinstance(ext.value, x509.OCSPNoCheck)
2478
Alex Gaynord5f718c2015-07-05 11:19:38 -04002479
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002480@pytest.mark.requires_backend_interface(interface=DSABackend)
2481@pytest.mark.requires_backend_interface(interface=X509Backend)
2482class TestDSACertificate(object):
2483 def test_load_dsa_cert(self, backend):
2484 cert = _load_cert(
2485 os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
2486 x509.load_pem_x509_certificate,
2487 backend
2488 )
2489 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
2490 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002491 assert isinstance(public_key, dsa.DSAPublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002492 num = public_key.public_numbers()
2493 assert num.y == int(
2494 "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94"
2495 "53b6656f13e543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2"
2496 "dea559f0b584c97a2b235b9b69b46bc6de1aed422a6f341832618bcaae2"
2497 "198aba388099dafb05ff0b5efecb3b0ae169a62e1c72022af50ae68af3b"
2498 "033c18e6eec1f7df4692c456ccafb79cc7e08da0a5786e9816ceda651d6"
2499 "1b4bb7b81c2783da97cea62df67af5e85991fdc13aff10fc60e06586386"
2500 "b96bb78d65750f542f86951e05a6d81baadbcd35a2e5cad4119923ae6a2"
2501 "002091a3d17017f93c52970113cdc119970b9074ca506eac91c3dd37632"
2502 "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c", 16
2503 )
2504 assert num.parameter_numbers.g == int(
2505 "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67"
2506 "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b"
2507 "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2"
2508 "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa"
2509 "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f"
2510 "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a"
2511 "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0"
2512 "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76"
2513 "fa6247676a6d3ac945844a083509c6a1b436baca", 16
2514 )
2515 assert num.parameter_numbers.p == int(
2516 "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3"
2517 "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330"
2518 "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e"
2519 "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a"
2520 "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4"
2521 "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2"
2522 "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93"
2523 "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d"
2524 "833e36468f3907cfca788a3cb790f0341c8a31bf", 16
2525 )
2526 assert num.parameter_numbers.q == int(
2527 "822ff5d234e073b901cf5941f58e1f538e71d40d", 16
2528 )
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002529
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002530 @pytest.mark.parametrize(
2531 ("path", "loader_func"),
2532 [
2533 [
2534 os.path.join("x509", "requests", "dsa_sha1.pem"),
2535 x509.load_pem_x509_csr
2536 ],
2537 [
2538 os.path.join("x509", "requests", "dsa_sha1.der"),
2539 x509.load_der_x509_csr
2540 ],
2541 ]
2542 )
2543 def test_load_dsa_request(self, path, loader_func, backend):
2544 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002545 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2546 public_key = request.public_key()
2547 assert isinstance(public_key, dsa.DSAPublicKey)
2548 subject = request.subject
2549 assert isinstance(subject, x509.Name)
2550 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002551 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2552 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2553 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2554 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2555 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002556 ]
2557
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002558
2559@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2560@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -06002561class TestECDSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002562 def test_load_ecdsa_cert(self, backend):
2563 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrera693cfd2014-11-27 07:47:58 -10002564 cert = _load_cert(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002565 os.path.join("x509", "ecdsa_root.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -10002566 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -10002567 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002568 )
Paul Kehrer8802a5b2015-02-13 12:06:57 -06002569 assert isinstance(cert.signature_hash_algorithm, hashes.SHA384)
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002570 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002571 assert isinstance(public_key, ec.EllipticCurvePublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002572 num = public_key.public_numbers()
2573 assert num.x == int(
2574 "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f"
2575 "6f0ccd00bba615b51467e9e2d9fee8e630c17", 16
2576 )
2577 assert num.y == int(
2578 "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7"
2579 "2deae88a7a16bb543ce67dc23ff031ca3e23e", 16
2580 )
2581 assert isinstance(num.curve, ec.SECP384R1)
Paul Kehrer6c660a82014-12-12 11:50:44 -06002582
2583 def test_load_ecdsa_no_named_curve(self, backend):
2584 _skip_curve_unsupported(backend, ec.SECP256R1())
2585 cert = _load_cert(
2586 os.path.join("x509", "custom", "ec_no_named_curve.pem"),
2587 x509.load_pem_x509_certificate,
2588 backend
2589 )
2590 with pytest.raises(NotImplementedError):
2591 cert.public_key()
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002592
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002593 @pytest.mark.parametrize(
2594 ("path", "loader_func"),
2595 [
2596 [
2597 os.path.join("x509", "requests", "ec_sha256.pem"),
2598 x509.load_pem_x509_csr
2599 ],
2600 [
2601 os.path.join("x509", "requests", "ec_sha256.der"),
2602 x509.load_der_x509_csr
2603 ],
2604 ]
2605 )
2606 def test_load_ecdsa_certificate_request(self, path, loader_func, backend):
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002607 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002608 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002609 assert isinstance(request.signature_hash_algorithm, hashes.SHA256)
2610 public_key = request.public_key()
2611 assert isinstance(public_key, ec.EllipticCurvePublicKey)
2612 subject = request.subject
2613 assert isinstance(subject, x509.Name)
2614 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002615 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2616 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2617 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2618 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2619 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002620 ]
2621
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002622
Paul Kehrer806bfb22015-02-02 17:05:24 -06002623class TestNameAttribute(object):
Alex Gaynora56ff412015-02-10 17:26:32 -05002624 def test_init_bad_oid(self):
2625 with pytest.raises(TypeError):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002626 x509.NameAttribute(None, u'value')
Alex Gaynora56ff412015-02-10 17:26:32 -05002627
Ian Cordasco7618fbe2015-06-16 19:12:17 -05002628 def test_init_bad_value(self):
2629 with pytest.raises(TypeError):
2630 x509.NameAttribute(
2631 x509.ObjectIdentifier('oid'),
2632 b'bytes'
2633 )
2634
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002635 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002636 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002637 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002638 ) == x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002639 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002640 )
2641
2642 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002643 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002644 x509.ObjectIdentifier('2.5.4.3'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002645 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002646 x509.ObjectIdentifier('2.5.4.5'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002647 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002648 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002649 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002650 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002651 x509.ObjectIdentifier('oid'), u'value2'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002652 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002653 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002654 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002655 ) != object()
2656
Paul Kehrera498be82015-02-12 15:00:56 -06002657 def test_repr(self):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002658 na = x509.NameAttribute(x509.ObjectIdentifier('2.5.4.3'), u'value')
Ian Cordascoa908d692015-06-16 21:35:24 -05002659 if six.PY3:
2660 assert repr(na) == (
2661 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2662 "nName)>, value='value')>"
2663 )
2664 else:
2665 assert repr(na) == (
2666 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2667 "nName)>, value=u'value')>"
2668 )
Paul Kehrera498be82015-02-12 15:00:56 -06002669
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002670
2671class TestObjectIdentifier(object):
2672 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002673 oid1 = x509.ObjectIdentifier('oid')
2674 oid2 = x509.ObjectIdentifier('oid')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002675 assert oid1 == oid2
2676
2677 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002678 oid1 = x509.ObjectIdentifier('oid')
2679 assert oid1 != x509.ObjectIdentifier('oid1')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002680 assert oid1 != object()
2681
2682 def test_repr(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002683 oid = x509.ObjectIdentifier("2.5.4.3")
2684 assert repr(oid) == "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>"
2685 oid = x509.ObjectIdentifier("oid1")
2686 assert repr(oid) == "<ObjectIdentifier(oid=oid1, name=Unknown OID)>"
Paul Kehrer719d5362015-01-01 20:03:52 -06002687
Brendan McCollam1b3b3ce2015-08-25 10:55:44 -05002688 def test_name_property(self):
2689 oid = x509.ObjectIdentifier("2.5.4.3")
2690 assert oid._name == 'commonName'
2691 oid = x509.ObjectIdentifier("oid1")
2692 assert oid._name == 'Unknown OID'
2693
Paul Kehrer719d5362015-01-01 20:03:52 -06002694
2695class TestName(object):
2696 def test_eq(self):
2697 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002698 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2699 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002700 ])
2701 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002702 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2703 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002704 ])
2705 assert name1 == name2
2706
2707 def test_ne(self):
2708 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002709 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2710 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002711 ])
2712 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002713 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
2714 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002715 ])
2716 assert name1 != name2
2717 assert name1 != object()
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002718
2719 def test_repr(self):
2720 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002721 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2722 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002723 ])
2724
Ian Cordascoa908d692015-06-16 21:35:24 -05002725 if six.PY3:
2726 assert repr(name) == (
2727 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2728 "=commonName)>, value='cryptography.io')>, <NameAttribute(oid="
2729 "<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, valu"
2730 "e='PyCA')>])>"
2731 )
2732 else:
2733 assert repr(name) == (
2734 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2735 "=commonName)>, value=u'cryptography.io')>, <NameAttribute(oid"
2736 "=<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, val"
2737 "ue=u'PyCA')>])>"
2738 )