blob: 99ac69ee8661793ea45d8a569194f15180785f31 [file] [log] [blame]
Paul Kehrer016e08a2014-11-26 09:41:18 -10001# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import absolute_import, division, print_function
6
Paul Kehrer0307c372014-11-27 09:49:31 -10007import binascii
Paul Kehrer016e08a2014-11-26 09:41:18 -10008import datetime
Paul Kehrer235e5a12015-07-10 19:45:47 -05009import ipaddress
Paul Kehrer016e08a2014-11-26 09:41:18 -100010import os
Paul Kehrer016e08a2014-11-26 09:41:18 -100011
12import pytest
13
Ian Cordascoa908d692015-06-16 21:35:24 -050014import six
15
Paul Kehrer474a6472015-07-11 12:29:52 -050016from cryptography import utils, x509
Paul Kehrer8802a5b2015-02-13 12:06:57 -060017from cryptography.exceptions import UnsupportedAlgorithm
Paul Kehrerf1ef3512014-11-26 17:36:05 -100018from cryptography.hazmat.backends.interfaces import (
19 DSABackend, EllipticCurveBackend, RSABackend, X509Backend
20)
Andre Caron476c5df2015-05-18 10:23:28 -040021from cryptography.hazmat.primitives import hashes, serialization
Alex Gaynor32c57df2015-02-23 21:51:27 -080022from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
Paul Kehrereba19e62015-08-10 18:44:24 -050023from cryptography.x509.oid import NameOID
Paul Kehrer016e08a2014-11-26 09:41:18 -100024
Ian Cordasco8ed8edc2015-06-22 20:11:17 -050025from .hazmat.primitives.fixtures_dsa import DSA_KEY_2048
Ian Cordasco85fc4d52015-08-01 20:29:31 -050026from .hazmat.primitives.fixtures_rsa import RSA_KEY_2048, RSA_KEY_512
Ian Cordasco4d46eb72015-06-17 12:08:27 -050027from .hazmat.primitives.test_ec import _skip_curve_unsupported
Paul Kehrera9d78c12014-11-26 10:59:03 -100028from .utils import load_vectors_from_file
Paul Kehrer016e08a2014-11-26 09:41:18 -100029
30
Paul Kehrer69b64e42015-08-09 00:00:44 -050031@utils.register_interface(x509.ExtensionType)
32class DummyExtension(object):
33 oid = x509.ObjectIdentifier("1.2.3.4")
34
35
Paul Kehrer474a6472015-07-11 12:29:52 -050036@utils.register_interface(x509.GeneralName)
37class FakeGeneralName(object):
38 def __init__(self, value):
39 self._value = value
40
41 value = utils.read_only_property("_value")
42
43
Paul Kehrer41120322014-12-02 18:31:14 -100044def _load_cert(filename, loader, backend):
Paul Kehrer016e08a2014-11-26 09:41:18 -100045 cert = load_vectors_from_file(
Paul Kehrera693cfd2014-11-27 07:47:58 -100046 filename=filename,
47 loader=lambda pemfile: loader(pemfile.read(), backend),
48 mode="rb"
Paul Kehrer016e08a2014-11-26 09:41:18 -100049 )
50 return cert
51
52
53@pytest.mark.requires_backend_interface(interface=RSABackend)
54@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -060055class TestRSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -100056 def test_load_pem_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -100057 cert = _load_cert(
58 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -100059 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -100060 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -100061 )
Paul Kehrere76cd272014-12-14 19:00:51 -060062 assert isinstance(cert, x509.Certificate)
63 assert cert.serial == 11559813051657483483
64 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
65 assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8"
Paul Kehrer8802a5b2015-02-13 12:06:57 -060066 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
Paul Kehrerf1ef3512014-11-26 17:36:05 -100067
68 def test_load_der_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -100069 cert = _load_cert(
70 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -100071 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -100072 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -100073 )
Paul Kehrere76cd272014-12-14 19:00:51 -060074 assert isinstance(cert, x509.Certificate)
75 assert cert.serial == 2
76 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
77 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer8802a5b2015-02-13 12:06:57 -060078 assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
Paul Kehrerf1ef3512014-11-26 17:36:05 -100079
Paul Kehrer719d5362015-01-01 20:03:52 -060080 def test_issuer(self, backend):
81 cert = _load_cert(
82 os.path.join(
83 "x509", "PKITS_data", "certs",
84 "Validpre2000UTCnotBeforeDateTest3EE.crt"
85 ),
86 x509.load_der_x509_certificate,
87 backend
88 )
89 issuer = cert.issuer
90 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -060091 assert list(issuer) == [
Paul Kehrereba19e62015-08-10 18:44:24 -050092 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -060093 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -050094 NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -060095 ),
Paul Kehrereba19e62015-08-10 18:44:24 -050096 x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -060097 ]
Paul Kehrereba19e62015-08-10 18:44:24 -050098 assert issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
99 x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -0600100 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600101
102 def test_all_issuer_name_types(self, backend):
103 cert = _load_cert(
104 os.path.join(
105 "x509", "custom",
106 "all_supported_names.pem"
107 ),
108 x509.load_pem_x509_certificate,
109 backend
110 )
111 issuer = cert.issuer
112
113 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600114 assert list(issuer) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500115 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
116 x509.NameAttribute(NameOID.COUNTRY_NAME, u'CA'),
117 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
118 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Illinois'),
119 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Chicago'),
120 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
121 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Zero, LLC'),
122 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'One, LLC'),
123 x509.NameAttribute(NameOID.COMMON_NAME, u'common name 0'),
124 x509.NameAttribute(NameOID.COMMON_NAME, u'common name 1'),
125 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 0'),
126 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 1'),
127 x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier0'),
128 x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier1'),
129 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'123'),
130 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'456'),
131 x509.NameAttribute(NameOID.TITLE, u'Title 0'),
132 x509.NameAttribute(NameOID.TITLE, u'Title 1'),
133 x509.NameAttribute(NameOID.SURNAME, u'Surname 0'),
134 x509.NameAttribute(NameOID.SURNAME, u'Surname 1'),
135 x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 0'),
136 x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 1'),
137 x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 0'),
138 x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 1'),
139 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Last Gen'),
140 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Next Gen'),
141 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc0'),
142 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc1'),
143 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test0@test.local'),
144 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test1@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600145 ]
146
Paul Kehrer719d5362015-01-01 20:03:52 -0600147 def test_subject(self, backend):
148 cert = _load_cert(
149 os.path.join(
150 "x509", "PKITS_data", "certs",
151 "Validpre2000UTCnotBeforeDateTest3EE.crt"
152 ),
153 x509.load_der_x509_certificate,
154 backend
155 )
156 subject = cert.subject
157 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600158 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500159 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600160 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500161 NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -0600162 ),
163 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500164 NameOID.COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500165 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600166 )
167 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500168 assert subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600169 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500170 NameOID.COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500171 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600172 )
173 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600174
175 def test_unicode_name(self, backend):
176 cert = _load_cert(
177 os.path.join(
178 "x509", "custom",
179 "utf8_common_name.pem"
180 ),
181 x509.load_pem_x509_certificate,
182 backend
183 )
Paul Kehrereba19e62015-08-10 18:44:24 -0500184 assert cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600185 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500186 NameOID.COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530187 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600188 )
189 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500190 assert cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600191 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500192 NameOID.COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530193 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600194 )
195 ]
196
197 def test_all_subject_name_types(self, backend):
198 cert = _load_cert(
199 os.path.join(
200 "x509", "custom",
201 "all_supported_names.pem"
202 ),
203 x509.load_pem_x509_certificate,
204 backend
205 )
206 subject = cert.subject
207 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600208 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500209 x509.NameAttribute(NameOID.COUNTRY_NAME, u'AU'),
210 x509.NameAttribute(NameOID.COUNTRY_NAME, u'DE'),
211 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'California'),
212 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'New York'),
213 x509.NameAttribute(NameOID.LOCALITY_NAME, u'San Francisco'),
214 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Ithaca'),
215 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org Zero, LLC'),
216 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org One, LLC'),
217 x509.NameAttribute(NameOID.COMMON_NAME, u'CN 0'),
218 x509.NameAttribute(NameOID.COMMON_NAME, u'CN 1'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600219 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500220 NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 0'
Paul Kehrer719d5362015-01-01 20:03:52 -0600221 ),
222 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500223 NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 1'
Paul Kehrer719d5362015-01-01 20:03:52 -0600224 ),
Paul Kehrereba19e62015-08-10 18:44:24 -0500225 x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified0'),
226 x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified1'),
227 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'789'),
228 x509.NameAttribute(NameOID.SERIAL_NUMBER, u'012'),
229 x509.NameAttribute(NameOID.TITLE, u'Title IX'),
230 x509.NameAttribute(NameOID.TITLE, u'Title X'),
231 x509.NameAttribute(NameOID.SURNAME, u'Last 0'),
232 x509.NameAttribute(NameOID.SURNAME, u'Last 1'),
233 x509.NameAttribute(NameOID.GIVEN_NAME, u'First 0'),
234 x509.NameAttribute(NameOID.GIVEN_NAME, u'First 1'),
235 x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 0'),
236 x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 1'),
237 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'32X'),
238 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Dreamcast'),
239 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc2'),
240 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc3'),
241 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test2@test.local'),
242 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test3@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600243 ]
244
Paul Kehrer016e08a2014-11-26 09:41:18 -1000245 def test_load_good_ca_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000246 cert = _load_cert(
247 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000248 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000249 backend
250 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000251
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600252 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
253 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrer016e08a2014-11-26 09:41:18 -1000254 assert cert.serial == 2
255 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -0800256 assert isinstance(public_key, rsa.RSAPublicKey)
Paul Kehrere76cd272014-12-14 19:00:51 -0600257 assert cert.version is x509.Version.v3
Paul Kehrer0307c372014-11-27 09:49:31 -1000258 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
Paul Kehrer4e1db792014-11-27 10:50:55 -1000259 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer016e08a2014-11-26 09:41:18 -1000260
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000261 def test_utc_pre_2000_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000262 cert = _load_cert(
263 os.path.join(
264 "x509", "PKITS_data", "certs",
265 "Validpre2000UTCnotBeforeDateTest3EE.crt"
266 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000267 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000268 backend
269 )
270
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600271 assert cert.not_valid_before == datetime.datetime(1950, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000272
273 def test_pre_2000_utc_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000274 cert = _load_cert(
275 os.path.join(
276 "x509", "PKITS_data", "certs",
277 "Invalidpre2000UTCEEnotAfterDateTest7EE.crt"
278 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000279 x509.load_der_x509_certificate,
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000280 backend
281 )
282
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600283 assert cert.not_valid_after == datetime.datetime(1999, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000284
285 def test_post_2000_utc_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000286 cert = _load_cert(
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000287 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000288 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000289 backend
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000290 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600291 assert cert.not_valid_before == datetime.datetime(
292 2014, 11, 26, 21, 41, 20
293 )
294 assert cert.not_valid_after == datetime.datetime(
295 2014, 12, 26, 21, 41, 20
296 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000297
298 def test_generalized_time_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000299 cert = _load_cert(
300 os.path.join(
301 "x509", "PKITS_data", "certs",
302 "ValidGeneralizedTimenotBeforeDateTest4EE.crt"
303 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000304 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000305 backend
306 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600307 assert cert.not_valid_before == datetime.datetime(2002, 1, 1, 12, 1)
308 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrere76cd272014-12-14 19:00:51 -0600309 assert cert.version is x509.Version.v3
Paul Kehrer016e08a2014-11-26 09:41:18 -1000310
311 def test_generalized_time_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000312 cert = _load_cert(
313 os.path.join(
314 "x509", "PKITS_data", "certs",
315 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
316 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000317 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000318 backend
319 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600320 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
321 assert cert.not_valid_after == datetime.datetime(2050, 1, 1, 12, 1)
Paul Kehrere76cd272014-12-14 19:00:51 -0600322 assert cert.version is x509.Version.v3
Paul Kehrera9d78c12014-11-26 10:59:03 -1000323
324 def test_invalid_version_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000325 cert = _load_cert(
Paul Kehrera9d78c12014-11-26 10:59:03 -1000326 os.path.join("x509", "custom", "invalid_version.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000327 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000328 backend
Paul Kehrera9d78c12014-11-26 10:59:03 -1000329 )
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600330 with pytest.raises(x509.InvalidVersion) as exc:
Paul Kehrera9d78c12014-11-26 10:59:03 -1000331 cert.version
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000332
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600333 assert exc.value.parsed_version == 7
334
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -0500335 def test_eq(self, backend):
336 cert = _load_cert(
337 os.path.join("x509", "custom", "post2000utctime.pem"),
338 x509.load_pem_x509_certificate,
339 backend
340 )
341 cert2 = _load_cert(
342 os.path.join("x509", "custom", "post2000utctime.pem"),
343 x509.load_pem_x509_certificate,
344 backend
345 )
346 assert cert == cert2
347
348 def test_ne(self, backend):
349 cert = _load_cert(
350 os.path.join("x509", "custom", "post2000utctime.pem"),
351 x509.load_pem_x509_certificate,
352 backend
353 )
354 cert2 = _load_cert(
355 os.path.join(
356 "x509", "PKITS_data", "certs",
357 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
358 ),
359 x509.load_der_x509_certificate,
360 backend
361 )
362 assert cert != cert2
363 assert cert != object()
364
Alex Gaynor969f3a52015-07-06 18:52:41 -0400365 def test_hash(self, backend):
366 cert1 = _load_cert(
367 os.path.join("x509", "custom", "post2000utctime.pem"),
368 x509.load_pem_x509_certificate,
369 backend
370 )
371 cert2 = _load_cert(
372 os.path.join("x509", "custom", "post2000utctime.pem"),
373 x509.load_pem_x509_certificate,
374 backend
375 )
376 cert3 = _load_cert(
377 os.path.join(
378 "x509", "PKITS_data", "certs",
379 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
380 ),
381 x509.load_der_x509_certificate,
382 backend
383 )
384
385 assert hash(cert1) == hash(cert2)
386 assert hash(cert1) != hash(cert3)
387
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000388 def test_version_1_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000389 cert = _load_cert(
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000390 os.path.join("x509", "v1_cert.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000391 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000392 backend
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000393 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600394 assert cert.version is x509.Version.v1
Paul Kehrer7638c312014-11-26 11:13:31 -1000395
396 def test_invalid_pem(self, backend):
397 with pytest.raises(ValueError):
398 x509.load_pem_x509_certificate(b"notacert", backend)
399
400 def test_invalid_der(self, backend):
401 with pytest.raises(ValueError):
402 x509.load_der_x509_certificate(b"notacert", backend)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000403
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600404 def test_unsupported_signature_hash_algorithm_cert(self, backend):
405 cert = _load_cert(
406 os.path.join("x509", "verisign_md2_root.pem"),
407 x509.load_pem_x509_certificate,
408 backend
409 )
410 with pytest.raises(UnsupportedAlgorithm):
411 cert.signature_hash_algorithm
412
Andre Carona8aded62015-05-19 20:11:57 -0400413 def test_public_bytes_pem(self, backend):
414 # Load an existing certificate.
415 cert = _load_cert(
416 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
417 x509.load_der_x509_certificate,
418 backend
419 )
420
421 # Encode it to PEM and load it back.
422 cert = x509.load_pem_x509_certificate(cert.public_bytes(
423 encoding=serialization.Encoding.PEM,
424 ), backend)
425
426 # We should recover what we had to start with.
427 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
428 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
429 assert cert.serial == 2
430 public_key = cert.public_key()
431 assert isinstance(public_key, rsa.RSAPublicKey)
432 assert cert.version is x509.Version.v3
433 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
434 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
435
436 def test_public_bytes_der(self, backend):
437 # Load an existing certificate.
438 cert = _load_cert(
439 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
440 x509.load_der_x509_certificate,
441 backend
442 )
443
444 # Encode it to DER and load it back.
445 cert = x509.load_der_x509_certificate(cert.public_bytes(
446 encoding=serialization.Encoding.DER,
447 ), backend)
448
449 # We should recover what we had to start with.
450 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
451 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
452 assert cert.serial == 2
453 public_key = cert.public_key()
454 assert isinstance(public_key, rsa.RSAPublicKey)
455 assert cert.version is x509.Version.v3
456 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
457 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
458
459 def test_public_bytes_invalid_encoding(self, backend):
460 cert = _load_cert(
461 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
462 x509.load_der_x509_certificate,
463 backend
464 )
465
466 with pytest.raises(TypeError):
467 cert.public_bytes('NotAnEncoding')
468
469 @pytest.mark.parametrize(
470 ("cert_path", "loader_func", "encoding"),
471 [
472 (
473 os.path.join("x509", "v1_cert.pem"),
474 x509.load_pem_x509_certificate,
475 serialization.Encoding.PEM,
476 ),
477 (
478 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
479 x509.load_der_x509_certificate,
480 serialization.Encoding.DER,
481 ),
482 ]
483 )
484 def test_public_bytes_match(self, cert_path, loader_func, encoding,
485 backend):
486 cert_bytes = load_vectors_from_file(
487 cert_path, lambda pemfile: pemfile.read(), mode="rb"
488 )
489 cert = loader_func(cert_bytes, backend)
490 serialized = cert.public_bytes(encoding)
491 assert serialized == cert_bytes
492
Major Haydenf315af22015-06-17 14:02:26 -0500493 def test_certificate_repr(self, backend):
494 cert = _load_cert(
495 os.path.join(
496 "x509", "cryptography.io.pem"
497 ),
498 x509.load_pem_x509_certificate,
499 backend
500 )
501 if six.PY3:
502 assert repr(cert) == (
503 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
504 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value='GT487"
505 "42965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11, "
506 "name=organizationalUnitName)>, value='See www.rapidssl.com/re"
507 "sources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier(oi"
508 "d=2.5.4.11, name=organizationalUnitName)>, value='Domain Cont"
509 "rol Validated - RapidSSL(R)')>, <NameAttribute(oid=<ObjectIde"
510 "ntifier(oid=2.5.4.3, name=commonName)>, value='www.cryptograp"
511 "hy.io')>])>, ...)>"
512 )
513 else:
514 assert repr(cert) == (
515 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
516 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value=u'GT48"
517 "742965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11,"
518 " name=organizationalUnitName)>, value=u'See www.rapidssl.com/"
519 "resources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier("
520 "oid=2.5.4.11, name=organizationalUnitName)>, value=u'Domain C"
521 "ontrol Validated - RapidSSL(R)')>, <NameAttribute(oid=<Object"
522 "Identifier(oid=2.5.4.3, name=commonName)>, value=u'www.crypto"
523 "graphy.io')>])>, ...)>"
524 )
525
Andre Carona8aded62015-05-19 20:11:57 -0400526
527@pytest.mark.requires_backend_interface(interface=RSABackend)
528@pytest.mark.requires_backend_interface(interface=X509Backend)
529class TestRSACertificateRequest(object):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500530 @pytest.mark.parametrize(
531 ("path", "loader_func"),
532 [
533 [
534 os.path.join("x509", "requests", "rsa_sha1.pem"),
535 x509.load_pem_x509_csr
536 ],
537 [
538 os.path.join("x509", "requests", "rsa_sha1.der"),
539 x509.load_der_x509_csr
540 ],
541 ]
542 )
543 def test_load_rsa_certificate_request(self, path, loader_func, backend):
544 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600545 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
546 public_key = request.public_key()
547 assert isinstance(public_key, rsa.RSAPublicKey)
548 subject = request.subject
549 assert isinstance(subject, x509.Name)
550 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500551 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
552 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
553 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
554 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
555 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600556 ]
Andre Caron6e721a92015-05-17 15:08:48 -0400557 extensions = request.extensions
558 assert isinstance(extensions, x509.Extensions)
559 assert list(extensions) == []
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600560
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500561 @pytest.mark.parametrize(
562 "loader_func",
563 [x509.load_pem_x509_csr, x509.load_der_x509_csr]
564 )
565 def test_invalid_certificate_request(self, loader_func, backend):
Paul Kehrerb759e292015-03-17 07:34:41 -0500566 with pytest.raises(ValueError):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500567 loader_func(b"notacsr", backend)
Paul Kehrerb759e292015-03-17 07:34:41 -0500568
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600569 def test_unsupported_signature_hash_algorithm_request(self, backend):
570 request = _load_cert(
571 os.path.join("x509", "requests", "rsa_md4.pem"),
Paul Kehrer31e39882015-03-11 11:37:04 -0500572 x509.load_pem_x509_csr,
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600573 backend
574 )
575 with pytest.raises(UnsupportedAlgorithm):
576 request.signature_hash_algorithm
577
Andre Caron6e721a92015-05-17 15:08:48 -0400578 def test_duplicate_extension(self, backend):
579 request = _load_cert(
580 os.path.join(
581 "x509", "requests", "two_basic_constraints.pem"
582 ),
583 x509.load_pem_x509_csr,
584 backend
585 )
586 with pytest.raises(x509.DuplicateExtension) as exc:
587 request.extensions
588
589 assert exc.value.oid == x509.OID_BASIC_CONSTRAINTS
590
591 def test_unsupported_critical_extension(self, backend):
592 request = _load_cert(
593 os.path.join(
594 "x509", "requests", "unsupported_extension_critical.pem"
595 ),
596 x509.load_pem_x509_csr,
597 backend
598 )
599 with pytest.raises(x509.UnsupportedExtension) as exc:
600 request.extensions
601
602 assert exc.value.oid == x509.ObjectIdentifier('1.2.3.4')
603
604 def test_unsupported_extension(self, backend):
605 request = _load_cert(
606 os.path.join(
607 "x509", "requests", "unsupported_extension.pem"
608 ),
609 x509.load_pem_x509_csr,
610 backend
611 )
612 extensions = request.extensions
613 assert len(extensions) == 0
614
615 def test_request_basic_constraints(self, backend):
616 request = _load_cert(
617 os.path.join(
618 "x509", "requests", "basic_constraints.pem"
619 ),
620 x509.load_pem_x509_csr,
621 backend
622 )
623 extensions = request.extensions
624 assert isinstance(extensions, x509.Extensions)
625 assert list(extensions) == [
626 x509.Extension(
627 x509.OID_BASIC_CONSTRAINTS,
628 True,
Ian Cordasco0112b022015-06-16 17:51:18 -0500629 x509.BasicConstraints(ca=True, path_length=1),
Andre Caron6e721a92015-05-17 15:08:48 -0400630 ),
631 ]
632
Alex Gaynor37b82df2015-07-03 10:26:37 -0400633 def test_subject_alt_name(self, backend):
634 request = _load_cert(
635 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
636 x509.load_pem_x509_csr,
637 backend,
638 )
639 ext = request.extensions.get_extension_for_oid(
640 x509.OID_SUBJECT_ALTERNATIVE_NAME
641 )
642 assert list(ext.value) == [
643 x509.DNSName(u"cryptography.io"),
644 x509.DNSName(u"sub.cryptography.io"),
645 ]
646
Andre Caronf27e4f42015-05-18 17:54:59 -0400647 def test_public_bytes_pem(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400648 # Load an existing CSR.
649 request = _load_cert(
650 os.path.join("x509", "requests", "rsa_sha1.pem"),
651 x509.load_pem_x509_csr,
652 backend
653 )
654
655 # Encode it to PEM and load it back.
656 request = x509.load_pem_x509_csr(request.public_bytes(
657 encoding=serialization.Encoding.PEM,
658 ), backend)
659
660 # We should recover what we had to start with.
661 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
662 public_key = request.public_key()
663 assert isinstance(public_key, rsa.RSAPublicKey)
664 subject = request.subject
665 assert isinstance(subject, x509.Name)
666 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500667 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
668 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
669 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
670 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
671 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400672 ]
673
Andre Caronf27e4f42015-05-18 17:54:59 -0400674 def test_public_bytes_der(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400675 # Load an existing CSR.
676 request = _load_cert(
677 os.path.join("x509", "requests", "rsa_sha1.pem"),
678 x509.load_pem_x509_csr,
679 backend
680 )
681
682 # Encode it to DER and load it back.
683 request = x509.load_der_x509_csr(request.public_bytes(
684 encoding=serialization.Encoding.DER,
685 ), backend)
686
687 # We should recover what we had to start with.
688 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
689 public_key = request.public_key()
690 assert isinstance(public_key, rsa.RSAPublicKey)
691 subject = request.subject
692 assert isinstance(subject, x509.Name)
693 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -0500694 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
695 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
696 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
697 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
698 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400699 ]
700
Andre Caronf27e4f42015-05-18 17:54:59 -0400701 def test_public_bytes_invalid_encoding(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400702 request = _load_cert(
703 os.path.join("x509", "requests", "rsa_sha1.pem"),
704 x509.load_pem_x509_csr,
705 backend
706 )
707
708 with pytest.raises(TypeError):
709 request.public_bytes('NotAnEncoding')
710
Andre Caronacb18972015-05-18 21:04:15 -0400711 @pytest.mark.parametrize(
712 ("request_path", "loader_func", "encoding"),
713 [
714 (
715 os.path.join("x509", "requests", "rsa_sha1.pem"),
716 x509.load_pem_x509_csr,
717 serialization.Encoding.PEM,
718 ),
719 (
720 os.path.join("x509", "requests", "rsa_sha1.der"),
721 x509.load_der_x509_csr,
722 serialization.Encoding.DER,
723 ),
724 ]
725 )
726 def test_public_bytes_match(self, request_path, loader_func, encoding,
727 backend):
728 request_bytes = load_vectors_from_file(
729 request_path, lambda pemfile: pemfile.read(), mode="rb"
730 )
731 request = loader_func(request_bytes, backend)
732 serialized = request.public_bytes(encoding)
733 assert serialized == request_bytes
734
Alex Gaynor70c8f8b2015-07-06 21:02:54 -0400735 def test_eq(self, backend):
736 request1 = _load_cert(
737 os.path.join("x509", "requests", "rsa_sha1.pem"),
738 x509.load_pem_x509_csr,
739 backend
740 )
741 request2 = _load_cert(
742 os.path.join("x509", "requests", "rsa_sha1.pem"),
743 x509.load_pem_x509_csr,
744 backend
745 )
746
747 assert request1 == request2
748
749 def test_ne(self, backend):
750 request1 = _load_cert(
751 os.path.join("x509", "requests", "rsa_sha1.pem"),
752 x509.load_pem_x509_csr,
753 backend
754 )
755 request2 = _load_cert(
Alex Gaynoreb2df542015-07-06 21:50:15 -0400756 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
Alex Gaynor70c8f8b2015-07-06 21:02:54 -0400757 x509.load_pem_x509_csr,
758 backend
759 )
760
761 assert request1 != request2
762 assert request1 != object()
763
Alex Gaynor978137d2015-07-08 20:59:16 -0400764 def test_hash(self, backend):
765 request1 = _load_cert(
766 os.path.join("x509", "requests", "rsa_sha1.pem"),
767 x509.load_pem_x509_csr,
768 backend
769 )
770 request2 = _load_cert(
771 os.path.join("x509", "requests", "rsa_sha1.pem"),
772 x509.load_pem_x509_csr,
773 backend
774 )
775 request3 = _load_cert(
776 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
777 x509.load_pem_x509_csr,
778 backend
779 )
780
781 assert hash(request1) == hash(request2)
782 assert hash(request1) != hash(request3)
783
Andre Caron9bbfcea2015-05-18 20:55:29 -0400784 def test_build_cert(self, backend):
Ian Cordascoe4e52a42015-07-19 10:15:37 -0500785 issuer_private_key = RSA_KEY_2048.private_key(backend)
786 subject_private_key = RSA_KEY_2048.private_key(backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -0400787
Andre Caron9bbfcea2015-05-18 20:55:29 -0400788 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
789 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
Ian Cordascob3ed4842015-07-01 22:46:03 -0500790
Ian Cordasco893246f2015-07-24 14:52:18 -0500791 builder = x509.CertificateBuilder().serial_number(
Ian Cordascob3ed4842015-07-01 22:46:03 -0500792 777
793 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500794 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
795 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
796 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
797 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
798 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -0500799 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500800 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
801 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
802 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
803 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
804 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -0500805 ])).public_key(
806 subject_private_key.public_key()
807 ).add_extension(
Ian Cordasco8887a572015-07-19 10:26:59 -0500808 x509.BasicConstraints(ca=False, path_length=None), True,
Ian Cordasco9e0666e2015-07-20 11:42:51 -0500809 ).add_extension(
810 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
811 critical=False,
Ian Cordascob3ed4842015-07-01 22:46:03 -0500812 ).not_valid_before(
813 not_valid_before
814 ).not_valid_after(
815 not_valid_after
816 )
817
Paul Kehrer9add80e2015-08-03 17:53:14 +0100818 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -0400819
820 assert cert.version is x509.Version.v3
821 assert cert.not_valid_before == not_valid_before
822 assert cert.not_valid_after == not_valid_after
823 basic_constraints = cert.extensions.get_extension_for_oid(
824 x509.OID_BASIC_CONSTRAINTS
825 )
826 assert basic_constraints.value.ca is False
827 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -0500828 subject_alternative_name = cert.extensions.get_extension_for_oid(
829 x509.OID_SUBJECT_ALTERNATIVE_NAME
830 )
831 assert list(subject_alternative_name.value) == [
832 x509.DNSName(u"cryptography.io"),
833 ]
Andre Caron9bbfcea2015-05-18 20:55:29 -0400834
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000835
Ian Cordasco747a2172015-07-19 11:00:14 -0500836class TestCertificateBuilder(object):
Paul Kehrer25f19222015-08-04 23:05:09 +0100837 @pytest.mark.requires_backend_interface(interface=RSABackend)
838 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrera03c3252015-08-09 10:59:29 -0500839 def test_checks_for_unsupported_extensions(self, backend):
840 private_key = RSA_KEY_2048.private_key(backend)
841 builder = x509.CertificateBuilder().subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500842 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera03c3252015-08-09 10:59:29 -0500843 ])).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500844 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera03c3252015-08-09 10:59:29 -0500845 ])).public_key(
846 private_key.public_key()
847 ).serial_number(
848 777
849 ).not_valid_before(
850 datetime.datetime(1999, 1, 1)
851 ).not_valid_after(
852 datetime.datetime(2020, 1, 1)
853 ).add_extension(
854 DummyExtension(), False
855 )
856
857 with pytest.raises(NotImplementedError):
858 builder.sign(private_key, hashes.SHA1(), backend)
859
860 @pytest.mark.requires_backend_interface(interface=RSABackend)
861 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer25f19222015-08-04 23:05:09 +0100862 def test_no_subject_name(self, backend):
863 subject_private_key = RSA_KEY_2048.private_key(backend)
864 builder = x509.CertificateBuilder().serial_number(
865 777
866 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500867 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +0100868 ])).public_key(
869 subject_private_key.public_key()
870 ).not_valid_before(
871 datetime.datetime(2002, 1, 1, 12, 1)
872 ).not_valid_after(
873 datetime.datetime(2030, 12, 31, 8, 30)
874 )
875 with pytest.raises(ValueError):
876 builder.sign(subject_private_key, hashes.SHA256(), backend)
877
878 @pytest.mark.requires_backend_interface(interface=RSABackend)
879 @pytest.mark.requires_backend_interface(interface=X509Backend)
880 def test_no_issuer_name(self, backend):
881 subject_private_key = RSA_KEY_2048.private_key(backend)
882 builder = x509.CertificateBuilder().serial_number(
883 777
884 ).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500885 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +0100886 ])).public_key(
887 subject_private_key.public_key()
888 ).not_valid_before(
889 datetime.datetime(2002, 1, 1, 12, 1)
890 ).not_valid_after(
891 datetime.datetime(2030, 12, 31, 8, 30)
892 )
893 with pytest.raises(ValueError):
894 builder.sign(subject_private_key, hashes.SHA256(), backend)
895
896 @pytest.mark.requires_backend_interface(interface=RSABackend)
897 @pytest.mark.requires_backend_interface(interface=X509Backend)
898 def test_no_public_key(self, backend):
899 subject_private_key = RSA_KEY_2048.private_key(backend)
900 builder = x509.CertificateBuilder().serial_number(
901 777
902 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500903 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +0100904 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500905 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +0100906 ])).not_valid_before(
907 datetime.datetime(2002, 1, 1, 12, 1)
908 ).not_valid_after(
909 datetime.datetime(2030, 12, 31, 8, 30)
910 )
911 with pytest.raises(ValueError):
912 builder.sign(subject_private_key, hashes.SHA256(), backend)
913
914 @pytest.mark.requires_backend_interface(interface=RSABackend)
915 @pytest.mark.requires_backend_interface(interface=X509Backend)
916 def test_no_not_valid_before(self, backend):
917 subject_private_key = RSA_KEY_2048.private_key(backend)
918 builder = x509.CertificateBuilder().serial_number(
919 777
920 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500921 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +0100922 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500923 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +0100924 ])).public_key(
925 subject_private_key.public_key()
926 ).not_valid_after(
927 datetime.datetime(2030, 12, 31, 8, 30)
928 )
929 with pytest.raises(ValueError):
930 builder.sign(subject_private_key, hashes.SHA256(), backend)
931
932 @pytest.mark.requires_backend_interface(interface=RSABackend)
933 @pytest.mark.requires_backend_interface(interface=X509Backend)
934 def test_no_not_valid_after(self, backend):
935 subject_private_key = RSA_KEY_2048.private_key(backend)
936 builder = x509.CertificateBuilder().serial_number(
937 777
938 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500939 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +0100940 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500941 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +0100942 ])).public_key(
943 subject_private_key.public_key()
944 ).not_valid_before(
945 datetime.datetime(2002, 1, 1, 12, 1)
946 )
947 with pytest.raises(ValueError):
948 builder.sign(subject_private_key, hashes.SHA256(), backend)
949
950 @pytest.mark.requires_backend_interface(interface=RSABackend)
951 @pytest.mark.requires_backend_interface(interface=X509Backend)
952 def test_no_serial_number(self, backend):
953 subject_private_key = RSA_KEY_2048.private_key(backend)
954 builder = x509.CertificateBuilder().issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500955 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +0100956 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500957 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer25f19222015-08-04 23:05:09 +0100958 ])).public_key(
959 subject_private_key.public_key()
960 ).not_valid_before(
961 datetime.datetime(2002, 1, 1, 12, 1)
962 ).not_valid_after(
963 datetime.datetime(2030, 12, 31, 8, 30)
964 )
965 with pytest.raises(ValueError):
966 builder.sign(subject_private_key, hashes.SHA256(), backend)
967
Ian Cordasco747a2172015-07-19 11:00:14 -0500968 def test_issuer_name_must_be_a_name_type(self):
969 builder = x509.CertificateBuilder()
970
971 with pytest.raises(TypeError):
972 builder.issuer_name("subject")
973
974 with pytest.raises(TypeError):
975 builder.issuer_name(object)
976
977 def test_issuer_name_may_only_be_set_once(self):
978 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500979 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -0500980 ])
981 builder = x509.CertificateBuilder().issuer_name(name)
982
983 with pytest.raises(ValueError):
984 builder.issuer_name(name)
985
986 def test_subject_name_must_be_a_name_type(self):
987 builder = x509.CertificateBuilder()
988
989 with pytest.raises(TypeError):
990 builder.subject_name("subject")
991
992 with pytest.raises(TypeError):
993 builder.subject_name(object)
994
995 def test_subject_name_may_only_be_set_once(self):
996 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -0500997 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -0500998 ])
999 builder = x509.CertificateBuilder().subject_name(name)
1000
1001 with pytest.raises(ValueError):
1002 builder.subject_name(name)
1003
1004 @pytest.mark.requires_backend_interface(interface=RSABackend)
1005 @pytest.mark.requires_backend_interface(interface=X509Backend)
1006 def test_public_key_must_be_public_key(self, backend):
1007 private_key = RSA_KEY_2048.private_key(backend)
1008 builder = x509.CertificateBuilder()
1009
1010 with pytest.raises(TypeError):
1011 builder.public_key(private_key)
1012
1013 @pytest.mark.requires_backend_interface(interface=RSABackend)
1014 @pytest.mark.requires_backend_interface(interface=X509Backend)
1015 def test_public_key_may_only_be_set_once(self, backend):
1016 private_key = RSA_KEY_2048.private_key(backend)
1017 public_key = private_key.public_key()
1018 builder = x509.CertificateBuilder().public_key(public_key)
1019
1020 with pytest.raises(ValueError):
1021 builder.public_key(public_key)
1022
1023 def test_serial_number_must_be_an_integer_type(self):
1024 with pytest.raises(TypeError):
1025 x509.CertificateBuilder().serial_number(10.0)
1026
Ian Cordascob4a155d2015-08-01 23:07:19 -05001027 def test_serial_number_must_be_non_negative(self):
1028 with pytest.raises(ValueError):
1029 x509.CertificateBuilder().serial_number(-10)
1030
1031 def test_serial_number_must_be_less_than_160_bits_long(self):
1032 with pytest.raises(ValueError):
1033 # 2 raised to the 160th power is actually 161 bits
1034 x509.CertificateBuilder().serial_number(2 ** 160)
1035
Ian Cordasco747a2172015-07-19 11:00:14 -05001036 def test_serial_number_may_only_be_set_once(self):
1037 builder = x509.CertificateBuilder().serial_number(10)
1038
1039 with pytest.raises(ValueError):
1040 builder.serial_number(20)
1041
1042 def test_invalid_not_valid_after(self):
1043 with pytest.raises(TypeError):
1044 x509.CertificateBuilder().not_valid_after(104204304504)
1045
1046 with pytest.raises(TypeError):
1047 x509.CertificateBuilder().not_valid_after(datetime.time())
1048
Ian Cordascob4a155d2015-08-01 23:07:19 -05001049 with pytest.raises(ValueError):
1050 x509.CertificateBuilder().not_valid_after(
1051 datetime.datetime(1960, 8, 10)
1052 )
1053
Ian Cordasco747a2172015-07-19 11:00:14 -05001054 def test_not_valid_after_may_only_be_set_once(self):
1055 builder = x509.CertificateBuilder().not_valid_after(
1056 datetime.datetime.now()
1057 )
1058
1059 with pytest.raises(ValueError):
1060 builder.not_valid_after(
1061 datetime.datetime.now()
1062 )
1063
1064 def test_invalid_not_valid_before(self):
1065 with pytest.raises(TypeError):
1066 x509.CertificateBuilder().not_valid_before(104204304504)
1067
1068 with pytest.raises(TypeError):
1069 x509.CertificateBuilder().not_valid_before(datetime.time())
1070
Ian Cordascob4a155d2015-08-01 23:07:19 -05001071 with pytest.raises(ValueError):
1072 x509.CertificateBuilder().not_valid_before(
1073 datetime.datetime(1960, 8, 10)
1074 )
1075
Ian Cordasco747a2172015-07-19 11:00:14 -05001076 def test_not_valid_before_may_only_be_set_once(self):
1077 builder = x509.CertificateBuilder().not_valid_before(
1078 datetime.datetime.now()
1079 )
1080
1081 with pytest.raises(ValueError):
1082 builder.not_valid_before(
1083 datetime.datetime.now()
1084 )
1085
1086 def test_add_extension_checks_for_duplicates(self):
1087 builder = x509.CertificateBuilder().add_extension(
1088 x509.BasicConstraints(ca=False, path_length=None), True,
1089 )
1090
1091 with pytest.raises(ValueError):
1092 builder.add_extension(
1093 x509.BasicConstraints(ca=False, path_length=None), True,
1094 )
1095
Paul Kehrer08f950e2015-08-08 22:14:42 -05001096 def test_add_invalid_extension_type(self):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001097 builder = x509.CertificateBuilder()
1098
Paul Kehrer08f950e2015-08-08 22:14:42 -05001099 with pytest.raises(TypeError):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001100 builder.add_extension(object(), False)
1101
Ian Cordascob77c7162015-07-20 21:22:33 -05001102 @pytest.mark.requires_backend_interface(interface=RSABackend)
1103 @pytest.mark.requires_backend_interface(interface=X509Backend)
1104 def test_sign_with_unsupported_hash(self, backend):
1105 private_key = RSA_KEY_2048.private_key(backend)
1106 builder = x509.CertificateBuilder()
Paul Kehrer25f19222015-08-04 23:05:09 +01001107 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001108 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer25f19222015-08-04 23:05:09 +01001109 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001110 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer25f19222015-08-04 23:05:09 +01001111 ).serial_number(
1112 1
1113 ).public_key(
1114 private_key.public_key()
1115 ).not_valid_before(
1116 datetime.datetime(2002, 1, 1, 12, 1)
1117 ).not_valid_after(
1118 datetime.datetime(2032, 1, 1, 12, 1)
1119 )
Ian Cordascob77c7162015-07-20 21:22:33 -05001120
1121 with pytest.raises(TypeError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001122 builder.sign(private_key, object(), backend)
Ian Cordascob77c7162015-07-20 21:22:33 -05001123
Ian Cordasco56561b12015-07-24 16:38:50 -05001124 @pytest.mark.requires_backend_interface(interface=DSABackend)
1125 @pytest.mark.requires_backend_interface(interface=X509Backend)
1126 def test_sign_with_dsa_private_key_is_unsupported(self, backend):
1127 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1128 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1129
1130 private_key = DSA_KEY_2048.private_key(backend)
1131 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001132 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001133 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001134 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001135 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001136 ).serial_number(
1137 1
1138 ).public_key(
1139 private_key.public_key()
1140 ).not_valid_before(
1141 datetime.datetime(2002, 1, 1, 12, 1)
1142 ).not_valid_after(
1143 datetime.datetime(2032, 1, 1, 12, 1)
1144 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001145
1146 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001147 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001148
1149 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1150 @pytest.mark.requires_backend_interface(interface=X509Backend)
1151 def test_sign_with_ec_private_key_is_unsupported(self, backend):
1152 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1153 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1154
1155 _skip_curve_unsupported(backend, ec.SECP256R1())
1156 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1157 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001158 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001159 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001160 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001161 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001162 ).serial_number(
1163 1
1164 ).public_key(
1165 private_key.public_key()
1166 ).not_valid_before(
1167 datetime.datetime(2002, 1, 1, 12, 1)
1168 ).not_valid_after(
1169 datetime.datetime(2032, 1, 1, 12, 1)
1170 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001171
1172 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001173 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001174
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001175 @pytest.mark.parametrize(
1176 "cdp",
1177 [
1178 x509.CRLDistributionPoints([
1179 x509.DistributionPoint(
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001180 full_name=None,
1181 relative_name=x509.Name([
1182 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001183 NameOID.COMMON_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001184 u"indirect CRL for indirectCRL CA3"
1185 ),
1186 ]),
1187 reasons=None,
1188 crl_issuer=[x509.DirectoryName(
1189 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001190 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001191 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001192 NameOID.ORGANIZATION_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001193 u"Test Certificates 2011"
1194 ),
1195 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001196 NameOID.ORGANIZATIONAL_UNIT_NAME,
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001197 u"indirectCRL CA3 cRLIssuer"
1198 ),
1199 ])
1200 )],
1201 )
1202 ]),
1203 x509.CRLDistributionPoints([
1204 x509.DistributionPoint(
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001205 full_name=[x509.DirectoryName(
1206 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001207 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001208 ])
1209 )],
1210 relative_name=None,
1211 reasons=None,
1212 crl_issuer=[x509.DirectoryName(
1213 x509.Name([
1214 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001215 NameOID.ORGANIZATION_NAME,
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001216 u"cryptography Testing"
1217 ),
1218 ])
1219 )],
1220 )
1221 ]),
1222 x509.CRLDistributionPoints([
1223 x509.DistributionPoint(
Paul Kehrerc6cf8f32015-08-08 09:47:44 -05001224 full_name=[
1225 x509.UniformResourceIdentifier(
1226 u"http://myhost.com/myca.crl"
1227 ),
1228 x509.UniformResourceIdentifier(
1229 u"http://backup.myhost.com/myca.crl"
1230 )
1231 ],
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001232 relative_name=None,
1233 reasons=frozenset([
1234 x509.ReasonFlags.key_compromise,
1235 x509.ReasonFlags.ca_compromise
1236 ]),
1237 crl_issuer=[x509.DirectoryName(
1238 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001239 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001240 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001241 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001242 ),
1243 ])
1244 )],
1245 )
1246 ]),
1247 x509.CRLDistributionPoints([
1248 x509.DistributionPoint(
1249 full_name=[x509.UniformResourceIdentifier(
1250 u"http://domain.com/some.crl"
1251 )],
1252 relative_name=None,
1253 reasons=frozenset([
1254 x509.ReasonFlags.key_compromise,
1255 x509.ReasonFlags.ca_compromise,
1256 x509.ReasonFlags.affiliation_changed,
1257 x509.ReasonFlags.superseded,
1258 x509.ReasonFlags.privilege_withdrawn,
1259 x509.ReasonFlags.cessation_of_operation,
1260 x509.ReasonFlags.aa_compromise,
1261 x509.ReasonFlags.certificate_hold,
1262 ]),
1263 crl_issuer=None
1264 )
1265 ]),
1266 x509.CRLDistributionPoints([
1267 x509.DistributionPoint(
1268 full_name=None,
1269 relative_name=None,
1270 reasons=None,
1271 crl_issuer=[x509.DirectoryName(
1272 x509.Name([
1273 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001274 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001275 ),
1276 ])
1277 )],
1278 )
1279 ]),
1280 x509.CRLDistributionPoints([
1281 x509.DistributionPoint(
1282 full_name=[x509.UniformResourceIdentifier(
1283 u"http://domain.com/some.crl"
1284 )],
1285 relative_name=None,
1286 reasons=frozenset([x509.ReasonFlags.aa_compromise]),
1287 crl_issuer=None
1288 )
1289 ])
1290 ]
1291 )
1292 @pytest.mark.requires_backend_interface(interface=RSABackend)
1293 @pytest.mark.requires_backend_interface(interface=X509Backend)
1294 def test_crl_distribution_points(self, backend, cdp):
1295 issuer_private_key = RSA_KEY_2048.private_key(backend)
1296 subject_private_key = RSA_KEY_2048.private_key(backend)
1297
1298 builder = x509.CertificateBuilder().serial_number(
1299 4444444
1300 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001301 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001302 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001303 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001304 ])).public_key(
1305 subject_private_key.public_key()
1306 ).add_extension(
1307 cdp,
1308 critical=False,
1309 ).not_valid_before(
1310 datetime.datetime(2002, 1, 1, 12, 1)
1311 ).not_valid_after(
1312 datetime.datetime(2030, 12, 31, 8, 30)
1313 )
1314
1315 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
1316
1317 ext = cert.extensions.get_extension_for_oid(
1318 x509.OID_CRL_DISTRIBUTION_POINTS
1319 )
1320 assert ext.critical is False
1321 assert ext.value == cdp
1322
Ian Cordasco56561b12015-07-24 16:38:50 -05001323 @pytest.mark.requires_backend_interface(interface=DSABackend)
1324 @pytest.mark.requires_backend_interface(interface=X509Backend)
1325 def test_build_cert_with_dsa_private_key(self, backend):
1326 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1327 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1328
1329 issuer_private_key = DSA_KEY_2048.private_key(backend)
1330 subject_private_key = DSA_KEY_2048.private_key(backend)
1331
1332 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1333 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1334
1335 builder = x509.CertificateBuilder().serial_number(
1336 777
1337 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001338 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001339 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001340 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001341 ])).public_key(
1342 subject_private_key.public_key()
1343 ).add_extension(
1344 x509.BasicConstraints(ca=False, path_length=None), True,
1345 ).add_extension(
1346 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1347 critical=False,
1348 ).not_valid_before(
1349 not_valid_before
1350 ).not_valid_after(
1351 not_valid_after
1352 )
1353
Paul Kehrer9add80e2015-08-03 17:53:14 +01001354 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001355
1356 assert cert.version is x509.Version.v3
1357 assert cert.not_valid_before == not_valid_before
1358 assert cert.not_valid_after == not_valid_after
1359 basic_constraints = cert.extensions.get_extension_for_oid(
1360 x509.OID_BASIC_CONSTRAINTS
1361 )
1362 assert basic_constraints.value.ca is False
1363 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001364 subject_alternative_name = cert.extensions.get_extension_for_oid(
1365 x509.OID_SUBJECT_ALTERNATIVE_NAME
1366 )
1367 assert list(subject_alternative_name.value) == [
1368 x509.DNSName(u"cryptography.io"),
1369 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001370
1371 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1372 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco85fc4d52015-08-01 20:29:31 -05001373 def test_build_cert_with_ec_private_key(self, backend):
Ian Cordasco56561b12015-07-24 16:38:50 -05001374 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1375 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1376
1377 _skip_curve_unsupported(backend, ec.SECP256R1())
1378 issuer_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1379 subject_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1380
1381 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1382 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1383
1384 builder = x509.CertificateBuilder().serial_number(
1385 777
1386 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001387 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001388 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001389 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001390 ])).public_key(
1391 subject_private_key.public_key()
1392 ).add_extension(
1393 x509.BasicConstraints(ca=False, path_length=None), True,
1394 ).add_extension(
1395 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1396 critical=False,
1397 ).not_valid_before(
1398 not_valid_before
1399 ).not_valid_after(
1400 not_valid_after
1401 )
1402
Paul Kehrer9add80e2015-08-03 17:53:14 +01001403 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001404
1405 assert cert.version is x509.Version.v3
1406 assert cert.not_valid_before == not_valid_before
1407 assert cert.not_valid_after == not_valid_after
1408 basic_constraints = cert.extensions.get_extension_for_oid(
1409 x509.OID_BASIC_CONSTRAINTS
1410 )
1411 assert basic_constraints.value.ca is False
1412 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001413 subject_alternative_name = cert.extensions.get_extension_for_oid(
1414 x509.OID_SUBJECT_ALTERNATIVE_NAME
1415 )
1416 assert list(subject_alternative_name.value) == [
1417 x509.DNSName(u"cryptography.io"),
1418 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001419
Ian Cordasco8690eff2015-07-24 16:42:58 -05001420 @pytest.mark.requires_backend_interface(interface=RSABackend)
1421 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco19f5a492015-08-01 11:06:17 -05001422 def test_build_cert_with_rsa_key_too_small(self, backend):
Ian Cordasco8690eff2015-07-24 16:42:58 -05001423 issuer_private_key = RSA_KEY_512.private_key(backend)
1424 subject_private_key = RSA_KEY_512.private_key(backend)
1425
1426 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1427 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1428
1429 builder = x509.CertificateBuilder().serial_number(
1430 777
1431 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001432 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001433 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001434 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001435 ])).public_key(
1436 subject_private_key.public_key()
Ian Cordasco8690eff2015-07-24 16:42:58 -05001437 ).not_valid_before(
1438 not_valid_before
1439 ).not_valid_after(
1440 not_valid_after
1441 )
1442
Ian Cordasco19f5a492015-08-01 11:06:17 -05001443 with pytest.raises(ValueError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001444 builder.sign(issuer_private_key, hashes.SHA512(), backend)
Ian Cordasco8690eff2015-07-24 16:42:58 -05001445
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001446 @pytest.mark.requires_backend_interface(interface=RSABackend)
1447 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer69b64e42015-08-09 00:00:44 -05001448 def test_issuer_alt_name(self, backend):
1449 issuer_private_key = RSA_KEY_2048.private_key(backend)
1450 subject_private_key = RSA_KEY_2048.private_key(backend)
1451
1452 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1453 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1454
1455 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001456 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer69b64e42015-08-09 00:00:44 -05001457 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001458 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer69b64e42015-08-09 00:00:44 -05001459 ).not_valid_before(
1460 not_valid_before
1461 ).not_valid_after(
1462 not_valid_after
1463 ).public_key(
1464 subject_private_key.public_key()
1465 ).serial_number(
1466 123
1467 ).add_extension(
1468 x509.IssuerAlternativeName([
1469 x509.DNSName(u"myissuer"),
1470 x509.RFC822Name(u"email@domain.com"),
1471 ]), critical=False
1472 ).sign(issuer_private_key, hashes.SHA256(), backend)
1473
1474 ext = cert.extensions.get_extension_for_oid(
1475 x509.OID_ISSUER_ALTERNATIVE_NAME
1476 )
1477 assert ext.critical is False
1478 assert ext.value == x509.IssuerAlternativeName([
1479 x509.DNSName(u"myissuer"),
1480 x509.RFC822Name(u"email@domain.com"),
1481 ])
1482
1483 @pytest.mark.requires_backend_interface(interface=RSABackend)
1484 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001485 def test_extended_key_usage(self, backend):
1486 issuer_private_key = RSA_KEY_2048.private_key(backend)
1487 subject_private_key = RSA_KEY_2048.private_key(backend)
1488
1489 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1490 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1491
1492 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001493 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001494 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001495 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001496 ).not_valid_before(
1497 not_valid_before
1498 ).not_valid_after(
1499 not_valid_after
1500 ).public_key(
1501 subject_private_key.public_key()
1502 ).serial_number(
1503 123
1504 ).add_extension(
1505 x509.ExtendedKeyUsage([
1506 x509.OID_CLIENT_AUTH,
1507 x509.OID_SERVER_AUTH,
1508 x509.OID_CODE_SIGNING,
1509 ]), critical=False
1510 ).sign(issuer_private_key, hashes.SHA256(), backend)
1511
1512 eku = cert.extensions.get_extension_for_oid(
1513 x509.OID_EXTENDED_KEY_USAGE
1514 )
1515 assert eku.critical is False
1516 assert eku.value == x509.ExtendedKeyUsage([
1517 x509.OID_CLIENT_AUTH,
1518 x509.OID_SERVER_AUTH,
1519 x509.OID_CODE_SIGNING,
1520 ])
1521
1522 @pytest.mark.requires_backend_interface(interface=RSABackend)
1523 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer683d4d82015-08-06 23:13:45 +01001524 def test_inhibit_any_policy(self, backend):
1525 issuer_private_key = RSA_KEY_2048.private_key(backend)
1526 subject_private_key = RSA_KEY_2048.private_key(backend)
1527
1528 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1529 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1530
1531 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001532 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer683d4d82015-08-06 23:13:45 +01001533 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001534 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer683d4d82015-08-06 23:13:45 +01001535 ).not_valid_before(
1536 not_valid_before
1537 ).not_valid_after(
1538 not_valid_after
1539 ).public_key(
1540 subject_private_key.public_key()
1541 ).serial_number(
1542 123
1543 ).add_extension(
1544 x509.InhibitAnyPolicy(3), critical=False
1545 ).sign(issuer_private_key, hashes.SHA256(), backend)
1546
1547 ext = cert.extensions.get_extension_for_oid(
1548 x509.OID_INHIBIT_ANY_POLICY
1549 )
1550 assert ext.value == x509.InhibitAnyPolicy(3)
1551
1552 @pytest.mark.requires_backend_interface(interface=RSABackend)
1553 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001554 def test_key_usage(self, backend):
1555 issuer_private_key = RSA_KEY_2048.private_key(backend)
1556 subject_private_key = RSA_KEY_2048.private_key(backend)
1557
1558 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1559 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1560
1561 cert = x509.CertificateBuilder().subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001562 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001563 ).issuer_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001564 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001565 ).not_valid_before(
1566 not_valid_before
1567 ).not_valid_after(
1568 not_valid_after
1569 ).public_key(
1570 subject_private_key.public_key()
1571 ).serial_number(
1572 123
1573 ).add_extension(
1574 x509.KeyUsage(
1575 digital_signature=True,
1576 content_commitment=True,
1577 key_encipherment=False,
1578 data_encipherment=False,
1579 key_agreement=False,
1580 key_cert_sign=True,
1581 crl_sign=False,
1582 encipher_only=False,
1583 decipher_only=False
1584 ),
1585 critical=False
1586 ).sign(issuer_private_key, hashes.SHA256(), backend)
1587
1588 ext = cert.extensions.get_extension_for_oid(x509.OID_KEY_USAGE)
1589 assert ext.critical is False
1590 assert ext.value == x509.KeyUsage(
1591 digital_signature=True,
1592 content_commitment=True,
1593 key_encipherment=False,
1594 data_encipherment=False,
1595 key_agreement=False,
1596 key_cert_sign=True,
1597 crl_sign=False,
1598 encipher_only=False,
1599 decipher_only=False
1600 )
1601
Ian Cordasco747a2172015-07-19 11:00:14 -05001602
Andre Caron0ef595f2015-05-18 13:53:43 -04001603@pytest.mark.requires_backend_interface(interface=X509Backend)
1604class TestCertificateSigningRequestBuilder(object):
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001605 @pytest.mark.requires_backend_interface(interface=RSABackend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001606 def test_sign_invalid_hash_algorithm(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001607 private_key = RSA_KEY_2048.private_key(backend)
1608
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001609 builder = x509.CertificateSigningRequestBuilder().subject_name(
1610 x509.Name([])
1611 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001612 with pytest.raises(TypeError):
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001613 builder.sign(private_key, 'NotAHash', backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001614
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001615 @pytest.mark.requires_backend_interface(interface=RSABackend)
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001616 def test_no_subject_name(self, backend):
1617 private_key = RSA_KEY_2048.private_key(backend)
1618
1619 builder = x509.CertificateSigningRequestBuilder()
1620 with pytest.raises(ValueError):
1621 builder.sign(private_key, hashes.SHA256(), backend)
1622
1623 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001624 def test_build_ca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001625 private_key = RSA_KEY_2048.private_key(backend)
1626
Andre Carona9a51172015-06-06 20:18:44 -04001627 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04001628 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001629 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Andre Caron99d0f902015-06-01 08:36:59 -04001630 ])
Andre Caron472fd692015-06-06 20:04:44 -04001631 ).add_extension(
Ian Cordasco41f51ce2015-06-17 11:49:11 -05001632 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001633 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001634
1635 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1636 public_key = request.public_key()
1637 assert isinstance(public_key, rsa.RSAPublicKey)
1638 subject = request.subject
1639 assert isinstance(subject, x509.Name)
1640 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001641 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Andre Caron0ef595f2015-05-18 13:53:43 -04001642 ]
1643 basic_constraints = request.extensions.get_extension_for_oid(
1644 x509.OID_BASIC_CONSTRAINTS
1645 )
1646 assert basic_constraints.value.ca is True
1647 assert basic_constraints.value.path_length == 2
1648
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001649 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001650 def test_build_ca_request_with_unicode(self, backend):
1651 private_key = RSA_KEY_2048.private_key(backend)
1652
1653 request = x509.CertificateSigningRequestBuilder().subject_name(
1654 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001655 x509.NameAttribute(NameOID.ORGANIZATION_NAME,
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001656 u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001657 ])
1658 ).add_extension(
1659 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001660 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001661
1662 loaded_request = x509.load_pem_x509_csr(
1663 request.public_bytes(encoding=serialization.Encoding.PEM), backend
1664 )
1665 subject = loaded_request.subject
1666 assert isinstance(subject, x509.Name)
1667 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001668 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001669 ]
1670
1671 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001672 def test_build_nonca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001673 private_key = RSA_KEY_2048.private_key(backend)
1674
Andre Carona9a51172015-06-06 20:18:44 -04001675 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04001676 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001677 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Andre Caron99d0f902015-06-01 08:36:59 -04001678 ])
Andre Caron472fd692015-06-06 20:04:44 -04001679 ).add_extension(
Ian Cordasco0112b022015-06-16 17:51:18 -05001680 x509.BasicConstraints(ca=False, path_length=None), critical=True,
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001681 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001682
1683 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1684 public_key = request.public_key()
1685 assert isinstance(public_key, rsa.RSAPublicKey)
1686 subject = request.subject
1687 assert isinstance(subject, x509.Name)
1688 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001689 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Andre Caron0ef595f2015-05-18 13:53:43 -04001690 ]
1691 basic_constraints = request.extensions.get_extension_for_oid(
1692 x509.OID_BASIC_CONSTRAINTS
1693 )
1694 assert basic_constraints.value.ca is False
1695 assert basic_constraints.value.path_length is None
1696
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001697 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1698 def test_build_ca_request_with_ec(self, backend):
1699 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1700 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1701
Ian Cordasco8cdcdfc2015-06-24 22:00:26 -05001702 _skip_curve_unsupported(backend, ec.SECP256R1())
1703 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001704
1705 request = x509.CertificateSigningRequestBuilder().subject_name(
1706 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001707 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001708 ])
1709 ).add_extension(
1710 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001711 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001712
1713 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1714 public_key = request.public_key()
1715 assert isinstance(public_key, ec.EllipticCurvePublicKey)
1716 subject = request.subject
1717 assert isinstance(subject, x509.Name)
1718 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001719 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001720 ]
1721 basic_constraints = request.extensions.get_extension_for_oid(
1722 x509.OID_BASIC_CONSTRAINTS
1723 )
1724 assert basic_constraints.value.ca is True
1725 assert basic_constraints.value.path_length == 2
1726
1727 @pytest.mark.requires_backend_interface(interface=DSABackend)
1728 def test_build_ca_request_with_dsa(self, backend):
1729 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1730 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1731
1732 private_key = DSA_KEY_2048.private_key(backend)
1733
1734 request = x509.CertificateSigningRequestBuilder().subject_name(
1735 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001736 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001737 ])
1738 ).add_extension(
1739 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001740 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001741
1742 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1743 public_key = request.public_key()
1744 assert isinstance(public_key, dsa.DSAPublicKey)
1745 subject = request.subject
1746 assert isinstance(subject, x509.Name)
1747 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05001748 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001749 ]
1750 basic_constraints = request.extensions.get_extension_for_oid(
1751 x509.OID_BASIC_CONSTRAINTS
1752 )
1753 assert basic_constraints.value.ca is True
1754 assert basic_constraints.value.path_length == 2
1755
Paul Kehrerff917802015-06-26 17:29:04 -05001756 def test_add_duplicate_extension(self):
Andre Caronfc164c52015-05-31 17:36:18 -04001757 builder = x509.CertificateSigningRequestBuilder().add_extension(
Andre Caron472fd692015-06-06 20:04:44 -04001758 x509.BasicConstraints(True, 2), critical=True,
Andre Caronfc164c52015-05-31 17:36:18 -04001759 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001760 with pytest.raises(ValueError):
Andre Caron472fd692015-06-06 20:04:44 -04001761 builder.add_extension(
1762 x509.BasicConstraints(True, 2), critical=True,
1763 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001764
Paul Kehrerff917802015-06-26 17:29:04 -05001765 def test_set_invalid_subject(self):
Andre Caron0ef595f2015-05-18 13:53:43 -04001766 builder = x509.CertificateSigningRequestBuilder()
1767 with pytest.raises(TypeError):
Andre Carona9a51172015-06-06 20:18:44 -04001768 builder.subject_name('NotAName')
Andre Caron0ef595f2015-05-18 13:53:43 -04001769
Paul Kehrere59fd222015-08-08 22:50:19 -05001770 def test_add_invalid_extension_type(self):
Ian Cordasco34853f32015-06-21 10:50:53 -05001771 builder = x509.CertificateSigningRequestBuilder()
Andre Caron0ef595f2015-05-18 13:53:43 -04001772
Paul Kehrere59fd222015-08-08 22:50:19 -05001773 with pytest.raises(TypeError):
1774 builder.add_extension(object(), False)
1775
1776 def test_add_unsupported_extension(self, backend):
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05001777 private_key = RSA_KEY_2048.private_key(backend)
1778 builder = x509.CertificateSigningRequestBuilder()
1779 builder = builder.subject_name(
1780 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001781 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05001782 ])
1783 ).add_extension(
Alex Gaynor7583f7f2015-07-03 10:56:49 -04001784 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1785 critical=False,
1786 ).add_extension(
Paul Kehrer69b64e42015-08-09 00:00:44 -05001787 DummyExtension(), False
Paul Kehrerdce91f02015-07-23 20:31:12 +01001788 )
1789 with pytest.raises(NotImplementedError):
1790 builder.sign(private_key, hashes.SHA256(), backend)
1791
1792 def test_key_usage(self, backend):
1793 private_key = RSA_KEY_2048.private_key(backend)
1794 builder = x509.CertificateSigningRequestBuilder()
1795 request = builder.subject_name(
1796 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001797 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerdce91f02015-07-23 20:31:12 +01001798 ])
1799 ).add_extension(
Alex Gaynorac7f70a2015-06-28 11:07:52 -04001800 x509.KeyUsage(
1801 digital_signature=True,
1802 content_commitment=True,
1803 key_encipherment=False,
1804 data_encipherment=False,
1805 key_agreement=False,
1806 key_cert_sign=True,
1807 crl_sign=False,
1808 encipher_only=False,
1809 decipher_only=False
1810 ),
Alex Gaynor887a4082015-07-03 04:29:03 -04001811 critical=False
Paul Kehrerdce91f02015-07-23 20:31:12 +01001812 ).sign(private_key, hashes.SHA256(), backend)
1813 assert len(request.extensions) == 1
1814 ext = request.extensions.get_extension_for_oid(x509.OID_KEY_USAGE)
1815 assert ext.critical is False
1816 assert ext.value == x509.KeyUsage(
1817 digital_signature=True,
1818 content_commitment=True,
1819 key_encipherment=False,
1820 data_encipherment=False,
1821 key_agreement=False,
1822 key_cert_sign=True,
1823 crl_sign=False,
1824 encipher_only=False,
1825 decipher_only=False
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05001826 )
Paul Kehrerdce91f02015-07-23 20:31:12 +01001827
1828 def test_key_usage_key_agreement_bit(self, backend):
1829 private_key = RSA_KEY_2048.private_key(backend)
1830 builder = x509.CertificateSigningRequestBuilder()
1831 request = builder.subject_name(
1832 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001833 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerdce91f02015-07-23 20:31:12 +01001834 ])
1835 ).add_extension(
1836 x509.KeyUsage(
1837 digital_signature=False,
1838 content_commitment=False,
1839 key_encipherment=False,
1840 data_encipherment=False,
1841 key_agreement=True,
1842 key_cert_sign=True,
1843 crl_sign=False,
1844 encipher_only=False,
1845 decipher_only=True
1846 ),
1847 critical=False
1848 ).sign(private_key, hashes.SHA256(), backend)
1849 assert len(request.extensions) == 1
1850 ext = request.extensions.get_extension_for_oid(x509.OID_KEY_USAGE)
1851 assert ext.critical is False
1852 assert ext.value == x509.KeyUsage(
1853 digital_signature=False,
1854 content_commitment=False,
1855 key_encipherment=False,
1856 data_encipherment=False,
1857 key_agreement=True,
1858 key_cert_sign=True,
1859 crl_sign=False,
1860 encipher_only=False,
1861 decipher_only=True
1862 )
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05001863
Paul Kehrer8bfbace2015-07-23 19:10:28 +01001864 def test_add_two_extensions(self, backend):
1865 private_key = RSA_KEY_2048.private_key(backend)
1866 builder = x509.CertificateSigningRequestBuilder()
1867 request = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05001868 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer8bfbace2015-07-23 19:10:28 +01001869 ).add_extension(
1870 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1871 critical=False,
1872 ).add_extension(
1873 x509.BasicConstraints(ca=True, path_length=2), critical=True
1874 ).sign(private_key, hashes.SHA1(), backend)
1875
1876 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1877 public_key = request.public_key()
1878 assert isinstance(public_key, rsa.RSAPublicKey)
1879 basic_constraints = request.extensions.get_extension_for_oid(
1880 x509.OID_BASIC_CONSTRAINTS
1881 )
1882 assert basic_constraints.value.ca is True
1883 assert basic_constraints.value.path_length == 2
1884 ext = request.extensions.get_extension_for_oid(
1885 x509.OID_SUBJECT_ALTERNATIVE_NAME
1886 )
1887 assert list(ext.value) == [x509.DNSName(u"cryptography.io")]
Paul Kehrerff917802015-06-26 17:29:04 -05001888
Andre Caron0ef595f2015-05-18 13:53:43 -04001889 def test_set_subject_twice(self):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001890 builder = x509.CertificateSigningRequestBuilder()
1891 builder = builder.subject_name(
Paul Kehrere76cd272014-12-14 19:00:51 -06001892 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001893 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrera693cfd2014-11-27 07:47:58 -10001894 ])
Paul Kehrer4903adc2014-12-13 16:57:50 -06001895 )
Paul Kehrer41120322014-12-02 18:31:14 -10001896 with pytest.raises(ValueError):
Paul Kehrera693cfd2014-11-27 07:47:58 -10001897 builder.subject_name(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001898 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001899 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001900 ])
Alex Gaynor32c57df2015-02-23 21:51:27 -08001901 )
Alex Gaynorfcadda62015-03-10 10:01:18 -04001902
Alex Gaynord3e84162015-06-28 10:14:55 -04001903 def test_subject_alt_names(self, backend):
1904 private_key = RSA_KEY_2048.private_key(backend)
1905
1906 csr = x509.CertificateSigningRequestBuilder().subject_name(
1907 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001908 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Alex Gaynord3e84162015-06-28 10:14:55 -04001909 ])
1910 ).add_extension(
1911 x509.SubjectAlternativeName([
Alex Gaynor6431d502015-07-05 12:28:46 -04001912 x509.DNSName(u"example.com"),
1913 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05001914 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05001915 x509.DirectoryName(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001916 x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05001917 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001918 NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
Paul Kehrer9ce25a92015-07-10 11:08:31 -05001919 )
1920 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05001921 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
1922 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05001923 x509.OtherName(
1924 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
1925 value=b"0\x03\x02\x01\x05"
1926 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05001927 x509.RFC822Name(u"test@example.com"),
1928 x509.RFC822Name(u"email"),
1929 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05001930 x509.UniformResourceIdentifier(
1931 u"https://\u043f\u044b\u043a\u0430.cryptography"
1932 ),
1933 x509.UniformResourceIdentifier(
1934 u"gopher://cryptography:70/some/path"
1935 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04001936 ]),
1937 critical=False,
1938 ).sign(private_key, hashes.SHA256(), backend)
1939
1940 assert len(csr.extensions) == 1
1941 ext = csr.extensions.get_extension_for_oid(
1942 x509.OID_SUBJECT_ALTERNATIVE_NAME
1943 )
1944 assert not ext.critical
1945 assert ext.oid == x509.OID_SUBJECT_ALTERNATIVE_NAME
1946 assert list(ext.value) == [
Alex Gaynor6431d502015-07-05 12:28:46 -04001947 x509.DNSName(u"example.com"),
1948 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05001949 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05001950 x509.DirectoryName(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001951 x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05001952 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05001953 NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
Paul Kehrer9ce25a92015-07-10 11:08:31 -05001954 ),
1955 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05001956 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
1957 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05001958 x509.OtherName(
1959 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
1960 value=b"0\x03\x02\x01\x05"
1961 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05001962 x509.RFC822Name(u"test@example.com"),
1963 x509.RFC822Name(u"email"),
1964 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05001965 x509.UniformResourceIdentifier(
1966 u"https://\u043f\u044b\u043a\u0430.cryptography"
1967 ),
1968 x509.UniformResourceIdentifier(
1969 u"gopher://cryptography:70/some/path"
1970 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04001971 ]
1972
Paul Kehrer500ed9d2015-07-10 20:51:36 -05001973 def test_invalid_asn1_othername(self, backend):
1974 private_key = RSA_KEY_2048.private_key(backend)
1975
1976 builder = x509.CertificateSigningRequestBuilder().subject_name(
1977 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001978 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Paul Kehrer500ed9d2015-07-10 20:51:36 -05001979 ])
1980 ).add_extension(
1981 x509.SubjectAlternativeName([
1982 x509.OtherName(
1983 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
1984 value=b"\x01\x02\x01\x05"
1985 ),
1986 ]),
1987 critical=False,
1988 )
1989 with pytest.raises(ValueError):
1990 builder.sign(private_key, hashes.SHA256(), backend)
1991
Alex Gaynord5f718c2015-07-05 11:19:38 -04001992 def test_subject_alt_name_unsupported_general_name(self, backend):
1993 private_key = RSA_KEY_2048.private_key(backend)
1994
1995 builder = x509.CertificateSigningRequestBuilder().subject_name(
1996 x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05001997 x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
Alex Gaynord5f718c2015-07-05 11:19:38 -04001998 ])
1999 ).add_extension(
Paul Kehrer474a6472015-07-11 12:29:52 -05002000 x509.SubjectAlternativeName([FakeGeneralName("")]),
Alex Gaynord5f718c2015-07-05 11:19:38 -04002001 critical=False,
2002 )
2003
Paul Kehrer474a6472015-07-11 12:29:52 -05002004 with pytest.raises(ValueError):
Alex Gaynord5f718c2015-07-05 11:19:38 -04002005 builder.sign(private_key, hashes.SHA256(), backend)
2006
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002007 def test_extended_key_usage(self, backend):
2008 private_key = RSA_KEY_2048.private_key(backend)
2009 builder = x509.CertificateSigningRequestBuilder()
2010 request = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002011 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002012 ).add_extension(
2013 x509.ExtendedKeyUsage([
2014 x509.OID_CLIENT_AUTH,
2015 x509.OID_SERVER_AUTH,
2016 x509.OID_CODE_SIGNING,
2017 ]), critical=False
2018 ).sign(private_key, hashes.SHA256(), backend)
2019
2020 eku = request.extensions.get_extension_for_oid(
2021 x509.OID_EXTENDED_KEY_USAGE
2022 )
2023 assert eku.critical is False
2024 assert eku.value == x509.ExtendedKeyUsage([
2025 x509.OID_CLIENT_AUTH,
2026 x509.OID_SERVER_AUTH,
2027 x509.OID_CODE_SIGNING,
2028 ])
2029
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002030 @pytest.mark.requires_backend_interface(interface=RSABackend)
2031 def test_rsa_key_too_small(self, backend):
2032 private_key = rsa.generate_private_key(65537, 512, backend)
2033 builder = x509.CertificateSigningRequestBuilder()
2034 builder = builder.subject_name(
Paul Kehrereba19e62015-08-10 18:44:24 -05002035 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002036 )
2037
2038 with pytest.raises(ValueError) as exc:
2039 builder.sign(private_key, hashes.SHA512(), backend)
2040
Paul Kehrer6a71f8d2015-07-25 19:15:59 +01002041 assert str(exc.value) == "Digest too big for RSA key"
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002042
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002043 @pytest.mark.requires_backend_interface(interface=RSABackend)
2044 @pytest.mark.requires_backend_interface(interface=X509Backend)
2045 def test_build_cert_with_aia(self, backend):
2046 issuer_private_key = RSA_KEY_2048.private_key(backend)
2047 subject_private_key = RSA_KEY_2048.private_key(backend)
2048
2049 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2050 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2051
2052 aia = x509.AuthorityInformationAccess([
2053 x509.AccessDescription(
2054 x509.OID_OCSP,
2055 x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
2056 ),
2057 x509.AccessDescription(
2058 x509.OID_CA_ISSUERS,
2059 x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
2060 )
2061 ])
2062
2063 builder = x509.CertificateBuilder().serial_number(
2064 777
2065 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002066 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002067 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002068 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002069 ])).public_key(
2070 subject_private_key.public_key()
2071 ).add_extension(
2072 aia, critical=False
2073 ).not_valid_before(
2074 not_valid_before
2075 ).not_valid_after(
2076 not_valid_after
2077 )
2078
2079 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2080
2081 ext = cert.extensions.get_extension_for_oid(
2082 x509.OID_AUTHORITY_INFORMATION_ACCESS
2083 )
2084 assert ext.value == aia
2085
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002086 @pytest.mark.requires_backend_interface(interface=RSABackend)
2087 @pytest.mark.requires_backend_interface(interface=X509Backend)
2088 def test_build_cert_with_ski(self, backend):
2089 issuer_private_key = RSA_KEY_2048.private_key(backend)
2090 subject_private_key = RSA_KEY_2048.private_key(backend)
2091
2092 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2093 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2094
2095 ski = x509.SubjectKeyIdentifier.from_public_key(
2096 subject_private_key.public_key()
2097 )
2098
2099 builder = x509.CertificateBuilder().serial_number(
2100 777
2101 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002102 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002103 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002104 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002105 ])).public_key(
2106 subject_private_key.public_key()
2107 ).add_extension(
2108 ski, critical=False
2109 ).not_valid_before(
2110 not_valid_before
2111 ).not_valid_after(
2112 not_valid_after
2113 )
2114
2115 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2116
2117 ext = cert.extensions.get_extension_for_oid(
2118 x509.OID_SUBJECT_KEY_IDENTIFIER
2119 )
2120 assert ext.value == ski
2121
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002122 @pytest.mark.parametrize(
2123 "aki",
2124 [
2125 x509.AuthorityKeyIdentifier(
2126 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2127 b"\xcbY",
2128 None,
2129 None
2130 ),
2131 x509.AuthorityKeyIdentifier(
2132 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2133 b"\xcbY",
2134 [
2135 x509.DirectoryName(
2136 x509.Name([
2137 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002138 NameOID.ORGANIZATION_NAME, u"PyCA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002139 ),
2140 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002141 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002142 )
2143 ])
2144 )
2145 ],
2146 333
2147 ),
2148 x509.AuthorityKeyIdentifier(
2149 None,
2150 [
2151 x509.DirectoryName(
2152 x509.Name([
2153 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002154 NameOID.ORGANIZATION_NAME, u"PyCA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002155 ),
2156 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -05002157 NameOID.COMMON_NAME, u"cryptography CA"
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002158 )
2159 ])
2160 )
2161 ],
2162 333
2163 ),
2164 ]
2165 )
2166 @pytest.mark.requires_backend_interface(interface=RSABackend)
2167 @pytest.mark.requires_backend_interface(interface=X509Backend)
2168 def test_build_cert_with_aki(self, aki, backend):
2169 issuer_private_key = RSA_KEY_2048.private_key(backend)
2170 subject_private_key = RSA_KEY_2048.private_key(backend)
2171
2172 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2173 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2174
2175 builder = x509.CertificateBuilder().serial_number(
2176 777
2177 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002178 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002179 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002180 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002181 ])).public_key(
2182 subject_private_key.public_key()
2183 ).add_extension(
2184 aki, critical=False
2185 ).not_valid_before(
2186 not_valid_before
2187 ).not_valid_after(
2188 not_valid_after
2189 )
2190
2191 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2192
2193 ext = cert.extensions.get_extension_for_oid(
2194 x509.OID_AUTHORITY_KEY_IDENTIFIER
2195 )
2196 assert ext.value == aki
2197
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002198 def test_ocsp_nocheck(self, backend):
2199 issuer_private_key = RSA_KEY_2048.private_key(backend)
2200 subject_private_key = RSA_KEY_2048.private_key(backend)
2201
2202 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2203 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2204
2205 builder = x509.CertificateBuilder().serial_number(
2206 777
2207 ).issuer_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002208 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002209 ])).subject_name(x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002210 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
Paul Kehrerf7d1b722015-08-06 18:49:45 +01002211 ])).public_key(
2212 subject_private_key.public_key()
2213 ).add_extension(
2214 x509.OCSPNoCheck(), critical=False
2215 ).not_valid_before(
2216 not_valid_before
2217 ).not_valid_after(
2218 not_valid_after
2219 )
2220
2221 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2222
2223 ext = cert.extensions.get_extension_for_oid(
2224 x509.OID_OCSP_NO_CHECK
2225 )
2226 assert isinstance(ext.value, x509.OCSPNoCheck)
2227
Alex Gaynord5f718c2015-07-05 11:19:38 -04002228
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002229@pytest.mark.requires_backend_interface(interface=DSABackend)
2230@pytest.mark.requires_backend_interface(interface=X509Backend)
2231class TestDSACertificate(object):
2232 def test_load_dsa_cert(self, backend):
2233 cert = _load_cert(
2234 os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
2235 x509.load_pem_x509_certificate,
2236 backend
2237 )
2238 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
2239 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002240 assert isinstance(public_key, dsa.DSAPublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002241 num = public_key.public_numbers()
2242 assert num.y == int(
2243 "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94"
2244 "53b6656f13e543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2"
2245 "dea559f0b584c97a2b235b9b69b46bc6de1aed422a6f341832618bcaae2"
2246 "198aba388099dafb05ff0b5efecb3b0ae169a62e1c72022af50ae68af3b"
2247 "033c18e6eec1f7df4692c456ccafb79cc7e08da0a5786e9816ceda651d6"
2248 "1b4bb7b81c2783da97cea62df67af5e85991fdc13aff10fc60e06586386"
2249 "b96bb78d65750f542f86951e05a6d81baadbcd35a2e5cad4119923ae6a2"
2250 "002091a3d17017f93c52970113cdc119970b9074ca506eac91c3dd37632"
2251 "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c", 16
2252 )
2253 assert num.parameter_numbers.g == int(
2254 "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67"
2255 "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b"
2256 "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2"
2257 "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa"
2258 "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f"
2259 "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a"
2260 "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0"
2261 "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76"
2262 "fa6247676a6d3ac945844a083509c6a1b436baca", 16
2263 )
2264 assert num.parameter_numbers.p == int(
2265 "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3"
2266 "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330"
2267 "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e"
2268 "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a"
2269 "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4"
2270 "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2"
2271 "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93"
2272 "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d"
2273 "833e36468f3907cfca788a3cb790f0341c8a31bf", 16
2274 )
2275 assert num.parameter_numbers.q == int(
2276 "822ff5d234e073b901cf5941f58e1f538e71d40d", 16
2277 )
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002278
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002279 @pytest.mark.parametrize(
2280 ("path", "loader_func"),
2281 [
2282 [
2283 os.path.join("x509", "requests", "dsa_sha1.pem"),
2284 x509.load_pem_x509_csr
2285 ],
2286 [
2287 os.path.join("x509", "requests", "dsa_sha1.der"),
2288 x509.load_der_x509_csr
2289 ],
2290 ]
2291 )
2292 def test_load_dsa_request(self, path, loader_func, backend):
2293 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002294 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2295 public_key = request.public_key()
2296 assert isinstance(public_key, dsa.DSAPublicKey)
2297 subject = request.subject
2298 assert isinstance(subject, x509.Name)
2299 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002300 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2301 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2302 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2303 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2304 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002305 ]
2306
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002307
2308@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2309@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -06002310class TestECDSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002311 def test_load_ecdsa_cert(self, backend):
2312 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrera693cfd2014-11-27 07:47:58 -10002313 cert = _load_cert(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002314 os.path.join("x509", "ecdsa_root.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -10002315 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -10002316 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002317 )
Paul Kehrer8802a5b2015-02-13 12:06:57 -06002318 assert isinstance(cert.signature_hash_algorithm, hashes.SHA384)
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002319 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002320 assert isinstance(public_key, ec.EllipticCurvePublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002321 num = public_key.public_numbers()
2322 assert num.x == int(
2323 "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f"
2324 "6f0ccd00bba615b51467e9e2d9fee8e630c17", 16
2325 )
2326 assert num.y == int(
2327 "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7"
2328 "2deae88a7a16bb543ce67dc23ff031ca3e23e", 16
2329 )
2330 assert isinstance(num.curve, ec.SECP384R1)
Paul Kehrer6c660a82014-12-12 11:50:44 -06002331
2332 def test_load_ecdsa_no_named_curve(self, backend):
2333 _skip_curve_unsupported(backend, ec.SECP256R1())
2334 cert = _load_cert(
2335 os.path.join("x509", "custom", "ec_no_named_curve.pem"),
2336 x509.load_pem_x509_certificate,
2337 backend
2338 )
2339 with pytest.raises(NotImplementedError):
2340 cert.public_key()
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002341
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002342 @pytest.mark.parametrize(
2343 ("path", "loader_func"),
2344 [
2345 [
2346 os.path.join("x509", "requests", "ec_sha256.pem"),
2347 x509.load_pem_x509_csr
2348 ],
2349 [
2350 os.path.join("x509", "requests", "ec_sha256.der"),
2351 x509.load_der_x509_csr
2352 ],
2353 ]
2354 )
2355 def test_load_ecdsa_certificate_request(self, path, loader_func, backend):
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002356 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002357 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002358 assert isinstance(request.signature_hash_algorithm, hashes.SHA256)
2359 public_key = request.public_key()
2360 assert isinstance(public_key, ec.EllipticCurvePublicKey)
2361 subject = request.subject
2362 assert isinstance(subject, x509.Name)
2363 assert list(subject) == [
Paul Kehrereba19e62015-08-10 18:44:24 -05002364 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2365 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2366 x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2367 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2368 x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002369 ]
2370
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002371
Paul Kehrer806bfb22015-02-02 17:05:24 -06002372class TestNameAttribute(object):
Alex Gaynora56ff412015-02-10 17:26:32 -05002373 def test_init_bad_oid(self):
2374 with pytest.raises(TypeError):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002375 x509.NameAttribute(None, u'value')
Alex Gaynora56ff412015-02-10 17:26:32 -05002376
Ian Cordasco7618fbe2015-06-16 19:12:17 -05002377 def test_init_bad_value(self):
2378 with pytest.raises(TypeError):
2379 x509.NameAttribute(
2380 x509.ObjectIdentifier('oid'),
2381 b'bytes'
2382 )
2383
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002384 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002385 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002386 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002387 ) == x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002388 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002389 )
2390
2391 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002392 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002393 x509.ObjectIdentifier('2.5.4.3'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002394 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002395 x509.ObjectIdentifier('2.5.4.5'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002396 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002397 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002398 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002399 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002400 x509.ObjectIdentifier('oid'), u'value2'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002401 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002402 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002403 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002404 ) != object()
2405
Paul Kehrera498be82015-02-12 15:00:56 -06002406 def test_repr(self):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002407 na = x509.NameAttribute(x509.ObjectIdentifier('2.5.4.3'), u'value')
Ian Cordascoa908d692015-06-16 21:35:24 -05002408 if six.PY3:
2409 assert repr(na) == (
2410 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2411 "nName)>, value='value')>"
2412 )
2413 else:
2414 assert repr(na) == (
2415 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2416 "nName)>, value=u'value')>"
2417 )
Paul Kehrera498be82015-02-12 15:00:56 -06002418
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002419
2420class TestObjectIdentifier(object):
2421 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002422 oid1 = x509.ObjectIdentifier('oid')
2423 oid2 = x509.ObjectIdentifier('oid')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002424 assert oid1 == oid2
2425
2426 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002427 oid1 = x509.ObjectIdentifier('oid')
2428 assert oid1 != x509.ObjectIdentifier('oid1')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002429 assert oid1 != object()
2430
2431 def test_repr(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002432 oid = x509.ObjectIdentifier("2.5.4.3")
2433 assert repr(oid) == "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>"
2434 oid = x509.ObjectIdentifier("oid1")
2435 assert repr(oid) == "<ObjectIdentifier(oid=oid1, name=Unknown OID)>"
Paul Kehrer719d5362015-01-01 20:03:52 -06002436
2437
2438class TestName(object):
2439 def test_eq(self):
2440 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002441 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2442 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002443 ])
2444 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002445 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2446 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002447 ])
2448 assert name1 == name2
2449
2450 def test_ne(self):
2451 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002452 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2453 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002454 ])
2455 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002456 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
2457 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002458 ])
2459 assert name1 != name2
2460 assert name1 != object()
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002461
2462 def test_repr(self):
2463 name = x509.Name([
Paul Kehrereba19e62015-08-10 18:44:24 -05002464 x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
2465 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002466 ])
2467
Ian Cordascoa908d692015-06-16 21:35:24 -05002468 if six.PY3:
2469 assert repr(name) == (
2470 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2471 "=commonName)>, value='cryptography.io')>, <NameAttribute(oid="
2472 "<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, valu"
2473 "e='PyCA')>])>"
2474 )
2475 else:
2476 assert repr(name) == (
2477 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2478 "=commonName)>, value=u'cryptography.io')>, <NameAttribute(oid"
2479 "=<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, val"
2480 "ue=u'PyCA')>])>"
2481 )