blob: 4072ef15dcab32428948509c63d513e63180241a [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
Paul Kehrer8b5d0942015-10-27 09:35:17 +090012from pyasn1.codec.der import decoder
13
14from pyasn1_modules import rfc2459
Paul Kehrer5a2bb542015-10-19 23:45:59 -050015
Paul Kehrer016e08a2014-11-26 09:41:18 -100016import pytest
17
Ian Cordascoa908d692015-06-16 21:35:24 -050018import six
19
Paul Kehrer474a6472015-07-11 12:29:52 -050020from cryptography import utils, x509
Paul Kehrer8802a5b2015-02-13 12:06:57 -060021from cryptography.exceptions import UnsupportedAlgorithm
Paul Kehrerf1ef3512014-11-26 17:36:05 -100022from cryptography.hazmat.backends.interfaces import (
23 DSABackend, EllipticCurveBackend, RSABackend, X509Backend
24)
Andre Caron476c5df2015-05-18 10:23:28 -040025from cryptography.hazmat.primitives import hashes, serialization
Alex Gaynor32c57df2015-02-23 21:51:27 -080026from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
Paul Kehrer9e102db2015-08-10 21:53:09 -050027from cryptography.x509.oid import (
28 AuthorityInformationAccessOID, ExtendedKeyUsageOID, ExtensionOID, NameOID
29)
Paul Kehrer016e08a2014-11-26 09:41:18 -100030
Ian Cordasco8ed8edc2015-06-22 20:11:17 -050031from .hazmat.primitives.fixtures_dsa import DSA_KEY_2048
Ian Cordasco85fc4d52015-08-01 20:29:31 -050032from .hazmat.primitives.fixtures_rsa import RSA_KEY_2048, RSA_KEY_512
Ian Cordasco4d46eb72015-06-17 12:08:27 -050033from .hazmat.primitives.test_ec import _skip_curve_unsupported
Paul Kehrera9d78c12014-11-26 10:59:03 -100034from .utils import load_vectors_from_file
Paul Kehrer016e08a2014-11-26 09:41:18 -100035
36
Paul Kehrer69b64e42015-08-09 00:00:44 -050037@utils.register_interface(x509.ExtensionType)
38class DummyExtension(object):
39 oid = x509.ObjectIdentifier("1.2.3.4")
40
41
Paul Kehrer474a6472015-07-11 12:29:52 -050042@utils.register_interface(x509.GeneralName)
43class FakeGeneralName(object):
44 def __init__(self, value):
45 self._value = value
46
47 value = utils.read_only_property("_value")
48
49
Paul Kehrer41120322014-12-02 18:31:14 -100050def _load_cert(filename, loader, backend):
Paul Kehrer016e08a2014-11-26 09:41:18 -100051 cert = load_vectors_from_file(
Paul Kehrera693cfd2014-11-27 07:47:58 -100052 filename=filename,
53 loader=lambda pemfile: loader(pemfile.read(), backend),
54 mode="rb"
Paul Kehrer016e08a2014-11-26 09:41:18 -100055 )
56 return cert
57
58
Erik Trauschkedc570402015-09-24 20:24:28 -070059@pytest.mark.requires_backend_interface(interface=X509Backend)
60class TestCertificateRevocationList(object):
61 def test_load_pem_crl(self, backend):
62 crl = _load_cert(
63 os.path.join("x509", "custom", "crl_all_reasons.pem"),
64 x509.load_pem_x509_crl,
65 backend
66 )
67
68 assert isinstance(crl, x509.CertificateRevocationList)
69 fingerprint = binascii.hexlify(crl.fingerprint(hashes.SHA1()))
70 assert fingerprint == b"3234b0cb4c0cedf6423724b736729dcfc9e441ef"
71 assert isinstance(crl.signature_hash_algorithm, hashes.SHA256)
72
73 def test_load_der_crl(self, backend):
74 crl = _load_cert(
75 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
76 x509.load_der_x509_crl,
77 backend
78 )
79
80 assert isinstance(crl, x509.CertificateRevocationList)
81 fingerprint = binascii.hexlify(crl.fingerprint(hashes.SHA1()))
82 assert fingerprint == b"dd3db63c50f4c4a13e090f14053227cb1011a5ad"
83 assert isinstance(crl.signature_hash_algorithm, hashes.SHA256)
84
85 def test_invalid_pem(self, backend):
86 with pytest.raises(ValueError):
87 x509.load_pem_x509_crl(b"notacrl", backend)
88
89 def test_invalid_der(self, backend):
90 with pytest.raises(ValueError):
91 x509.load_der_x509_crl(b"notacrl", backend)
92
93 def test_unknown_signature_algorithm(self, backend):
94 crl = _load_cert(
95 os.path.join(
96 "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
97 ),
98 x509.load_pem_x509_crl,
99 backend
100 )
101
102 with pytest.raises(UnsupportedAlgorithm):
103 crl.signature_hash_algorithm()
104
105 def test_issuer(self, backend):
106 crl = _load_cert(
107 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
108 x509.load_der_x509_crl,
109 backend
110 )
111
112 assert isinstance(crl.issuer, x509.Name)
113 assert list(crl.issuer) == [
114 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
115 x509.NameAttribute(
116 x509.OID_ORGANIZATION_NAME, u'Test Certificates 2011'
117 ),
118 x509.NameAttribute(x509.OID_COMMON_NAME, u'Good CA')
119 ]
120 assert crl.issuer.get_attributes_for_oid(x509.OID_COMMON_NAME) == [
121 x509.NameAttribute(x509.OID_COMMON_NAME, u'Good CA')
122 ]
123
124 def test_equality(self, backend):
125 crl1 = _load_cert(
126 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
127 x509.load_der_x509_crl,
128 backend
129 )
130
131 crl2 = _load_cert(
132 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
133 x509.load_der_x509_crl,
134 backend
135 )
136
137 crl3 = _load_cert(
138 os.path.join("x509", "custom", "crl_all_reasons.pem"),
139 x509.load_pem_x509_crl,
140 backend
141 )
142
143 assert crl1 == crl2
144 assert crl1 != crl3
145 assert crl1 != object()
146
147 def test_update_dates(self, backend):
148 crl = _load_cert(
149 os.path.join("x509", "custom", "crl_all_reasons.pem"),
150 x509.load_pem_x509_crl,
151 backend
152 )
153
154 assert isinstance(crl.next_update, datetime.datetime)
155 assert isinstance(crl.last_update, datetime.datetime)
156
157 assert crl.next_update.isoformat() == "2016-01-01T00:00:00"
158 assert crl.last_update.isoformat() == "2015-01-01T00:00:00"
159
Erik Trauschke77f5a252015-10-14 08:06:38 -0700160 def test_revoked_cert_retrieval(self, backend):
Erik Trauschkedc570402015-09-24 20:24:28 -0700161 crl = _load_cert(
162 os.path.join("x509", "custom", "crl_all_reasons.pem"),
163 x509.load_pem_x509_crl,
164 backend
165 )
166
Erik Trauschke77f5a252015-10-14 08:06:38 -0700167 for r in crl:
Paul Kehrer0219e662015-10-21 20:18:24 -0500168 assert isinstance(r, x509.RevokedCertificate)
Erik Trauschkedc570402015-09-24 20:24:28 -0700169
Erik Trauschke77f5a252015-10-14 08:06:38 -0700170 # Check that len() works for CRLs.
171 assert len(crl) == 12
172
Erik Trauschkedc570402015-09-24 20:24:28 -0700173 def test_extensions(self, backend):
174 crl = _load_cert(
175 os.path.join("x509", "custom", "crl_all_reasons.pem"),
176 x509.load_pem_x509_crl,
177 backend
178 )
179
180 # CRL extensions are currently not supported in the OpenSSL backend.
181 with pytest.raises(NotImplementedError):
Paul Kehrer0219e662015-10-21 20:18:24 -0500182 crl.extensions
Erik Trauschkedc570402015-09-24 20:24:28 -0700183
184
185@pytest.mark.requires_backend_interface(interface=X509Backend)
186class TestRevokedCertificate(object):
187
188 def test_revoked_basics(self, backend):
189 crl = _load_cert(
190 os.path.join("x509", "custom", "crl_all_reasons.pem"),
191 x509.load_pem_x509_crl,
192 backend
193 )
194
Erik Trauschke77f5a252015-10-14 08:06:38 -0700195 for i, rev in enumerate(crl):
Erik Trauschkedc570402015-09-24 20:24:28 -0700196 assert isinstance(rev, x509.RevokedCertificate)
197 assert isinstance(rev.serial_number, int)
198 assert isinstance(rev.revocation_date, datetime.datetime)
199 assert isinstance(rev.extensions, x509.Extensions)
200
201 assert rev.serial_number == i
202 assert rev.revocation_date.isoformat() == "2015-01-01T00:00:00"
203
204 def test_revoked_extensions(self, backend):
205 crl = _load_cert(
206 os.path.join("x509", "custom", "crl_all_reasons.pem"),
207 x509.load_pem_x509_crl,
208 backend
209 )
210
Erik Trauschked4e7d432015-10-15 14:45:38 -0700211 exp_issuer = x509.GeneralNames([
212 x509.DirectoryName(x509.Name([
213 x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
214 x509.NameAttribute(x509.OID_COMMON_NAME, u"cryptography.io"),
215 ]))
216 ])
217
Erik Trauschkedc570402015-09-24 20:24:28 -0700218 # First revoked cert doesn't have extensions, test if it is handled
219 # correctly.
Erik Trauschke77f5a252015-10-14 08:06:38 -0700220 rev0 = crl[0]
Erik Trauschkedc570402015-09-24 20:24:28 -0700221 # It should return an empty Extensions object.
222 assert isinstance(rev0.extensions, x509.Extensions)
223 assert len(rev0.extensions) == 0
224 with pytest.raises(x509.ExtensionNotFound):
225 rev0.extensions.get_extension_for_oid(x509.OID_CRL_REASON)
Erik Trauschkecee79f82015-10-21 10:48:28 -0700226 with pytest.raises(x509.ExtensionNotFound):
Erik Trauschke32bbfe02015-10-21 08:04:55 -0700227 rev0.extensions.get_extension_for_oid(x509.OID_CERTIFICATE_ISSUER)
Erik Trauschkecee79f82015-10-21 10:48:28 -0700228 with pytest.raises(x509.ExtensionNotFound):
Erik Trauschke32bbfe02015-10-21 08:04:55 -0700229 rev0.extensions.get_extension_for_oid(x509.OID_INVALIDITY_DATE)
Erik Trauschkedc570402015-09-24 20:24:28 -0700230
231 # Test manual retrieval of extension values.
Erik Trauschke77f5a252015-10-14 08:06:38 -0700232 rev1 = crl[1]
Erik Trauschkedc570402015-09-24 20:24:28 -0700233 assert isinstance(rev1.extensions, x509.Extensions)
234
235 reason = rev1.extensions.get_extension_for_oid(
236 x509.OID_CRL_REASON).value
237 assert reason == x509.ReasonFlags.unspecified
238
Erik Trauschked4e7d432015-10-15 14:45:38 -0700239 issuer = rev1.extensions.get_extension_for_oid(
240 x509.OID_CERTIFICATE_ISSUER).value
241 assert issuer == exp_issuer
242
Erik Trauschkedc570402015-09-24 20:24:28 -0700243 date = rev1.extensions.get_extension_for_oid(
244 x509.OID_INVALIDITY_DATE).value
245 assert isinstance(date, datetime.datetime)
246 assert date.isoformat() == "2015-01-01T00:00:00"
247
Erik Trauschkedc570402015-09-24 20:24:28 -0700248 # Check if all reason flags can be found in the CRL.
249 flags = set(x509.ReasonFlags)
Erik Trauschke32bbfe02015-10-21 08:04:55 -0700250 for rev in crl:
251 try:
252 r = rev.extensions.get_extension_for_oid(x509.OID_CRL_REASON)
253 except x509.ExtensionNotFound:
254 # Not all revoked certs have a reason extension.
255 pass
256 else:
257 flags.discard(r.value)
258
Erik Trauschkedc570402015-09-24 20:24:28 -0700259 assert len(flags) == 0
260
261 def test_duplicate_entry_ext(self, backend):
262 crl = _load_cert(
263 os.path.join("x509", "custom", "crl_dup_entry_ext.pem"),
264 x509.load_pem_x509_crl,
265 backend
266 )
267
268 with pytest.raises(x509.DuplicateExtension):
Erik Trauschke77f5a252015-10-14 08:06:38 -0700269 crl[0].extensions
Erik Trauschkedc570402015-09-24 20:24:28 -0700270
271 def test_unsupported_crit_entry_ext(self, backend):
272 crl = _load_cert(
273 os.path.join(
274 "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
275 ),
276 x509.load_pem_x509_crl,
277 backend
278 )
279
280 with pytest.raises(x509.UnsupportedExtension):
Erik Trauschke77f5a252015-10-14 08:06:38 -0700281 crl[0].extensions
Erik Trauschkedc570402015-09-24 20:24:28 -0700282
283 def test_unsupported_reason(self, backend):
284 crl = _load_cert(
285 os.path.join(
286 "x509", "custom", "crl_unsupported_reason.pem"
287 ),
288 x509.load_pem_x509_crl,
289 backend
290 )
291
292 with pytest.raises(ValueError):
Erik Trauschke77f5a252015-10-14 08:06:38 -0700293 crl[0].extensions
Erik Trauschkedc570402015-09-24 20:24:28 -0700294
Erik Trauschked4e7d432015-10-15 14:45:38 -0700295 def test_invalid_cert_issuer_ext(self, backend):
Erik Trauschkedc570402015-09-24 20:24:28 -0700296 crl = _load_cert(
Erik Trauschked4e7d432015-10-15 14:45:38 -0700297 os.path.join(
298 "x509", "custom", "crl_inval_cert_issuer_entry_ext.pem"
299 ),
Erik Trauschkedc570402015-09-24 20:24:28 -0700300 x509.load_pem_x509_crl,
301 backend
302 )
303
Erik Trauschked4e7d432015-10-15 14:45:38 -0700304 with pytest.raises(ValueError):
305 crl[0].extensions
Erik Trauschkedc570402015-09-24 20:24:28 -0700306
307
Paul Kehrer016e08a2014-11-26 09:41:18 -1000308@pytest.mark.requires_backend_interface(interface=RSABackend)
309@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -0600310class TestRSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000311 def test_load_pem_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000312 cert = _load_cert(
313 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000314 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000315 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000316 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600317 assert isinstance(cert, x509.Certificate)
318 assert cert.serial == 11559813051657483483
319 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
320 assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8"
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600321 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000322
323 def test_load_der_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000324 cert = _load_cert(
325 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000326 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000327 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000328 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600329 assert isinstance(cert, x509.Certificate)
330 assert cert.serial == 2
331 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
332 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600333 assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000334
Paul Kehrer719d5362015-01-01 20:03:52 -0600335 def test_issuer(self, backend):
336 cert = _load_cert(
337 os.path.join(
338 "x509", "PKITS_data", "certs",
339 "Validpre2000UTCnotBeforeDateTest3EE.crt"
340 ),
341 x509.load_der_x509_certificate,
342 backend
343 )
344 issuer = cert.issuer
345 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600346 assert list(issuer) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500347 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600348 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500349 NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -0600350 ),
Paul Kehrereba19e62015-08-10 18:44:24 -0500351 x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -0600352 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500353 assert issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
354 x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -0600355 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600356
357 def test_all_issuer_name_types(self, backend):
358 cert = _load_cert(
359 os.path.join(
360 "x509", "custom",
361 "all_supported_names.pem"
362 ),
363 x509.load_pem_x509_certificate,
364 backend
365 )
366 issuer = cert.issuer
367
368 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600369 assert list(issuer) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500370 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
371 x509.NameAttribute(NameOID.COUNTRY_NAME, u'CA'),
372 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
373 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Illinois'),
374 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Chicago'),
375 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
376 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Zero, LLC'),
377 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'One, LLC'),
378 x509.NameAttribute(NameOID.COMMON_NAME, u'common name 0'),
379 x509.NameAttribute(NameOID.COMMON_NAME, u'common name 1'),
380 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 0'),
381 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 1'),
382 x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier0'),
383 x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier1'),
384 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'123'),
385 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'456'),
386 x509.NameAttribute(NameOID.TITLE, u'Title 0'),
387 x509.NameAttribute(NameOID.TITLE, u'Title 1'),
388 x509.NameAttribute(NameOID.SURNAME, u'Surname 0'),
389 x509.NameAttribute(NameOID.SURNAME, u'Surname 1'),
390 x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 0'),
391 x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 1'),
392 x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 0'),
393 x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 1'),
394 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Last Gen'),
395 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Next Gen'),
396 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc0'),
397 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc1'),
398 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test0@test.local'),
399 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test1@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600400 ]
401
Paul Kehrer719d5362015-01-01 20:03:52 -0600402 def test_subject(self, backend):
403 cert = _load_cert(
404 os.path.join(
405 "x509", "PKITS_data", "certs",
406 "Validpre2000UTCnotBeforeDateTest3EE.crt"
407 ),
408 x509.load_der_x509_certificate,
409 backend
410 )
411 subject = cert.subject
412 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600413 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500414 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600415 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500416 NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -0600417 ),
418 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500419 NameOID.COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500420 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600421 )
422 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500423 assert subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600424 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500425 NameOID.COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500426 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600427 )
428 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600429
430 def test_unicode_name(self, backend):
431 cert = _load_cert(
432 os.path.join(
433 "x509", "custom",
434 "utf8_common_name.pem"
435 ),
436 x509.load_pem_x509_certificate,
437 backend
438 )
Paul Kehrereba19e62015-08-10 18:44:24 -0500439 assert cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600440 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500441 NameOID.COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530442 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600443 )
444 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500445 assert cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600446 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500447 NameOID.COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530448 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600449 )
450 ]
451
452 def test_all_subject_name_types(self, backend):
453 cert = _load_cert(
454 os.path.join(
455 "x509", "custom",
456 "all_supported_names.pem"
457 ),
458 x509.load_pem_x509_certificate,
459 backend
460 )
461 subject = cert.subject
462 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600463 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500464 x509.NameAttribute(NameOID.COUNTRY_NAME, u'AU'),
465 x509.NameAttribute(NameOID.COUNTRY_NAME, u'DE'),
466 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'California'),
467 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'New York'),
468 x509.NameAttribute(NameOID.LOCALITY_NAME, u'San Francisco'),
469 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Ithaca'),
470 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org Zero, LLC'),
471 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org One, LLC'),
472 x509.NameAttribute(NameOID.COMMON_NAME, u'CN 0'),
473 x509.NameAttribute(NameOID.COMMON_NAME, u'CN 1'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600474 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500475 NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 0'
Paul Kehrer719d5362015-01-01 20:03:52 -0600476 ),
477 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500478 NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 1'
Paul Kehrer719d5362015-01-01 20:03:52 -0600479 ),
Paul Kehrereba19e62015-08-10 18:44:24 -0500480 x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified0'),
481 x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified1'),
482 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'789'),
483 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'012'),
484 x509.NameAttribute(NameOID.TITLE, u'Title IX'),
485 x509.NameAttribute(NameOID.TITLE, u'Title X'),
486 x509.NameAttribute(NameOID.SURNAME, u'Last 0'),
487 x509.NameAttribute(NameOID.SURNAME, u'Last 1'),
488 x509.NameAttribute(NameOID.GIVEN_NAME, u'First 0'),
489 x509.NameAttribute(NameOID.GIVEN_NAME, u'First 1'),
490 x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 0'),
491 x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 1'),
492 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'32X'),
493 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Dreamcast'),
494 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc2'),
495 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc3'),
496 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test2@test.local'),
497 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test3@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600498 ]
499
Paul Kehrer016e08a2014-11-26 09:41:18 -1000500 def test_load_good_ca_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000501 cert = _load_cert(
502 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000503 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000504 backend
505 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000506
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600507 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
508 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrer016e08a2014-11-26 09:41:18 -1000509 assert cert.serial == 2
510 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -0800511 assert isinstance(public_key, rsa.RSAPublicKey)
Paul Kehrere76cd272014-12-14 19:00:51 -0600512 assert cert.version is x509.Version.v3
Paul Kehrer0307c372014-11-27 09:49:31 -1000513 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
Paul Kehrer4e1db792014-11-27 10:50:55 -1000514 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer016e08a2014-11-26 09:41:18 -1000515
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000516 def test_utc_pre_2000_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000517 cert = _load_cert(
518 os.path.join(
519 "x509", "PKITS_data", "certs",
520 "Validpre2000UTCnotBeforeDateTest3EE.crt"
521 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000522 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000523 backend
524 )
525
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600526 assert cert.not_valid_before == datetime.datetime(1950, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000527
528 def test_pre_2000_utc_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000529 cert = _load_cert(
530 os.path.join(
531 "x509", "PKITS_data", "certs",
532 "Invalidpre2000UTCEEnotAfterDateTest7EE.crt"
533 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000534 x509.load_der_x509_certificate,
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000535 backend
536 )
537
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600538 assert cert.not_valid_after == datetime.datetime(1999, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000539
540 def test_post_2000_utc_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000541 cert = _load_cert(
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000542 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000543 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000544 backend
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000545 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600546 assert cert.not_valid_before == datetime.datetime(
547 2014, 11, 26, 21, 41, 20
548 )
549 assert cert.not_valid_after == datetime.datetime(
550 2014, 12, 26, 21, 41, 20
551 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000552
553 def test_generalized_time_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000554 cert = _load_cert(
555 os.path.join(
556 "x509", "PKITS_data", "certs",
557 "ValidGeneralizedTimenotBeforeDateTest4EE.crt"
558 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000559 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000560 backend
561 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600562 assert cert.not_valid_before == datetime.datetime(2002, 1, 1, 12, 1)
563 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrere76cd272014-12-14 19:00:51 -0600564 assert cert.version is x509.Version.v3
Paul Kehrer016e08a2014-11-26 09:41:18 -1000565
566 def test_generalized_time_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000567 cert = _load_cert(
568 os.path.join(
569 "x509", "PKITS_data", "certs",
570 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
571 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000572 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000573 backend
574 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600575 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
576 assert cert.not_valid_after == datetime.datetime(2050, 1, 1, 12, 1)
Paul Kehrere76cd272014-12-14 19:00:51 -0600577 assert cert.version is x509.Version.v3
Paul Kehrera9d78c12014-11-26 10:59:03 -1000578
579 def test_invalid_version_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000580 cert = _load_cert(
Paul Kehrera9d78c12014-11-26 10:59:03 -1000581 os.path.join("x509", "custom", "invalid_version.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000582 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000583 backend
Paul Kehrera9d78c12014-11-26 10:59:03 -1000584 )
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600585 with pytest.raises(x509.InvalidVersion) as exc:
Paul Kehrera9d78c12014-11-26 10:59:03 -1000586 cert.version
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000587
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600588 assert exc.value.parsed_version == 7
589
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -0500590 def test_eq(self, backend):
591 cert = _load_cert(
592 os.path.join("x509", "custom", "post2000utctime.pem"),
593 x509.load_pem_x509_certificate,
594 backend
595 )
596 cert2 = _load_cert(
597 os.path.join("x509", "custom", "post2000utctime.pem"),
598 x509.load_pem_x509_certificate,
599 backend
600 )
601 assert cert == cert2
602
603 def test_ne(self, backend):
604 cert = _load_cert(
605 os.path.join("x509", "custom", "post2000utctime.pem"),
606 x509.load_pem_x509_certificate,
607 backend
608 )
609 cert2 = _load_cert(
610 os.path.join(
611 "x509", "PKITS_data", "certs",
612 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
613 ),
614 x509.load_der_x509_certificate,
615 backend
616 )
617 assert cert != cert2
618 assert cert != object()
619
Alex Gaynor969f3a52015-07-06 18:52:41 -0400620 def test_hash(self, backend):
621 cert1 = _load_cert(
622 os.path.join("x509", "custom", "post2000utctime.pem"),
623 x509.load_pem_x509_certificate,
624 backend
625 )
626 cert2 = _load_cert(
627 os.path.join("x509", "custom", "post2000utctime.pem"),
628 x509.load_pem_x509_certificate,
629 backend
630 )
631 cert3 = _load_cert(
632 os.path.join(
633 "x509", "PKITS_data", "certs",
634 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
635 ),
636 x509.load_der_x509_certificate,
637 backend
638 )
639
640 assert hash(cert1) == hash(cert2)
641 assert hash(cert1) != hash(cert3)
642
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000643 def test_version_1_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000644 cert = _load_cert(
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000645 os.path.join("x509", "v1_cert.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000646 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000647 backend
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000648 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600649 assert cert.version is x509.Version.v1
Paul Kehrer7638c312014-11-26 11:13:31 -1000650
651 def test_invalid_pem(self, backend):
652 with pytest.raises(ValueError):
653 x509.load_pem_x509_certificate(b"notacert", backend)
654
655 def test_invalid_der(self, backend):
656 with pytest.raises(ValueError):
657 x509.load_der_x509_certificate(b"notacert", backend)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000658
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600659 def test_unsupported_signature_hash_algorithm_cert(self, backend):
660 cert = _load_cert(
661 os.path.join("x509", "verisign_md2_root.pem"),
662 x509.load_pem_x509_certificate,
663 backend
664 )
665 with pytest.raises(UnsupportedAlgorithm):
666 cert.signature_hash_algorithm
667
Andre Carona8aded62015-05-19 20:11:57 -0400668 def test_public_bytes_pem(self, backend):
669 # Load an existing certificate.
670 cert = _load_cert(
671 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
672 x509.load_der_x509_certificate,
673 backend
674 )
675
676 # Encode it to PEM and load it back.
677 cert = x509.load_pem_x509_certificate(cert.public_bytes(
678 encoding=serialization.Encoding.PEM,
679 ), backend)
680
681 # We should recover what we had to start with.
682 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
683 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
684 assert cert.serial == 2
685 public_key = cert.public_key()
686 assert isinstance(public_key, rsa.RSAPublicKey)
687 assert cert.version is x509.Version.v3
688 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
689 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
690
691 def test_public_bytes_der(self, backend):
692 # Load an existing certificate.
693 cert = _load_cert(
694 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
695 x509.load_der_x509_certificate,
696 backend
697 )
698
699 # Encode it to DER and load it back.
700 cert = x509.load_der_x509_certificate(cert.public_bytes(
701 encoding=serialization.Encoding.DER,
702 ), backend)
703
704 # We should recover what we had to start with.
705 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
706 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
707 assert cert.serial == 2
708 public_key = cert.public_key()
709 assert isinstance(public_key, rsa.RSAPublicKey)
710 assert cert.version is x509.Version.v3
711 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
712 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
713
714 def test_public_bytes_invalid_encoding(self, backend):
715 cert = _load_cert(
716 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
717 x509.load_der_x509_certificate,
718 backend
719 )
720
721 with pytest.raises(TypeError):
722 cert.public_bytes('NotAnEncoding')
723
724 @pytest.mark.parametrize(
725 ("cert_path", "loader_func", "encoding"),
726 [
727 (
728 os.path.join("x509", "v1_cert.pem"),
729 x509.load_pem_x509_certificate,
730 serialization.Encoding.PEM,
731 ),
732 (
733 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
734 x509.load_der_x509_certificate,
735 serialization.Encoding.DER,
736 ),
737 ]
738 )
739 def test_public_bytes_match(self, cert_path, loader_func, encoding,
740 backend):
741 cert_bytes = load_vectors_from_file(
742 cert_path, lambda pemfile: pemfile.read(), mode="rb"
743 )
744 cert = loader_func(cert_bytes, backend)
745 serialized = cert.public_bytes(encoding)
746 assert serialized == cert_bytes
747
Major Haydenf315af22015-06-17 14:02:26 -0500748 def test_certificate_repr(self, backend):
749 cert = _load_cert(
750 os.path.join(
751 "x509", "cryptography.io.pem"
752 ),
753 x509.load_pem_x509_certificate,
754 backend
755 )
756 if six.PY3:
757 assert repr(cert) == (
758 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
759 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value='GT487"
760 "42965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11, "
761 "name=organizationalUnitName)>, value='See www.rapidssl.com/re"
762 "sources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier(oi"
763 "d=2.5.4.11, name=organizationalUnitName)>, value='Domain Cont"
764 "rol Validated - RapidSSL(R)')>, <NameAttribute(oid=<ObjectIde"
765 "ntifier(oid=2.5.4.3, name=commonName)>, value='www.cryptograp"
766 "hy.io')>])>, ...)>"
767 )
768 else:
769 assert repr(cert) == (
770 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
771 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value=u'GT48"
772 "742965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11,"
773 " name=organizationalUnitName)>, value=u'See www.rapidssl.com/"
774 "resources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier("
775 "oid=2.5.4.11, name=organizationalUnitName)>, value=u'Domain C"
776 "ontrol Validated - RapidSSL(R)')>, <NameAttribute(oid=<Object"
777 "Identifier(oid=2.5.4.3, name=commonName)>, value=u'www.crypto"
778 "graphy.io')>])>, ...)>"
779 )
780
Andre Carona8aded62015-05-19 20:11:57 -0400781
782@pytest.mark.requires_backend_interface(interface=RSABackend)
783@pytest.mark.requires_backend_interface(interface=X509Backend)
784class TestRSACertificateRequest(object):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500785 @pytest.mark.parametrize(
786 ("path", "loader_func"),
787 [
788 [
789 os.path.join("x509", "requests", "rsa_sha1.pem"),
790 x509.load_pem_x509_csr
791 ],
792 [
793 os.path.join("x509", "requests", "rsa_sha1.der"),
794 x509.load_der_x509_csr
795 ],
796 ]
797 )
798 def test_load_rsa_certificate_request(self, path, loader_func, backend):
799 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600800 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
801 public_key = request.public_key()
802 assert isinstance(public_key, rsa.RSAPublicKey)
803 subject = request.subject
804 assert isinstance(subject, x509.Name)
805 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500806 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
807 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
808 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
809 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
810 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600811 ]
Andre Caron6e721a92015-05-17 15:08:48 -0400812 extensions = request.extensions
813 assert isinstance(extensions, x509.Extensions)
814 assert list(extensions) == []
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600815
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500816 @pytest.mark.parametrize(
817 "loader_func",
818 [x509.load_pem_x509_csr, x509.load_der_x509_csr]
819 )
820 def test_invalid_certificate_request(self, loader_func, backend):
Paul Kehrerb759e292015-03-17 07:34:41 -0500821 with pytest.raises(ValueError):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500822 loader_func(b"notacsr", backend)
Paul Kehrerb759e292015-03-17 07:34:41 -0500823
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600824 def test_unsupported_signature_hash_algorithm_request(self, backend):
825 request = _load_cert(
826 os.path.join("x509", "requests", "rsa_md4.pem"),
Paul Kehrer31e39882015-03-11 11:37:04 -0500827 x509.load_pem_x509_csr,
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600828 backend
829 )
830 with pytest.raises(UnsupportedAlgorithm):
831 request.signature_hash_algorithm
832
Andre Caron6e721a92015-05-17 15:08:48 -0400833 def test_duplicate_extension(self, backend):
834 request = _load_cert(
835 os.path.join(
836 "x509", "requests", "two_basic_constraints.pem"
837 ),
838 x509.load_pem_x509_csr,
839 backend
840 )
841 with pytest.raises(x509.DuplicateExtension) as exc:
842 request.extensions
843
Paul Kehrerd44e4132015-08-10 19:13:13 -0500844 assert exc.value.oid == ExtensionOID.BASIC_CONSTRAINTS
Andre Caron6e721a92015-05-17 15:08:48 -0400845
846 def test_unsupported_critical_extension(self, backend):
847 request = _load_cert(
848 os.path.join(
849 "x509", "requests", "unsupported_extension_critical.pem"
850 ),
851 x509.load_pem_x509_csr,
852 backend
853 )
854 with pytest.raises(x509.UnsupportedExtension) as exc:
855 request.extensions
856
857 assert exc.value.oid == x509.ObjectIdentifier('1.2.3.4')
858
859 def test_unsupported_extension(self, backend):
860 request = _load_cert(
861 os.path.join(
862 "x509", "requests", "unsupported_extension.pem"
863 ),
864 x509.load_pem_x509_csr,
865 backend
866 )
867 extensions = request.extensions
868 assert len(extensions) == 0
869
870 def test_request_basic_constraints(self, backend):
871 request = _load_cert(
872 os.path.join(
873 "x509", "requests", "basic_constraints.pem"
874 ),
875 x509.load_pem_x509_csr,
876 backend
877 )
878 extensions = request.extensions
879 assert isinstance(extensions, x509.Extensions)
880 assert list(extensions) == [
881 x509.Extension(
Paul Kehrerd44e4132015-08-10 19:13:13 -0500882 ExtensionOID.BASIC_CONSTRAINTS,
Andre Caron6e721a92015-05-17 15:08:48 -0400883 True,
Ian Cordasco0112b022015-06-16 17:51:18 -0500884 x509.BasicConstraints(ca=True, path_length=1),
Andre Caron6e721a92015-05-17 15:08:48 -0400885 ),
886 ]
887
Alex Gaynor37b82df2015-07-03 10:26:37 -0400888 def test_subject_alt_name(self, backend):
889 request = _load_cert(
890 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
891 x509.load_pem_x509_csr,
892 backend,
893 )
894 ext = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -0500895 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynor37b82df2015-07-03 10:26:37 -0400896 )
897 assert list(ext.value) == [
898 x509.DNSName(u"cryptography.io"),
899 x509.DNSName(u"sub.cryptography.io"),
900 ]
901
Andre Caronf27e4f42015-05-18 17:54:59 -0400902 def test_public_bytes_pem(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400903 # Load an existing CSR.
904 request = _load_cert(
905 os.path.join("x509", "requests", "rsa_sha1.pem"),
906 x509.load_pem_x509_csr,
907 backend
908 )
909
910 # Encode it to PEM and load it back.
911 request = x509.load_pem_x509_csr(request.public_bytes(
912 encoding=serialization.Encoding.PEM,
913 ), backend)
914
915 # We should recover what we had to start with.
916 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
917 public_key = request.public_key()
918 assert isinstance(public_key, rsa.RSAPublicKey)
919 subject = request.subject
920 assert isinstance(subject, x509.Name)
921 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500922 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
923 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
924 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
925 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
926 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400927 ]
928
Andre Caronf27e4f42015-05-18 17:54:59 -0400929 def test_public_bytes_der(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400930 # Load an existing CSR.
931 request = _load_cert(
932 os.path.join("x509", "requests", "rsa_sha1.pem"),
933 x509.load_pem_x509_csr,
934 backend
935 )
936
937 # Encode it to DER and load it back.
938 request = x509.load_der_x509_csr(request.public_bytes(
939 encoding=serialization.Encoding.DER,
940 ), backend)
941
942 # We should recover what we had to start with.
943 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
944 public_key = request.public_key()
945 assert isinstance(public_key, rsa.RSAPublicKey)
946 subject = request.subject
947 assert isinstance(subject, x509.Name)
948 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500949 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
950 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
951 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
952 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
953 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400954 ]
955
Andre Caronf27e4f42015-05-18 17:54:59 -0400956 def test_public_bytes_invalid_encoding(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400957 request = _load_cert(
958 os.path.join("x509", "requests", "rsa_sha1.pem"),
959 x509.load_pem_x509_csr,
960 backend
961 )
962
963 with pytest.raises(TypeError):
964 request.public_bytes('NotAnEncoding')
965
Andre Caronacb18972015-05-18 21:04:15 -0400966 @pytest.mark.parametrize(
967 ("request_path", "loader_func", "encoding"),
968 [
969 (
970 os.path.join("x509", "requests", "rsa_sha1.pem"),
971 x509.load_pem_x509_csr,
972 serialization.Encoding.PEM,
973 ),
974 (
975 os.path.join("x509", "requests", "rsa_sha1.der"),
976 x509.load_der_x509_csr,
977 serialization.Encoding.DER,
978 ),
979 ]
980 )
981 def test_public_bytes_match(self, request_path, loader_func, encoding,
982 backend):
983 request_bytes = load_vectors_from_file(
984 request_path, lambda pemfile: pemfile.read(), mode="rb"
985 )
986 request = loader_func(request_bytes, backend)
987 serialized = request.public_bytes(encoding)
988 assert serialized == request_bytes
989
Alex Gaynor70c8f8b2015-07-06 21:02:54 -0400990 def test_eq(self, backend):
991 request1 = _load_cert(
992 os.path.join("x509", "requests", "rsa_sha1.pem"),
993 x509.load_pem_x509_csr,
994 backend
995 )
996 request2 = _load_cert(
997 os.path.join("x509", "requests", "rsa_sha1.pem"),
998 x509.load_pem_x509_csr,
999 backend
1000 )
1001
1002 assert request1 == request2
1003
1004 def test_ne(self, backend):
1005 request1 = _load_cert(
1006 os.path.join("x509", "requests", "rsa_sha1.pem"),
1007 x509.load_pem_x509_csr,
1008 backend
1009 )
1010 request2 = _load_cert(
Alex Gaynoreb2df542015-07-06 21:50:15 -04001011 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001012 x509.load_pem_x509_csr,
1013 backend
1014 )
1015
1016 assert request1 != request2
1017 assert request1 != object()
1018
Alex Gaynor978137d2015-07-08 20:59:16 -04001019 def test_hash(self, backend):
1020 request1 = _load_cert(
1021 os.path.join("x509", "requests", "rsa_sha1.pem"),
1022 x509.load_pem_x509_csr,
1023 backend
1024 )
1025 request2 = _load_cert(
1026 os.path.join("x509", "requests", "rsa_sha1.pem"),
1027 x509.load_pem_x509_csr,
1028 backend
1029 )
1030 request3 = _load_cert(
1031 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
1032 x509.load_pem_x509_csr,
1033 backend
1034 )
1035
1036 assert hash(request1) == hash(request2)
1037 assert hash(request1) != hash(request3)
1038
Andre Caron9bbfcea2015-05-18 20:55:29 -04001039 def test_build_cert(self, backend):
Ian Cordascoe4e52a42015-07-19 10:15:37 -05001040 issuer_private_key = RSA_KEY_2048.private_key(backend)
1041 subject_private_key = RSA_KEY_2048.private_key(backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001042
Andre Caron9bbfcea2015-05-18 20:55:29 -04001043 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1044 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
Ian Cordascob3ed4842015-07-01 22:46:03 -05001045
Ian Cordasco893246f2015-07-24 14:52:18 -05001046 builder = x509.CertificateBuilder().serial_number(
Ian Cordascob3ed4842015-07-01 22:46:03 -05001047 777
1048 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001049 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1050 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1051 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1052 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1053 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -05001054 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001055 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1056 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1057 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1058 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1059 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -05001060 ])).public_key(
1061 subject_private_key.public_key()
1062 ).add_extension(
Ian Cordasco8887a572015-07-19 10:26:59 -05001063 x509.BasicConstraints(ca=False, path_length=None), True,
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001064 ).add_extension(
1065 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1066 critical=False,
Ian Cordascob3ed4842015-07-01 22:46:03 -05001067 ).not_valid_before(
1068 not_valid_before
1069 ).not_valid_after(
1070 not_valid_after
1071 )
1072
Paul Kehrer9add80e2015-08-03 17:53:14 +01001073 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001074
1075 assert cert.version is x509.Version.v3
1076 assert cert.not_valid_before == not_valid_before
1077 assert cert.not_valid_after == not_valid_after
1078 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001079 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron9bbfcea2015-05-18 20:55:29 -04001080 )
1081 assert basic_constraints.value.ca is False
1082 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001083 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001084 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001085 )
1086 assert list(subject_alternative_name.value) == [
1087 x509.DNSName(u"cryptography.io"),
1088 ]
Andre Caron9bbfcea2015-05-18 20:55:29 -04001089
Paul Kehrer5a2bb542015-10-19 23:45:59 -05001090 def test_build_cert_printable_string_country_name(self, backend):
1091 issuer_private_key = RSA_KEY_2048.private_key(backend)
1092 subject_private_key = RSA_KEY_2048.private_key(backend)
1093
1094 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1095 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1096
1097 builder = x509.CertificateBuilder().serial_number(
1098 777
1099 ).issuer_name(x509.Name([
1100 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1101 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1102 ])).subject_name(x509.Name([
1103 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1104 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1105 ])).public_key(
1106 subject_private_key.public_key()
1107 ).not_valid_before(
1108 not_valid_before
1109 ).not_valid_after(
1110 not_valid_after
1111 )
1112
1113 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
1114
Paul Kehrer8b5d0942015-10-27 09:35:17 +09001115 parsed, _ = decoder.decode(
1116 cert.public_bytes(serialization.Encoding.DER),
1117 asn1Spec=rfc2459.Certificate()
Paul Kehrer5a2bb542015-10-19 23:45:59 -05001118 )
Paul Kehrer8b5d0942015-10-27 09:35:17 +09001119 tbs_cert = parsed.getComponentByName('tbsCertificate')
1120 subject = tbs_cert.getComponentByName('subject')
1121 issuer = tbs_cert.getComponentByName('issuer')
1122 # \x13 is printable string. The first byte of the value of the
1123 # node corresponds to the ASN.1 string type.
Paul Kehrer225a08f2015-10-27 10:51:00 +09001124 assert subject[0][0][0][1][0] == b"\x13"[0]
1125 assert issuer[0][0][0][1][0] == b"\x13"[0]
Paul Kehrer5a2bb542015-10-19 23:45:59 -05001126
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001127
Ian Cordasco747a2172015-07-19 11:00:14 -05001128class TestCertificateBuilder(object):
Paul Kehrer25f19222015-08-04 23:05:09 +01001129 @pytest.mark.requires_backend_interface(interface=RSABackend)
1130 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrera03c3252015-08-09 10:59:29 -05001131 def test_checks_for_unsupported_extensions(self, backend):
1132 private_key = RSA_KEY_2048.private_key(backend)
1133 builder = x509.CertificateBuilder().subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001134 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera03c3252015-08-09 10:59:29 -05001135 ])).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001136 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera03c3252015-08-09 10:59:29 -05001137 ])).public_key(
1138 private_key.public_key()
1139 ).serial_number(
1140 777
1141 ).not_valid_before(
1142 datetime.datetime(1999, 1, 1)
1143 ).not_valid_after(
1144 datetime.datetime(2020, 1, 1)
1145 ).add_extension(
1146 DummyExtension(), False
1147 )
1148
1149 with pytest.raises(NotImplementedError):
1150 builder.sign(private_key, hashes.SHA1(), backend)
1151
1152 @pytest.mark.requires_backend_interface(interface=RSABackend)
1153 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer25f19222015-08-04 23:05:09 +01001154 def test_no_subject_name(self, backend):
1155 subject_private_key = RSA_KEY_2048.private_key(backend)
1156 builder = x509.CertificateBuilder().serial_number(
1157 777
1158 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001159 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001160 ])).public_key(
1161 subject_private_key.public_key()
1162 ).not_valid_before(
1163 datetime.datetime(2002, 1, 1, 12, 1)
1164 ).not_valid_after(
1165 datetime.datetime(2030, 12, 31, 8, 30)
1166 )
1167 with pytest.raises(ValueError):
1168 builder.sign(subject_private_key, hashes.SHA256(), backend)
1169
1170 @pytest.mark.requires_backend_interface(interface=RSABackend)
1171 @pytest.mark.requires_backend_interface(interface=X509Backend)
1172 def test_no_issuer_name(self, backend):
1173 subject_private_key = RSA_KEY_2048.private_key(backend)
1174 builder = x509.CertificateBuilder().serial_number(
1175 777
1176 ).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001177 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001178 ])).public_key(
1179 subject_private_key.public_key()
1180 ).not_valid_before(
1181 datetime.datetime(2002, 1, 1, 12, 1)
1182 ).not_valid_after(
1183 datetime.datetime(2030, 12, 31, 8, 30)
1184 )
1185 with pytest.raises(ValueError):
1186 builder.sign(subject_private_key, hashes.SHA256(), backend)
1187
1188 @pytest.mark.requires_backend_interface(interface=RSABackend)
1189 @pytest.mark.requires_backend_interface(interface=X509Backend)
1190 def test_no_public_key(self, backend):
1191 subject_private_key = RSA_KEY_2048.private_key(backend)
1192 builder = x509.CertificateBuilder().serial_number(
1193 777
1194 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001195 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001196 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001197 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001198 ])).not_valid_before(
1199 datetime.datetime(2002, 1, 1, 12, 1)
1200 ).not_valid_after(
1201 datetime.datetime(2030, 12, 31, 8, 30)
1202 )
1203 with pytest.raises(ValueError):
1204 builder.sign(subject_private_key, hashes.SHA256(), backend)
1205
1206 @pytest.mark.requires_backend_interface(interface=RSABackend)
1207 @pytest.mark.requires_backend_interface(interface=X509Backend)
1208 def test_no_not_valid_before(self, backend):
1209 subject_private_key = RSA_KEY_2048.private_key(backend)
1210 builder = x509.CertificateBuilder().serial_number(
1211 777
1212 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001213 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001214 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001215 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001216 ])).public_key(
1217 subject_private_key.public_key()
1218 ).not_valid_after(
1219 datetime.datetime(2030, 12, 31, 8, 30)
1220 )
1221 with pytest.raises(ValueError):
1222 builder.sign(subject_private_key, hashes.SHA256(), backend)
1223
1224 @pytest.mark.requires_backend_interface(interface=RSABackend)
1225 @pytest.mark.requires_backend_interface(interface=X509Backend)
1226 def test_no_not_valid_after(self, backend):
1227 subject_private_key = RSA_KEY_2048.private_key(backend)
1228 builder = x509.CertificateBuilder().serial_number(
1229 777
1230 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001231 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001232 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001233 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001234 ])).public_key(
1235 subject_private_key.public_key()
1236 ).not_valid_before(
1237 datetime.datetime(2002, 1, 1, 12, 1)
1238 )
1239 with pytest.raises(ValueError):
1240 builder.sign(subject_private_key, hashes.SHA256(), backend)
1241
1242 @pytest.mark.requires_backend_interface(interface=RSABackend)
1243 @pytest.mark.requires_backend_interface(interface=X509Backend)
1244 def test_no_serial_number(self, backend):
1245 subject_private_key = RSA_KEY_2048.private_key(backend)
1246 builder = x509.CertificateBuilder().issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001247 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001248 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001249 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +01001250 ])).public_key(
1251 subject_private_key.public_key()
1252 ).not_valid_before(
1253 datetime.datetime(2002, 1, 1, 12, 1)
1254 ).not_valid_after(
1255 datetime.datetime(2030, 12, 31, 8, 30)
1256 )
1257 with pytest.raises(ValueError):
1258 builder.sign(subject_private_key, hashes.SHA256(), backend)
1259
Ian Cordasco747a2172015-07-19 11:00:14 -05001260 def test_issuer_name_must_be_a_name_type(self):
1261 builder = x509.CertificateBuilder()
1262
1263 with pytest.raises(TypeError):
1264 builder.issuer_name("subject")
1265
1266 with pytest.raises(TypeError):
1267 builder.issuer_name(object)
1268
1269 def test_issuer_name_may_only_be_set_once(self):
1270 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001271 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -05001272 ])
1273 builder = x509.CertificateBuilder().issuer_name(name)
1274
1275 with pytest.raises(ValueError):
1276 builder.issuer_name(name)
1277
1278 def test_subject_name_must_be_a_name_type(self):
1279 builder = x509.CertificateBuilder()
1280
1281 with pytest.raises(TypeError):
1282 builder.subject_name("subject")
1283
1284 with pytest.raises(TypeError):
1285 builder.subject_name(object)
1286
1287 def test_subject_name_may_only_be_set_once(self):
1288 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001289 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -05001290 ])
1291 builder = x509.CertificateBuilder().subject_name(name)
1292
1293 with pytest.raises(ValueError):
1294 builder.subject_name(name)
1295
1296 @pytest.mark.requires_backend_interface(interface=RSABackend)
1297 @pytest.mark.requires_backend_interface(interface=X509Backend)
1298 def test_public_key_must_be_public_key(self, backend):
1299 private_key = RSA_KEY_2048.private_key(backend)
1300 builder = x509.CertificateBuilder()
1301
1302 with pytest.raises(TypeError):
1303 builder.public_key(private_key)
1304
1305 @pytest.mark.requires_backend_interface(interface=RSABackend)
1306 @pytest.mark.requires_backend_interface(interface=X509Backend)
1307 def test_public_key_may_only_be_set_once(self, backend):
1308 private_key = RSA_KEY_2048.private_key(backend)
1309 public_key = private_key.public_key()
1310 builder = x509.CertificateBuilder().public_key(public_key)
1311
1312 with pytest.raises(ValueError):
1313 builder.public_key(public_key)
1314
1315 def test_serial_number_must_be_an_integer_type(self):
1316 with pytest.raises(TypeError):
1317 x509.CertificateBuilder().serial_number(10.0)
1318
Ian Cordascob4a155d2015-08-01 23:07:19 -05001319 def test_serial_number_must_be_non_negative(self):
1320 with pytest.raises(ValueError):
1321 x509.CertificateBuilder().serial_number(-10)
1322
1323 def test_serial_number_must_be_less_than_160_bits_long(self):
1324 with pytest.raises(ValueError):
1325 # 2 raised to the 160th power is actually 161 bits
1326 x509.CertificateBuilder().serial_number(2 ** 160)
1327
Ian Cordasco747a2172015-07-19 11:00:14 -05001328 def test_serial_number_may_only_be_set_once(self):
1329 builder = x509.CertificateBuilder().serial_number(10)
1330
1331 with pytest.raises(ValueError):
1332 builder.serial_number(20)
1333
1334 def test_invalid_not_valid_after(self):
1335 with pytest.raises(TypeError):
1336 x509.CertificateBuilder().not_valid_after(104204304504)
1337
1338 with pytest.raises(TypeError):
1339 x509.CertificateBuilder().not_valid_after(datetime.time())
1340
Ian Cordascob4a155d2015-08-01 23:07:19 -05001341 with pytest.raises(ValueError):
1342 x509.CertificateBuilder().not_valid_after(
1343 datetime.datetime(1960, 8, 10)
1344 )
1345
Ian Cordasco747a2172015-07-19 11:00:14 -05001346 def test_not_valid_after_may_only_be_set_once(self):
1347 builder = x509.CertificateBuilder().not_valid_after(
1348 datetime.datetime.now()
1349 )
1350
1351 with pytest.raises(ValueError):
1352 builder.not_valid_after(
1353 datetime.datetime.now()
1354 )
1355
1356 def test_invalid_not_valid_before(self):
1357 with pytest.raises(TypeError):
1358 x509.CertificateBuilder().not_valid_before(104204304504)
1359
1360 with pytest.raises(TypeError):
1361 x509.CertificateBuilder().not_valid_before(datetime.time())
1362
Ian Cordascob4a155d2015-08-01 23:07:19 -05001363 with pytest.raises(ValueError):
1364 x509.CertificateBuilder().not_valid_before(
1365 datetime.datetime(1960, 8, 10)
1366 )
1367
Ian Cordasco747a2172015-07-19 11:00:14 -05001368 def test_not_valid_before_may_only_be_set_once(self):
1369 builder = x509.CertificateBuilder().not_valid_before(
1370 datetime.datetime.now()
1371 )
1372
1373 with pytest.raises(ValueError):
1374 builder.not_valid_before(
1375 datetime.datetime.now()
1376 )
1377
1378 def test_add_extension_checks_for_duplicates(self):
1379 builder = x509.CertificateBuilder().add_extension(
1380 x509.BasicConstraints(ca=False, path_length=None), True,
1381 )
1382
1383 with pytest.raises(ValueError):
1384 builder.add_extension(
1385 x509.BasicConstraints(ca=False, path_length=None), True,
1386 )
1387
Paul Kehrer08f950e2015-08-08 22:14:42 -05001388 def test_add_invalid_extension_type(self):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001389 builder = x509.CertificateBuilder()
1390
Paul Kehrer08f950e2015-08-08 22:14:42 -05001391 with pytest.raises(TypeError):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001392 builder.add_extension(object(), False)
1393
Ian Cordascob77c7162015-07-20 21:22:33 -05001394 @pytest.mark.requires_backend_interface(interface=RSABackend)
1395 @pytest.mark.requires_backend_interface(interface=X509Backend)
1396 def test_sign_with_unsupported_hash(self, backend):
1397 private_key = RSA_KEY_2048.private_key(backend)
1398 builder = x509.CertificateBuilder()
Paul Kehrer25f19222015-08-04 23:05:09 +01001399 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001400 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer25f19222015-08-04 23:05:09 +01001401 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001402 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer25f19222015-08-04 23:05:09 +01001403 ).serial_number(
1404 1
1405 ).public_key(
1406 private_key.public_key()
1407 ).not_valid_before(
1408 datetime.datetime(2002, 1, 1, 12, 1)
1409 ).not_valid_after(
1410 datetime.datetime(2032, 1, 1, 12, 1)
1411 )
Ian Cordascob77c7162015-07-20 21:22:33 -05001412
1413 with pytest.raises(TypeError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001414 builder.sign(private_key, object(), backend)
Ian Cordascob77c7162015-07-20 21:22:33 -05001415
Ian Cordasco56561b12015-07-24 16:38:50 -05001416 @pytest.mark.requires_backend_interface(interface=DSABackend)
1417 @pytest.mark.requires_backend_interface(interface=X509Backend)
1418 def test_sign_with_dsa_private_key_is_unsupported(self, backend):
1419 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1420 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1421
1422 private_key = DSA_KEY_2048.private_key(backend)
1423 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001424 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001425 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001426 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001427 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001428 ).serial_number(
1429 1
1430 ).public_key(
1431 private_key.public_key()
1432 ).not_valid_before(
1433 datetime.datetime(2002, 1, 1, 12, 1)
1434 ).not_valid_after(
1435 datetime.datetime(2032, 1, 1, 12, 1)
1436 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001437
1438 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001439 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001440
1441 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1442 @pytest.mark.requires_backend_interface(interface=X509Backend)
1443 def test_sign_with_ec_private_key_is_unsupported(self, backend):
1444 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1445 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1446
1447 _skip_curve_unsupported(backend, ec.SECP256R1())
1448 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1449 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001450 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001451 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001452 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001453 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001454 ).serial_number(
1455 1
1456 ).public_key(
1457 private_key.public_key()
1458 ).not_valid_before(
1459 datetime.datetime(2002, 1, 1, 12, 1)
1460 ).not_valid_after(
1461 datetime.datetime(2032, 1, 1, 12, 1)
1462 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001463
1464 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001465 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001466
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001467 @pytest.mark.parametrize(
1468 "cdp",
1469 [
1470 x509.CRLDistributionPoints([
1471 x509.DistributionPoint(
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001472 full_name=None,
1473 relative_name=x509.Name([
1474 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001475 NameOID.COMMON_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001476 u"indirect CRL for indirectCRL CA3"
1477 ),
1478 ]),
1479 reasons=None,
1480 crl_issuer=[x509.DirectoryName(
1481 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001482 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001483 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001484 NameOID.ORGANIZATION_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001485 u"Test Certificates 2011"
1486 ),
1487 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001488 NameOID.ORGANIZATIONAL_UNIT_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001489 u"indirectCRL CA3 cRLIssuer"
1490 ),
1491 ])
1492 )],
1493 )
1494 ]),
1495 x509.CRLDistributionPoints([
1496 x509.DistributionPoint(
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001497 full_name=[x509.DirectoryName(
1498 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001499 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001500 ])
1501 )],
1502 relative_name=None,
1503 reasons=None,
1504 crl_issuer=[x509.DirectoryName(
1505 x509.Name([
1506 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001507 NameOID.ORGANIZATION_NAME,
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001508 u"cryptography Testing"
1509 ),
1510 ])
1511 )],
1512 )
1513 ]),
1514 x509.CRLDistributionPoints([
1515 x509.DistributionPoint(
Paul Kehrerc6cf8f32015-08-08 09:47:44 -05001516 full_name=[
1517 x509.UniformResourceIdentifier(
1518 u"http://myhost.com/myca.crl"
1519 ),
1520 x509.UniformResourceIdentifier(
1521 u"http://backup.myhost.com/myca.crl"
1522 )
1523 ],
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001524 relative_name=None,
1525 reasons=frozenset([
1526 x509.ReasonFlags.key_compromise,
1527 x509.ReasonFlags.ca_compromise
1528 ]),
1529 crl_issuer=[x509.DirectoryName(
1530 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001531 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001532 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001533 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001534 ),
1535 ])
1536 )],
1537 )
1538 ]),
1539 x509.CRLDistributionPoints([
1540 x509.DistributionPoint(
1541 full_name=[x509.UniformResourceIdentifier(
1542 u"http://domain.com/some.crl"
1543 )],
1544 relative_name=None,
1545 reasons=frozenset([
1546 x509.ReasonFlags.key_compromise,
1547 x509.ReasonFlags.ca_compromise,
1548 x509.ReasonFlags.affiliation_changed,
1549 x509.ReasonFlags.superseded,
1550 x509.ReasonFlags.privilege_withdrawn,
1551 x509.ReasonFlags.cessation_of_operation,
1552 x509.ReasonFlags.aa_compromise,
1553 x509.ReasonFlags.certificate_hold,
1554 ]),
1555 crl_issuer=None
1556 )
1557 ]),
1558 x509.CRLDistributionPoints([
1559 x509.DistributionPoint(
1560 full_name=None,
1561 relative_name=None,
1562 reasons=None,
1563 crl_issuer=[x509.DirectoryName(
1564 x509.Name([
1565 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001566 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001567 ),
1568 ])
1569 )],
1570 )
1571 ]),
1572 x509.CRLDistributionPoints([
1573 x509.DistributionPoint(
1574 full_name=[x509.UniformResourceIdentifier(
1575 u"http://domain.com/some.crl"
1576 )],
1577 relative_name=None,
1578 reasons=frozenset([x509.ReasonFlags.aa_compromise]),
1579 crl_issuer=None
1580 )
1581 ])
1582 ]
1583 )
1584 @pytest.mark.requires_backend_interface(interface=RSABackend)
1585 @pytest.mark.requires_backend_interface(interface=X509Backend)
1586 def test_crl_distribution_points(self, backend, cdp):
1587 issuer_private_key = RSA_KEY_2048.private_key(backend)
1588 subject_private_key = RSA_KEY_2048.private_key(backend)
1589
1590 builder = x509.CertificateBuilder().serial_number(
1591 4444444
1592 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001593 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001594 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001595 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001596 ])).public_key(
1597 subject_private_key.public_key()
1598 ).add_extension(
1599 cdp,
1600 critical=False,
1601 ).not_valid_before(
1602 datetime.datetime(2002, 1, 1, 12, 1)
1603 ).not_valid_after(
1604 datetime.datetime(2030, 12, 31, 8, 30)
1605 )
1606
1607 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
1608
1609 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001610 ExtensionOID.CRL_DISTRIBUTION_POINTS
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001611 )
1612 assert ext.critical is False
1613 assert ext.value == cdp
1614
Ian Cordasco56561b12015-07-24 16:38:50 -05001615 @pytest.mark.requires_backend_interface(interface=DSABackend)
1616 @pytest.mark.requires_backend_interface(interface=X509Backend)
1617 def test_build_cert_with_dsa_private_key(self, backend):
1618 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1619 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1620
1621 issuer_private_key = DSA_KEY_2048.private_key(backend)
1622 subject_private_key = DSA_KEY_2048.private_key(backend)
1623
1624 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1625 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1626
1627 builder = x509.CertificateBuilder().serial_number(
1628 777
1629 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001630 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001631 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001632 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001633 ])).public_key(
1634 subject_private_key.public_key()
1635 ).add_extension(
1636 x509.BasicConstraints(ca=False, path_length=None), True,
1637 ).add_extension(
1638 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1639 critical=False,
1640 ).not_valid_before(
1641 not_valid_before
1642 ).not_valid_after(
1643 not_valid_after
1644 )
1645
Paul Kehrer9add80e2015-08-03 17:53:14 +01001646 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001647
1648 assert cert.version is x509.Version.v3
1649 assert cert.not_valid_before == not_valid_before
1650 assert cert.not_valid_after == not_valid_after
1651 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001652 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco56561b12015-07-24 16:38:50 -05001653 )
1654 assert basic_constraints.value.ca is False
1655 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001656 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001657 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001658 )
1659 assert list(subject_alternative_name.value) == [
1660 x509.DNSName(u"cryptography.io"),
1661 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001662
1663 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1664 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco85fc4d52015-08-01 20:29:31 -05001665 def test_build_cert_with_ec_private_key(self, backend):
Ian Cordasco56561b12015-07-24 16:38:50 -05001666 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1667 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1668
1669 _skip_curve_unsupported(backend, ec.SECP256R1())
1670 issuer_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1671 subject_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1672
1673 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1674 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1675
1676 builder = x509.CertificateBuilder().serial_number(
1677 777
1678 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001679 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001680 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001681 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001682 ])).public_key(
1683 subject_private_key.public_key()
1684 ).add_extension(
1685 x509.BasicConstraints(ca=False, path_length=None), True,
1686 ).add_extension(
1687 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1688 critical=False,
1689 ).not_valid_before(
1690 not_valid_before
1691 ).not_valid_after(
1692 not_valid_after
1693 )
1694
Paul Kehrer9add80e2015-08-03 17:53:14 +01001695 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001696
1697 assert cert.version is x509.Version.v3
1698 assert cert.not_valid_before == not_valid_before
1699 assert cert.not_valid_after == not_valid_after
1700 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001701 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco56561b12015-07-24 16:38:50 -05001702 )
1703 assert basic_constraints.value.ca is False
1704 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001705 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001706 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001707 )
1708 assert list(subject_alternative_name.value) == [
1709 x509.DNSName(u"cryptography.io"),
1710 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001711
Ian Cordasco8690eff2015-07-24 16:42:58 -05001712 @pytest.mark.requires_backend_interface(interface=RSABackend)
1713 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco19f5a492015-08-01 11:06:17 -05001714 def test_build_cert_with_rsa_key_too_small(self, backend):
Ian Cordasco8690eff2015-07-24 16:42:58 -05001715 issuer_private_key = RSA_KEY_512.private_key(backend)
1716 subject_private_key = RSA_KEY_512.private_key(backend)
1717
1718 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1719 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1720
1721 builder = x509.CertificateBuilder().serial_number(
1722 777
1723 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001724 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001725 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001726 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001727 ])).public_key(
1728 subject_private_key.public_key()
Ian Cordasco8690eff2015-07-24 16:42:58 -05001729 ).not_valid_before(
1730 not_valid_before
1731 ).not_valid_after(
1732 not_valid_after
1733 )
1734
Ian Cordasco19f5a492015-08-01 11:06:17 -05001735 with pytest.raises(ValueError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001736 builder.sign(issuer_private_key, hashes.SHA512(), backend)
Ian Cordasco8690eff2015-07-24 16:42:58 -05001737
Paul Kehrerdf387002015-07-27 15:19:57 +01001738 @pytest.mark.parametrize(
1739 "cp",
1740 [
1741 x509.CertificatePolicies([
1742 x509.PolicyInformation(
1743 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
1744 [u"http://other.com/cps"]
1745 )
1746 ]),
1747 x509.CertificatePolicies([
1748 x509.PolicyInformation(
1749 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
1750 None
1751 )
1752 ]),
1753 x509.CertificatePolicies([
1754 x509.PolicyInformation(
1755 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
1756 [
1757 u"http://example.com/cps",
1758 u"http://other.com/cps",
1759 x509.UserNotice(
1760 x509.NoticeReference(u"my org", [1, 2, 3, 4]),
1761 u"thing"
1762 )
1763 ]
1764 )
1765 ]),
1766 x509.CertificatePolicies([
1767 x509.PolicyInformation(
1768 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
1769 [
1770 u"http://example.com/cps",
1771 x509.UserNotice(
1772 x509.NoticeReference(u"UTF8\u2122'", [1, 2, 3, 4]),
1773 u"We heart UTF8!\u2122"
1774 )
1775 ]
1776 )
1777 ]),
1778 x509.CertificatePolicies([
1779 x509.PolicyInformation(
1780 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
1781 [x509.UserNotice(None, u"thing")]
1782 )
1783 ]),
1784 x509.CertificatePolicies([
1785 x509.PolicyInformation(
1786 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
1787 [
1788 x509.UserNotice(
1789 x509.NoticeReference(u"my org", [1, 2, 3, 4]),
1790 None
1791 )
1792 ]
1793 )
1794 ])
1795 ]
1796 )
1797 @pytest.mark.requires_backend_interface(interface=RSABackend)
1798 @pytest.mark.requires_backend_interface(interface=X509Backend)
1799 def test_certificate_policies(self, cp, backend):
1800 issuer_private_key = RSA_KEY_2048.private_key(backend)
1801 subject_private_key = RSA_KEY_2048.private_key(backend)
1802
1803 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1804 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1805
1806 cert = x509.CertificateBuilder().subject_name(
1807 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1808 ).issuer_name(
1809 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1810 ).not_valid_before(
1811 not_valid_before
1812 ).not_valid_after(
1813 not_valid_after
1814 ).public_key(
1815 subject_private_key.public_key()
1816 ).serial_number(
1817 123
1818 ).add_extension(
1819 cp, critical=False
1820 ).sign(issuer_private_key, hashes.SHA256(), backend)
1821
1822 ext = cert.extensions.get_extension_for_oid(
1823 x509.OID_CERTIFICATE_POLICIES
1824 )
1825 assert ext.value == cp
1826
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001827 @pytest.mark.requires_backend_interface(interface=RSABackend)
1828 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer69b64e42015-08-09 00:00:44 -05001829 def test_issuer_alt_name(self, backend):
1830 issuer_private_key = RSA_KEY_2048.private_key(backend)
1831 subject_private_key = RSA_KEY_2048.private_key(backend)
1832
1833 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1834 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1835
1836 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001837 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer69b64e42015-08-09 00:00:44 -05001838 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001839 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer69b64e42015-08-09 00:00:44 -05001840 ).not_valid_before(
1841 not_valid_before
1842 ).not_valid_after(
1843 not_valid_after
1844 ).public_key(
1845 subject_private_key.public_key()
1846 ).serial_number(
1847 123
1848 ).add_extension(
1849 x509.IssuerAlternativeName([
1850 x509.DNSName(u"myissuer"),
1851 x509.RFC822Name(u"email@domain.com"),
1852 ]), critical=False
1853 ).sign(issuer_private_key, hashes.SHA256(), backend)
1854
1855 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001856 ExtensionOID.ISSUER_ALTERNATIVE_NAME
Paul Kehrer69b64e42015-08-09 00:00:44 -05001857 )
1858 assert ext.critical is False
1859 assert ext.value == x509.IssuerAlternativeName([
1860 x509.DNSName(u"myissuer"),
1861 x509.RFC822Name(u"email@domain.com"),
1862 ])
1863
1864 @pytest.mark.requires_backend_interface(interface=RSABackend)
1865 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001866 def test_extended_key_usage(self, backend):
1867 issuer_private_key = RSA_KEY_2048.private_key(backend)
1868 subject_private_key = RSA_KEY_2048.private_key(backend)
1869
1870 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1871 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1872
1873 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001874 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001875 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001876 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001877 ).not_valid_before(
1878 not_valid_before
1879 ).not_valid_after(
1880 not_valid_after
1881 ).public_key(
1882 subject_private_key.public_key()
1883 ).serial_number(
1884 123
1885 ).add_extension(
1886 x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05001887 ExtendedKeyUsageOID.CLIENT_AUTH,
1888 ExtendedKeyUsageOID.SERVER_AUTH,
1889 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001890 ]), critical=False
1891 ).sign(issuer_private_key, hashes.SHA256(), backend)
1892
1893 eku = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001894 ExtensionOID.EXTENDED_KEY_USAGE
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001895 )
1896 assert eku.critical is False
1897 assert eku.value == x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05001898 ExtendedKeyUsageOID.CLIENT_AUTH,
1899 ExtendedKeyUsageOID.SERVER_AUTH,
1900 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001901 ])
1902
1903 @pytest.mark.requires_backend_interface(interface=RSABackend)
1904 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer683d4d82015-08-06 23:13:45 +01001905 def test_inhibit_any_policy(self, backend):
1906 issuer_private_key = RSA_KEY_2048.private_key(backend)
1907 subject_private_key = RSA_KEY_2048.private_key(backend)
1908
1909 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1910 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1911
1912 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001913 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer683d4d82015-08-06 23:13:45 +01001914 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001915 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer683d4d82015-08-06 23:13:45 +01001916 ).not_valid_before(
1917 not_valid_before
1918 ).not_valid_after(
1919 not_valid_after
1920 ).public_key(
1921 subject_private_key.public_key()
1922 ).serial_number(
1923 123
1924 ).add_extension(
1925 x509.InhibitAnyPolicy(3), critical=False
1926 ).sign(issuer_private_key, hashes.SHA256(), backend)
1927
1928 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001929 ExtensionOID.INHIBIT_ANY_POLICY
Paul Kehrer683d4d82015-08-06 23:13:45 +01001930 )
1931 assert ext.value == x509.InhibitAnyPolicy(3)
1932
1933 @pytest.mark.requires_backend_interface(interface=RSABackend)
1934 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001935 def test_key_usage(self, backend):
1936 issuer_private_key = RSA_KEY_2048.private_key(backend)
1937 subject_private_key = RSA_KEY_2048.private_key(backend)
1938
1939 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1940 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1941
1942 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001943 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001944 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001945 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001946 ).not_valid_before(
1947 not_valid_before
1948 ).not_valid_after(
1949 not_valid_after
1950 ).public_key(
1951 subject_private_key.public_key()
1952 ).serial_number(
1953 123
1954 ).add_extension(
1955 x509.KeyUsage(
1956 digital_signature=True,
1957 content_commitment=True,
1958 key_encipherment=False,
1959 data_encipherment=False,
1960 key_agreement=False,
1961 key_cert_sign=True,
1962 crl_sign=False,
1963 encipher_only=False,
1964 decipher_only=False
1965 ),
1966 critical=False
1967 ).sign(issuer_private_key, hashes.SHA256(), backend)
1968
Paul Kehrerd44e4132015-08-10 19:13:13 -05001969 ext = cert.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001970 assert ext.critical is False
1971 assert ext.value == x509.KeyUsage(
1972 digital_signature=True,
1973 content_commitment=True,
1974 key_encipherment=False,
1975 data_encipherment=False,
1976 key_agreement=False,
1977 key_cert_sign=True,
1978 crl_sign=False,
1979 encipher_only=False,
1980 decipher_only=False
1981 )
1982
vicente.fiebig6b55c4e2015-10-01 18:24:58 -03001983 @pytest.mark.requires_backend_interface(interface=RSABackend)
1984 @pytest.mark.requires_backend_interface(interface=X509Backend)
1985 def test_build_ca_request_with_path_length_none(self, backend):
1986 private_key = RSA_KEY_2048.private_key(backend)
1987
1988 request = x509.CertificateSigningRequestBuilder().subject_name(
1989 x509.Name([
1990 x509.NameAttribute(NameOID.ORGANIZATION_NAME,
1991 u'PyCA'),
1992 ])
1993 ).add_extension(
1994 x509.BasicConstraints(ca=True, path_length=None), critical=True
1995 ).sign(private_key, hashes.SHA1(), backend)
1996
1997 loaded_request = x509.load_pem_x509_csr(
1998 request.public_bytes(encoding=serialization.Encoding.PEM), backend
1999 )
2000 subject = loaded_request.subject
2001 assert isinstance(subject, x509.Name)
2002 basic_constraints = request.extensions.get_extension_for_oid(
2003 ExtensionOID.BASIC_CONSTRAINTS
2004 )
2005 assert basic_constraints.value.path_length is None
2006
Ian Cordasco747a2172015-07-19 11:00:14 -05002007
Andre Caron0ef595f2015-05-18 13:53:43 -04002008@pytest.mark.requires_backend_interface(interface=X509Backend)
2009class TestCertificateSigningRequestBuilder(object):
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002010 @pytest.mark.requires_backend_interface(interface=RSABackend)
Andre Caron0ef595f2015-05-18 13:53:43 -04002011 def test_sign_invalid_hash_algorithm(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05002012 private_key = RSA_KEY_2048.private_key(backend)
2013
Alex Gaynorba19c2e2015-06-27 00:07:09 -04002014 builder = x509.CertificateSigningRequestBuilder().subject_name(
2015 x509.Name([])
2016 )
Andre Caron0ef595f2015-05-18 13:53:43 -04002017 with pytest.raises(TypeError):
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04002018 builder.sign(private_key, 'NotAHash', backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04002019
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002020 @pytest.mark.requires_backend_interface(interface=RSABackend)
Alex Gaynorba19c2e2015-06-27 00:07:09 -04002021 def test_no_subject_name(self, backend):
2022 private_key = RSA_KEY_2048.private_key(backend)
2023
2024 builder = x509.CertificateSigningRequestBuilder()
2025 with pytest.raises(ValueError):
2026 builder.sign(private_key, hashes.SHA256(), backend)
2027
2028 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002029 def test_build_ca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05002030 private_key = RSA_KEY_2048.private_key(backend)
2031
Andre Carona9a51172015-06-06 20:18:44 -04002032 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04002033 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002034 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Andre Caron99d0f902015-06-01 08:36:59 -04002035 ])
Andre Caron472fd692015-06-06 20:04:44 -04002036 ).add_extension(
Ian Cordasco41f51ce2015-06-17 11:49:11 -05002037 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04002038 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04002039
2040 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2041 public_key = request.public_key()
2042 assert isinstance(public_key, rsa.RSAPublicKey)
2043 subject = request.subject
2044 assert isinstance(subject, x509.Name)
2045 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002046 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Andre Caron0ef595f2015-05-18 13:53:43 -04002047 ]
2048 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002049 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron0ef595f2015-05-18 13:53:43 -04002050 )
2051 assert basic_constraints.value.ca is True
2052 assert basic_constraints.value.path_length == 2
2053
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002054 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05002055 def test_build_ca_request_with_unicode(self, backend):
2056 private_key = RSA_KEY_2048.private_key(backend)
2057
2058 request = x509.CertificateSigningRequestBuilder().subject_name(
2059 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002060 x509.NameAttribute(NameOID.ORGANIZATION_NAME,
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05002061 u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05002062 ])
2063 ).add_extension(
2064 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04002065 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05002066
2067 loaded_request = x509.load_pem_x509_csr(
2068 request.public_bytes(encoding=serialization.Encoding.PEM), backend
2069 )
2070 subject = loaded_request.subject
2071 assert isinstance(subject, x509.Name)
2072 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002073 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05002074 ]
2075
2076 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002077 def test_build_nonca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05002078 private_key = RSA_KEY_2048.private_key(backend)
2079
Andre Carona9a51172015-06-06 20:18:44 -04002080 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04002081 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002082 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Andre Caron99d0f902015-06-01 08:36:59 -04002083 ])
Andre Caron472fd692015-06-06 20:04:44 -04002084 ).add_extension(
Ian Cordasco0112b022015-06-16 17:51:18 -05002085 x509.BasicConstraints(ca=False, path_length=None), critical=True,
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04002086 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04002087
2088 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2089 public_key = request.public_key()
2090 assert isinstance(public_key, rsa.RSAPublicKey)
2091 subject = request.subject
2092 assert isinstance(subject, x509.Name)
2093 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002094 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Andre Caron0ef595f2015-05-18 13:53:43 -04002095 ]
2096 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002097 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron0ef595f2015-05-18 13:53:43 -04002098 )
2099 assert basic_constraints.value.ca is False
2100 assert basic_constraints.value.path_length is None
2101
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002102 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2103 def test_build_ca_request_with_ec(self, backend):
2104 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
2105 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
2106
Ian Cordasco8cdcdfc2015-06-24 22:00:26 -05002107 _skip_curve_unsupported(backend, ec.SECP256R1())
2108 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002109
2110 request = x509.CertificateSigningRequestBuilder().subject_name(
2111 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002112 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002113 ])
2114 ).add_extension(
2115 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04002116 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002117
2118 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2119 public_key = request.public_key()
2120 assert isinstance(public_key, ec.EllipticCurvePublicKey)
2121 subject = request.subject
2122 assert isinstance(subject, x509.Name)
2123 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002124 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002125 ]
2126 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002127 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002128 )
2129 assert basic_constraints.value.ca is True
2130 assert basic_constraints.value.path_length == 2
2131
2132 @pytest.mark.requires_backend_interface(interface=DSABackend)
2133 def test_build_ca_request_with_dsa(self, backend):
2134 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
2135 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
2136
2137 private_key = DSA_KEY_2048.private_key(backend)
2138
2139 request = x509.CertificateSigningRequestBuilder().subject_name(
2140 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002141 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002142 ])
2143 ).add_extension(
2144 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04002145 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002146
2147 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2148 public_key = request.public_key()
2149 assert isinstance(public_key, dsa.DSAPublicKey)
2150 subject = request.subject
2151 assert isinstance(subject, x509.Name)
2152 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002153 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002154 ]
2155 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002156 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05002157 )
2158 assert basic_constraints.value.ca is True
2159 assert basic_constraints.value.path_length == 2
2160
Paul Kehrerff917802015-06-26 17:29:04 -05002161 def test_add_duplicate_extension(self):
Andre Caronfc164c52015-05-31 17:36:18 -04002162 builder = x509.CertificateSigningRequestBuilder().add_extension(
Andre Caron472fd692015-06-06 20:04:44 -04002163 x509.BasicConstraints(True, 2), critical=True,
Andre Caronfc164c52015-05-31 17:36:18 -04002164 )
Andre Caron0ef595f2015-05-18 13:53:43 -04002165 with pytest.raises(ValueError):
Andre Caron472fd692015-06-06 20:04:44 -04002166 builder.add_extension(
2167 x509.BasicConstraints(True, 2), critical=True,
2168 )
Andre Caron0ef595f2015-05-18 13:53:43 -04002169
Paul Kehrerff917802015-06-26 17:29:04 -05002170 def test_set_invalid_subject(self):
Andre Caron0ef595f2015-05-18 13:53:43 -04002171 builder = x509.CertificateSigningRequestBuilder()
2172 with pytest.raises(TypeError):
Andre Carona9a51172015-06-06 20:18:44 -04002173 builder.subject_name('NotAName')
Andre Caron0ef595f2015-05-18 13:53:43 -04002174
Paul Kehrere59fd222015-08-08 22:50:19 -05002175 def test_add_invalid_extension_type(self):
Ian Cordasco34853f32015-06-21 10:50:53 -05002176 builder = x509.CertificateSigningRequestBuilder()
Andre Caron0ef595f2015-05-18 13:53:43 -04002177
Paul Kehrere59fd222015-08-08 22:50:19 -05002178 with pytest.raises(TypeError):
2179 builder.add_extension(object(), False)
2180
2181 def test_add_unsupported_extension(self, backend):
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002182 private_key = RSA_KEY_2048.private_key(backend)
2183 builder = x509.CertificateSigningRequestBuilder()
2184 builder = builder.subject_name(
2185 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002186 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002187 ])
2188 ).add_extension(
Alex Gaynor7583f7f2015-07-03 10:56:49 -04002189 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
2190 critical=False,
2191 ).add_extension(
Paul Kehrer69b64e42015-08-09 00:00:44 -05002192 DummyExtension(), False
Paul Kehrerdce91f02015-07-23 20:31:12 +01002193 )
2194 with pytest.raises(NotImplementedError):
2195 builder.sign(private_key, hashes.SHA256(), backend)
2196
2197 def test_key_usage(self, backend):
2198 private_key = RSA_KEY_2048.private_key(backend)
2199 builder = x509.CertificateSigningRequestBuilder()
2200 request = builder.subject_name(
2201 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002202 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerdce91f02015-07-23 20:31:12 +01002203 ])
2204 ).add_extension(
Alex Gaynorac7f70a2015-06-28 11:07:52 -04002205 x509.KeyUsage(
2206 digital_signature=True,
2207 content_commitment=True,
2208 key_encipherment=False,
2209 data_encipherment=False,
2210 key_agreement=False,
2211 key_cert_sign=True,
2212 crl_sign=False,
2213 encipher_only=False,
2214 decipher_only=False
2215 ),
Alex Gaynor887a4082015-07-03 04:29:03 -04002216 critical=False
Paul Kehrerdce91f02015-07-23 20:31:12 +01002217 ).sign(private_key, hashes.SHA256(), backend)
2218 assert len(request.extensions) == 1
Paul Kehrerd44e4132015-08-10 19:13:13 -05002219 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrerdce91f02015-07-23 20:31:12 +01002220 assert ext.critical is False
2221 assert ext.value == x509.KeyUsage(
2222 digital_signature=True,
2223 content_commitment=True,
2224 key_encipherment=False,
2225 data_encipherment=False,
2226 key_agreement=False,
2227 key_cert_sign=True,
2228 crl_sign=False,
2229 encipher_only=False,
2230 decipher_only=False
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002231 )
Paul Kehrerdce91f02015-07-23 20:31:12 +01002232
2233 def test_key_usage_key_agreement_bit(self, backend):
2234 private_key = RSA_KEY_2048.private_key(backend)
2235 builder = x509.CertificateSigningRequestBuilder()
2236 request = builder.subject_name(
2237 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002238 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerdce91f02015-07-23 20:31:12 +01002239 ])
2240 ).add_extension(
2241 x509.KeyUsage(
2242 digital_signature=False,
2243 content_commitment=False,
2244 key_encipherment=False,
2245 data_encipherment=False,
2246 key_agreement=True,
2247 key_cert_sign=True,
2248 crl_sign=False,
2249 encipher_only=False,
2250 decipher_only=True
2251 ),
2252 critical=False
2253 ).sign(private_key, hashes.SHA256(), backend)
2254 assert len(request.extensions) == 1
Paul Kehrerd44e4132015-08-10 19:13:13 -05002255 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrerdce91f02015-07-23 20:31:12 +01002256 assert ext.critical is False
2257 assert ext.value == x509.KeyUsage(
2258 digital_signature=False,
2259 content_commitment=False,
2260 key_encipherment=False,
2261 data_encipherment=False,
2262 key_agreement=True,
2263 key_cert_sign=True,
2264 crl_sign=False,
2265 encipher_only=False,
2266 decipher_only=True
2267 )
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05002268
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002269 def test_add_two_extensions(self, backend):
2270 private_key = RSA_KEY_2048.private_key(backend)
2271 builder = x509.CertificateSigningRequestBuilder()
2272 request = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002273 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002274 ).add_extension(
2275 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
2276 critical=False,
2277 ).add_extension(
2278 x509.BasicConstraints(ca=True, path_length=2), critical=True
2279 ).sign(private_key, hashes.SHA1(), backend)
2280
2281 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2282 public_key = request.public_key()
2283 assert isinstance(public_key, rsa.RSAPublicKey)
2284 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002285 ExtensionOID.BASIC_CONSTRAINTS
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002286 )
2287 assert basic_constraints.value.ca is True
2288 assert basic_constraints.value.path_length == 2
2289 ext = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002290 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Paul Kehrer8bfbace2015-07-23 19:10:28 +01002291 )
2292 assert list(ext.value) == [x509.DNSName(u"cryptography.io")]
Paul Kehrerff917802015-06-26 17:29:04 -05002293
Andre Caron0ef595f2015-05-18 13:53:43 -04002294 def test_set_subject_twice(self):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002295 builder = x509.CertificateSigningRequestBuilder()
2296 builder = builder.subject_name(
Paul Kehrere76cd272014-12-14 19:00:51 -06002297 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002298 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera693cfd2014-11-27 07:47:58 -10002299 ])
Paul Kehrer4903adc2014-12-13 16:57:50 -06002300 )
Paul Kehrer41120322014-12-02 18:31:14 -10002301 with pytest.raises(ValueError):
Paul Kehrera693cfd2014-11-27 07:47:58 -10002302 builder.subject_name(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002303 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002304 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002305 ])
Alex Gaynor32c57df2015-02-23 21:51:27 -08002306 )
Alex Gaynorfcadda62015-03-10 10:01:18 -04002307
Alex Gaynord3e84162015-06-28 10:14:55 -04002308 def test_subject_alt_names(self, backend):
2309 private_key = RSA_KEY_2048.private_key(backend)
2310
2311 csr = x509.CertificateSigningRequestBuilder().subject_name(
2312 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002313 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Alex Gaynord3e84162015-06-28 10:14:55 -04002314 ])
2315 ).add_extension(
2316 x509.SubjectAlternativeName([
Alex Gaynor6431d502015-07-05 12:28:46 -04002317 x509.DNSName(u"example.com"),
2318 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05002319 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002320 x509.DirectoryName(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002321 x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002322 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002323 NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002324 )
2325 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05002326 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
2327 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05002328 x509.OtherName(
2329 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2330 value=b"0\x03\x02\x01\x05"
2331 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05002332 x509.RFC822Name(u"test@example.com"),
2333 x509.RFC822Name(u"email"),
2334 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05002335 x509.UniformResourceIdentifier(
2336 u"https://\u043f\u044b\u043a\u0430.cryptography"
2337 ),
2338 x509.UniformResourceIdentifier(
2339 u"gopher://cryptography:70/some/path"
2340 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04002341 ]),
2342 critical=False,
2343 ).sign(private_key, hashes.SHA256(), backend)
2344
2345 assert len(csr.extensions) == 1
2346 ext = csr.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002347 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynord3e84162015-06-28 10:14:55 -04002348 )
2349 assert not ext.critical
Paul Kehrerd44e4132015-08-10 19:13:13 -05002350 assert ext.oid == ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynord3e84162015-06-28 10:14:55 -04002351 assert list(ext.value) == [
Alex Gaynor6431d502015-07-05 12:28:46 -04002352 x509.DNSName(u"example.com"),
2353 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05002354 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002355 x509.DirectoryName(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002356 x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002357 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002358 NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
Paul Kehrer9ce25a92015-07-10 11:08:31 -05002359 ),
2360 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05002361 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
2362 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05002363 x509.OtherName(
2364 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2365 value=b"0\x03\x02\x01\x05"
2366 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05002367 x509.RFC822Name(u"test@example.com"),
2368 x509.RFC822Name(u"email"),
2369 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05002370 x509.UniformResourceIdentifier(
2371 u"https://\u043f\u044b\u043a\u0430.cryptography"
2372 ),
2373 x509.UniformResourceIdentifier(
2374 u"gopher://cryptography:70/some/path"
2375 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04002376 ]
2377
Paul Kehrer500ed9d2015-07-10 20:51:36 -05002378 def test_invalid_asn1_othername(self, backend):
2379 private_key = RSA_KEY_2048.private_key(backend)
2380
2381 builder = x509.CertificateSigningRequestBuilder().subject_name(
2382 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002383 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Paul Kehrer500ed9d2015-07-10 20:51:36 -05002384 ])
2385 ).add_extension(
2386 x509.SubjectAlternativeName([
2387 x509.OtherName(
2388 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
2389 value=b"\x01\x02\x01\x05"
2390 ),
2391 ]),
2392 critical=False,
2393 )
2394 with pytest.raises(ValueError):
2395 builder.sign(private_key, hashes.SHA256(), backend)
2396
Alex Gaynord5f718c2015-07-05 11:19:38 -04002397 def test_subject_alt_name_unsupported_general_name(self, backend):
2398 private_key = RSA_KEY_2048.private_key(backend)
2399
2400 builder = x509.CertificateSigningRequestBuilder().subject_name(
2401 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002402 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Alex Gaynord5f718c2015-07-05 11:19:38 -04002403 ])
2404 ).add_extension(
Paul Kehrer474a6472015-07-11 12:29:52 -05002405 x509.SubjectAlternativeName([FakeGeneralName("")]),
Alex Gaynord5f718c2015-07-05 11:19:38 -04002406 critical=False,
2407 )
2408
Paul Kehrer474a6472015-07-11 12:29:52 -05002409 with pytest.raises(ValueError):
Alex Gaynord5f718c2015-07-05 11:19:38 -04002410 builder.sign(private_key, hashes.SHA256(), backend)
2411
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002412 def test_extended_key_usage(self, backend):
2413 private_key = RSA_KEY_2048.private_key(backend)
2414 builder = x509.CertificateSigningRequestBuilder()
2415 request = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002416 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002417 ).add_extension(
2418 x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05002419 ExtendedKeyUsageOID.CLIENT_AUTH,
2420 ExtendedKeyUsageOID.SERVER_AUTH,
2421 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002422 ]), critical=False
2423 ).sign(private_key, hashes.SHA256(), backend)
2424
2425 eku = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002426 ExtensionOID.EXTENDED_KEY_USAGE
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002427 )
2428 assert eku.critical is False
2429 assert eku.value == x509.ExtendedKeyUsage([
Paul Kehrer9e102db2015-08-10 21:53:09 -05002430 ExtendedKeyUsageOID.CLIENT_AUTH,
2431 ExtendedKeyUsageOID.SERVER_AUTH,
2432 ExtendedKeyUsageOID.CODE_SIGNING,
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002433 ])
2434
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002435 @pytest.mark.requires_backend_interface(interface=RSABackend)
2436 def test_rsa_key_too_small(self, backend):
2437 private_key = rsa.generate_private_key(65537, 512, backend)
2438 builder = x509.CertificateSigningRequestBuilder()
2439 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002440 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002441 )
2442
2443 with pytest.raises(ValueError) as exc:
2444 builder.sign(private_key, hashes.SHA512(), backend)
2445
Paul Kehrer6a71f8d2015-07-25 19:15:59 +01002446 assert str(exc.value) == "Digest too big for RSA key"
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002447
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002448 @pytest.mark.requires_backend_interface(interface=RSABackend)
2449 @pytest.mark.requires_backend_interface(interface=X509Backend)
2450 def test_build_cert_with_aia(self, backend):
2451 issuer_private_key = RSA_KEY_2048.private_key(backend)
2452 subject_private_key = RSA_KEY_2048.private_key(backend)
2453
2454 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2455 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2456
2457 aia = x509.AuthorityInformationAccess([
2458 x509.AccessDescription(
Paul Kehrer9e102db2015-08-10 21:53:09 -05002459 AuthorityInformationAccessOID.OCSP,
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002460 x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
2461 ),
2462 x509.AccessDescription(
Paul Kehrer9e102db2015-08-10 21:53:09 -05002463 AuthorityInformationAccessOID.CA_ISSUERS,
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002464 x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
2465 )
2466 ])
2467
2468 builder = x509.CertificateBuilder().serial_number(
2469 777
2470 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002471 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002472 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002473 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002474 ])).public_key(
2475 subject_private_key.public_key()
2476 ).add_extension(
2477 aia, critical=False
2478 ).not_valid_before(
2479 not_valid_before
2480 ).not_valid_after(
2481 not_valid_after
2482 )
2483
2484 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2485
2486 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002487 ExtensionOID.AUTHORITY_INFORMATION_ACCESS
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002488 )
2489 assert ext.value == aia
2490
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002491 @pytest.mark.requires_backend_interface(interface=RSABackend)
2492 @pytest.mark.requires_backend_interface(interface=X509Backend)
2493 def test_build_cert_with_ski(self, backend):
2494 issuer_private_key = RSA_KEY_2048.private_key(backend)
2495 subject_private_key = RSA_KEY_2048.private_key(backend)
2496
2497 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2498 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2499
2500 ski = x509.SubjectKeyIdentifier.from_public_key(
2501 subject_private_key.public_key()
2502 )
2503
2504 builder = x509.CertificateBuilder().serial_number(
2505 777
2506 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002507 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002508 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002509 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002510 ])).public_key(
2511 subject_private_key.public_key()
2512 ).add_extension(
2513 ski, critical=False
2514 ).not_valid_before(
2515 not_valid_before
2516 ).not_valid_after(
2517 not_valid_after
2518 )
2519
2520 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2521
2522 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002523 ExtensionOID.SUBJECT_KEY_IDENTIFIER
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002524 )
2525 assert ext.value == ski
2526
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002527 @pytest.mark.parametrize(
2528 "aki",
2529 [
2530 x509.AuthorityKeyIdentifier(
2531 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2532 b"\xcbY",
2533 None,
2534 None
2535 ),
2536 x509.AuthorityKeyIdentifier(
2537 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2538 b"\xcbY",
2539 [
2540 x509.DirectoryName(
2541 x509.Name([
2542 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002543 NameOID.ORGANIZATION_NAME, u"PyCA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002544 ),
2545 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002546 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002547 )
2548 ])
2549 )
2550 ],
2551 333
2552 ),
2553 x509.AuthorityKeyIdentifier(
2554 None,
2555 [
2556 x509.DirectoryName(
2557 x509.Name([
2558 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002559 NameOID.ORGANIZATION_NAME, u"PyCA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002560 ),
2561 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002562 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002563 )
2564 ])
2565 )
2566 ],
2567 333
2568 ),
2569 ]
2570 )
2571 @pytest.mark.requires_backend_interface(interface=RSABackend)
2572 @pytest.mark.requires_backend_interface(interface=X509Backend)
2573 def test_build_cert_with_aki(self, aki, backend):
2574 issuer_private_key = RSA_KEY_2048.private_key(backend)
2575 subject_private_key = RSA_KEY_2048.private_key(backend)
2576
2577 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2578 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2579
2580 builder = x509.CertificateBuilder().serial_number(
2581 777
2582 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002583 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002584 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002585 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002586 ])).public_key(
2587 subject_private_key.public_key()
2588 ).add_extension(
2589 aki, critical=False
2590 ).not_valid_before(
2591 not_valid_before
2592 ).not_valid_after(
2593 not_valid_after
2594 )
2595
2596 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2597
2598 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002599 ExtensionOID.AUTHORITY_KEY_IDENTIFIER
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002600 )
2601 assert ext.value == aki
2602
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002603 def test_ocsp_nocheck(self, backend):
2604 issuer_private_key = RSA_KEY_2048.private_key(backend)
2605 subject_private_key = RSA_KEY_2048.private_key(backend)
2606
2607 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2608 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2609
2610 builder = x509.CertificateBuilder().serial_number(
2611 777
2612 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002613 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002614 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002615 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002616 ])).public_key(
2617 subject_private_key.public_key()
2618 ).add_extension(
2619 x509.OCSPNoCheck(), critical=False
2620 ).not_valid_before(
2621 not_valid_before
2622 ).not_valid_after(
2623 not_valid_after
2624 )
2625
2626 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2627
2628 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002629 ExtensionOID.OCSP_NO_CHECK
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002630 )
2631 assert isinstance(ext.value, x509.OCSPNoCheck)
2632
Alex Gaynord5f718c2015-07-05 11:19:38 -04002633
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002634@pytest.mark.requires_backend_interface(interface=DSABackend)
2635@pytest.mark.requires_backend_interface(interface=X509Backend)
2636class TestDSACertificate(object):
2637 def test_load_dsa_cert(self, backend):
2638 cert = _load_cert(
2639 os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
2640 x509.load_pem_x509_certificate,
2641 backend
2642 )
2643 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
2644 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002645 assert isinstance(public_key, dsa.DSAPublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002646 num = public_key.public_numbers()
2647 assert num.y == int(
2648 "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94"
2649 "53b6656f13e543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2"
2650 "dea559f0b584c97a2b235b9b69b46bc6de1aed422a6f341832618bcaae2"
2651 "198aba388099dafb05ff0b5efecb3b0ae169a62e1c72022af50ae68af3b"
2652 "033c18e6eec1f7df4692c456ccafb79cc7e08da0a5786e9816ceda651d6"
2653 "1b4bb7b81c2783da97cea62df67af5e85991fdc13aff10fc60e06586386"
2654 "b96bb78d65750f542f86951e05a6d81baadbcd35a2e5cad4119923ae6a2"
2655 "002091a3d17017f93c52970113cdc119970b9074ca506eac91c3dd37632"
2656 "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c", 16
2657 )
2658 assert num.parameter_numbers.g == int(
2659 "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67"
2660 "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b"
2661 "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2"
2662 "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa"
2663 "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f"
2664 "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a"
2665 "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0"
2666 "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76"
2667 "fa6247676a6d3ac945844a083509c6a1b436baca", 16
2668 )
2669 assert num.parameter_numbers.p == int(
2670 "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3"
2671 "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330"
2672 "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e"
2673 "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a"
2674 "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4"
2675 "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2"
2676 "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93"
2677 "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d"
2678 "833e36468f3907cfca788a3cb790f0341c8a31bf", 16
2679 )
2680 assert num.parameter_numbers.q == int(
2681 "822ff5d234e073b901cf5941f58e1f538e71d40d", 16
2682 )
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002683
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002684 @pytest.mark.parametrize(
2685 ("path", "loader_func"),
2686 [
2687 [
2688 os.path.join("x509", "requests", "dsa_sha1.pem"),
2689 x509.load_pem_x509_csr
2690 ],
2691 [
2692 os.path.join("x509", "requests", "dsa_sha1.der"),
2693 x509.load_der_x509_csr
2694 ],
2695 ]
2696 )
2697 def test_load_dsa_request(self, path, loader_func, backend):
2698 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002699 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2700 public_key = request.public_key()
2701 assert isinstance(public_key, dsa.DSAPublicKey)
2702 subject = request.subject
2703 assert isinstance(subject, x509.Name)
2704 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002705 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2706 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2707 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2708 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2709 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002710 ]
2711
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002712
2713@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2714@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -06002715class TestECDSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002716 def test_load_ecdsa_cert(self, backend):
2717 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrera693cfd2014-11-27 07:47:58 -10002718 cert = _load_cert(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002719 os.path.join("x509", "ecdsa_root.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -10002720 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -10002721 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002722 )
Paul Kehrer8802a5b2015-02-13 12:06:57 -06002723 assert isinstance(cert.signature_hash_algorithm, hashes.SHA384)
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002724 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002725 assert isinstance(public_key, ec.EllipticCurvePublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002726 num = public_key.public_numbers()
2727 assert num.x == int(
2728 "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f"
2729 "6f0ccd00bba615b51467e9e2d9fee8e630c17", 16
2730 )
2731 assert num.y == int(
2732 "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7"
2733 "2deae88a7a16bb543ce67dc23ff031ca3e23e", 16
2734 )
2735 assert isinstance(num.curve, ec.SECP384R1)
Paul Kehrer6c660a82014-12-12 11:50:44 -06002736
2737 def test_load_ecdsa_no_named_curve(self, backend):
2738 _skip_curve_unsupported(backend, ec.SECP256R1())
2739 cert = _load_cert(
2740 os.path.join("x509", "custom", "ec_no_named_curve.pem"),
2741 x509.load_pem_x509_certificate,
2742 backend
2743 )
2744 with pytest.raises(NotImplementedError):
2745 cert.public_key()
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002746
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002747 @pytest.mark.parametrize(
2748 ("path", "loader_func"),
2749 [
2750 [
2751 os.path.join("x509", "requests", "ec_sha256.pem"),
2752 x509.load_pem_x509_csr
2753 ],
2754 [
2755 os.path.join("x509", "requests", "ec_sha256.der"),
2756 x509.load_der_x509_csr
2757 ],
2758 ]
2759 )
2760 def test_load_ecdsa_certificate_request(self, path, loader_func, backend):
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002761 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002762 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002763 assert isinstance(request.signature_hash_algorithm, hashes.SHA256)
2764 public_key = request.public_key()
2765 assert isinstance(public_key, ec.EllipticCurvePublicKey)
2766 subject = request.subject
2767 assert isinstance(subject, x509.Name)
2768 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002769 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2770 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2771 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2772 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2773 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002774 ]
2775
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002776
Alex Gaynor96605fc2015-10-10 09:03:07 -04002777@pytest.mark.requires_backend_interface(interface=X509Backend)
2778class TestOtherCertificate(object):
2779 def test_unsupported_subject_public_key_info(self, backend):
2780 cert = _load_cert(
2781 os.path.join(
2782 "x509", "custom", "unsupported_subject_public_key_info.pem"
2783 ),
2784 x509.load_pem_x509_certificate,
2785 backend,
2786 )
2787
2788 with pytest.raises(ValueError):
2789 cert.public_key()
2790
2791
Paul Kehrer806bfb22015-02-02 17:05:24 -06002792class TestNameAttribute(object):
Alex Gaynora56ff412015-02-10 17:26:32 -05002793 def test_init_bad_oid(self):
2794 with pytest.raises(TypeError):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002795 x509.NameAttribute(None, u'value')
Alex Gaynora56ff412015-02-10 17:26:32 -05002796
Ian Cordasco7618fbe2015-06-16 19:12:17 -05002797 def test_init_bad_value(self):
2798 with pytest.raises(TypeError):
2799 x509.NameAttribute(
2800 x509.ObjectIdentifier('oid'),
2801 b'bytes'
2802 )
2803
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002804 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002805 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002806 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002807 ) == x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002808 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002809 )
2810
2811 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002812 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002813 x509.ObjectIdentifier('2.5.4.3'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002814 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002815 x509.ObjectIdentifier('2.5.4.5'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002816 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002817 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002818 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002819 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002820 x509.ObjectIdentifier('oid'), u'value2'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002821 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002822 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002823 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002824 ) != object()
2825
Paul Kehrera498be82015-02-12 15:00:56 -06002826 def test_repr(self):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002827 na = x509.NameAttribute(x509.ObjectIdentifier('2.5.4.3'), u'value')
Ian Cordascoa908d692015-06-16 21:35:24 -05002828 if six.PY3:
2829 assert repr(na) == (
2830 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2831 "nName)>, value='value')>"
2832 )
2833 else:
2834 assert repr(na) == (
2835 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2836 "nName)>, value=u'value')>"
2837 )
Paul Kehrera498be82015-02-12 15:00:56 -06002838
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002839
2840class TestObjectIdentifier(object):
2841 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002842 oid1 = x509.ObjectIdentifier('oid')
2843 oid2 = x509.ObjectIdentifier('oid')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002844 assert oid1 == oid2
2845
2846 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002847 oid1 = x509.ObjectIdentifier('oid')
2848 assert oid1 != x509.ObjectIdentifier('oid1')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002849 assert oid1 != object()
2850
2851 def test_repr(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002852 oid = x509.ObjectIdentifier("2.5.4.3")
2853 assert repr(oid) == "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>"
2854 oid = x509.ObjectIdentifier("oid1")
2855 assert repr(oid) == "<ObjectIdentifier(oid=oid1, name=Unknown OID)>"
Paul Kehrer719d5362015-01-01 20:03:52 -06002856
Brendan McCollam1b3b3ce2015-08-25 10:55:44 -05002857 def test_name_property(self):
2858 oid = x509.ObjectIdentifier("2.5.4.3")
2859 assert oid._name == 'commonName'
2860 oid = x509.ObjectIdentifier("oid1")
2861 assert oid._name == 'Unknown OID'
2862
Paul Kehrer719d5362015-01-01 20:03:52 -06002863
2864class TestName(object):
2865 def test_eq(self):
2866 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002867 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2868 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002869 ])
2870 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002871 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2872 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002873 ])
2874 assert name1 == name2
2875
2876 def test_ne(self):
2877 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002878 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2879 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002880 ])
2881 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002882 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
2883 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002884 ])
2885 assert name1 != name2
2886 assert name1 != object()
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002887
Alex Gaynor1aecec72015-10-24 19:26:02 -04002888 def test_hash(self):
Alex Gaynor9442fa92015-10-24 18:32:10 -04002889 name1 = x509.Name([
2890 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2891 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
2892 ])
2893 name2 = x509.Name([
2894 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2895 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
2896 ])
2897 name3 = x509.Name([
2898 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
2899 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2900 ])
2901
2902 assert hash(name1) == hash(name2)
2903 assert hash(name1) != hash(name3)
2904
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002905 def test_repr(self):
2906 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002907 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2908 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002909 ])
2910
Ian Cordascoa908d692015-06-16 21:35:24 -05002911 if six.PY3:
2912 assert repr(name) == (
2913 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2914 "=commonName)>, value='cryptography.io')>, <NameAttribute(oid="
2915 "<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, valu"
2916 "e='PyCA')>])>"
2917 )
2918 else:
2919 assert repr(name) == (
2920 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2921 "=commonName)>, value=u'cryptography.io')>, <NameAttribute(oid"
2922 "=<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, val"
2923 "ue=u'PyCA')>])>"
2924 )