blob: ce52ffac345c8df55089cf806f16813c131b0a77 [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 Kehrer016e08a2014-11-26 09:41:18 -100023
Ian Cordasco8ed8edc2015-06-22 20:11:17 -050024from .hazmat.primitives.fixtures_dsa import DSA_KEY_2048
Ian Cordasco85fc4d52015-08-01 20:29:31 -050025from .hazmat.primitives.fixtures_rsa import RSA_KEY_2048, RSA_KEY_512
Ian Cordasco4d46eb72015-06-17 12:08:27 -050026from .hazmat.primitives.test_ec import _skip_curve_unsupported
Paul Kehrera9d78c12014-11-26 10:59:03 -100027from .utils import load_vectors_from_file
Paul Kehrer016e08a2014-11-26 09:41:18 -100028
29
Paul Kehrer69b64e42015-08-09 00:00:44 -050030@utils.register_interface(x509.ExtensionType)
31class DummyExtension(object):
32 oid = x509.ObjectIdentifier("1.2.3.4")
33
34
Paul Kehrer474a6472015-07-11 12:29:52 -050035@utils.register_interface(x509.GeneralName)
36class FakeGeneralName(object):
37 def __init__(self, value):
38 self._value = value
39
40 value = utils.read_only_property("_value")
41
42
Paul Kehrer41120322014-12-02 18:31:14 -100043def _load_cert(filename, loader, backend):
Paul Kehrer016e08a2014-11-26 09:41:18 -100044 cert = load_vectors_from_file(
Paul Kehrera693cfd2014-11-27 07:47:58 -100045 filename=filename,
46 loader=lambda pemfile: loader(pemfile.read(), backend),
47 mode="rb"
Paul Kehrer016e08a2014-11-26 09:41:18 -100048 )
49 return cert
50
51
52@pytest.mark.requires_backend_interface(interface=RSABackend)
53@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -060054class TestRSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -100055 def test_load_pem_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -100056 cert = _load_cert(
57 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -100058 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -100059 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -100060 )
Paul Kehrere76cd272014-12-14 19:00:51 -060061 assert isinstance(cert, x509.Certificate)
62 assert cert.serial == 11559813051657483483
63 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
64 assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8"
Paul Kehrer8802a5b2015-02-13 12:06:57 -060065 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
Paul Kehrerf1ef3512014-11-26 17:36:05 -100066
67 def test_load_der_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -100068 cert = _load_cert(
69 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -100070 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -100071 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -100072 )
Paul Kehrere76cd272014-12-14 19:00:51 -060073 assert isinstance(cert, x509.Certificate)
74 assert cert.serial == 2
75 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
76 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer8802a5b2015-02-13 12:06:57 -060077 assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
Paul Kehrerf1ef3512014-11-26 17:36:05 -100078
Paul Kehrer719d5362015-01-01 20:03:52 -060079 def test_issuer(self, backend):
80 cert = _load_cert(
81 os.path.join(
82 "x509", "PKITS_data", "certs",
83 "Validpre2000UTCnotBeforeDateTest3EE.crt"
84 ),
85 x509.load_der_x509_certificate,
86 backend
87 )
88 issuer = cert.issuer
89 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -060090 assert list(issuer) == [
Ian Cordasco82fc3762015-06-16 20:59:50 -050091 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -060092 x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -050093 x509.OID_ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -060094 ),
Ian Cordasco82fc3762015-06-16 20:59:50 -050095 x509.NameAttribute(x509.OID_COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -060096 ]
Paul Kehrere901d642015-02-11 18:50:58 -060097 assert issuer.get_attributes_for_oid(x509.OID_COMMON_NAME) == [
Ian Cordasco82fc3762015-06-16 20:59:50 -050098 x509.NameAttribute(x509.OID_COMMON_NAME, u'Good CA')
Paul Kehrer719d5362015-01-01 20:03:52 -060099 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600100
101 def test_all_issuer_name_types(self, backend):
102 cert = _load_cert(
103 os.path.join(
104 "x509", "custom",
105 "all_supported_names.pem"
106 ),
107 x509.load_pem_x509_certificate,
108 backend
109 )
110 issuer = cert.issuer
111
112 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600113 assert list(issuer) == [
Ian Cordasco82fc3762015-06-16 20:59:50 -0500114 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
115 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'CA'),
116 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
117 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Illinois'),
118 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Chicago'),
119 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
120 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'Zero, LLC'),
121 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'One, LLC'),
122 x509.NameAttribute(x509.OID_COMMON_NAME, u'common name 0'),
123 x509.NameAttribute(x509.OID_COMMON_NAME, u'common name 1'),
124 x509.NameAttribute(x509.OID_ORGANIZATIONAL_UNIT_NAME, u'OU 0'),
125 x509.NameAttribute(x509.OID_ORGANIZATIONAL_UNIT_NAME, u'OU 1'),
126 x509.NameAttribute(x509.OID_DN_QUALIFIER, u'dnQualifier0'),
127 x509.NameAttribute(x509.OID_DN_QUALIFIER, u'dnQualifier1'),
128 x509.NameAttribute(x509.OID_SERIAL_NUMBER, u'123'),
129 x509.NameAttribute(x509.OID_SERIAL_NUMBER, u'456'),
130 x509.NameAttribute(x509.OID_TITLE, u'Title 0'),
131 x509.NameAttribute(x509.OID_TITLE, u'Title 1'),
132 x509.NameAttribute(x509.OID_SURNAME, u'Surname 0'),
133 x509.NameAttribute(x509.OID_SURNAME, u'Surname 1'),
134 x509.NameAttribute(x509.OID_GIVEN_NAME, u'Given Name 0'),
135 x509.NameAttribute(x509.OID_GIVEN_NAME, u'Given Name 1'),
136 x509.NameAttribute(x509.OID_PSEUDONYM, u'Incognito 0'),
137 x509.NameAttribute(x509.OID_PSEUDONYM, u'Incognito 1'),
138 x509.NameAttribute(x509.OID_GENERATION_QUALIFIER, u'Last Gen'),
139 x509.NameAttribute(x509.OID_GENERATION_QUALIFIER, u'Next Gen'),
140 x509.NameAttribute(x509.OID_DOMAIN_COMPONENT, u'dc0'),
141 x509.NameAttribute(x509.OID_DOMAIN_COMPONENT, u'dc1'),
142 x509.NameAttribute(x509.OID_EMAIL_ADDRESS, u'test0@test.local'),
143 x509.NameAttribute(x509.OID_EMAIL_ADDRESS, u'test1@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600144 ]
145
Paul Kehrer719d5362015-01-01 20:03:52 -0600146 def test_subject(self, backend):
147 cert = _load_cert(
148 os.path.join(
149 "x509", "PKITS_data", "certs",
150 "Validpre2000UTCnotBeforeDateTest3EE.crt"
151 ),
152 x509.load_der_x509_certificate,
153 backend
154 )
155 subject = cert.subject
156 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600157 assert list(subject) == [
Ian Cordasco82fc3762015-06-16 20:59:50 -0500158 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600159 x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -0500160 x509.OID_ORGANIZATION_NAME, u'Test Certificates 2011'
Paul Kehrer719d5362015-01-01 20:03:52 -0600161 ),
162 x509.NameAttribute(
163 x509.OID_COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500164 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600165 )
166 ]
Paul Kehrere901d642015-02-11 18:50:58 -0600167 assert subject.get_attributes_for_oid(x509.OID_COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600168 x509.NameAttribute(
169 x509.OID_COMMON_NAME,
Ian Cordasco82fc3762015-06-16 20:59:50 -0500170 u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
Paul Kehrer719d5362015-01-01 20:03:52 -0600171 )
172 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600173
174 def test_unicode_name(self, backend):
175 cert = _load_cert(
176 os.path.join(
177 "x509", "custom",
178 "utf8_common_name.pem"
179 ),
180 x509.load_pem_x509_certificate,
181 backend
182 )
Paul Kehrere901d642015-02-11 18:50:58 -0600183 assert cert.subject.get_attributes_for_oid(x509.OID_COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600184 x509.NameAttribute(
185 x509.OID_COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530186 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600187 )
188 ]
Paul Kehrere901d642015-02-11 18:50:58 -0600189 assert cert.issuer.get_attributes_for_oid(x509.OID_COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600190 x509.NameAttribute(
191 x509.OID_COMMON_NAME,
Eeshan Gargf1234152015-04-29 18:41:00 +0530192 u'We heart UTF8!\u2122'
Paul Kehrer719d5362015-01-01 20:03:52 -0600193 )
194 ]
195
196 def test_all_subject_name_types(self, backend):
197 cert = _load_cert(
198 os.path.join(
199 "x509", "custom",
200 "all_supported_names.pem"
201 ),
202 x509.load_pem_x509_certificate,
203 backend
204 )
205 subject = cert.subject
206 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600207 assert list(subject) == [
Ian Cordasco82fc3762015-06-16 20:59:50 -0500208 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'AU'),
209 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'DE'),
210 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'California'),
211 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'New York'),
212 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'San Francisco'),
213 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Ithaca'),
214 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'Org Zero, LLC'),
215 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'Org One, LLC'),
216 x509.NameAttribute(x509.OID_COMMON_NAME, u'CN 0'),
217 x509.NameAttribute(x509.OID_COMMON_NAME, u'CN 1'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600218 x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -0500219 x509.OID_ORGANIZATIONAL_UNIT_NAME, u'Engineering 0'
Paul Kehrer719d5362015-01-01 20:03:52 -0600220 ),
221 x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -0500222 x509.OID_ORGANIZATIONAL_UNIT_NAME, u'Engineering 1'
Paul Kehrer719d5362015-01-01 20:03:52 -0600223 ),
Ian Cordasco82fc3762015-06-16 20:59:50 -0500224 x509.NameAttribute(x509.OID_DN_QUALIFIER, u'qualified0'),
225 x509.NameAttribute(x509.OID_DN_QUALIFIER, u'qualified1'),
226 x509.NameAttribute(x509.OID_SERIAL_NUMBER, u'789'),
227 x509.NameAttribute(x509.OID_SERIAL_NUMBER, u'012'),
228 x509.NameAttribute(x509.OID_TITLE, u'Title IX'),
229 x509.NameAttribute(x509.OID_TITLE, u'Title X'),
230 x509.NameAttribute(x509.OID_SURNAME, u'Last 0'),
231 x509.NameAttribute(x509.OID_SURNAME, u'Last 1'),
232 x509.NameAttribute(x509.OID_GIVEN_NAME, u'First 0'),
233 x509.NameAttribute(x509.OID_GIVEN_NAME, u'First 1'),
234 x509.NameAttribute(x509.OID_PSEUDONYM, u'Guy Incognito 0'),
235 x509.NameAttribute(x509.OID_PSEUDONYM, u'Guy Incognito 1'),
236 x509.NameAttribute(x509.OID_GENERATION_QUALIFIER, u'32X'),
237 x509.NameAttribute(x509.OID_GENERATION_QUALIFIER, u'Dreamcast'),
238 x509.NameAttribute(x509.OID_DOMAIN_COMPONENT, u'dc2'),
239 x509.NameAttribute(x509.OID_DOMAIN_COMPONENT, u'dc3'),
240 x509.NameAttribute(x509.OID_EMAIL_ADDRESS, u'test2@test.local'),
241 x509.NameAttribute(x509.OID_EMAIL_ADDRESS, u'test3@test.local'),
Paul Kehrer719d5362015-01-01 20:03:52 -0600242 ]
243
Paul Kehrer016e08a2014-11-26 09:41:18 -1000244 def test_load_good_ca_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000245 cert = _load_cert(
246 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000247 x509.load_der_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000248 backend
249 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000250
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600251 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
252 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrer016e08a2014-11-26 09:41:18 -1000253 assert cert.serial == 2
254 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -0800255 assert isinstance(public_key, rsa.RSAPublicKey)
Paul Kehrere76cd272014-12-14 19:00:51 -0600256 assert cert.version is x509.Version.v3
Paul Kehrer0307c372014-11-27 09:49:31 -1000257 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
Paul Kehrer4e1db792014-11-27 10:50:55 -1000258 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer016e08a2014-11-26 09:41:18 -1000259
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000260 def test_utc_pre_2000_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000261 cert = _load_cert(
262 os.path.join(
263 "x509", "PKITS_data", "certs",
264 "Validpre2000UTCnotBeforeDateTest3EE.crt"
265 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000266 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000267 backend
268 )
269
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600270 assert cert.not_valid_before == datetime.datetime(1950, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000271
272 def test_pre_2000_utc_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000273 cert = _load_cert(
274 os.path.join(
275 "x509", "PKITS_data", "certs",
276 "Invalidpre2000UTCEEnotAfterDateTest7EE.crt"
277 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000278 x509.load_der_x509_certificate,
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000279 backend
280 )
281
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600282 assert cert.not_valid_after == datetime.datetime(1999, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000283
284 def test_post_2000_utc_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000285 cert = _load_cert(
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000286 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000287 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000288 backend
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000289 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600290 assert cert.not_valid_before == datetime.datetime(
291 2014, 11, 26, 21, 41, 20
292 )
293 assert cert.not_valid_after == datetime.datetime(
294 2014, 12, 26, 21, 41, 20
295 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000296
297 def test_generalized_time_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000298 cert = _load_cert(
299 os.path.join(
300 "x509", "PKITS_data", "certs",
301 "ValidGeneralizedTimenotBeforeDateTest4EE.crt"
302 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000303 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000304 backend
305 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600306 assert cert.not_valid_before == datetime.datetime(2002, 1, 1, 12, 1)
307 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrere76cd272014-12-14 19:00:51 -0600308 assert cert.version is x509.Version.v3
Paul Kehrer016e08a2014-11-26 09:41:18 -1000309
310 def test_generalized_time_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000311 cert = _load_cert(
312 os.path.join(
313 "x509", "PKITS_data", "certs",
314 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
315 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000316 x509.load_der_x509_certificate,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000317 backend
318 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600319 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
320 assert cert.not_valid_after == datetime.datetime(2050, 1, 1, 12, 1)
Paul Kehrere76cd272014-12-14 19:00:51 -0600321 assert cert.version is x509.Version.v3
Paul Kehrera9d78c12014-11-26 10:59:03 -1000322
323 def test_invalid_version_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000324 cert = _load_cert(
Paul Kehrera9d78c12014-11-26 10:59:03 -1000325 os.path.join("x509", "custom", "invalid_version.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000326 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000327 backend
Paul Kehrera9d78c12014-11-26 10:59:03 -1000328 )
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600329 with pytest.raises(x509.InvalidVersion) as exc:
Paul Kehrera9d78c12014-11-26 10:59:03 -1000330 cert.version
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000331
Paul Kehrerd5cccf72014-12-15 17:20:33 -0600332 assert exc.value.parsed_version == 7
333
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -0500334 def test_eq(self, backend):
335 cert = _load_cert(
336 os.path.join("x509", "custom", "post2000utctime.pem"),
337 x509.load_pem_x509_certificate,
338 backend
339 )
340 cert2 = _load_cert(
341 os.path.join("x509", "custom", "post2000utctime.pem"),
342 x509.load_pem_x509_certificate,
343 backend
344 )
345 assert cert == cert2
346
347 def test_ne(self, backend):
348 cert = _load_cert(
349 os.path.join("x509", "custom", "post2000utctime.pem"),
350 x509.load_pem_x509_certificate,
351 backend
352 )
353 cert2 = _load_cert(
354 os.path.join(
355 "x509", "PKITS_data", "certs",
356 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
357 ),
358 x509.load_der_x509_certificate,
359 backend
360 )
361 assert cert != cert2
362 assert cert != object()
363
Alex Gaynor969f3a52015-07-06 18:52:41 -0400364 def test_hash(self, backend):
365 cert1 = _load_cert(
366 os.path.join("x509", "custom", "post2000utctime.pem"),
367 x509.load_pem_x509_certificate,
368 backend
369 )
370 cert2 = _load_cert(
371 os.path.join("x509", "custom", "post2000utctime.pem"),
372 x509.load_pem_x509_certificate,
373 backend
374 )
375 cert3 = _load_cert(
376 os.path.join(
377 "x509", "PKITS_data", "certs",
378 "ValidGeneralizedTimenotAfterDateTest8EE.crt"
379 ),
380 x509.load_der_x509_certificate,
381 backend
382 )
383
384 assert hash(cert1) == hash(cert2)
385 assert hash(cert1) != hash(cert3)
386
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000387 def test_version_1_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000388 cert = _load_cert(
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000389 os.path.join("x509", "v1_cert.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000390 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000391 backend
Paul Kehrer30c5ccd2014-11-26 11:10:28 -1000392 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600393 assert cert.version is x509.Version.v1
Paul Kehrer7638c312014-11-26 11:13:31 -1000394
395 def test_invalid_pem(self, backend):
396 with pytest.raises(ValueError):
397 x509.load_pem_x509_certificate(b"notacert", backend)
398
399 def test_invalid_der(self, backend):
400 with pytest.raises(ValueError):
401 x509.load_der_x509_certificate(b"notacert", backend)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000402
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600403 def test_unsupported_signature_hash_algorithm_cert(self, backend):
404 cert = _load_cert(
405 os.path.join("x509", "verisign_md2_root.pem"),
406 x509.load_pem_x509_certificate,
407 backend
408 )
409 with pytest.raises(UnsupportedAlgorithm):
410 cert.signature_hash_algorithm
411
Andre Carona8aded62015-05-19 20:11:57 -0400412 def test_public_bytes_pem(self, backend):
413 # Load an existing certificate.
414 cert = _load_cert(
415 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
416 x509.load_der_x509_certificate,
417 backend
418 )
419
420 # Encode it to PEM and load it back.
421 cert = x509.load_pem_x509_certificate(cert.public_bytes(
422 encoding=serialization.Encoding.PEM,
423 ), backend)
424
425 # We should recover what we had to start with.
426 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
427 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
428 assert cert.serial == 2
429 public_key = cert.public_key()
430 assert isinstance(public_key, rsa.RSAPublicKey)
431 assert cert.version is x509.Version.v3
432 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
433 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
434
435 def test_public_bytes_der(self, backend):
436 # Load an existing certificate.
437 cert = _load_cert(
438 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
439 x509.load_der_x509_certificate,
440 backend
441 )
442
443 # Encode it to DER and load it back.
444 cert = x509.load_der_x509_certificate(cert.public_bytes(
445 encoding=serialization.Encoding.DER,
446 ), backend)
447
448 # We should recover what we had to start with.
449 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
450 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
451 assert cert.serial == 2
452 public_key = cert.public_key()
453 assert isinstance(public_key, rsa.RSAPublicKey)
454 assert cert.version is x509.Version.v3
455 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
456 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
457
458 def test_public_bytes_invalid_encoding(self, backend):
459 cert = _load_cert(
460 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
461 x509.load_der_x509_certificate,
462 backend
463 )
464
465 with pytest.raises(TypeError):
466 cert.public_bytes('NotAnEncoding')
467
468 @pytest.mark.parametrize(
469 ("cert_path", "loader_func", "encoding"),
470 [
471 (
472 os.path.join("x509", "v1_cert.pem"),
473 x509.load_pem_x509_certificate,
474 serialization.Encoding.PEM,
475 ),
476 (
477 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
478 x509.load_der_x509_certificate,
479 serialization.Encoding.DER,
480 ),
481 ]
482 )
483 def test_public_bytes_match(self, cert_path, loader_func, encoding,
484 backend):
485 cert_bytes = load_vectors_from_file(
486 cert_path, lambda pemfile: pemfile.read(), mode="rb"
487 )
488 cert = loader_func(cert_bytes, backend)
489 serialized = cert.public_bytes(encoding)
490 assert serialized == cert_bytes
491
Major Haydenf315af22015-06-17 14:02:26 -0500492 def test_certificate_repr(self, backend):
493 cert = _load_cert(
494 os.path.join(
495 "x509", "cryptography.io.pem"
496 ),
497 x509.load_pem_x509_certificate,
498 backend
499 )
500 if six.PY3:
501 assert repr(cert) == (
502 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
503 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value='GT487"
504 "42965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11, "
505 "name=organizationalUnitName)>, value='See www.rapidssl.com/re"
506 "sources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier(oi"
507 "d=2.5.4.11, name=organizationalUnitName)>, value='Domain Cont"
508 "rol Validated - RapidSSL(R)')>, <NameAttribute(oid=<ObjectIde"
509 "ntifier(oid=2.5.4.3, name=commonName)>, value='www.cryptograp"
510 "hy.io')>])>, ...)>"
511 )
512 else:
513 assert repr(cert) == (
514 "<Certificate(subject=<Name([<NameAttribute(oid=<ObjectIdentif"
515 "ier(oid=2.5.4.11, name=organizationalUnitName)>, value=u'GT48"
516 "742965')>, <NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.11,"
517 " name=organizationalUnitName)>, value=u'See www.rapidssl.com/"
518 "resources/cps (c)14')>, <NameAttribute(oid=<ObjectIdentifier("
519 "oid=2.5.4.11, name=organizationalUnitName)>, value=u'Domain C"
520 "ontrol Validated - RapidSSL(R)')>, <NameAttribute(oid=<Object"
521 "Identifier(oid=2.5.4.3, name=commonName)>, value=u'www.crypto"
522 "graphy.io')>])>, ...)>"
523 )
524
Andre Carona8aded62015-05-19 20:11:57 -0400525
526@pytest.mark.requires_backend_interface(interface=RSABackend)
527@pytest.mark.requires_backend_interface(interface=X509Backend)
528class TestRSACertificateRequest(object):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500529 @pytest.mark.parametrize(
530 ("path", "loader_func"),
531 [
532 [
533 os.path.join("x509", "requests", "rsa_sha1.pem"),
534 x509.load_pem_x509_csr
535 ],
536 [
537 os.path.join("x509", "requests", "rsa_sha1.der"),
538 x509.load_der_x509_csr
539 ],
540 ]
541 )
542 def test_load_rsa_certificate_request(self, path, loader_func, backend):
543 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600544 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
545 public_key = request.public_key()
546 assert isinstance(public_key, rsa.RSAPublicKey)
547 subject = request.subject
548 assert isinstance(subject, x509.Name)
549 assert list(subject) == [
Ian Cordasco82fc3762015-06-16 20:59:50 -0500550 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
551 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
552 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
553 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
554 x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600555 ]
Andre Caron6e721a92015-05-17 15:08:48 -0400556 extensions = request.extensions
557 assert isinstance(extensions, x509.Extensions)
558 assert list(extensions) == []
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600559
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500560 @pytest.mark.parametrize(
561 "loader_func",
562 [x509.load_pem_x509_csr, x509.load_der_x509_csr]
563 )
564 def test_invalid_certificate_request(self, loader_func, backend):
Paul Kehrerb759e292015-03-17 07:34:41 -0500565 with pytest.raises(ValueError):
Paul Kehrer1effb6e2015-03-30 15:05:59 -0500566 loader_func(b"notacsr", backend)
Paul Kehrerb759e292015-03-17 07:34:41 -0500567
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600568 def test_unsupported_signature_hash_algorithm_request(self, backend):
569 request = _load_cert(
570 os.path.join("x509", "requests", "rsa_md4.pem"),
Paul Kehrer31e39882015-03-11 11:37:04 -0500571 x509.load_pem_x509_csr,
Paul Kehrerdc480ad2015-02-23 12:14:54 -0600572 backend
573 )
574 with pytest.raises(UnsupportedAlgorithm):
575 request.signature_hash_algorithm
576
Andre Caron6e721a92015-05-17 15:08:48 -0400577 def test_duplicate_extension(self, backend):
578 request = _load_cert(
579 os.path.join(
580 "x509", "requests", "two_basic_constraints.pem"
581 ),
582 x509.load_pem_x509_csr,
583 backend
584 )
585 with pytest.raises(x509.DuplicateExtension) as exc:
586 request.extensions
587
588 assert exc.value.oid == x509.OID_BASIC_CONSTRAINTS
589
590 def test_unsupported_critical_extension(self, backend):
591 request = _load_cert(
592 os.path.join(
593 "x509", "requests", "unsupported_extension_critical.pem"
594 ),
595 x509.load_pem_x509_csr,
596 backend
597 )
598 with pytest.raises(x509.UnsupportedExtension) as exc:
599 request.extensions
600
601 assert exc.value.oid == x509.ObjectIdentifier('1.2.3.4')
602
603 def test_unsupported_extension(self, backend):
604 request = _load_cert(
605 os.path.join(
606 "x509", "requests", "unsupported_extension.pem"
607 ),
608 x509.load_pem_x509_csr,
609 backend
610 )
611 extensions = request.extensions
612 assert len(extensions) == 0
613
614 def test_request_basic_constraints(self, backend):
615 request = _load_cert(
616 os.path.join(
617 "x509", "requests", "basic_constraints.pem"
618 ),
619 x509.load_pem_x509_csr,
620 backend
621 )
622 extensions = request.extensions
623 assert isinstance(extensions, x509.Extensions)
624 assert list(extensions) == [
625 x509.Extension(
626 x509.OID_BASIC_CONSTRAINTS,
627 True,
Ian Cordasco0112b022015-06-16 17:51:18 -0500628 x509.BasicConstraints(ca=True, path_length=1),
Andre Caron6e721a92015-05-17 15:08:48 -0400629 ),
630 ]
631
Alex Gaynor37b82df2015-07-03 10:26:37 -0400632 def test_subject_alt_name(self, backend):
633 request = _load_cert(
634 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
635 x509.load_pem_x509_csr,
636 backend,
637 )
638 ext = request.extensions.get_extension_for_oid(
639 x509.OID_SUBJECT_ALTERNATIVE_NAME
640 )
641 assert list(ext.value) == [
642 x509.DNSName(u"cryptography.io"),
643 x509.DNSName(u"sub.cryptography.io"),
644 ]
645
Andre Caronf27e4f42015-05-18 17:54:59 -0400646 def test_public_bytes_pem(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400647 # Load an existing CSR.
648 request = _load_cert(
649 os.path.join("x509", "requests", "rsa_sha1.pem"),
650 x509.load_pem_x509_csr,
651 backend
652 )
653
654 # Encode it to PEM and load it back.
655 request = x509.load_pem_x509_csr(request.public_bytes(
656 encoding=serialization.Encoding.PEM,
657 ), backend)
658
659 # We should recover what we had to start with.
660 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
661 public_key = request.public_key()
662 assert isinstance(public_key, rsa.RSAPublicKey)
663 subject = request.subject
664 assert isinstance(subject, x509.Name)
665 assert list(subject) == [
Ian Cordasco82fc3762015-06-16 20:59:50 -0500666 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
667 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
668 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
669 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
670 x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400671 ]
672
Andre Caronf27e4f42015-05-18 17:54:59 -0400673 def test_public_bytes_der(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400674 # Load an existing CSR.
675 request = _load_cert(
676 os.path.join("x509", "requests", "rsa_sha1.pem"),
677 x509.load_pem_x509_csr,
678 backend
679 )
680
681 # Encode it to DER and load it back.
682 request = x509.load_der_x509_csr(request.public_bytes(
683 encoding=serialization.Encoding.DER,
684 ), backend)
685
686 # We should recover what we had to start with.
687 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
688 public_key = request.public_key()
689 assert isinstance(public_key, rsa.RSAPublicKey)
690 subject = request.subject
691 assert isinstance(subject, x509.Name)
692 assert list(subject) == [
Ian Cordasco82fc3762015-06-16 20:59:50 -0500693 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
694 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
695 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
696 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
697 x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
Andre Caron476c5df2015-05-18 10:23:28 -0400698 ]
699
Andre Caronf27e4f42015-05-18 17:54:59 -0400700 def test_public_bytes_invalid_encoding(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -0400701 request = _load_cert(
702 os.path.join("x509", "requests", "rsa_sha1.pem"),
703 x509.load_pem_x509_csr,
704 backend
705 )
706
707 with pytest.raises(TypeError):
708 request.public_bytes('NotAnEncoding')
709
Andre Caronacb18972015-05-18 21:04:15 -0400710 @pytest.mark.parametrize(
711 ("request_path", "loader_func", "encoding"),
712 [
713 (
714 os.path.join("x509", "requests", "rsa_sha1.pem"),
715 x509.load_pem_x509_csr,
716 serialization.Encoding.PEM,
717 ),
718 (
719 os.path.join("x509", "requests", "rsa_sha1.der"),
720 x509.load_der_x509_csr,
721 serialization.Encoding.DER,
722 ),
723 ]
724 )
725 def test_public_bytes_match(self, request_path, loader_func, encoding,
726 backend):
727 request_bytes = load_vectors_from_file(
728 request_path, lambda pemfile: pemfile.read(), mode="rb"
729 )
730 request = loader_func(request_bytes, backend)
731 serialized = request.public_bytes(encoding)
732 assert serialized == request_bytes
733
Alex Gaynor70c8f8b2015-07-06 21:02:54 -0400734 def test_eq(self, backend):
735 request1 = _load_cert(
736 os.path.join("x509", "requests", "rsa_sha1.pem"),
737 x509.load_pem_x509_csr,
738 backend
739 )
740 request2 = _load_cert(
741 os.path.join("x509", "requests", "rsa_sha1.pem"),
742 x509.load_pem_x509_csr,
743 backend
744 )
745
746 assert request1 == request2
747
748 def test_ne(self, backend):
749 request1 = _load_cert(
750 os.path.join("x509", "requests", "rsa_sha1.pem"),
751 x509.load_pem_x509_csr,
752 backend
753 )
754 request2 = _load_cert(
Alex Gaynoreb2df542015-07-06 21:50:15 -0400755 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
Alex Gaynor70c8f8b2015-07-06 21:02:54 -0400756 x509.load_pem_x509_csr,
757 backend
758 )
759
760 assert request1 != request2
761 assert request1 != object()
762
Alex Gaynor978137d2015-07-08 20:59:16 -0400763 def test_hash(self, backend):
764 request1 = _load_cert(
765 os.path.join("x509", "requests", "rsa_sha1.pem"),
766 x509.load_pem_x509_csr,
767 backend
768 )
769 request2 = _load_cert(
770 os.path.join("x509", "requests", "rsa_sha1.pem"),
771 x509.load_pem_x509_csr,
772 backend
773 )
774 request3 = _load_cert(
775 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
776 x509.load_pem_x509_csr,
777 backend
778 )
779
780 assert hash(request1) == hash(request2)
781 assert hash(request1) != hash(request3)
782
Andre Caron9bbfcea2015-05-18 20:55:29 -0400783 def test_build_cert(self, backend):
Ian Cordascoe4e52a42015-07-19 10:15:37 -0500784 issuer_private_key = RSA_KEY_2048.private_key(backend)
785 subject_private_key = RSA_KEY_2048.private_key(backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -0400786
Andre Caron9bbfcea2015-05-18 20:55:29 -0400787 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
788 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
Ian Cordascob3ed4842015-07-01 22:46:03 -0500789
Ian Cordasco893246f2015-07-24 14:52:18 -0500790 builder = x509.CertificateBuilder().serial_number(
Ian Cordascob3ed4842015-07-01 22:46:03 -0500791 777
792 ).issuer_name(x509.Name([
Ian Cordascobe9985b2015-07-18 23:22:19 -0500793 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
794 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
795 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
796 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
797 x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -0500798 ])).subject_name(x509.Name([
Ian Cordascobe9985b2015-07-18 23:22:19 -0500799 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
800 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
801 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
802 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
803 x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
Ian Cordascob3ed4842015-07-01 22:46:03 -0500804 ])).public_key(
805 subject_private_key.public_key()
806 ).add_extension(
Ian Cordasco8887a572015-07-19 10:26:59 -0500807 x509.BasicConstraints(ca=False, path_length=None), True,
Ian Cordasco9e0666e2015-07-20 11:42:51 -0500808 ).add_extension(
809 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
810 critical=False,
Ian Cordascob3ed4842015-07-01 22:46:03 -0500811 ).not_valid_before(
812 not_valid_before
813 ).not_valid_after(
814 not_valid_after
815 )
816
Paul Kehrer9add80e2015-08-03 17:53:14 +0100817 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -0400818
819 assert cert.version is x509.Version.v3
820 assert cert.not_valid_before == not_valid_before
821 assert cert.not_valid_after == not_valid_after
822 basic_constraints = cert.extensions.get_extension_for_oid(
823 x509.OID_BASIC_CONSTRAINTS
824 )
825 assert basic_constraints.value.ca is False
826 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -0500827 subject_alternative_name = cert.extensions.get_extension_for_oid(
828 x509.OID_SUBJECT_ALTERNATIVE_NAME
829 )
830 assert list(subject_alternative_name.value) == [
831 x509.DNSName(u"cryptography.io"),
832 ]
Andre Caron9bbfcea2015-05-18 20:55:29 -0400833
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000834
Ian Cordasco747a2172015-07-19 11:00:14 -0500835class TestCertificateBuilder(object):
Paul Kehrer25f19222015-08-04 23:05:09 +0100836 @pytest.mark.requires_backend_interface(interface=RSABackend)
837 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrera03c3252015-08-09 10:59:29 -0500838 def test_checks_for_unsupported_extensions(self, backend):
839 private_key = RSA_KEY_2048.private_key(backend)
840 builder = x509.CertificateBuilder().subject_name(x509.Name([
841 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
842 ])).issuer_name(x509.Name([
843 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
844 ])).public_key(
845 private_key.public_key()
846 ).serial_number(
847 777
848 ).not_valid_before(
849 datetime.datetime(1999, 1, 1)
850 ).not_valid_after(
851 datetime.datetime(2020, 1, 1)
852 ).add_extension(
853 DummyExtension(), False
854 )
855
856 with pytest.raises(NotImplementedError):
857 builder.sign(private_key, hashes.SHA1(), backend)
858
859 @pytest.mark.requires_backend_interface(interface=RSABackend)
860 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer25f19222015-08-04 23:05:09 +0100861 def test_no_subject_name(self, backend):
862 subject_private_key = RSA_KEY_2048.private_key(backend)
863 builder = x509.CertificateBuilder().serial_number(
864 777
865 ).issuer_name(x509.Name([
866 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
867 ])).public_key(
868 subject_private_key.public_key()
869 ).not_valid_before(
870 datetime.datetime(2002, 1, 1, 12, 1)
871 ).not_valid_after(
872 datetime.datetime(2030, 12, 31, 8, 30)
873 )
874 with pytest.raises(ValueError):
875 builder.sign(subject_private_key, hashes.SHA256(), backend)
876
877 @pytest.mark.requires_backend_interface(interface=RSABackend)
878 @pytest.mark.requires_backend_interface(interface=X509Backend)
879 def test_no_issuer_name(self, backend):
880 subject_private_key = RSA_KEY_2048.private_key(backend)
881 builder = x509.CertificateBuilder().serial_number(
882 777
883 ).subject_name(x509.Name([
884 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
885 ])).public_key(
886 subject_private_key.public_key()
887 ).not_valid_before(
888 datetime.datetime(2002, 1, 1, 12, 1)
889 ).not_valid_after(
890 datetime.datetime(2030, 12, 31, 8, 30)
891 )
892 with pytest.raises(ValueError):
893 builder.sign(subject_private_key, hashes.SHA256(), backend)
894
895 @pytest.mark.requires_backend_interface(interface=RSABackend)
896 @pytest.mark.requires_backend_interface(interface=X509Backend)
897 def test_no_public_key(self, backend):
898 subject_private_key = RSA_KEY_2048.private_key(backend)
899 builder = x509.CertificateBuilder().serial_number(
900 777
901 ).issuer_name(x509.Name([
902 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
903 ])).subject_name(x509.Name([
904 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
905 ])).not_valid_before(
906 datetime.datetime(2002, 1, 1, 12, 1)
907 ).not_valid_after(
908 datetime.datetime(2030, 12, 31, 8, 30)
909 )
910 with pytest.raises(ValueError):
911 builder.sign(subject_private_key, hashes.SHA256(), backend)
912
913 @pytest.mark.requires_backend_interface(interface=RSABackend)
914 @pytest.mark.requires_backend_interface(interface=X509Backend)
915 def test_no_not_valid_before(self, backend):
916 subject_private_key = RSA_KEY_2048.private_key(backend)
917 builder = x509.CertificateBuilder().serial_number(
918 777
919 ).issuer_name(x509.Name([
920 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
921 ])).subject_name(x509.Name([
922 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
923 ])).public_key(
924 subject_private_key.public_key()
925 ).not_valid_after(
926 datetime.datetime(2030, 12, 31, 8, 30)
927 )
928 with pytest.raises(ValueError):
929 builder.sign(subject_private_key, hashes.SHA256(), backend)
930
931 @pytest.mark.requires_backend_interface(interface=RSABackend)
932 @pytest.mark.requires_backend_interface(interface=X509Backend)
933 def test_no_not_valid_after(self, backend):
934 subject_private_key = RSA_KEY_2048.private_key(backend)
935 builder = x509.CertificateBuilder().serial_number(
936 777
937 ).issuer_name(x509.Name([
938 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
939 ])).subject_name(x509.Name([
940 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
941 ])).public_key(
942 subject_private_key.public_key()
943 ).not_valid_before(
944 datetime.datetime(2002, 1, 1, 12, 1)
945 )
946 with pytest.raises(ValueError):
947 builder.sign(subject_private_key, hashes.SHA256(), backend)
948
949 @pytest.mark.requires_backend_interface(interface=RSABackend)
950 @pytest.mark.requires_backend_interface(interface=X509Backend)
951 def test_no_serial_number(self, backend):
952 subject_private_key = RSA_KEY_2048.private_key(backend)
953 builder = x509.CertificateBuilder().issuer_name(x509.Name([
954 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
955 ])).subject_name(x509.Name([
956 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
957 ])).public_key(
958 subject_private_key.public_key()
959 ).not_valid_before(
960 datetime.datetime(2002, 1, 1, 12, 1)
961 ).not_valid_after(
962 datetime.datetime(2030, 12, 31, 8, 30)
963 )
964 with pytest.raises(ValueError):
965 builder.sign(subject_private_key, hashes.SHA256(), backend)
966
Ian Cordasco747a2172015-07-19 11:00:14 -0500967 def test_issuer_name_must_be_a_name_type(self):
968 builder = x509.CertificateBuilder()
969
970 with pytest.raises(TypeError):
971 builder.issuer_name("subject")
972
973 with pytest.raises(TypeError):
974 builder.issuer_name(object)
975
976 def test_issuer_name_may_only_be_set_once(self):
977 name = x509.Name([
978 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -0500979 ])
980 builder = x509.CertificateBuilder().issuer_name(name)
981
982 with pytest.raises(ValueError):
983 builder.issuer_name(name)
984
985 def test_subject_name_must_be_a_name_type(self):
986 builder = x509.CertificateBuilder()
987
988 with pytest.raises(TypeError):
989 builder.subject_name("subject")
990
991 with pytest.raises(TypeError):
992 builder.subject_name(object)
993
994 def test_subject_name_may_only_be_set_once(self):
995 name = x509.Name([
996 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Ian Cordasco747a2172015-07-19 11:00:14 -0500997 ])
998 builder = x509.CertificateBuilder().subject_name(name)
999
1000 with pytest.raises(ValueError):
1001 builder.subject_name(name)
1002
1003 @pytest.mark.requires_backend_interface(interface=RSABackend)
1004 @pytest.mark.requires_backend_interface(interface=X509Backend)
1005 def test_public_key_must_be_public_key(self, backend):
1006 private_key = RSA_KEY_2048.private_key(backend)
1007 builder = x509.CertificateBuilder()
1008
1009 with pytest.raises(TypeError):
1010 builder.public_key(private_key)
1011
1012 @pytest.mark.requires_backend_interface(interface=RSABackend)
1013 @pytest.mark.requires_backend_interface(interface=X509Backend)
1014 def test_public_key_may_only_be_set_once(self, backend):
1015 private_key = RSA_KEY_2048.private_key(backend)
1016 public_key = private_key.public_key()
1017 builder = x509.CertificateBuilder().public_key(public_key)
1018
1019 with pytest.raises(ValueError):
1020 builder.public_key(public_key)
1021
1022 def test_serial_number_must_be_an_integer_type(self):
1023 with pytest.raises(TypeError):
1024 x509.CertificateBuilder().serial_number(10.0)
1025
Ian Cordascob4a155d2015-08-01 23:07:19 -05001026 def test_serial_number_must_be_non_negative(self):
1027 with pytest.raises(ValueError):
1028 x509.CertificateBuilder().serial_number(-10)
1029
1030 def test_serial_number_must_be_less_than_160_bits_long(self):
1031 with pytest.raises(ValueError):
1032 # 2 raised to the 160th power is actually 161 bits
1033 x509.CertificateBuilder().serial_number(2 ** 160)
1034
Ian Cordasco747a2172015-07-19 11:00:14 -05001035 def test_serial_number_may_only_be_set_once(self):
1036 builder = x509.CertificateBuilder().serial_number(10)
1037
1038 with pytest.raises(ValueError):
1039 builder.serial_number(20)
1040
1041 def test_invalid_not_valid_after(self):
1042 with pytest.raises(TypeError):
1043 x509.CertificateBuilder().not_valid_after(104204304504)
1044
1045 with pytest.raises(TypeError):
1046 x509.CertificateBuilder().not_valid_after(datetime.time())
1047
Ian Cordascob4a155d2015-08-01 23:07:19 -05001048 with pytest.raises(ValueError):
1049 x509.CertificateBuilder().not_valid_after(
1050 datetime.datetime(1960, 8, 10)
1051 )
1052
Ian Cordasco747a2172015-07-19 11:00:14 -05001053 def test_not_valid_after_may_only_be_set_once(self):
1054 builder = x509.CertificateBuilder().not_valid_after(
1055 datetime.datetime.now()
1056 )
1057
1058 with pytest.raises(ValueError):
1059 builder.not_valid_after(
1060 datetime.datetime.now()
1061 )
1062
1063 def test_invalid_not_valid_before(self):
1064 with pytest.raises(TypeError):
1065 x509.CertificateBuilder().not_valid_before(104204304504)
1066
1067 with pytest.raises(TypeError):
1068 x509.CertificateBuilder().not_valid_before(datetime.time())
1069
Ian Cordascob4a155d2015-08-01 23:07:19 -05001070 with pytest.raises(ValueError):
1071 x509.CertificateBuilder().not_valid_before(
1072 datetime.datetime(1960, 8, 10)
1073 )
1074
Ian Cordasco747a2172015-07-19 11:00:14 -05001075 def test_not_valid_before_may_only_be_set_once(self):
1076 builder = x509.CertificateBuilder().not_valid_before(
1077 datetime.datetime.now()
1078 )
1079
1080 with pytest.raises(ValueError):
1081 builder.not_valid_before(
1082 datetime.datetime.now()
1083 )
1084
1085 def test_add_extension_checks_for_duplicates(self):
1086 builder = x509.CertificateBuilder().add_extension(
1087 x509.BasicConstraints(ca=False, path_length=None), True,
1088 )
1089
1090 with pytest.raises(ValueError):
1091 builder.add_extension(
1092 x509.BasicConstraints(ca=False, path_length=None), True,
1093 )
1094
Paul Kehrer08f950e2015-08-08 22:14:42 -05001095 def test_add_invalid_extension_type(self):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001096 builder = x509.CertificateBuilder()
1097
Paul Kehrer08f950e2015-08-08 22:14:42 -05001098 with pytest.raises(TypeError):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05001099 builder.add_extension(object(), False)
1100
Ian Cordascob77c7162015-07-20 21:22:33 -05001101 @pytest.mark.requires_backend_interface(interface=RSABackend)
1102 @pytest.mark.requires_backend_interface(interface=X509Backend)
1103 def test_sign_with_unsupported_hash(self, backend):
1104 private_key = RSA_KEY_2048.private_key(backend)
1105 builder = x509.CertificateBuilder()
Paul Kehrer25f19222015-08-04 23:05:09 +01001106 builder = builder.subject_name(
1107 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1108 ).issuer_name(
1109 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1110 ).serial_number(
1111 1
1112 ).public_key(
1113 private_key.public_key()
1114 ).not_valid_before(
1115 datetime.datetime(2002, 1, 1, 12, 1)
1116 ).not_valid_after(
1117 datetime.datetime(2032, 1, 1, 12, 1)
1118 )
Ian Cordascob77c7162015-07-20 21:22:33 -05001119
1120 with pytest.raises(TypeError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001121 builder.sign(private_key, object(), backend)
Ian Cordascob77c7162015-07-20 21:22:33 -05001122
Ian Cordasco56561b12015-07-24 16:38:50 -05001123 @pytest.mark.requires_backend_interface(interface=DSABackend)
1124 @pytest.mark.requires_backend_interface(interface=X509Backend)
1125 def test_sign_with_dsa_private_key_is_unsupported(self, backend):
1126 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1127 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1128
1129 private_key = DSA_KEY_2048.private_key(backend)
1130 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001131 builder = builder.subject_name(
1132 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1133 ).issuer_name(
1134 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1135 ).serial_number(
1136 1
1137 ).public_key(
1138 private_key.public_key()
1139 ).not_valid_before(
1140 datetime.datetime(2002, 1, 1, 12, 1)
1141 ).not_valid_after(
1142 datetime.datetime(2032, 1, 1, 12, 1)
1143 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001144
1145 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001146 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001147
1148 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1149 @pytest.mark.requires_backend_interface(interface=X509Backend)
1150 def test_sign_with_ec_private_key_is_unsupported(self, backend):
1151 if backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000:
1152 pytest.skip("Requires an older OpenSSL. Must be < 1.0.1")
1153
1154 _skip_curve_unsupported(backend, ec.SECP256R1())
1155 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1156 builder = x509.CertificateBuilder()
Paul Kehrer7d792fc2015-08-05 00:18:03 +01001157 builder = builder.subject_name(
1158 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1159 ).issuer_name(
1160 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1161 ).serial_number(
1162 1
1163 ).public_key(
1164 private_key.public_key()
1165 ).not_valid_before(
1166 datetime.datetime(2002, 1, 1, 12, 1)
1167 ).not_valid_after(
1168 datetime.datetime(2032, 1, 1, 12, 1)
1169 )
Ian Cordasco56561b12015-07-24 16:38:50 -05001170
1171 with pytest.raises(NotImplementedError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001172 builder.sign(private_key, hashes.SHA512(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001173
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001174 @pytest.mark.parametrize(
1175 "cdp",
1176 [
1177 x509.CRLDistributionPoints([
1178 x509.DistributionPoint(
Paul Kehrer1cd8fee2015-08-04 07:55:40 +01001179 full_name=None,
1180 relative_name=x509.Name([
1181 x509.NameAttribute(
1182 x509.OID_COMMON_NAME,
1183 u"indirect CRL for indirectCRL CA3"
1184 ),
1185 ]),
1186 reasons=None,
1187 crl_issuer=[x509.DirectoryName(
1188 x509.Name([
1189 x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
1190 x509.NameAttribute(
1191 x509.OID_ORGANIZATION_NAME,
1192 u"Test Certificates 2011"
1193 ),
1194 x509.NameAttribute(
1195 x509.OID_ORGANIZATIONAL_UNIT_NAME,
1196 u"indirectCRL CA3 cRLIssuer"
1197 ),
1198 ])
1199 )],
1200 )
1201 ]),
1202 x509.CRLDistributionPoints([
1203 x509.DistributionPoint(
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001204 full_name=[x509.DirectoryName(
1205 x509.Name([
1206 x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
1207 ])
1208 )],
1209 relative_name=None,
1210 reasons=None,
1211 crl_issuer=[x509.DirectoryName(
1212 x509.Name([
1213 x509.NameAttribute(
1214 x509.OID_ORGANIZATION_NAME,
1215 u"cryptography Testing"
1216 ),
1217 ])
1218 )],
1219 )
1220 ]),
1221 x509.CRLDistributionPoints([
1222 x509.DistributionPoint(
Paul Kehrerc6cf8f32015-08-08 09:47:44 -05001223 full_name=[
1224 x509.UniformResourceIdentifier(
1225 u"http://myhost.com/myca.crl"
1226 ),
1227 x509.UniformResourceIdentifier(
1228 u"http://backup.myhost.com/myca.crl"
1229 )
1230 ],
Paul Kehrera4d5bab2015-08-03 21:54:43 +01001231 relative_name=None,
1232 reasons=frozenset([
1233 x509.ReasonFlags.key_compromise,
1234 x509.ReasonFlags.ca_compromise
1235 ]),
1236 crl_issuer=[x509.DirectoryName(
1237 x509.Name([
1238 x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
1239 x509.NameAttribute(
1240 x509.OID_COMMON_NAME, u"cryptography CA"
1241 ),
1242 ])
1243 )],
1244 )
1245 ]),
1246 x509.CRLDistributionPoints([
1247 x509.DistributionPoint(
1248 full_name=[x509.UniformResourceIdentifier(
1249 u"http://domain.com/some.crl"
1250 )],
1251 relative_name=None,
1252 reasons=frozenset([
1253 x509.ReasonFlags.key_compromise,
1254 x509.ReasonFlags.ca_compromise,
1255 x509.ReasonFlags.affiliation_changed,
1256 x509.ReasonFlags.superseded,
1257 x509.ReasonFlags.privilege_withdrawn,
1258 x509.ReasonFlags.cessation_of_operation,
1259 x509.ReasonFlags.aa_compromise,
1260 x509.ReasonFlags.certificate_hold,
1261 ]),
1262 crl_issuer=None
1263 )
1264 ]),
1265 x509.CRLDistributionPoints([
1266 x509.DistributionPoint(
1267 full_name=None,
1268 relative_name=None,
1269 reasons=None,
1270 crl_issuer=[x509.DirectoryName(
1271 x509.Name([
1272 x509.NameAttribute(
1273 x509.OID_COMMON_NAME, u"cryptography CA"
1274 ),
1275 ])
1276 )],
1277 )
1278 ]),
1279 x509.CRLDistributionPoints([
1280 x509.DistributionPoint(
1281 full_name=[x509.UniformResourceIdentifier(
1282 u"http://domain.com/some.crl"
1283 )],
1284 relative_name=None,
1285 reasons=frozenset([x509.ReasonFlags.aa_compromise]),
1286 crl_issuer=None
1287 )
1288 ])
1289 ]
1290 )
1291 @pytest.mark.requires_backend_interface(interface=RSABackend)
1292 @pytest.mark.requires_backend_interface(interface=X509Backend)
1293 def test_crl_distribution_points(self, backend, cdp):
1294 issuer_private_key = RSA_KEY_2048.private_key(backend)
1295 subject_private_key = RSA_KEY_2048.private_key(backend)
1296
1297 builder = x509.CertificateBuilder().serial_number(
1298 4444444
1299 ).issuer_name(x509.Name([
1300 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
1301 ])).subject_name(x509.Name([
1302 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
1303 ])).public_key(
1304 subject_private_key.public_key()
1305 ).add_extension(
1306 cdp,
1307 critical=False,
1308 ).not_valid_before(
1309 datetime.datetime(2002, 1, 1, 12, 1)
1310 ).not_valid_after(
1311 datetime.datetime(2030, 12, 31, 8, 30)
1312 )
1313
1314 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
1315
1316 ext = cert.extensions.get_extension_for_oid(
1317 x509.OID_CRL_DISTRIBUTION_POINTS
1318 )
1319 assert ext.critical is False
1320 assert ext.value == cdp
1321
Ian Cordasco56561b12015-07-24 16:38:50 -05001322 @pytest.mark.requires_backend_interface(interface=DSABackend)
1323 @pytest.mark.requires_backend_interface(interface=X509Backend)
1324 def test_build_cert_with_dsa_private_key(self, backend):
1325 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1326 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1327
1328 issuer_private_key = DSA_KEY_2048.private_key(backend)
1329 subject_private_key = DSA_KEY_2048.private_key(backend)
1330
1331 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1332 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1333
1334 builder = x509.CertificateBuilder().serial_number(
1335 777
1336 ).issuer_name(x509.Name([
1337 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001338 ])).subject_name(x509.Name([
1339 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001340 ])).public_key(
1341 subject_private_key.public_key()
1342 ).add_extension(
1343 x509.BasicConstraints(ca=False, path_length=None), True,
1344 ).add_extension(
1345 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1346 critical=False,
1347 ).not_valid_before(
1348 not_valid_before
1349 ).not_valid_after(
1350 not_valid_after
1351 )
1352
Paul Kehrer9add80e2015-08-03 17:53:14 +01001353 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001354
1355 assert cert.version is x509.Version.v3
1356 assert cert.not_valid_before == not_valid_before
1357 assert cert.not_valid_after == not_valid_after
1358 basic_constraints = cert.extensions.get_extension_for_oid(
1359 x509.OID_BASIC_CONSTRAINTS
1360 )
1361 assert basic_constraints.value.ca is False
1362 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001363 subject_alternative_name = cert.extensions.get_extension_for_oid(
1364 x509.OID_SUBJECT_ALTERNATIVE_NAME
1365 )
1366 assert list(subject_alternative_name.value) == [
1367 x509.DNSName(u"cryptography.io"),
1368 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001369
1370 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1371 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco85fc4d52015-08-01 20:29:31 -05001372 def test_build_cert_with_ec_private_key(self, backend):
Ian Cordasco56561b12015-07-24 16:38:50 -05001373 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1374 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1375
1376 _skip_curve_unsupported(backend, ec.SECP256R1())
1377 issuer_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1378 subject_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
1379
1380 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1381 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1382
1383 builder = x509.CertificateBuilder().serial_number(
1384 777
1385 ).issuer_name(x509.Name([
1386 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001387 ])).subject_name(x509.Name([
1388 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Ian Cordasco56561b12015-07-24 16:38:50 -05001389 ])).public_key(
1390 subject_private_key.public_key()
1391 ).add_extension(
1392 x509.BasicConstraints(ca=False, path_length=None), True,
1393 ).add_extension(
1394 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1395 critical=False,
1396 ).not_valid_before(
1397 not_valid_before
1398 ).not_valid_after(
1399 not_valid_after
1400 )
1401
Paul Kehrer9add80e2015-08-03 17:53:14 +01001402 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05001403
1404 assert cert.version is x509.Version.v3
1405 assert cert.not_valid_before == not_valid_before
1406 assert cert.not_valid_after == not_valid_after
1407 basic_constraints = cert.extensions.get_extension_for_oid(
1408 x509.OID_BASIC_CONSTRAINTS
1409 )
1410 assert basic_constraints.value.ca is False
1411 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001412 subject_alternative_name = cert.extensions.get_extension_for_oid(
1413 x509.OID_SUBJECT_ALTERNATIVE_NAME
1414 )
1415 assert list(subject_alternative_name.value) == [
1416 x509.DNSName(u"cryptography.io"),
1417 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05001418
Ian Cordasco8690eff2015-07-24 16:42:58 -05001419 @pytest.mark.requires_backend_interface(interface=RSABackend)
1420 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco19f5a492015-08-01 11:06:17 -05001421 def test_build_cert_with_rsa_key_too_small(self, backend):
Ian Cordasco8690eff2015-07-24 16:42:58 -05001422 issuer_private_key = RSA_KEY_512.private_key(backend)
1423 subject_private_key = RSA_KEY_512.private_key(backend)
1424
1425 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1426 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1427
1428 builder = x509.CertificateBuilder().serial_number(
1429 777
1430 ).issuer_name(x509.Name([
1431 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001432 ])).subject_name(x509.Name([
1433 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Ian Cordasco8690eff2015-07-24 16:42:58 -05001434 ])).public_key(
1435 subject_private_key.public_key()
Ian Cordasco8690eff2015-07-24 16:42:58 -05001436 ).not_valid_before(
1437 not_valid_before
1438 ).not_valid_after(
1439 not_valid_after
1440 )
1441
Ian Cordasco19f5a492015-08-01 11:06:17 -05001442 with pytest.raises(ValueError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01001443 builder.sign(issuer_private_key, hashes.SHA512(), backend)
Ian Cordasco8690eff2015-07-24 16:42:58 -05001444
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001445 @pytest.mark.requires_backend_interface(interface=RSABackend)
1446 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer69b64e42015-08-09 00:00:44 -05001447 def test_issuer_alt_name(self, backend):
1448 issuer_private_key = RSA_KEY_2048.private_key(backend)
1449 subject_private_key = RSA_KEY_2048.private_key(backend)
1450
1451 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1452 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1453
1454 cert = x509.CertificateBuilder().subject_name(
1455 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1456 ).issuer_name(
1457 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1458 ).not_valid_before(
1459 not_valid_before
1460 ).not_valid_after(
1461 not_valid_after
1462 ).public_key(
1463 subject_private_key.public_key()
1464 ).serial_number(
1465 123
1466 ).add_extension(
1467 x509.IssuerAlternativeName([
1468 x509.DNSName(u"myissuer"),
1469 x509.RFC822Name(u"email@domain.com"),
1470 ]), critical=False
1471 ).sign(issuer_private_key, hashes.SHA256(), backend)
1472
1473 ext = cert.extensions.get_extension_for_oid(
1474 x509.OID_ISSUER_ALTERNATIVE_NAME
1475 )
1476 assert ext.critical is False
1477 assert ext.value == x509.IssuerAlternativeName([
1478 x509.DNSName(u"myissuer"),
1479 x509.RFC822Name(u"email@domain.com"),
1480 ])
1481
1482 @pytest.mark.requires_backend_interface(interface=RSABackend)
1483 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001484 def test_extended_key_usage(self, backend):
1485 issuer_private_key = RSA_KEY_2048.private_key(backend)
1486 subject_private_key = RSA_KEY_2048.private_key(backend)
1487
1488 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1489 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1490
1491 cert = x509.CertificateBuilder().subject_name(
1492 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1493 ).issuer_name(
1494 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1495 ).not_valid_before(
1496 not_valid_before
1497 ).not_valid_after(
1498 not_valid_after
1499 ).public_key(
1500 subject_private_key.public_key()
1501 ).serial_number(
1502 123
1503 ).add_extension(
1504 x509.ExtendedKeyUsage([
1505 x509.OID_CLIENT_AUTH,
1506 x509.OID_SERVER_AUTH,
1507 x509.OID_CODE_SIGNING,
1508 ]), critical=False
1509 ).sign(issuer_private_key, hashes.SHA256(), backend)
1510
1511 eku = cert.extensions.get_extension_for_oid(
1512 x509.OID_EXTENDED_KEY_USAGE
1513 )
1514 assert eku.critical is False
1515 assert eku.value == x509.ExtendedKeyUsage([
1516 x509.OID_CLIENT_AUTH,
1517 x509.OID_SERVER_AUTH,
1518 x509.OID_CODE_SIGNING,
1519 ])
1520
1521 @pytest.mark.requires_backend_interface(interface=RSABackend)
1522 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer683d4d82015-08-06 23:13:45 +01001523 def test_inhibit_any_policy(self, backend):
1524 issuer_private_key = RSA_KEY_2048.private_key(backend)
1525 subject_private_key = RSA_KEY_2048.private_key(backend)
1526
1527 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1528 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1529
1530 cert = x509.CertificateBuilder().subject_name(
1531 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1532 ).issuer_name(
1533 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1534 ).not_valid_before(
1535 not_valid_before
1536 ).not_valid_after(
1537 not_valid_after
1538 ).public_key(
1539 subject_private_key.public_key()
1540 ).serial_number(
1541 123
1542 ).add_extension(
1543 x509.InhibitAnyPolicy(3), critical=False
1544 ).sign(issuer_private_key, hashes.SHA256(), backend)
1545
1546 ext = cert.extensions.get_extension_for_oid(
1547 x509.OID_INHIBIT_ANY_POLICY
1548 )
1549 assert ext.value == x509.InhibitAnyPolicy(3)
1550
1551 @pytest.mark.requires_backend_interface(interface=RSABackend)
1552 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01001553 def test_key_usage(self, backend):
1554 issuer_private_key = RSA_KEY_2048.private_key(backend)
1555 subject_private_key = RSA_KEY_2048.private_key(backend)
1556
1557 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1558 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1559
1560 cert = x509.CertificateBuilder().subject_name(
1561 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1562 ).issuer_name(
1563 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1564 ).not_valid_before(
1565 not_valid_before
1566 ).not_valid_after(
1567 not_valid_after
1568 ).public_key(
1569 subject_private_key.public_key()
1570 ).serial_number(
1571 123
1572 ).add_extension(
1573 x509.KeyUsage(
1574 digital_signature=True,
1575 content_commitment=True,
1576 key_encipherment=False,
1577 data_encipherment=False,
1578 key_agreement=False,
1579 key_cert_sign=True,
1580 crl_sign=False,
1581 encipher_only=False,
1582 decipher_only=False
1583 ),
1584 critical=False
1585 ).sign(issuer_private_key, hashes.SHA256(), backend)
1586
1587 ext = cert.extensions.get_extension_for_oid(x509.OID_KEY_USAGE)
1588 assert ext.critical is False
1589 assert ext.value == x509.KeyUsage(
1590 digital_signature=True,
1591 content_commitment=True,
1592 key_encipherment=False,
1593 data_encipherment=False,
1594 key_agreement=False,
1595 key_cert_sign=True,
1596 crl_sign=False,
1597 encipher_only=False,
1598 decipher_only=False
1599 )
1600
Ian Cordasco747a2172015-07-19 11:00:14 -05001601
Andre Caron0ef595f2015-05-18 13:53:43 -04001602@pytest.mark.requires_backend_interface(interface=X509Backend)
1603class TestCertificateSigningRequestBuilder(object):
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001604 @pytest.mark.requires_backend_interface(interface=RSABackend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001605 def test_sign_invalid_hash_algorithm(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001606 private_key = RSA_KEY_2048.private_key(backend)
1607
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001608 builder = x509.CertificateSigningRequestBuilder().subject_name(
1609 x509.Name([])
1610 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001611 with pytest.raises(TypeError):
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001612 builder.sign(private_key, 'NotAHash', backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001613
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001614 @pytest.mark.requires_backend_interface(interface=RSABackend)
Alex Gaynorba19c2e2015-06-27 00:07:09 -04001615 def test_no_subject_name(self, backend):
1616 private_key = RSA_KEY_2048.private_key(backend)
1617
1618 builder = x509.CertificateSigningRequestBuilder()
1619 with pytest.raises(ValueError):
1620 builder.sign(private_key, hashes.SHA256(), backend)
1621
1622 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001623 def test_build_ca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001624 private_key = RSA_KEY_2048.private_key(backend)
1625
Andre Carona9a51172015-06-06 20:18:44 -04001626 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04001627 x509.Name([
Ian Cordasco94b34d32015-06-17 10:55:07 -05001628 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
Andre Caron99d0f902015-06-01 08:36:59 -04001629 ])
Andre Caron472fd692015-06-06 20:04:44 -04001630 ).add_extension(
Ian Cordasco41f51ce2015-06-17 11:49:11 -05001631 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001632 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001633
1634 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1635 public_key = request.public_key()
1636 assert isinstance(public_key, rsa.RSAPublicKey)
1637 subject = request.subject
1638 assert isinstance(subject, x509.Name)
1639 assert list(subject) == [
Ian Cordasco94b34d32015-06-17 10:55:07 -05001640 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
Andre Caron0ef595f2015-05-18 13:53:43 -04001641 ]
1642 basic_constraints = request.extensions.get_extension_for_oid(
1643 x509.OID_BASIC_CONSTRAINTS
1644 )
1645 assert basic_constraints.value.ca is True
1646 assert basic_constraints.value.path_length == 2
1647
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001648 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001649 def test_build_ca_request_with_unicode(self, backend):
1650 private_key = RSA_KEY_2048.private_key(backend)
1651
1652 request = x509.CertificateSigningRequestBuilder().subject_name(
1653 x509.Name([
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001654 x509.NameAttribute(x509.OID_ORGANIZATION_NAME,
1655 u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001656 ])
1657 ).add_extension(
1658 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001659 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001660
1661 loaded_request = x509.load_pem_x509_csr(
1662 request.public_bytes(encoding=serialization.Encoding.PEM), backend
1663 )
1664 subject = loaded_request.subject
1665 assert isinstance(subject, x509.Name)
1666 assert list(subject) == [
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001667 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA\U0001f37a'),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05001668 ]
1669
1670 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001671 def test_build_nonca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05001672 private_key = RSA_KEY_2048.private_key(backend)
1673
Andre Carona9a51172015-06-06 20:18:44 -04001674 request = x509.CertificateSigningRequestBuilder().subject_name(
Andre Caron99d0f902015-06-01 08:36:59 -04001675 x509.Name([
Ian Cordasco94b34d32015-06-17 10:55:07 -05001676 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Andre Caron99d0f902015-06-01 08:36:59 -04001677 ])
Andre Caron472fd692015-06-06 20:04:44 -04001678 ).add_extension(
Ian Cordasco0112b022015-06-16 17:51:18 -05001679 x509.BasicConstraints(ca=False, path_length=None), critical=True,
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001680 ).sign(private_key, hashes.SHA1(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04001681
1682 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1683 public_key = request.public_key()
1684 assert isinstance(public_key, rsa.RSAPublicKey)
1685 subject = request.subject
1686 assert isinstance(subject, x509.Name)
1687 assert list(subject) == [
Ian Cordasco94b34d32015-06-17 10:55:07 -05001688 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Andre Caron0ef595f2015-05-18 13:53:43 -04001689 ]
1690 basic_constraints = request.extensions.get_extension_for_oid(
1691 x509.OID_BASIC_CONSTRAINTS
1692 )
1693 assert basic_constraints.value.ca is False
1694 assert basic_constraints.value.path_length is None
1695
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001696 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
1697 def test_build_ca_request_with_ec(self, backend):
1698 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1699 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1700
Ian Cordasco8cdcdfc2015-06-24 22:00:26 -05001701 _skip_curve_unsupported(backend, ec.SECP256R1())
1702 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001703
1704 request = x509.CertificateSigningRequestBuilder().subject_name(
1705 x509.Name([
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001706 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001707 ])
1708 ).add_extension(
1709 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001710 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001711
1712 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1713 public_key = request.public_key()
1714 assert isinstance(public_key, ec.EllipticCurvePublicKey)
1715 subject = request.subject
1716 assert isinstance(subject, x509.Name)
1717 assert list(subject) == [
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001718 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001719 ]
1720 basic_constraints = request.extensions.get_extension_for_oid(
1721 x509.OID_BASIC_CONSTRAINTS
1722 )
1723 assert basic_constraints.value.ca is True
1724 assert basic_constraints.value.path_length == 2
1725
1726 @pytest.mark.requires_backend_interface(interface=DSABackend)
1727 def test_build_ca_request_with_dsa(self, backend):
1728 if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
1729 pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
1730
1731 private_key = DSA_KEY_2048.private_key(backend)
1732
1733 request = x509.CertificateSigningRequestBuilder().subject_name(
1734 x509.Name([
1735 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001736 ])
1737 ).add_extension(
1738 x509.BasicConstraints(ca=True, path_length=2), critical=True
Alex Gaynorb3b0fbe2015-06-26 19:57:18 -04001739 ).sign(private_key, hashes.SHA1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001740
1741 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1742 public_key = request.public_key()
1743 assert isinstance(public_key, dsa.DSAPublicKey)
1744 subject = request.subject
1745 assert isinstance(subject, x509.Name)
1746 assert list(subject) == [
1747 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05001748 ]
1749 basic_constraints = request.extensions.get_extension_for_oid(
1750 x509.OID_BASIC_CONSTRAINTS
1751 )
1752 assert basic_constraints.value.ca is True
1753 assert basic_constraints.value.path_length == 2
1754
Paul Kehrerff917802015-06-26 17:29:04 -05001755 def test_add_duplicate_extension(self):
Andre Caronfc164c52015-05-31 17:36:18 -04001756 builder = x509.CertificateSigningRequestBuilder().add_extension(
Andre Caron472fd692015-06-06 20:04:44 -04001757 x509.BasicConstraints(True, 2), critical=True,
Andre Caronfc164c52015-05-31 17:36:18 -04001758 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001759 with pytest.raises(ValueError):
Andre Caron472fd692015-06-06 20:04:44 -04001760 builder.add_extension(
1761 x509.BasicConstraints(True, 2), critical=True,
1762 )
Andre Caron0ef595f2015-05-18 13:53:43 -04001763
Paul Kehrerff917802015-06-26 17:29:04 -05001764 def test_set_invalid_subject(self):
Andre Caron0ef595f2015-05-18 13:53:43 -04001765 builder = x509.CertificateSigningRequestBuilder()
1766 with pytest.raises(TypeError):
Andre Carona9a51172015-06-06 20:18:44 -04001767 builder.subject_name('NotAName')
Andre Caron0ef595f2015-05-18 13:53:43 -04001768
Paul Kehrere59fd222015-08-08 22:50:19 -05001769 def test_add_invalid_extension_type(self):
Ian Cordasco34853f32015-06-21 10:50:53 -05001770 builder = x509.CertificateSigningRequestBuilder()
Andre Caron0ef595f2015-05-18 13:53:43 -04001771
Paul Kehrere59fd222015-08-08 22:50:19 -05001772 with pytest.raises(TypeError):
1773 builder.add_extension(object(), False)
1774
1775 def test_add_unsupported_extension(self, backend):
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05001776 private_key = RSA_KEY_2048.private_key(backend)
1777 builder = x509.CertificateSigningRequestBuilder()
1778 builder = builder.subject_name(
1779 x509.Name([
1780 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
1781 ])
1782 ).add_extension(
Alex Gaynor7583f7f2015-07-03 10:56:49 -04001783 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1784 critical=False,
1785 ).add_extension(
Paul Kehrer69b64e42015-08-09 00:00:44 -05001786 DummyExtension(), False
Paul Kehrerdce91f02015-07-23 20:31:12 +01001787 )
1788 with pytest.raises(NotImplementedError):
1789 builder.sign(private_key, hashes.SHA256(), backend)
1790
1791 def test_key_usage(self, backend):
1792 private_key = RSA_KEY_2048.private_key(backend)
1793 builder = x509.CertificateSigningRequestBuilder()
1794 request = builder.subject_name(
1795 x509.Name([
1796 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
1797 ])
1798 ).add_extension(
Alex Gaynorac7f70a2015-06-28 11:07:52 -04001799 x509.KeyUsage(
1800 digital_signature=True,
1801 content_commitment=True,
1802 key_encipherment=False,
1803 data_encipherment=False,
1804 key_agreement=False,
1805 key_cert_sign=True,
1806 crl_sign=False,
1807 encipher_only=False,
1808 decipher_only=False
1809 ),
Alex Gaynor887a4082015-07-03 04:29:03 -04001810 critical=False
Paul Kehrerdce91f02015-07-23 20:31:12 +01001811 ).sign(private_key, hashes.SHA256(), backend)
1812 assert len(request.extensions) == 1
1813 ext = request.extensions.get_extension_for_oid(x509.OID_KEY_USAGE)
1814 assert ext.critical is False
1815 assert ext.value == x509.KeyUsage(
1816 digital_signature=True,
1817 content_commitment=True,
1818 key_encipherment=False,
1819 data_encipherment=False,
1820 key_agreement=False,
1821 key_cert_sign=True,
1822 crl_sign=False,
1823 encipher_only=False,
1824 decipher_only=False
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05001825 )
Paul Kehrerdce91f02015-07-23 20:31:12 +01001826
1827 def test_key_usage_key_agreement_bit(self, backend):
1828 private_key = RSA_KEY_2048.private_key(backend)
1829 builder = x509.CertificateSigningRequestBuilder()
1830 request = builder.subject_name(
1831 x509.Name([
1832 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
1833 ])
1834 ).add_extension(
1835 x509.KeyUsage(
1836 digital_signature=False,
1837 content_commitment=False,
1838 key_encipherment=False,
1839 data_encipherment=False,
1840 key_agreement=True,
1841 key_cert_sign=True,
1842 crl_sign=False,
1843 encipher_only=False,
1844 decipher_only=True
1845 ),
1846 critical=False
1847 ).sign(private_key, hashes.SHA256(), backend)
1848 assert len(request.extensions) == 1
1849 ext = request.extensions.get_extension_for_oid(x509.OID_KEY_USAGE)
1850 assert ext.critical is False
1851 assert ext.value == x509.KeyUsage(
1852 digital_signature=False,
1853 content_commitment=False,
1854 key_encipherment=False,
1855 data_encipherment=False,
1856 key_agreement=True,
1857 key_cert_sign=True,
1858 crl_sign=False,
1859 encipher_only=False,
1860 decipher_only=True
1861 )
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05001862
Paul Kehrer8bfbace2015-07-23 19:10:28 +01001863 def test_add_two_extensions(self, backend):
1864 private_key = RSA_KEY_2048.private_key(backend)
1865 builder = x509.CertificateSigningRequestBuilder()
1866 request = builder.subject_name(
1867 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
1868 ).add_extension(
1869 x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1870 critical=False,
1871 ).add_extension(
1872 x509.BasicConstraints(ca=True, path_length=2), critical=True
1873 ).sign(private_key, hashes.SHA1(), backend)
1874
1875 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1876 public_key = request.public_key()
1877 assert isinstance(public_key, rsa.RSAPublicKey)
1878 basic_constraints = request.extensions.get_extension_for_oid(
1879 x509.OID_BASIC_CONSTRAINTS
1880 )
1881 assert basic_constraints.value.ca is True
1882 assert basic_constraints.value.path_length == 2
1883 ext = request.extensions.get_extension_for_oid(
1884 x509.OID_SUBJECT_ALTERNATIVE_NAME
1885 )
1886 assert list(ext.value) == [x509.DNSName(u"cryptography.io")]
Paul Kehrerff917802015-06-26 17:29:04 -05001887
Andre Caron0ef595f2015-05-18 13:53:43 -04001888 def test_set_subject_twice(self):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001889 builder = x509.CertificateSigningRequestBuilder()
1890 builder = builder.subject_name(
Paul Kehrere76cd272014-12-14 19:00:51 -06001891 x509.Name([
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001892 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Paul Kehrera693cfd2014-11-27 07:47:58 -10001893 ])
Paul Kehrer4903adc2014-12-13 16:57:50 -06001894 )
Paul Kehrer41120322014-12-02 18:31:14 -10001895 with pytest.raises(ValueError):
Paul Kehrera693cfd2014-11-27 07:47:58 -10001896 builder.subject_name(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001897 x509.Name([
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001898 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001899 ])
Alex Gaynor32c57df2015-02-23 21:51:27 -08001900 )
Alex Gaynorfcadda62015-03-10 10:01:18 -04001901
Alex Gaynord3e84162015-06-28 10:14:55 -04001902 def test_subject_alt_names(self, backend):
1903 private_key = RSA_KEY_2048.private_key(backend)
1904
1905 csr = x509.CertificateSigningRequestBuilder().subject_name(
1906 x509.Name([
1907 x509.NameAttribute(x509.OID_COMMON_NAME, u"SAN"),
1908 ])
1909 ).add_extension(
1910 x509.SubjectAlternativeName([
Alex Gaynor6431d502015-07-05 12:28:46 -04001911 x509.DNSName(u"example.com"),
1912 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05001913 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05001914 x509.DirectoryName(x509.Name([
1915 x509.NameAttribute(x509.OID_COMMON_NAME, u'PyCA'),
1916 x509.NameAttribute(
1917 x509.OID_ORGANIZATION_NAME, u'We heart UTF8!\u2122'
1918 )
1919 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05001920 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
1921 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05001922 x509.OtherName(
1923 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
1924 value=b"0\x03\x02\x01\x05"
1925 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05001926 x509.RFC822Name(u"test@example.com"),
1927 x509.RFC822Name(u"email"),
1928 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05001929 x509.UniformResourceIdentifier(
1930 u"https://\u043f\u044b\u043a\u0430.cryptography"
1931 ),
1932 x509.UniformResourceIdentifier(
1933 u"gopher://cryptography:70/some/path"
1934 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04001935 ]),
1936 critical=False,
1937 ).sign(private_key, hashes.SHA256(), backend)
1938
1939 assert len(csr.extensions) == 1
1940 ext = csr.extensions.get_extension_for_oid(
1941 x509.OID_SUBJECT_ALTERNATIVE_NAME
1942 )
1943 assert not ext.critical
1944 assert ext.oid == x509.OID_SUBJECT_ALTERNATIVE_NAME
1945 assert list(ext.value) == [
Alex Gaynor6431d502015-07-05 12:28:46 -04001946 x509.DNSName(u"example.com"),
1947 x509.DNSName(u"*.example.com"),
Paul Kehrera9e5a212015-07-05 23:38:25 -05001948 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
Paul Kehrer9ce25a92015-07-10 11:08:31 -05001949 x509.DirectoryName(x509.Name([
1950 x509.NameAttribute(x509.OID_COMMON_NAME, u'PyCA'),
1951 x509.NameAttribute(
1952 x509.OID_ORGANIZATION_NAME, u'We heart UTF8!\u2122'
1953 ),
1954 ])),
Paul Kehrer235e5a12015-07-10 19:45:47 -05001955 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
1956 x509.IPAddress(ipaddress.ip_address(u"ff::")),
Paul Kehrer22f5fbb2015-07-10 20:34:18 -05001957 x509.OtherName(
1958 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
1959 value=b"0\x03\x02\x01\x05"
1960 ),
Paul Kehrerf32abd72015-07-10 21:20:47 -05001961 x509.RFC822Name(u"test@example.com"),
1962 x509.RFC822Name(u"email"),
1963 x509.RFC822Name(u"email@em\xe5\xefl.com"),
Paul Kehrer474a6472015-07-11 12:29:52 -05001964 x509.UniformResourceIdentifier(
1965 u"https://\u043f\u044b\u043a\u0430.cryptography"
1966 ),
1967 x509.UniformResourceIdentifier(
1968 u"gopher://cryptography:70/some/path"
1969 ),
Alex Gaynord3e84162015-06-28 10:14:55 -04001970 ]
1971
Paul Kehrer500ed9d2015-07-10 20:51:36 -05001972 def test_invalid_asn1_othername(self, backend):
1973 private_key = RSA_KEY_2048.private_key(backend)
1974
1975 builder = x509.CertificateSigningRequestBuilder().subject_name(
1976 x509.Name([
1977 x509.NameAttribute(x509.OID_COMMON_NAME, u"SAN"),
1978 ])
1979 ).add_extension(
1980 x509.SubjectAlternativeName([
1981 x509.OtherName(
1982 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
1983 value=b"\x01\x02\x01\x05"
1984 ),
1985 ]),
1986 critical=False,
1987 )
1988 with pytest.raises(ValueError):
1989 builder.sign(private_key, hashes.SHA256(), backend)
1990
Alex Gaynord5f718c2015-07-05 11:19:38 -04001991 def test_subject_alt_name_unsupported_general_name(self, backend):
1992 private_key = RSA_KEY_2048.private_key(backend)
1993
1994 builder = x509.CertificateSigningRequestBuilder().subject_name(
1995 x509.Name([
1996 x509.NameAttribute(x509.OID_COMMON_NAME, u"SAN"),
1997 ])
1998 ).add_extension(
Paul Kehrer474a6472015-07-11 12:29:52 -05001999 x509.SubjectAlternativeName([FakeGeneralName("")]),
Alex Gaynord5f718c2015-07-05 11:19:38 -04002000 critical=False,
2001 )
2002
Paul Kehrer474a6472015-07-11 12:29:52 -05002003 with pytest.raises(ValueError):
Alex Gaynord5f718c2015-07-05 11:19:38 -04002004 builder.sign(private_key, hashes.SHA256(), backend)
2005
Paul Kehrer0b8f3272015-07-23 21:46:21 +01002006 def test_extended_key_usage(self, backend):
2007 private_key = RSA_KEY_2048.private_key(backend)
2008 builder = x509.CertificateSigningRequestBuilder()
2009 request = builder.subject_name(
2010 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
2011 ).add_extension(
2012 x509.ExtendedKeyUsage([
2013 x509.OID_CLIENT_AUTH,
2014 x509.OID_SERVER_AUTH,
2015 x509.OID_CODE_SIGNING,
2016 ]), critical=False
2017 ).sign(private_key, hashes.SHA256(), backend)
2018
2019 eku = request.extensions.get_extension_for_oid(
2020 x509.OID_EXTENDED_KEY_USAGE
2021 )
2022 assert eku.critical is False
2023 assert eku.value == x509.ExtendedKeyUsage([
2024 x509.OID_CLIENT_AUTH,
2025 x509.OID_SERVER_AUTH,
2026 x509.OID_CODE_SIGNING,
2027 ])
2028
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002029 @pytest.mark.requires_backend_interface(interface=RSABackend)
2030 def test_rsa_key_too_small(self, backend):
2031 private_key = rsa.generate_private_key(65537, 512, backend)
2032 builder = x509.CertificateSigningRequestBuilder()
2033 builder = builder.subject_name(
2034 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
2035 )
2036
2037 with pytest.raises(ValueError) as exc:
2038 builder.sign(private_key, hashes.SHA512(), backend)
2039
Paul Kehrer6a71f8d2015-07-25 19:15:59 +01002040 assert str(exc.value) == "Digest too big for RSA key"
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01002041
Paul Kehrer3b54ce22015-08-03 16:44:57 +01002042 @pytest.mark.requires_backend_interface(interface=RSABackend)
2043 @pytest.mark.requires_backend_interface(interface=X509Backend)
2044 def test_build_cert_with_aia(self, backend):
2045 issuer_private_key = RSA_KEY_2048.private_key(backend)
2046 subject_private_key = RSA_KEY_2048.private_key(backend)
2047
2048 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2049 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2050
2051 aia = x509.AuthorityInformationAccess([
2052 x509.AccessDescription(
2053 x509.OID_OCSP,
2054 x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
2055 ),
2056 x509.AccessDescription(
2057 x509.OID_CA_ISSUERS,
2058 x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
2059 )
2060 ])
2061
2062 builder = x509.CertificateBuilder().serial_number(
2063 777
2064 ).issuer_name(x509.Name([
2065 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
2066 ])).subject_name(x509.Name([
2067 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
2068 ])).public_key(
2069 subject_private_key.public_key()
2070 ).add_extension(
2071 aia, critical=False
2072 ).not_valid_before(
2073 not_valid_before
2074 ).not_valid_after(
2075 not_valid_after
2076 )
2077
2078 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2079
2080 ext = cert.extensions.get_extension_for_oid(
2081 x509.OID_AUTHORITY_INFORMATION_ACCESS
2082 )
2083 assert ext.value == aia
2084
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01002085 @pytest.mark.requires_backend_interface(interface=RSABackend)
2086 @pytest.mark.requires_backend_interface(interface=X509Backend)
2087 def test_build_cert_with_ski(self, backend):
2088 issuer_private_key = RSA_KEY_2048.private_key(backend)
2089 subject_private_key = RSA_KEY_2048.private_key(backend)
2090
2091 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2092 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2093
2094 ski = x509.SubjectKeyIdentifier.from_public_key(
2095 subject_private_key.public_key()
2096 )
2097
2098 builder = x509.CertificateBuilder().serial_number(
2099 777
2100 ).issuer_name(x509.Name([
2101 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
2102 ])).subject_name(x509.Name([
2103 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
2104 ])).public_key(
2105 subject_private_key.public_key()
2106 ).add_extension(
2107 ski, critical=False
2108 ).not_valid_before(
2109 not_valid_before
2110 ).not_valid_after(
2111 not_valid_after
2112 )
2113
2114 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2115
2116 ext = cert.extensions.get_extension_for_oid(
2117 x509.OID_SUBJECT_KEY_IDENTIFIER
2118 )
2119 assert ext.value == ski
2120
Paul Kehrercbdc10b2015-08-05 21:24:59 +01002121 @pytest.mark.parametrize(
2122 "aki",
2123 [
2124 x509.AuthorityKeyIdentifier(
2125 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2126 b"\xcbY",
2127 None,
2128 None
2129 ),
2130 x509.AuthorityKeyIdentifier(
2131 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
2132 b"\xcbY",
2133 [
2134 x509.DirectoryName(
2135 x509.Name([
2136 x509.NameAttribute(
2137 x509.OID_ORGANIZATION_NAME, u"PyCA"
2138 ),
2139 x509.NameAttribute(
2140 x509.OID_COMMON_NAME, u"cryptography CA"
2141 )
2142 ])
2143 )
2144 ],
2145 333
2146 ),
2147 x509.AuthorityKeyIdentifier(
2148 None,
2149 [
2150 x509.DirectoryName(
2151 x509.Name([
2152 x509.NameAttribute(
2153 x509.OID_ORGANIZATION_NAME, u"PyCA"
2154 ),
2155 x509.NameAttribute(
2156 x509.OID_COMMON_NAME, u"cryptography CA"
2157 )
2158 ])
2159 )
2160 ],
2161 333
2162 ),
2163 ]
2164 )
2165 @pytest.mark.requires_backend_interface(interface=RSABackend)
2166 @pytest.mark.requires_backend_interface(interface=X509Backend)
2167 def test_build_cert_with_aki(self, aki, backend):
2168 issuer_private_key = RSA_KEY_2048.private_key(backend)
2169 subject_private_key = RSA_KEY_2048.private_key(backend)
2170
2171 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2172 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2173
2174 builder = x509.CertificateBuilder().serial_number(
2175 777
2176 ).issuer_name(x509.Name([
2177 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
2178 ])).subject_name(x509.Name([
2179 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
2180 ])).public_key(
2181 subject_private_key.public_key()
2182 ).add_extension(
2183 aki, critical=False
2184 ).not_valid_before(
2185 not_valid_before
2186 ).not_valid_after(
2187 not_valid_after
2188 )
2189
2190 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2191
2192 ext = cert.extensions.get_extension_for_oid(
2193 x509.OID_AUTHORITY_KEY_IDENTIFIER
2194 )
2195 assert ext.value == aki
2196
Alex Gaynord5f718c2015-07-05 11:19:38 -04002197
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002198@pytest.mark.requires_backend_interface(interface=DSABackend)
2199@pytest.mark.requires_backend_interface(interface=X509Backend)
2200class TestDSACertificate(object):
2201 def test_load_dsa_cert(self, backend):
2202 cert = _load_cert(
2203 os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
2204 x509.load_pem_x509_certificate,
2205 backend
2206 )
2207 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
2208 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002209 assert isinstance(public_key, dsa.DSAPublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002210 num = public_key.public_numbers()
2211 assert num.y == int(
2212 "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94"
2213 "53b6656f13e543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2"
2214 "dea559f0b584c97a2b235b9b69b46bc6de1aed422a6f341832618bcaae2"
2215 "198aba388099dafb05ff0b5efecb3b0ae169a62e1c72022af50ae68af3b"
2216 "033c18e6eec1f7df4692c456ccafb79cc7e08da0a5786e9816ceda651d6"
2217 "1b4bb7b81c2783da97cea62df67af5e85991fdc13aff10fc60e06586386"
2218 "b96bb78d65750f542f86951e05a6d81baadbcd35a2e5cad4119923ae6a2"
2219 "002091a3d17017f93c52970113cdc119970b9074ca506eac91c3dd37632"
2220 "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c", 16
2221 )
2222 assert num.parameter_numbers.g == int(
2223 "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67"
2224 "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b"
2225 "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2"
2226 "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa"
2227 "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f"
2228 "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a"
2229 "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0"
2230 "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76"
2231 "fa6247676a6d3ac945844a083509c6a1b436baca", 16
2232 )
2233 assert num.parameter_numbers.p == int(
2234 "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3"
2235 "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330"
2236 "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e"
2237 "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a"
2238 "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4"
2239 "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2"
2240 "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93"
2241 "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d"
2242 "833e36468f3907cfca788a3cb790f0341c8a31bf", 16
2243 )
2244 assert num.parameter_numbers.q == int(
2245 "822ff5d234e073b901cf5941f58e1f538e71d40d", 16
2246 )
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002247
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002248 @pytest.mark.parametrize(
2249 ("path", "loader_func"),
2250 [
2251 [
2252 os.path.join("x509", "requests", "dsa_sha1.pem"),
2253 x509.load_pem_x509_csr
2254 ],
2255 [
2256 os.path.join("x509", "requests", "dsa_sha1.der"),
2257 x509.load_der_x509_csr
2258 ],
2259 ]
2260 )
2261 def test_load_dsa_request(self, path, loader_func, backend):
2262 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002263 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2264 public_key = request.public_key()
2265 assert isinstance(public_key, dsa.DSAPublicKey)
2266 subject = request.subject
2267 assert isinstance(subject, x509.Name)
2268 assert list(subject) == [
Ian Cordasco82fc3762015-06-16 20:59:50 -05002269 x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
2270 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
2271 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
2272 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
2273 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002274 ]
2275
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002276
2277@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2278@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -06002279class TestECDSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002280 def test_load_ecdsa_cert(self, backend):
2281 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrera693cfd2014-11-27 07:47:58 -10002282 cert = _load_cert(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002283 os.path.join("x509", "ecdsa_root.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -10002284 x509.load_pem_x509_certificate,
Paul Kehrera693cfd2014-11-27 07:47:58 -10002285 backend
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002286 )
Paul Kehrer8802a5b2015-02-13 12:06:57 -06002287 assert isinstance(cert.signature_hash_algorithm, hashes.SHA384)
Paul Kehrerf1ef3512014-11-26 17:36:05 -10002288 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08002289 assert isinstance(public_key, ec.EllipticCurvePublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04002290 num = public_key.public_numbers()
2291 assert num.x == int(
2292 "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f"
2293 "6f0ccd00bba615b51467e9e2d9fee8e630c17", 16
2294 )
2295 assert num.y == int(
2296 "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7"
2297 "2deae88a7a16bb543ce67dc23ff031ca3e23e", 16
2298 )
2299 assert isinstance(num.curve, ec.SECP384R1)
Paul Kehrer6c660a82014-12-12 11:50:44 -06002300
2301 def test_load_ecdsa_no_named_curve(self, backend):
2302 _skip_curve_unsupported(backend, ec.SECP256R1())
2303 cert = _load_cert(
2304 os.path.join("x509", "custom", "ec_no_named_curve.pem"),
2305 x509.load_pem_x509_certificate,
2306 backend
2307 )
2308 with pytest.raises(NotImplementedError):
2309 cert.public_key()
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002310
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002311 @pytest.mark.parametrize(
2312 ("path", "loader_func"),
2313 [
2314 [
2315 os.path.join("x509", "requests", "ec_sha256.pem"),
2316 x509.load_pem_x509_csr
2317 ],
2318 [
2319 os.path.join("x509", "requests", "ec_sha256.der"),
2320 x509.load_der_x509_csr
2321 ],
2322 ]
2323 )
2324 def test_load_ecdsa_certificate_request(self, path, loader_func, backend):
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002325 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrer1effb6e2015-03-30 15:05:59 -05002326 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002327 assert isinstance(request.signature_hash_algorithm, hashes.SHA256)
2328 public_key = request.public_key()
2329 assert isinstance(public_key, ec.EllipticCurvePublicKey)
2330 subject = request.subject
2331 assert isinstance(subject, x509.Name)
2332 assert list(subject) == [
Ian Cordasco82fc3762015-06-16 20:59:50 -05002333 x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
2334 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
2335 x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
2336 x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u'Texas'),
2337 x509.NameAttribute(x509.OID_LOCALITY_NAME, u'Austin'),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06002338 ]
2339
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002340
Paul Kehrer806bfb22015-02-02 17:05:24 -06002341class TestNameAttribute(object):
Alex Gaynora56ff412015-02-10 17:26:32 -05002342 def test_init_bad_oid(self):
2343 with pytest.raises(TypeError):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002344 x509.NameAttribute(None, u'value')
Alex Gaynora56ff412015-02-10 17:26:32 -05002345
Ian Cordasco7618fbe2015-06-16 19:12:17 -05002346 def test_init_bad_value(self):
2347 with pytest.raises(TypeError):
2348 x509.NameAttribute(
2349 x509.ObjectIdentifier('oid'),
2350 b'bytes'
2351 )
2352
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002353 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002354 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002355 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002356 ) == x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002357 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002358 )
2359
2360 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002361 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002362 x509.ObjectIdentifier('2.5.4.3'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002363 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002364 x509.ObjectIdentifier('2.5.4.5'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002365 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002366 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002367 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer806bfb22015-02-02 17:05:24 -06002368 ) != x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002369 x509.ObjectIdentifier('oid'), u'value2'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002370 )
Paul Kehrer806bfb22015-02-02 17:05:24 -06002371 assert x509.NameAttribute(
Ian Cordasco82fc3762015-06-16 20:59:50 -05002372 x509.ObjectIdentifier('oid'), u'value'
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002373 ) != object()
2374
Paul Kehrera498be82015-02-12 15:00:56 -06002375 def test_repr(self):
Ian Cordasco82fc3762015-06-16 20:59:50 -05002376 na = x509.NameAttribute(x509.ObjectIdentifier('2.5.4.3'), u'value')
Ian Cordascoa908d692015-06-16 21:35:24 -05002377 if six.PY3:
2378 assert repr(na) == (
2379 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2380 "nName)>, value='value')>"
2381 )
2382 else:
2383 assert repr(na) == (
2384 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
2385 "nName)>, value=u'value')>"
2386 )
Paul Kehrera498be82015-02-12 15:00:56 -06002387
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002388
2389class TestObjectIdentifier(object):
2390 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002391 oid1 = x509.ObjectIdentifier('oid')
2392 oid2 = x509.ObjectIdentifier('oid')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002393 assert oid1 == oid2
2394
2395 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002396 oid1 = x509.ObjectIdentifier('oid')
2397 assert oid1 != x509.ObjectIdentifier('oid1')
Paul Kehrer912d3fb2015-01-29 11:19:22 -06002398 assert oid1 != object()
2399
2400 def test_repr(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06002401 oid = x509.ObjectIdentifier("2.5.4.3")
2402 assert repr(oid) == "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>"
2403 oid = x509.ObjectIdentifier("oid1")
2404 assert repr(oid) == "<ObjectIdentifier(oid=oid1, name=Unknown OID)>"
Paul Kehrer719d5362015-01-01 20:03:52 -06002405
2406
2407class TestName(object):
2408 def test_eq(self):
2409 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002410 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2411 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002412 ])
2413 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002414 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2415 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002416 ])
2417 assert name1 == name2
2418
2419 def test_ne(self):
2420 name1 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002421 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
2422 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002423 ])
2424 name2 = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002425 x509.NameAttribute(x509.ObjectIdentifier('oid2'), u'value2'),
2426 x509.NameAttribute(x509.ObjectIdentifier('oid'), u'value1'),
Paul Kehrer719d5362015-01-01 20:03:52 -06002427 ])
2428 assert name1 != name2
2429 assert name1 != object()
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002430
2431 def test_repr(self):
2432 name = x509.Name([
Ian Cordasco82fc3762015-06-16 20:59:50 -05002433 x509.NameAttribute(x509.OID_COMMON_NAME, u'cryptography.io'),
2434 x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u'PyCA'),
Paul Kehrer1fb35c92015-04-11 15:42:54 -04002435 ])
2436
Ian Cordascoa908d692015-06-16 21:35:24 -05002437 if six.PY3:
2438 assert repr(name) == (
2439 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2440 "=commonName)>, value='cryptography.io')>, <NameAttribute(oid="
2441 "<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, valu"
2442 "e='PyCA')>])>"
2443 )
2444 else:
2445 assert repr(name) == (
2446 "<Name([<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name"
2447 "=commonName)>, value=u'cryptography.io')>, <NameAttribute(oid"
2448 "=<ObjectIdentifier(oid=2.5.4.10, name=organizationName)>, val"
2449 "ue=u'PyCA')>])>"
2450 )