blob: 146619b9a84b9824be7886a120abb992cb024168 [file] [log] [blame]
Lucia Lic6ba99d2021-11-08 22:06:11 +08001# -*- coding: utf-8 -*-
Paul Kehrer016e08a2014-11-26 09:41:18 -10002# This file is dual licensed under the terms of the Apache License, Version
3# 2.0, and the BSD License. See the LICENSE file in the root of this repository
4# for complete details.
5
6from __future__ import absolute_import, division, print_function
7
Paul Kehrer0307c372014-11-27 09:49:31 -10008import binascii
Lucia Lic6ba99d2021-11-08 22:06:11 +08009import collections
10import copy
Paul Kehrer016e08a2014-11-26 09:41:18 -100011import datetime
Paul Kehrer235e5a12015-07-10 19:45:47 -050012import ipaddress
Paul Kehrer016e08a2014-11-26 09:41:18 -100013import os
Paul Kehrer016e08a2014-11-26 09:41:18 -100014
15import pytest
16
InvalidInterrupt8e66ca62016-08-16 19:39:31 -070017import pytz
18
Ian Cordascoa908d692015-06-16 21:35:24 -050019import six
20
Paul Kehrer474a6472015-07-11 12:29:52 -050021from cryptography import utils, x509
Paul Kehrer8802a5b2015-02-13 12:06:57 -060022from cryptography.exceptions import UnsupportedAlgorithm
Lucia Lic6ba99d2021-11-08 22:06:11 +080023from cryptography.hazmat._der import (
24 BIT_STRING,
25 CONSTRUCTED,
26 CONTEXT_SPECIFIC,
27 DERReader,
28 GENERALIZED_TIME,
29 INTEGER,
30 OBJECT_IDENTIFIER,
31 PRINTABLE_STRING,
32 SEQUENCE,
33 SET,
34 UTC_TIME,
35)
Paul Kehrerf1ef3512014-11-26 17:36:05 -100036from cryptography.hazmat.backends.interfaces import (
Lucia Lic6ba99d2021-11-08 22:06:11 +080037 DSABackend,
38 EllipticCurveBackend,
39 RSABackend,
40 X509Backend,
Paul Kehrerf1ef3512014-11-26 17:36:05 -100041)
Andre Caron476c5df2015-05-18 10:23:28 -040042from cryptography.hazmat.primitives import hashes, serialization
Lucia Lic6ba99d2021-11-08 22:06:11 +080043from cryptography.hazmat.primitives.asymmetric import (
44 dh,
45 dsa,
46 ec,
47 ed25519,
48 ed448,
49 padding,
50 rsa,
Paul Kehrerd91e7c12015-10-01 16:50:42 -050051)
Lucia Lic6ba99d2021-11-08 22:06:11 +080052from cryptography.hazmat.primitives.asymmetric.utils import (
53 decode_dss_signature,
54)
55from cryptography.utils import int_from_bytes
Paul Kehrer72c92f52017-09-26 10:23:24 +080056from cryptography.x509.name import _ASN1Type
Paul Kehrer9e102db2015-08-10 21:53:09 -050057from cryptography.x509.oid import (
Lucia Lic6ba99d2021-11-08 22:06:11 +080058 AuthorityInformationAccessOID,
59 ExtendedKeyUsageOID,
60 ExtensionOID,
61 NameOID,
62 SignatureAlgorithmOID,
63 SubjectInformationAccessOID,
Paul Kehrer9e102db2015-08-10 21:53:09 -050064)
Paul Kehrer016e08a2014-11-26 09:41:18 -100065
Paul Kehrerec0e1cc2017-09-07 09:48:10 +080066from ..hazmat.primitives.fixtures_dsa import DSA_KEY_2048
67from ..hazmat.primitives.fixtures_ec import EC_KEY_SECP256R1
68from ..hazmat.primitives.fixtures_rsa import RSA_KEY_2048, RSA_KEY_512
69from ..hazmat.primitives.test_ec import _skip_curve_unsupported
Lucia Lic6ba99d2021-11-08 22:06:11 +080070from ..utils import load_nist_vectors, load_vectors_from_file
Paul Kehrer016e08a2014-11-26 09:41:18 -100071
72
Paul Kehrer69b64e42015-08-09 00:00:44 -050073@utils.register_interface(x509.ExtensionType)
74class DummyExtension(object):
75 oid = x509.ObjectIdentifier("1.2.3.4")
76
77
Paul Kehrer474a6472015-07-11 12:29:52 -050078@utils.register_interface(x509.GeneralName)
79class FakeGeneralName(object):
80 def __init__(self, value):
81 self._value = value
82
83 value = utils.read_only_property("_value")
84
85
Paul Kehrer41120322014-12-02 18:31:14 -100086def _load_cert(filename, loader, backend):
Paul Kehrer016e08a2014-11-26 09:41:18 -100087 cert = load_vectors_from_file(
Paul Kehrera693cfd2014-11-27 07:47:58 -100088 filename=filename,
89 loader=lambda pemfile: loader(pemfile.read(), backend),
Lucia Lic6ba99d2021-11-08 22:06:11 +080090 mode="rb",
Paul Kehrer016e08a2014-11-26 09:41:18 -100091 )
92 return cert
93
94
Lucia Lic6ba99d2021-11-08 22:06:11 +080095ParsedCertificate = collections.namedtuple(
96 "ParsedCertificate",
97 ["not_before_tag", "not_after_tag", "issuer", "subject"],
98)
99
100
101def _parse_cert(der):
102 # See the Certificate structured, defined in RFC 5280.
103 with DERReader(der).read_single_element(SEQUENCE) as cert:
104 tbs_cert = cert.read_element(SEQUENCE)
105 # Skip outer signature algorithm
106 _ = cert.read_element(SEQUENCE)
107 # Skip signature
108 _ = cert.read_element(BIT_STRING)
109
110 with tbs_cert:
111 # Skip version
112 _ = tbs_cert.read_optional_element(CONTEXT_SPECIFIC | CONSTRUCTED | 0)
113 # Skip serialNumber
114 _ = tbs_cert.read_element(INTEGER)
115 # Skip inner signature algorithm
116 _ = tbs_cert.read_element(SEQUENCE)
117 issuer = tbs_cert.read_element(SEQUENCE)
118 validity = tbs_cert.read_element(SEQUENCE)
119 subject = tbs_cert.read_element(SEQUENCE)
120 # Skip subjectPublicKeyInfo
121 _ = tbs_cert.read_element(SEQUENCE)
122 # Skip issuerUniqueID
123 _ = tbs_cert.read_optional_element(CONTEXT_SPECIFIC | CONSTRUCTED | 1)
124 # Skip subjectUniqueID
125 _ = tbs_cert.read_optional_element(CONTEXT_SPECIFIC | CONSTRUCTED | 2)
126 # Skip extensions
127 _ = tbs_cert.read_optional_element(CONTEXT_SPECIFIC | CONSTRUCTED | 3)
128
129 with validity:
130 not_before_tag, _ = validity.read_any_element()
131 not_after_tag, _ = validity.read_any_element()
132
133 return ParsedCertificate(
134 not_before_tag=not_before_tag,
135 not_after_tag=not_after_tag,
136 issuer=issuer,
137 subject=subject,
138 )
139
140
Erik Trauschkedc570402015-09-24 20:24:28 -0700141@pytest.mark.requires_backend_interface(interface=X509Backend)
142class TestCertificateRevocationList(object):
143 def test_load_pem_crl(self, backend):
144 crl = _load_cert(
145 os.path.join("x509", "custom", "crl_all_reasons.pem"),
146 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800147 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700148 )
149
150 assert isinstance(crl, x509.CertificateRevocationList)
151 fingerprint = binascii.hexlify(crl.fingerprint(hashes.SHA1()))
152 assert fingerprint == b"3234b0cb4c0cedf6423724b736729dcfc9e441ef"
153 assert isinstance(crl.signature_hash_algorithm, hashes.SHA256)
Paul Kehrerc7b29b82016-09-01 09:17:21 +0800154 assert (
Lucia Lic6ba99d2021-11-08 22:06:11 +0800155 crl.signature_algorithm_oid
156 == SignatureAlgorithmOID.RSA_WITH_SHA256
Paul Kehrerc7b29b82016-09-01 09:17:21 +0800157 )
Erik Trauschkedc570402015-09-24 20:24:28 -0700158
159 def test_load_der_crl(self, backend):
160 crl = _load_cert(
161 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
162 x509.load_der_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800163 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700164 )
165
166 assert isinstance(crl, x509.CertificateRevocationList)
167 fingerprint = binascii.hexlify(crl.fingerprint(hashes.SHA1()))
168 assert fingerprint == b"dd3db63c50f4c4a13e090f14053227cb1011a5ad"
169 assert isinstance(crl.signature_hash_algorithm, hashes.SHA256)
170
171 def test_invalid_pem(self, backend):
172 with pytest.raises(ValueError):
173 x509.load_pem_x509_crl(b"notacrl", backend)
174
175 def test_invalid_der(self, backend):
176 with pytest.raises(ValueError):
177 x509.load_der_x509_crl(b"notacrl", backend)
178
179 def test_unknown_signature_algorithm(self, backend):
180 crl = _load_cert(
181 os.path.join(
182 "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
183 ),
184 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800185 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700186 )
187
188 with pytest.raises(UnsupportedAlgorithm):
Lucia Lic6ba99d2021-11-08 22:06:11 +0800189 crl.signature_hash_algorithm()
Erik Trauschkedc570402015-09-24 20:24:28 -0700190
191 def test_issuer(self, backend):
192 crl = _load_cert(
193 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
194 x509.load_der_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800195 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700196 )
197
198 assert isinstance(crl.issuer, x509.Name)
199 assert list(crl.issuer) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800200 x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
Erik Trauschkedc570402015-09-24 20:24:28 -0700201 x509.NameAttribute(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800202 x509.OID_ORGANIZATION_NAME, u"Test Certificates 2011"
Erik Trauschkedc570402015-09-24 20:24:28 -0700203 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800204 x509.NameAttribute(x509.OID_COMMON_NAME, u"Good CA"),
Erik Trauschkedc570402015-09-24 20:24:28 -0700205 ]
206 assert crl.issuer.get_attributes_for_oid(x509.OID_COMMON_NAME) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800207 x509.NameAttribute(x509.OID_COMMON_NAME, u"Good CA")
Erik Trauschkedc570402015-09-24 20:24:28 -0700208 ]
209
210 def test_equality(self, backend):
211 crl1 = _load_cert(
212 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
213 x509.load_der_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800214 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700215 )
216
217 crl2 = _load_cert(
218 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
219 x509.load_der_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800220 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700221 )
222
223 crl3 = _load_cert(
224 os.path.join("x509", "custom", "crl_all_reasons.pem"),
225 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800226 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700227 )
228
229 assert crl1 == crl2
230 assert crl1 != crl3
231 assert crl1 != object()
232
233 def test_update_dates(self, backend):
234 crl = _load_cert(
235 os.path.join("x509", "custom", "crl_all_reasons.pem"),
236 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800237 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700238 )
239
240 assert isinstance(crl.next_update, datetime.datetime)
241 assert isinstance(crl.last_update, datetime.datetime)
242
243 assert crl.next_update.isoformat() == "2016-01-01T00:00:00"
244 assert crl.last_update.isoformat() == "2015-01-01T00:00:00"
245
Erik Trauschke77f5a252015-10-14 08:06:38 -0700246 def test_revoked_cert_retrieval(self, backend):
Erik Trauschkedc570402015-09-24 20:24:28 -0700247 crl = _load_cert(
248 os.path.join("x509", "custom", "crl_all_reasons.pem"),
249 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800250 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700251 )
252
Erik Trauschke77f5a252015-10-14 08:06:38 -0700253 for r in crl:
Paul Kehrer0219e662015-10-21 20:18:24 -0500254 assert isinstance(r, x509.RevokedCertificate)
Erik Trauschkedc570402015-09-24 20:24:28 -0700255
Erik Trauschke77f5a252015-10-14 08:06:38 -0700256 # Check that len() works for CRLs.
257 assert len(crl) == 12
258
Paul Kehrer5d187402018-07-16 20:49:51 +0530259 def test_get_revoked_certificate_by_serial_number(self, backend):
260 crl = _load_cert(
261 os.path.join(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800262 "x509", "PKITS_data", "crls", "LongSerialNumberCACRL.crl"
263 ),
Paul Kehrer5d187402018-07-16 20:49:51 +0530264 x509.load_der_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800265 backend,
Paul Kehrer5d187402018-07-16 20:49:51 +0530266 )
267 serial_number = 725064303890588110203033396814564464046290047507
268 revoked = crl.get_revoked_certificate_by_serial_number(serial_number)
269 assert revoked.serial_number == serial_number
270 assert crl.get_revoked_certificate_by_serial_number(500) is None
271
Paul Kehrer1f943ab2015-12-23 19:21:23 -0600272 def test_revoked_cert_retrieval_retain_only_revoked(self, backend):
273 """
274 This test attempts to trigger the crash condition described in
275 https://github.com/pyca/cryptography/issues/2557
Paul Kehrer7e75b622015-12-23 19:30:35 -0600276 PyPy does gc at its own pace, so it will only be reliable on CPython.
Paul Kehrer1f943ab2015-12-23 19:21:23 -0600277 """
Paul Kehrer7e75b622015-12-23 19:30:35 -0600278 revoked = _load_cert(
Paul Kehrer1f943ab2015-12-23 19:21:23 -0600279 os.path.join("x509", "custom", "crl_all_reasons.pem"),
280 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800281 backend,
Paul Kehrer7e75b622015-12-23 19:30:35 -0600282 )[11]
Paul Kehrer1f943ab2015-12-23 19:21:23 -0600283 assert revoked.revocation_date == datetime.datetime(2015, 1, 1, 0, 0)
284 assert revoked.serial_number == 11
285
Erik Trauschkedc570402015-09-24 20:24:28 -0700286 def test_extensions(self, backend):
287 crl = _load_cert(
Paul Kehrer2587d302015-12-22 17:20:42 -0600288 os.path.join("x509", "custom", "crl_ian_aia_aki.pem"),
289 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800290 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700291 )
292
Paul Kehrer51f39cb2015-12-21 21:17:39 -0600293 crl_number = crl.extensions.get_extension_for_oid(
294 ExtensionOID.CRL_NUMBER
295 )
296 aki = crl.extensions.get_extension_for_class(
297 x509.AuthorityKeyIdentifier
298 )
Paul Kehrer2587d302015-12-22 17:20:42 -0600299 aia = crl.extensions.get_extension_for_class(
300 x509.AuthorityInformationAccess
301 )
302 ian = crl.extensions.get_extension_for_class(
303 x509.IssuerAlternativeName
304 )
Paul Kehrer3b95cd72015-12-22 21:40:20 -0600305 assert crl_number.value == x509.CRLNumber(1)
Paul Kehrer51f39cb2015-12-21 21:17:39 -0600306 assert crl_number.critical is False
307 assert aki.value == x509.AuthorityKeyIdentifier(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800308 key_identifier=(b"yu\xbb\x84:\xcb,\xdez\t\xbe1\x1bC\xbc\x1c*MSX"),
Paul Kehrer51f39cb2015-12-21 21:17:39 -0600309 authority_cert_issuer=None,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800310 authority_cert_serial_number=None,
Paul Kehrer51f39cb2015-12-21 21:17:39 -0600311 )
Lucia Lic6ba99d2021-11-08 22:06:11 +0800312 assert aia.value == x509.AuthorityInformationAccess(
313 [
314 x509.AccessDescription(
315 AuthorityInformationAccessOID.CA_ISSUERS,
316 x509.DNSName(u"cryptography.io"),
317 )
318 ]
319 )
320 assert ian.value == x509.IssuerAlternativeName(
321 [x509.UniformResourceIdentifier(u"https://cryptography.io")]
322 )
Erik Trauschkedc570402015-09-24 20:24:28 -0700323
Paul Kehrer5e3cc982017-09-22 21:29:36 +0800324 def test_delta_crl_indicator(self, backend):
325 crl = _load_cert(
326 os.path.join("x509", "custom", "crl_delta_crl_indicator.pem"),
327 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800328 backend,
Paul Kehrer5e3cc982017-09-22 21:29:36 +0800329 )
330
331 dci = crl.extensions.get_extension_for_oid(
332 ExtensionOID.DELTA_CRL_INDICATOR
333 )
334 assert dci.value == x509.DeltaCRLIndicator(12345678901234567890)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800335 assert dci.critical is True
Paul Kehrer5e3cc982017-09-22 21:29:36 +0800336
Erik Trauschke6abe2bb2015-11-19 10:27:01 -0800337 def test_signature(self, backend):
338 crl = _load_cert(
339 os.path.join("x509", "custom", "crl_all_reasons.pem"),
340 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800341 backend,
Erik Trauschke6abe2bb2015-11-19 10:27:01 -0800342 )
343
344 assert crl.signature == binascii.unhexlify(
345 b"536a5a0794f68267361e7bc2f19167a3e667a2ab141535616855d8deb2ba1af"
346 b"9fd4546b1fe76b454eb436af7b28229fedff4634dfc9dd92254266219ae0ea8"
347 b"75d9ff972e9a2da23d5945f073da18c50a4265bfed9ca16586347800ef49dd1"
348 b"6856d7265f4f3c498a57f04dc04404e2bd2e2ada1f5697057aacef779a18371"
349 b"c621edc9a5c2b8ec1716e8fa22feeb7fcec0ce9156c8d344aa6ae8d1a5d99d0"
350 b"9386df36307df3b63c83908f4a61a0ff604c1e292ad63b349d1082ddd7ae1b7"
351 b"c178bba995523ec6999310c54da5706549797bfb1230f5593ba7b4353dade4f"
352 b"d2be13a57580a6eb20b5c4083f000abac3bf32cd8b75f23e4c8f4b3a79e1e2d"
353 b"58a472b0"
354 )
355
Erik Trauschke569aa6a2015-11-19 11:09:42 -0800356 def test_tbs_certlist_bytes(self, backend):
Erik Trauschke6abe2bb2015-11-19 10:27:01 -0800357 crl = _load_cert(
358 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
359 x509.load_der_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800360 backend,
Erik Trauschke6abe2bb2015-11-19 10:27:01 -0800361 )
362
363 ca_cert = _load_cert(
364 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
365 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800366 backend,
Erik Trauschke6abe2bb2015-11-19 10:27:01 -0800367 )
368
Alex Gaynorb916fa92017-12-03 18:16:22 -0600369 ca_cert.public_key().verify(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800370 crl.signature,
371 crl.tbs_certlist_bytes,
372 padding.PKCS1v15(),
373 crl.signature_hash_algorithm,
Erik Trauschke6abe2bb2015-11-19 10:27:01 -0800374 )
Erik Trauschke6abe2bb2015-11-19 10:27:01 -0800375
Paul Kehrer54a837d2015-12-20 23:42:32 -0600376 def test_public_bytes_pem(self, backend):
377 crl = _load_cert(
378 os.path.join("x509", "custom", "crl_empty.pem"),
379 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800380 backend,
Paul Kehrer54a837d2015-12-20 23:42:32 -0600381 )
382
383 # Encode it to PEM and load it back.
Lucia Lic6ba99d2021-11-08 22:06:11 +0800384 crl = x509.load_pem_x509_crl(
385 crl.public_bytes(
386 encoding=serialization.Encoding.PEM,
387 ),
388 backend,
389 )
Paul Kehrer54a837d2015-12-20 23:42:32 -0600390
391 assert len(crl) == 0
392 assert crl.last_update == datetime.datetime(2015, 12, 20, 23, 44, 47)
393 assert crl.next_update == datetime.datetime(2015, 12, 28, 0, 44, 47)
394
395 def test_public_bytes_der(self, backend):
396 crl = _load_cert(
397 os.path.join("x509", "custom", "crl_all_reasons.pem"),
398 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800399 backend,
Paul Kehrer54a837d2015-12-20 23:42:32 -0600400 )
401
402 # Encode it to DER and load it back.
Lucia Lic6ba99d2021-11-08 22:06:11 +0800403 crl = x509.load_der_x509_crl(
404 crl.public_bytes(
405 encoding=serialization.Encoding.DER,
406 ),
407 backend,
408 )
Paul Kehrer54a837d2015-12-20 23:42:32 -0600409
410 assert len(crl) == 12
411 assert crl.last_update == datetime.datetime(2015, 1, 1, 0, 0, 0)
412 assert crl.next_update == datetime.datetime(2016, 1, 1, 0, 0, 0)
413
Paul Kehrer2c918582015-12-21 09:25:36 -0600414 @pytest.mark.parametrize(
415 ("cert_path", "loader_func", "encoding"),
416 [
417 (
418 os.path.join("x509", "custom", "crl_all_reasons.pem"),
419 x509.load_pem_x509_crl,
420 serialization.Encoding.PEM,
421 ),
422 (
423 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
424 x509.load_der_x509_crl,
425 serialization.Encoding.DER,
426 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800427 ],
Paul Kehrer2c918582015-12-21 09:25:36 -0600428 )
Lucia Lic6ba99d2021-11-08 22:06:11 +0800429 def test_public_bytes_match(
430 self, cert_path, loader_func, encoding, backend
431 ):
Paul Kehrer2c918582015-12-21 09:25:36 -0600432 crl_bytes = load_vectors_from_file(
433 cert_path, lambda pemfile: pemfile.read(), mode="rb"
434 )
435 crl = loader_func(crl_bytes, backend)
436 serialized = crl.public_bytes(encoding)
437 assert serialized == crl_bytes
438
Paul Kehrer54a837d2015-12-20 23:42:32 -0600439 def test_public_bytes_invalid_encoding(self, backend):
440 crl = _load_cert(
441 os.path.join("x509", "custom", "crl_empty.pem"),
442 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800443 backend,
Paul Kehrer54a837d2015-12-20 23:42:32 -0600444 )
445
446 with pytest.raises(TypeError):
Lucia Lic6ba99d2021-11-08 22:06:11 +0800447 crl.public_bytes("NotAnEncoding")
Paul Kehrer54a837d2015-12-20 23:42:32 -0600448
Vincent Pelletier6c02ee82017-08-12 22:05:00 +0900449 def test_verify_bad(self, backend):
450 crl = _load_cert(
451 os.path.join("x509", "custom", "invalid_signature.pem"),
452 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800453 backend,
Vincent Pelletier6c02ee82017-08-12 22:05:00 +0900454 )
455 crt = _load_cert(
456 os.path.join("x509", "custom", "invalid_signature.pem"),
457 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800458 backend,
Vincent Pelletier6c02ee82017-08-12 22:05:00 +0900459 )
460
461 assert not crl.is_signature_valid(crt.public_key())
462
463 def test_verify_good(self, backend):
464 crl = _load_cert(
465 os.path.join("x509", "custom", "valid_signature.pem"),
466 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800467 backend,
Vincent Pelletier6c02ee82017-08-12 22:05:00 +0900468 )
469 crt = _load_cert(
470 os.path.join("x509", "custom", "valid_signature.pem"),
471 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800472 backend,
Vincent Pelletier6c02ee82017-08-12 22:05:00 +0900473 )
474
475 assert crl.is_signature_valid(crt.public_key())
476
477 def test_verify_argument_must_be_a_public_key(self, backend):
478 crl = _load_cert(
479 os.path.join("x509", "custom", "valid_signature.pem"),
480 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800481 backend,
Vincent Pelletier6c02ee82017-08-12 22:05:00 +0900482 )
483
484 with pytest.raises(TypeError):
485 crl.is_signature_valid("not a public key")
486
487 with pytest.raises(TypeError):
488 crl.is_signature_valid(object)
489
Erik Trauschkedc570402015-09-24 20:24:28 -0700490
491@pytest.mark.requires_backend_interface(interface=X509Backend)
492class TestRevokedCertificate(object):
Erik Trauschkedc570402015-09-24 20:24:28 -0700493 def test_revoked_basics(self, backend):
494 crl = _load_cert(
495 os.path.join("x509", "custom", "crl_all_reasons.pem"),
496 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800497 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700498 )
499
Erik Trauschke77f5a252015-10-14 08:06:38 -0700500 for i, rev in enumerate(crl):
Erik Trauschkedc570402015-09-24 20:24:28 -0700501 assert isinstance(rev, x509.RevokedCertificate)
502 assert isinstance(rev.serial_number, int)
503 assert isinstance(rev.revocation_date, datetime.datetime)
504 assert isinstance(rev.extensions, x509.Extensions)
505
506 assert rev.serial_number == i
507 assert rev.revocation_date.isoformat() == "2015-01-01T00:00:00"
508
509 def test_revoked_extensions(self, backend):
510 crl = _load_cert(
511 os.path.join("x509", "custom", "crl_all_reasons.pem"),
512 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800513 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700514 )
515
Paul Kehrer49bb7562015-12-25 16:17:40 -0600516 exp_issuer = [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800517 x509.DirectoryName(
518 x509.Name(
519 [
520 x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
521 x509.NameAttribute(
522 x509.OID_COMMON_NAME, u"cryptography.io"
523 ),
524 ]
525 )
526 )
Paul Kehrer49bb7562015-12-25 16:17:40 -0600527 ]
Erik Trauschked4e7d432015-10-15 14:45:38 -0700528
Erik Trauschkedc570402015-09-24 20:24:28 -0700529 # First revoked cert doesn't have extensions, test if it is handled
530 # correctly.
Erik Trauschke77f5a252015-10-14 08:06:38 -0700531 rev0 = crl[0]
Erik Trauschkedc570402015-09-24 20:24:28 -0700532 # It should return an empty Extensions object.
533 assert isinstance(rev0.extensions, x509.Extensions)
534 assert len(rev0.extensions) == 0
535 with pytest.raises(x509.ExtensionNotFound):
536 rev0.extensions.get_extension_for_oid(x509.OID_CRL_REASON)
Erik Trauschkecee79f82015-10-21 10:48:28 -0700537 with pytest.raises(x509.ExtensionNotFound):
Erik Trauschke32bbfe02015-10-21 08:04:55 -0700538 rev0.extensions.get_extension_for_oid(x509.OID_CERTIFICATE_ISSUER)
Erik Trauschkecee79f82015-10-21 10:48:28 -0700539 with pytest.raises(x509.ExtensionNotFound):
Erik Trauschke32bbfe02015-10-21 08:04:55 -0700540 rev0.extensions.get_extension_for_oid(x509.OID_INVALIDITY_DATE)
Erik Trauschkedc570402015-09-24 20:24:28 -0700541
542 # Test manual retrieval of extension values.
Erik Trauschke77f5a252015-10-14 08:06:38 -0700543 rev1 = crl[1]
Erik Trauschkedc570402015-09-24 20:24:28 -0700544 assert isinstance(rev1.extensions, x509.Extensions)
545
Lucia Lic6ba99d2021-11-08 22:06:11 +0800546 reason = rev1.extensions.get_extension_for_class(x509.CRLReason).value
Paul Kehrer7058ece2015-12-25 22:28:29 -0600547 assert reason == x509.CRLReason(x509.ReasonFlags.unspecified)
Erik Trauschkedc570402015-09-24 20:24:28 -0700548
Paul Kehrer49bb7562015-12-25 16:17:40 -0600549 issuer = rev1.extensions.get_extension_for_class(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800550 x509.CertificateIssuer
551 ).value
Paul Kehrer49bb7562015-12-25 16:17:40 -0600552 assert issuer == x509.CertificateIssuer(exp_issuer)
Erik Trauschked4e7d432015-10-15 14:45:38 -0700553
Paul Kehrer23c0bbc2015-12-25 22:35:19 -0600554 date = rev1.extensions.get_extension_for_class(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800555 x509.InvalidityDate
556 ).value
Paul Kehrer23c0bbc2015-12-25 22:35:19 -0600557 assert date == x509.InvalidityDate(datetime.datetime(2015, 1, 1, 0, 0))
Erik Trauschkedc570402015-09-24 20:24:28 -0700558
Erik Trauschkedc570402015-09-24 20:24:28 -0700559 # Check if all reason flags can be found in the CRL.
560 flags = set(x509.ReasonFlags)
Erik Trauschke32bbfe02015-10-21 08:04:55 -0700561 for rev in crl:
562 try:
Paul Kehrer7058ece2015-12-25 22:28:29 -0600563 r = rev.extensions.get_extension_for_class(x509.CRLReason)
Erik Trauschke32bbfe02015-10-21 08:04:55 -0700564 except x509.ExtensionNotFound:
565 # Not all revoked certs have a reason extension.
566 pass
567 else:
Paul Kehrer7058ece2015-12-25 22:28:29 -0600568 flags.discard(r.value.reason)
Erik Trauschke32bbfe02015-10-21 08:04:55 -0700569
Erik Trauschkedc570402015-09-24 20:24:28 -0700570 assert len(flags) == 0
571
Paul Kehrer9543a332015-12-20 18:48:24 -0600572 def test_no_revoked_certs(self, backend):
573 crl = _load_cert(
574 os.path.join("x509", "custom", "crl_empty.pem"),
575 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800576 backend,
Paul Kehrer9543a332015-12-20 18:48:24 -0600577 )
578 assert len(crl) == 0
579
Erik Trauschkedc570402015-09-24 20:24:28 -0700580 def test_duplicate_entry_ext(self, backend):
581 crl = _load_cert(
582 os.path.join("x509", "custom", "crl_dup_entry_ext.pem"),
583 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800584 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700585 )
586
587 with pytest.raises(x509.DuplicateExtension):
Erik Trauschke77f5a252015-10-14 08:06:38 -0700588 crl[0].extensions
Erik Trauschkedc570402015-09-24 20:24:28 -0700589
590 def test_unsupported_crit_entry_ext(self, backend):
591 crl = _load_cert(
592 os.path.join(
593 "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
594 ),
595 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800596 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700597 )
598
Alex Gaynord08ddd52017-05-20 09:01:54 -0700599 ext = crl[0].extensions.get_extension_for_oid(
600 x509.ObjectIdentifier("1.2.3.4")
601 )
602 assert ext.value.value == b"\n\x01\x00"
Erik Trauschkedc570402015-09-24 20:24:28 -0700603
604 def test_unsupported_reason(self, backend):
605 crl = _load_cert(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800606 os.path.join("x509", "custom", "crl_unsupported_reason.pem"),
Erik Trauschkedc570402015-09-24 20:24:28 -0700607 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800608 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700609 )
610
611 with pytest.raises(ValueError):
Erik Trauschke77f5a252015-10-14 08:06:38 -0700612 crl[0].extensions
Erik Trauschkedc570402015-09-24 20:24:28 -0700613
Erik Trauschked4e7d432015-10-15 14:45:38 -0700614 def test_invalid_cert_issuer_ext(self, backend):
Erik Trauschkedc570402015-09-24 20:24:28 -0700615 crl = _load_cert(
Erik Trauschked4e7d432015-10-15 14:45:38 -0700616 os.path.join(
617 "x509", "custom", "crl_inval_cert_issuer_entry_ext.pem"
618 ),
Erik Trauschkedc570402015-09-24 20:24:28 -0700619 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800620 backend,
Erik Trauschkedc570402015-09-24 20:24:28 -0700621 )
622
Erik Trauschked4e7d432015-10-15 14:45:38 -0700623 with pytest.raises(ValueError):
624 crl[0].extensions
Erik Trauschkedc570402015-09-24 20:24:28 -0700625
Alex Gaynor9f71bf72015-12-24 11:04:21 -0500626 def test_indexing(self, backend):
627 crl = _load_cert(
Alex Gaynora3fa8d62015-12-24 11:34:24 -0500628 os.path.join("x509", "custom", "crl_all_reasons.pem"),
Alex Gaynor9f71bf72015-12-24 11:04:21 -0500629 x509.load_pem_x509_crl,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800630 backend,
Alex Gaynor9f71bf72015-12-24 11:04:21 -0500631 )
632
633 with pytest.raises(IndexError):
Alex Gaynora3fa8d62015-12-24 11:34:24 -0500634 crl[-13]
Alex Gaynor9f71bf72015-12-24 11:04:21 -0500635 with pytest.raises(IndexError):
Alex Gaynora3fa8d62015-12-24 11:34:24 -0500636 crl[12]
637
638 assert crl[-1].serial_number == crl[11].serial_number
639 assert len(crl[2:4]) == 2
640 assert crl[2:4][0].serial_number == crl[2].serial_number
641 assert crl[2:4][1].serial_number == crl[3].serial_number
Alex Gaynor9f71bf72015-12-24 11:04:21 -0500642
Paul Kehrer18d49d02018-09-04 15:29:34 -0500643 def test_get_revoked_certificate_doesnt_reorder(self, backend):
644 private_key = RSA_KEY_2048.private_key(backend)
645 last_update = datetime.datetime(2002, 1, 1, 12, 1)
646 next_update = datetime.datetime(2030, 1, 1, 12, 1)
Lucia Lic6ba99d2021-11-08 22:06:11 +0800647 builder = (
648 x509.CertificateRevocationListBuilder()
649 .issuer_name(
650 x509.Name(
651 [
652 x509.NameAttribute(
653 NameOID.COMMON_NAME, u"cryptography.io CA"
654 )
655 ]
656 )
657 )
658 .last_update(last_update)
659 .next_update(next_update)
Paul Kehrer18d49d02018-09-04 15:29:34 -0500660 )
661 for i in [2, 500, 3, 49, 7, 1]:
Lucia Lic6ba99d2021-11-08 22:06:11 +0800662 revoked_cert = (
663 x509.RevokedCertificateBuilder()
664 .serial_number(i)
665 .revocation_date(datetime.datetime(2012, 1, 1, 1, 1))
666 .build(backend)
667 )
Paul Kehrer18d49d02018-09-04 15:29:34 -0500668 builder = builder.add_revoked_certificate(revoked_cert)
669 crl = builder.sign(private_key, hashes.SHA256(), backend)
670 assert crl[0].serial_number == 2
671 assert crl[2].serial_number == 3
672 # make sure get_revoked_certificate_by_serial_number doesn't affect
673 # ordering after being invoked
674 crl.get_revoked_certificate_by_serial_number(500)
675 assert crl[0].serial_number == 2
676 assert crl[2].serial_number == 3
677
Erik Trauschkedc570402015-09-24 20:24:28 -0700678
Paul Kehrer016e08a2014-11-26 09:41:18 -1000679@pytest.mark.requires_backend_interface(interface=RSABackend)
680@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -0600681class TestRSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000682 def test_load_pem_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000683 cert = _load_cert(
684 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -1000685 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800686 backend,
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000687 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600688 assert isinstance(cert, x509.Certificate)
Chelsea Winfreee295f3a2016-06-02 21:15:54 -0700689 assert cert.serial_number == 11559813051657483483
Paul Kehrere76cd272014-12-14 19:00:51 -0600690 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
691 assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8"
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600692 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
Paul Kehrerc7b29b82016-09-01 09:17:21 +0800693 assert (
694 cert.signature_algorithm_oid == SignatureAlgorithmOID.RSA_WITH_SHA1
695 )
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000696
Lucia Lic6ba99d2021-11-08 22:06:11 +0800697 def test_negative_serial_number(self, backend):
698 cert = _load_cert(
699 os.path.join("x509", "custom", "negative_serial.pem"),
700 x509.load_pem_x509_certificate,
701 backend,
702 )
703 assert cert.serial_number == -18008675309
704
Paul Kehrerf6f238e2016-11-11 10:41:31 -0800705 def test_alternate_rsa_with_sha1_oid(self, backend):
706 cert = _load_cert(
707 os.path.join("x509", "alternate-rsa-sha1-oid.pem"),
708 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800709 backend,
Paul Kehrerf6f238e2016-11-11 10:41:31 -0800710 )
711 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
712 assert (
Lucia Lic6ba99d2021-11-08 22:06:11 +0800713 cert.signature_algorithm_oid
714 == SignatureAlgorithmOID._RSA_WITH_SHA1
Paul Kehrerf6f238e2016-11-11 10:41:31 -0800715 )
716
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000717 def test_load_der_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000718 cert = _load_cert(
719 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000720 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800721 backend,
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000722 )
Paul Kehrere76cd272014-12-14 19:00:51 -0600723 assert isinstance(cert, x509.Certificate)
Chelsea Winfreee295f3a2016-06-02 21:15:54 -0700724 assert cert.serial_number == 2
Paul Kehrere76cd272014-12-14 19:00:51 -0600725 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
726 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer8802a5b2015-02-13 12:06:57 -0600727 assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
Paul Kehrerf1ef3512014-11-26 17:36:05 -1000728
Paul Kehrerd91e7c12015-10-01 16:50:42 -0500729 def test_signature(self, backend):
730 cert = _load_cert(
731 os.path.join("x509", "custom", "post2000utctime.pem"),
732 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800733 backend,
Paul Kehrerd91e7c12015-10-01 16:50:42 -0500734 )
735 assert cert.signature == binascii.unhexlify(
736 b"8e0f72fcbebe4755abcaf76c8ce0bae17cde4db16291638e1b1ce04a93cdb4c"
737 b"44a3486070986c5a880c14fdf8497e7d289b2630ccb21d24a3d1aa1b2d87482"
738 b"07f3a1e16ccdf8daa8a7ea1a33d49774f513edf09270bd8e665b6300a10f003"
739 b"66a59076905eb63cf10a81a0ca78a6ef3127f6cb2f6fb7f947fce22a30d8004"
740 b"8c243ba2c1a54c425fe12310e8a737638f4920354d4cce25cbd9dea25e6a2fe"
741 b"0d8579a5c8d929b9275be221975479f3f75075bcacf09526523b5fd67f7683f"
742 b"3cda420fabb1e9e6fc26bc0649cf61bb051d6932fac37066bb16f55903dfe78"
743 b"53dc5e505e2a10fbba4f9e93a0d3b53b7fa34b05d7ba6eef869bfc34b8e514f"
744 b"d5419f75"
745 )
746 assert len(cert.signature) == cert.public_key().key_size // 8
747
Paul Kehrerd2898052015-11-03 22:00:41 +0900748 def test_tbs_certificate_bytes(self, backend):
Paul Kehrerd91e7c12015-10-01 16:50:42 -0500749 cert = _load_cert(
750 os.path.join("x509", "custom", "post2000utctime.pem"),
751 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800752 backend,
Paul Kehrerd91e7c12015-10-01 16:50:42 -0500753 )
Paul Kehrerd2898052015-11-03 22:00:41 +0900754 assert cert.tbs_certificate_bytes == binascii.unhexlify(
Paul Kehrerd91e7c12015-10-01 16:50:42 -0500755 b"308202d8a003020102020900a06cb4b955f7f4db300d06092a864886f70d010"
756 b"10505003058310b3009060355040613024155311330110603550408130a536f"
757 b"6d652d53746174653121301f060355040a1318496e7465726e6574205769646"
758 b"769747320507479204c74643111300f0603550403130848656c6c6f20434130"
759 b"1e170d3134313132363231343132305a170d3134313232363231343132305a3"
760 b"058310b3009060355040613024155311330110603550408130a536f6d652d53"
761 b"746174653121301f060355040a1318496e7465726e657420576964676974732"
762 b"0507479204c74643111300f0603550403130848656c6c6f2043413082012230"
763 b"0d06092a864886f70d01010105000382010f003082010a0282010100b03af70"
764 b"2059e27f1e2284b56bbb26c039153bf81f295b73a49132990645ede4d2da0a9"
765 b"13c42e7d38d3589a00d3940d194f6e6d877c2ef812da22a275e83d8be786467"
766 b"48b4e7f23d10e873fd72f57a13dec732fc56ab138b1bb308399bb412cd73921"
767 b"4ef714e1976e09603405e2556299a05522510ac4574db5e9cb2cf5f99e8f48c"
768 b"1696ab3ea2d6d2ddab7d4e1b317188b76a572977f6ece0a4ad396f0150e7d8b"
769 b"1a9986c0cb90527ec26ca56e2914c270d2a198b632fa8a2fda55079d3d39864"
770 b"b6fb96ddbe331cacb3cb8783a8494ccccd886a3525078847ca01ca5f803e892"
771 b"14403e8a4b5499539c0b86f7a0daa45b204a8e079d8a5b03db7ba1ba3d7011a"
772 b"70203010001a381bc3081b9301d0603551d0e04160414d8e89dc777e4472656"
773 b"f1864695a9f66b7b0400ae3081890603551d23048181307f8014d8e89dc777e"
774 b"4472656f1864695a9f66b7b0400aea15ca45a3058310b300906035504061302"
775 b"4155311330110603550408130a536f6d652d53746174653121301f060355040"
776 b"a1318496e7465726e6574205769646769747320507479204c74643111300f06"
777 b"03550403130848656c6c6f204341820900a06cb4b955f7f4db300c0603551d1"
778 b"3040530030101ff"
779 )
Alex Gaynorb916fa92017-12-03 18:16:22 -0600780 cert.public_key().verify(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800781 cert.signature,
782 cert.tbs_certificate_bytes,
783 padding.PKCS1v15(),
784 cert.signature_hash_algorithm,
Paul Kehrerd91e7c12015-10-01 16:50:42 -0500785 )
Paul Kehrerd91e7c12015-10-01 16:50:42 -0500786
Paul Kehrer719d5362015-01-01 20:03:52 -0600787 def test_issuer(self, backend):
788 cert = _load_cert(
789 os.path.join(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800790 "x509",
791 "PKITS_data",
792 "certs",
793 "Validpre2000UTCnotBeforeDateTest3EE.crt",
Paul Kehrer719d5362015-01-01 20:03:52 -0600794 ),
795 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800796 backend,
Paul Kehrer719d5362015-01-01 20:03:52 -0600797 )
798 issuer = cert.issuer
799 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600800 assert list(issuer) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800801 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrer719d5362015-01-01 20:03:52 -0600802 x509.NameAttribute(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800803 NameOID.ORGANIZATION_NAME, u"Test Certificates 2011"
Paul Kehrer719d5362015-01-01 20:03:52 -0600804 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800805 x509.NameAttribute(NameOID.COMMON_NAME, u"Good CA"),
Paul Kehrer719d5362015-01-01 20:03:52 -0600806 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500807 assert issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800808 x509.NameAttribute(NameOID.COMMON_NAME, u"Good CA")
Paul Kehrer719d5362015-01-01 20:03:52 -0600809 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600810
811 def test_all_issuer_name_types(self, backend):
812 cert = _load_cert(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800813 os.path.join("x509", "custom", "all_supported_names.pem"),
Paul Kehrer719d5362015-01-01 20:03:52 -0600814 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800815 backend,
Paul Kehrer719d5362015-01-01 20:03:52 -0600816 )
817 issuer = cert.issuer
818
819 assert isinstance(issuer, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600820 assert list(issuer) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800821 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
822 x509.NameAttribute(NameOID.COUNTRY_NAME, u"CA"),
823 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Texas"),
824 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Illinois"),
825 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Chicago"),
826 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Austin"),
827 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Zero, LLC"),
828 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"One, LLC"),
829 x509.NameAttribute(NameOID.COMMON_NAME, u"common name 0"),
830 x509.NameAttribute(NameOID.COMMON_NAME, u"common name 1"),
831 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u"OU 0"),
832 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u"OU 1"),
833 x509.NameAttribute(NameOID.DN_QUALIFIER, u"dnQualifier0"),
834 x509.NameAttribute(NameOID.DN_QUALIFIER, u"dnQualifier1"),
835 x509.NameAttribute(NameOID.SERIAL_NUMBER, u"123"),
836 x509.NameAttribute(NameOID.SERIAL_NUMBER, u"456"),
837 x509.NameAttribute(NameOID.TITLE, u"Title 0"),
838 x509.NameAttribute(NameOID.TITLE, u"Title 1"),
839 x509.NameAttribute(NameOID.SURNAME, u"Surname 0"),
840 x509.NameAttribute(NameOID.SURNAME, u"Surname 1"),
841 x509.NameAttribute(NameOID.GIVEN_NAME, u"Given Name 0"),
842 x509.NameAttribute(NameOID.GIVEN_NAME, u"Given Name 1"),
843 x509.NameAttribute(NameOID.PSEUDONYM, u"Incognito 0"),
844 x509.NameAttribute(NameOID.PSEUDONYM, u"Incognito 1"),
845 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u"Last Gen"),
846 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u"Next Gen"),
847 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u"dc0"),
848 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u"dc1"),
849 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u"test0@test.local"),
850 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u"test1@test.local"),
Paul Kehrer719d5362015-01-01 20:03:52 -0600851 ]
852
Paul Kehrer719d5362015-01-01 20:03:52 -0600853 def test_subject(self, backend):
854 cert = _load_cert(
855 os.path.join(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800856 "x509",
857 "PKITS_data",
858 "certs",
859 "Validpre2000UTCnotBeforeDateTest3EE.crt",
Paul Kehrer719d5362015-01-01 20:03:52 -0600860 ),
861 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800862 backend,
Paul Kehrer719d5362015-01-01 20:03:52 -0600863 )
864 subject = cert.subject
865 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600866 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800867 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Paul Kehrer719d5362015-01-01 20:03:52 -0600868 x509.NameAttribute(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800869 NameOID.ORGANIZATION_NAME, u"Test Certificates 2011"
Paul Kehrer719d5362015-01-01 20:03:52 -0600870 ),
871 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500872 NameOID.COMMON_NAME,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800873 u"Valid pre2000 UTC notBefore Date EE Certificate Test3",
874 ),
Paul Kehrer719d5362015-01-01 20:03:52 -0600875 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500876 assert subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Paul Kehrer719d5362015-01-01 20:03:52 -0600877 x509.NameAttribute(
Paul Kehrereba19e62015-08-10 18:44:24 -0500878 NameOID.COMMON_NAME,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800879 u"Valid pre2000 UTC notBefore Date EE Certificate Test3",
Paul Kehrer719d5362015-01-01 20:03:52 -0600880 )
881 ]
Paul Kehrer719d5362015-01-01 20:03:52 -0600882
883 def test_unicode_name(self, backend):
884 cert = _load_cert(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800885 os.path.join("x509", "custom", "utf8_common_name.pem"),
Paul Kehrer719d5362015-01-01 20:03:52 -0600886 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800887 backend,
Paul Kehrer719d5362015-01-01 20:03:52 -0600888 )
Paul Kehrereba19e62015-08-10 18:44:24 -0500889 assert cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800890 x509.NameAttribute(NameOID.COMMON_NAME, u"We heart UTF8!\u2122")
Paul Kehrer719d5362015-01-01 20:03:52 -0600891 ]
Paul Kehrereba19e62015-08-10 18:44:24 -0500892 assert cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800893 x509.NameAttribute(NameOID.COMMON_NAME, u"We heart UTF8!\u2122")
Paul Kehrer719d5362015-01-01 20:03:52 -0600894 ]
895
Paul Kehrered321052017-10-11 08:11:44 +0800896 def test_non_ascii_dns_name(self, backend):
897 cert = _load_cert(
898 os.path.join("x509", "utf8-dnsname.pem"),
899 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800900 backend,
Paul Kehrered321052017-10-11 08:11:44 +0800901 )
902 san = cert.extensions.get_extension_for_class(
903 x509.SubjectAlternativeName
904 ).value
905
906 names = san.get_values_for_type(x509.DNSName)
907
908 assert names == [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800909 u"partner.biztositas.hu",
910 u"biztositas.hu",
911 u"*.biztositas.hu",
912 u"biztos\xedt\xe1s.hu",
913 u"*.biztos\xedt\xe1s.hu",
914 u"xn--biztosts-fza2j.hu",
915 u"*.xn--biztosts-fza2j.hu",
Paul Kehrered321052017-10-11 08:11:44 +0800916 ]
917
Paul Kehrer719d5362015-01-01 20:03:52 -0600918 def test_all_subject_name_types(self, backend):
919 cert = _load_cert(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800920 os.path.join("x509", "custom", "all_supported_names.pem"),
Paul Kehrer719d5362015-01-01 20:03:52 -0600921 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800922 backend,
Paul Kehrer719d5362015-01-01 20:03:52 -0600923 )
924 subject = cert.subject
925 assert isinstance(subject, x509.Name)
Paul Kehrer8b21a4a2015-02-14 07:56:36 -0600926 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +0800927 x509.NameAttribute(NameOID.COUNTRY_NAME, u"AU"),
928 x509.NameAttribute(NameOID.COUNTRY_NAME, u"DE"),
929 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"California"),
930 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"New York"),
931 x509.NameAttribute(NameOID.LOCALITY_NAME, u"San Francisco"),
932 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Ithaca"),
933 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Org Zero, LLC"),
934 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"Org One, LLC"),
935 x509.NameAttribute(NameOID.COMMON_NAME, u"CN 0"),
936 x509.NameAttribute(NameOID.COMMON_NAME, u"CN 1"),
Paul Kehrer719d5362015-01-01 20:03:52 -0600937 x509.NameAttribute(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800938 NameOID.ORGANIZATIONAL_UNIT_NAME, u"Engineering 0"
Paul Kehrer719d5362015-01-01 20:03:52 -0600939 ),
940 x509.NameAttribute(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800941 NameOID.ORGANIZATIONAL_UNIT_NAME, u"Engineering 1"
Paul Kehrer719d5362015-01-01 20:03:52 -0600942 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +0800943 x509.NameAttribute(NameOID.DN_QUALIFIER, u"qualified0"),
944 x509.NameAttribute(NameOID.DN_QUALIFIER, u"qualified1"),
945 x509.NameAttribute(NameOID.SERIAL_NUMBER, u"789"),
946 x509.NameAttribute(NameOID.SERIAL_NUMBER, u"012"),
947 x509.NameAttribute(NameOID.TITLE, u"Title IX"),
948 x509.NameAttribute(NameOID.TITLE, u"Title X"),
949 x509.NameAttribute(NameOID.SURNAME, u"Last 0"),
950 x509.NameAttribute(NameOID.SURNAME, u"Last 1"),
951 x509.NameAttribute(NameOID.GIVEN_NAME, u"First 0"),
952 x509.NameAttribute(NameOID.GIVEN_NAME, u"First 1"),
953 x509.NameAttribute(NameOID.PSEUDONYM, u"Guy Incognito 0"),
954 x509.NameAttribute(NameOID.PSEUDONYM, u"Guy Incognito 1"),
955 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u"32X"),
956 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u"Dreamcast"),
957 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u"dc2"),
958 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u"dc3"),
959 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u"test2@test.local"),
960 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u"test3@test.local"),
Paul Kehrer719d5362015-01-01 20:03:52 -0600961 ]
962
Paul Kehrer016e08a2014-11-26 09:41:18 -1000963 def test_load_good_ca_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000964 cert = _load_cert(
965 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
Paul Kehrer41120322014-12-02 18:31:14 -1000966 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800967 backend,
Paul Kehrera693cfd2014-11-27 07:47:58 -1000968 )
Paul Kehrer016e08a2014-11-26 09:41:18 -1000969
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600970 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
971 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Chelsea Winfreee295f3a2016-06-02 21:15:54 -0700972 assert cert.serial_number == 2
Paul Kehrer016e08a2014-11-26 09:41:18 -1000973 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -0800974 assert isinstance(public_key, rsa.RSAPublicKey)
Paul Kehrere76cd272014-12-14 19:00:51 -0600975 assert cert.version is x509.Version.v3
Paul Kehrer0307c372014-11-27 09:49:31 -1000976 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
Paul Kehrer4e1db792014-11-27 10:50:55 -1000977 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
Paul Kehrer016e08a2014-11-26 09:41:18 -1000978
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000979 def test_utc_pre_2000_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000980 cert = _load_cert(
981 os.path.join(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800982 "x509",
983 "PKITS_data",
984 "certs",
985 "Validpre2000UTCnotBeforeDateTest3EE.crt",
Paul Kehrera693cfd2014-11-27 07:47:58 -1000986 ),
Paul Kehrer41120322014-12-02 18:31:14 -1000987 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +0800988 backend,
Paul Kehrer016e08a2014-11-26 09:41:18 -1000989 )
990
Paul Kehrerd9fc7252014-12-11 12:25:00 -0600991 assert cert.not_valid_before == datetime.datetime(1950, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -1000992
993 def test_pre_2000_utc_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -1000994 cert = _load_cert(
995 os.path.join(
Lucia Lic6ba99d2021-11-08 22:06:11 +0800996 "x509",
997 "PKITS_data",
998 "certs",
999 "Invalidpre2000UTCEEnotAfterDateTest7EE.crt",
Paul Kehrera693cfd2014-11-27 07:47:58 -10001000 ),
Paul Kehrer41120322014-12-02 18:31:14 -10001001 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001002 backend,
Paul Kehrer1eb5b862014-11-26 11:44:03 -10001003 )
1004
Paul Kehrerd9fc7252014-12-11 12:25:00 -06001005 assert cert.not_valid_after == datetime.datetime(1999, 1, 1, 12, 1)
Paul Kehrer1eb5b862014-11-26 11:44:03 -10001006
1007 def test_post_2000_utc_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -10001008 cert = _load_cert(
Paul Kehrer1eb5b862014-11-26 11:44:03 -10001009 os.path.join("x509", "custom", "post2000utctime.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -10001010 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001011 backend,
Paul Kehrer1eb5b862014-11-26 11:44:03 -10001012 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -06001013 assert cert.not_valid_before == datetime.datetime(
1014 2014, 11, 26, 21, 41, 20
1015 )
1016 assert cert.not_valid_after == datetime.datetime(
1017 2014, 12, 26, 21, 41, 20
1018 )
Paul Kehrer016e08a2014-11-26 09:41:18 -10001019
1020 def test_generalized_time_not_before_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -10001021 cert = _load_cert(
1022 os.path.join(
Lucia Lic6ba99d2021-11-08 22:06:11 +08001023 "x509",
1024 "PKITS_data",
1025 "certs",
1026 "ValidGeneralizedTimenotBeforeDateTest4EE.crt",
Paul Kehrera693cfd2014-11-27 07:47:58 -10001027 ),
Paul Kehrer41120322014-12-02 18:31:14 -10001028 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001029 backend,
Paul Kehrer016e08a2014-11-26 09:41:18 -10001030 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -06001031 assert cert.not_valid_before == datetime.datetime(2002, 1, 1, 12, 1)
1032 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Paul Kehrere76cd272014-12-14 19:00:51 -06001033 assert cert.version is x509.Version.v3
Paul Kehrer016e08a2014-11-26 09:41:18 -10001034
1035 def test_generalized_time_not_after_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -10001036 cert = _load_cert(
1037 os.path.join(
Lucia Lic6ba99d2021-11-08 22:06:11 +08001038 "x509",
1039 "PKITS_data",
1040 "certs",
1041 "ValidGeneralizedTimenotAfterDateTest8EE.crt",
Paul Kehrera693cfd2014-11-27 07:47:58 -10001042 ),
Paul Kehrer41120322014-12-02 18:31:14 -10001043 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001044 backend,
Paul Kehrer016e08a2014-11-26 09:41:18 -10001045 )
Paul Kehrerd9fc7252014-12-11 12:25:00 -06001046 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
1047 assert cert.not_valid_after == datetime.datetime(2050, 1, 1, 12, 1)
Paul Kehrere76cd272014-12-14 19:00:51 -06001048 assert cert.version is x509.Version.v3
Paul Kehrera9d78c12014-11-26 10:59:03 -10001049
1050 def test_invalid_version_cert(self, backend):
Paul Kehrerd5cccf72014-12-15 17:20:33 -06001051 with pytest.raises(x509.InvalidVersion) as exc:
Lucia Lic6ba99d2021-11-08 22:06:11 +08001052 _load_cert(
1053 os.path.join("x509", "custom", "invalid_version.pem"),
1054 x509.load_pem_x509_certificate,
1055 backend,
1056 )
Paul Kehrer30c5ccd2014-11-26 11:10:28 -10001057
Paul Kehrerd5cccf72014-12-15 17:20:33 -06001058 assert exc.value.parsed_version == 7
1059
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -05001060 def test_eq(self, backend):
1061 cert = _load_cert(
1062 os.path.join("x509", "custom", "post2000utctime.pem"),
1063 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001064 backend,
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -05001065 )
1066 cert2 = _load_cert(
1067 os.path.join("x509", "custom", "post2000utctime.pem"),
1068 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001069 backend,
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -05001070 )
1071 assert cert == cert2
1072
1073 def test_ne(self, backend):
1074 cert = _load_cert(
1075 os.path.join("x509", "custom", "post2000utctime.pem"),
1076 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001077 backend,
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -05001078 )
1079 cert2 = _load_cert(
1080 os.path.join(
Lucia Lic6ba99d2021-11-08 22:06:11 +08001081 "x509",
1082 "PKITS_data",
1083 "certs",
1084 "ValidGeneralizedTimenotAfterDateTest8EE.crt",
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -05001085 ),
1086 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001087 backend,
Paul Kehrer8bbdc6f2015-04-30 16:47:16 -05001088 )
1089 assert cert != cert2
1090 assert cert != object()
1091
Alex Gaynor969f3a52015-07-06 18:52:41 -04001092 def test_hash(self, backend):
1093 cert1 = _load_cert(
1094 os.path.join("x509", "custom", "post2000utctime.pem"),
1095 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001096 backend,
Alex Gaynor969f3a52015-07-06 18:52:41 -04001097 )
1098 cert2 = _load_cert(
1099 os.path.join("x509", "custom", "post2000utctime.pem"),
1100 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001101 backend,
Alex Gaynor969f3a52015-07-06 18:52:41 -04001102 )
1103 cert3 = _load_cert(
1104 os.path.join(
Lucia Lic6ba99d2021-11-08 22:06:11 +08001105 "x509",
1106 "PKITS_data",
1107 "certs",
1108 "ValidGeneralizedTimenotAfterDateTest8EE.crt",
Alex Gaynor969f3a52015-07-06 18:52:41 -04001109 ),
1110 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001111 backend,
Alex Gaynor969f3a52015-07-06 18:52:41 -04001112 )
1113
1114 assert hash(cert1) == hash(cert2)
1115 assert hash(cert1) != hash(cert3)
1116
Paul Kehrer30c5ccd2014-11-26 11:10:28 -10001117 def test_version_1_cert(self, backend):
Paul Kehrera693cfd2014-11-27 07:47:58 -10001118 cert = _load_cert(
Paul Kehrer30c5ccd2014-11-26 11:10:28 -10001119 os.path.join("x509", "v1_cert.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -10001120 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001121 backend,
Paul Kehrer30c5ccd2014-11-26 11:10:28 -10001122 )
Paul Kehrere76cd272014-12-14 19:00:51 -06001123 assert cert.version is x509.Version.v1
Paul Kehrer7638c312014-11-26 11:13:31 -10001124
1125 def test_invalid_pem(self, backend):
1126 with pytest.raises(ValueError):
1127 x509.load_pem_x509_certificate(b"notacert", backend)
1128
1129 def test_invalid_der(self, backend):
1130 with pytest.raises(ValueError):
1131 x509.load_der_x509_certificate(b"notacert", backend)
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001132
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001133 def test_unsupported_signature_hash_algorithm_cert(self, backend):
1134 cert = _load_cert(
1135 os.path.join("x509", "verisign_md2_root.pem"),
1136 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001137 backend,
Paul Kehrer8802a5b2015-02-13 12:06:57 -06001138 )
1139 with pytest.raises(UnsupportedAlgorithm):
1140 cert.signature_hash_algorithm
1141
Andre Carona8aded62015-05-19 20:11:57 -04001142 def test_public_bytes_pem(self, backend):
1143 # Load an existing certificate.
1144 cert = _load_cert(
1145 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
1146 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001147 backend,
Andre Carona8aded62015-05-19 20:11:57 -04001148 )
1149
1150 # Encode it to PEM and load it back.
Lucia Lic6ba99d2021-11-08 22:06:11 +08001151 cert = x509.load_pem_x509_certificate(
1152 cert.public_bytes(
1153 encoding=serialization.Encoding.PEM,
1154 ),
1155 backend,
1156 )
Andre Carona8aded62015-05-19 20:11:57 -04001157
1158 # We should recover what we had to start with.
1159 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
1160 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Chelsea Winfreee295f3a2016-06-02 21:15:54 -07001161 assert cert.serial_number == 2
Andre Carona8aded62015-05-19 20:11:57 -04001162 public_key = cert.public_key()
1163 assert isinstance(public_key, rsa.RSAPublicKey)
1164 assert cert.version is x509.Version.v3
1165 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
1166 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
1167
1168 def test_public_bytes_der(self, backend):
1169 # Load an existing certificate.
1170 cert = _load_cert(
1171 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
1172 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001173 backend,
Andre Carona8aded62015-05-19 20:11:57 -04001174 )
1175
1176 # Encode it to DER and load it back.
Lucia Lic6ba99d2021-11-08 22:06:11 +08001177 cert = x509.load_der_x509_certificate(
1178 cert.public_bytes(
1179 encoding=serialization.Encoding.DER,
1180 ),
1181 backend,
1182 )
Andre Carona8aded62015-05-19 20:11:57 -04001183
1184 # We should recover what we had to start with.
1185 assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
1186 assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
Chelsea Winfreee295f3a2016-06-02 21:15:54 -07001187 assert cert.serial_number == 2
Andre Carona8aded62015-05-19 20:11:57 -04001188 public_key = cert.public_key()
1189 assert isinstance(public_key, rsa.RSAPublicKey)
1190 assert cert.version is x509.Version.v3
1191 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
1192 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
1193
1194 def test_public_bytes_invalid_encoding(self, backend):
1195 cert = _load_cert(
1196 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
1197 x509.load_der_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001198 backend,
Andre Carona8aded62015-05-19 20:11:57 -04001199 )
1200
1201 with pytest.raises(TypeError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08001202 cert.public_bytes("NotAnEncoding")
Andre Carona8aded62015-05-19 20:11:57 -04001203
1204 @pytest.mark.parametrize(
1205 ("cert_path", "loader_func", "encoding"),
1206 [
1207 (
1208 os.path.join("x509", "v1_cert.pem"),
1209 x509.load_pem_x509_certificate,
1210 serialization.Encoding.PEM,
1211 ),
1212 (
1213 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
1214 x509.load_der_x509_certificate,
1215 serialization.Encoding.DER,
1216 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08001217 ],
Andre Carona8aded62015-05-19 20:11:57 -04001218 )
Lucia Lic6ba99d2021-11-08 22:06:11 +08001219 def test_public_bytes_match(
1220 self, cert_path, loader_func, encoding, backend
1221 ):
Andre Carona8aded62015-05-19 20:11:57 -04001222 cert_bytes = load_vectors_from_file(
1223 cert_path, lambda pemfile: pemfile.read(), mode="rb"
1224 )
1225 cert = loader_func(cert_bytes, backend)
1226 serialized = cert.public_bytes(encoding)
1227 assert serialized == cert_bytes
1228
Major Haydenf315af22015-06-17 14:02:26 -05001229 def test_certificate_repr(self, backend):
1230 cert = _load_cert(
Lucia Lic6ba99d2021-11-08 22:06:11 +08001231 os.path.join("x509", "cryptography.io.pem"),
Major Haydenf315af22015-06-17 14:02:26 -05001232 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001233 backend,
Major Haydenf315af22015-06-17 14:02:26 -05001234 )
Marti Raudseppc3d38b52018-12-08 03:26:07 +02001235 assert repr(cert) == (
Marti Raudsepp82415572018-12-18 01:26:40 +02001236 "<Certificate(subject=<Name(OU=GT48742965,OU=See www.rapidssl.com"
1237 "/resources/cps (c)14,OU=Domain Control Validated - RapidSSL(R),"
Marti Raudseppc3d38b52018-12-08 03:26:07 +02001238 "CN=www.cryptography.io)>, ...)>"
1239 )
Major Haydenf315af22015-06-17 14:02:26 -05001240
Paul Kehrer5d669662017-09-11 09:16:34 +08001241 def test_parse_tls_feature_extension(self, backend):
1242 cert = _load_cert(
1243 os.path.join("x509", "tls-feature-ocsp-staple.pem"),
1244 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001245 backend,
Paul Kehrer5d669662017-09-11 09:16:34 +08001246 )
1247 ext = cert.extensions.get_extension_for_class(x509.TLSFeature)
1248 assert ext.critical is False
1249 assert ext.value == x509.TLSFeature(
1250 [x509.TLSFeatureType.status_request]
1251 )
1252
Andre Carona8aded62015-05-19 20:11:57 -04001253
1254@pytest.mark.requires_backend_interface(interface=RSABackend)
1255@pytest.mark.requires_backend_interface(interface=X509Backend)
1256class TestRSACertificateRequest(object):
Paul Kehrer1effb6e2015-03-30 15:05:59 -05001257 @pytest.mark.parametrize(
1258 ("path", "loader_func"),
1259 [
1260 [
1261 os.path.join("x509", "requests", "rsa_sha1.pem"),
Lucia Lic6ba99d2021-11-08 22:06:11 +08001262 x509.load_pem_x509_csr,
Paul Kehrer1effb6e2015-03-30 15:05:59 -05001263 ],
1264 [
1265 os.path.join("x509", "requests", "rsa_sha1.der"),
Lucia Lic6ba99d2021-11-08 22:06:11 +08001266 x509.load_der_x509_csr,
Paul Kehrer1effb6e2015-03-30 15:05:59 -05001267 ],
Lucia Lic6ba99d2021-11-08 22:06:11 +08001268 ],
Paul Kehrer1effb6e2015-03-30 15:05:59 -05001269 )
1270 def test_load_rsa_certificate_request(self, path, loader_func, backend):
1271 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001272 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
Paul Kehrerc7b29b82016-09-01 09:17:21 +08001273 assert (
Lucia Lic6ba99d2021-11-08 22:06:11 +08001274 request.signature_algorithm_oid
1275 == SignatureAlgorithmOID.RSA_WITH_SHA1
Paul Kehrerc7b29b82016-09-01 09:17:21 +08001276 )
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001277 public_key = request.public_key()
1278 assert isinstance(public_key, rsa.RSAPublicKey)
1279 subject = request.subject
1280 assert isinstance(subject, x509.Name)
1281 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +08001282 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
1283 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Texas"),
1284 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Austin"),
1285 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
1286 x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io"),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001287 ]
Andre Caron6e721a92015-05-17 15:08:48 -04001288 extensions = request.extensions
1289 assert isinstance(extensions, x509.Extensions)
1290 assert list(extensions) == []
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001291
Lucia Lic6ba99d2021-11-08 22:06:11 +08001292 def test_get_attribute_for_oid_challenge(self, backend):
1293 request = _load_cert(
1294 os.path.join("x509", "requests", "challenge.pem"),
1295 x509.load_pem_x509_csr,
1296 backend,
1297 )
1298 assert (
1299 request.get_attribute_for_oid(
1300 x509.oid.AttributeOID.CHALLENGE_PASSWORD
1301 )
1302 == b"challenge me!"
1303 )
1304
1305 def test_get_attribute_for_oid_multiple(self, backend):
1306 request = _load_cert(
1307 os.path.join("x509", "requests", "challenge-unstructured.pem"),
1308 x509.load_pem_x509_csr,
1309 backend,
1310 )
1311 assert (
1312 request.get_attribute_for_oid(
1313 x509.oid.AttributeOID.CHALLENGE_PASSWORD
1314 )
1315 == b"beauty"
1316 )
1317 assert (
1318 request.get_attribute_for_oid(
1319 x509.oid.AttributeOID.UNSTRUCTURED_NAME
1320 )
1321 == b"an unstructured field"
1322 )
1323
1324 def test_invalid_attribute_for_oid(self, backend):
1325 """
1326 This test deliberately triggers a ValueError because to parse
1327 CSR attributes we need to do a C cast. If we're wrong about the
1328 type that would be Very Bad so this test confirms we properly explode
1329 in the presence of the wrong types.
1330 """
1331 request = _load_cert(
1332 os.path.join("x509", "requests", "challenge-invalid.der"),
1333 x509.load_der_x509_csr,
1334 backend,
1335 )
1336 with pytest.raises(ValueError):
1337 request.get_attribute_for_oid(
1338 x509.oid.AttributeOID.CHALLENGE_PASSWORD
1339 )
1340
1341 def test_no_challenge_password(self, backend):
1342 request = _load_cert(
1343 os.path.join("x509", "requests", "rsa_sha256.pem"),
1344 x509.load_pem_x509_csr,
1345 backend,
1346 )
1347 with pytest.raises(x509.AttributeNotFound) as exc:
1348 request.get_attribute_for_oid(
1349 x509.oid.AttributeOID.CHALLENGE_PASSWORD
1350 )
1351 assert exc.value.oid == x509.oid.AttributeOID.CHALLENGE_PASSWORD
1352
Paul Kehrer1effb6e2015-03-30 15:05:59 -05001353 @pytest.mark.parametrize(
Lucia Lic6ba99d2021-11-08 22:06:11 +08001354 "loader_func", [x509.load_pem_x509_csr, x509.load_der_x509_csr]
Paul Kehrer1effb6e2015-03-30 15:05:59 -05001355 )
1356 def test_invalid_certificate_request(self, loader_func, backend):
Paul Kehrerb759e292015-03-17 07:34:41 -05001357 with pytest.raises(ValueError):
Paul Kehrer1effb6e2015-03-30 15:05:59 -05001358 loader_func(b"notacsr", backend)
Paul Kehrerb759e292015-03-17 07:34:41 -05001359
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001360 def test_unsupported_signature_hash_algorithm_request(self, backend):
1361 request = _load_cert(
1362 os.path.join("x509", "requests", "rsa_md4.pem"),
Paul Kehrer31e39882015-03-11 11:37:04 -05001363 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001364 backend,
Paul Kehrerdc480ad2015-02-23 12:14:54 -06001365 )
1366 with pytest.raises(UnsupportedAlgorithm):
1367 request.signature_hash_algorithm
1368
Andre Caron6e721a92015-05-17 15:08:48 -04001369 def test_duplicate_extension(self, backend):
1370 request = _load_cert(
Lucia Lic6ba99d2021-11-08 22:06:11 +08001371 os.path.join("x509", "requests", "two_basic_constraints.pem"),
Andre Caron6e721a92015-05-17 15:08:48 -04001372 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001373 backend,
Andre Caron6e721a92015-05-17 15:08:48 -04001374 )
1375 with pytest.raises(x509.DuplicateExtension) as exc:
1376 request.extensions
1377
Paul Kehrerd44e4132015-08-10 19:13:13 -05001378 assert exc.value.oid == ExtensionOID.BASIC_CONSTRAINTS
Andre Caron6e721a92015-05-17 15:08:48 -04001379
1380 def test_unsupported_critical_extension(self, backend):
1381 request = _load_cert(
1382 os.path.join(
1383 "x509", "requests", "unsupported_extension_critical.pem"
1384 ),
1385 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001386 backend,
Andre Caron6e721a92015-05-17 15:08:48 -04001387 )
Alex Gaynord08ddd52017-05-20 09:01:54 -07001388 ext = request.extensions.get_extension_for_oid(
Lucia Lic6ba99d2021-11-08 22:06:11 +08001389 x509.ObjectIdentifier("1.2.3.4")
Alex Gaynord08ddd52017-05-20 09:01:54 -07001390 )
1391 assert ext.value.value == b"value"
Andre Caron6e721a92015-05-17 15:08:48 -04001392
1393 def test_unsupported_extension(self, backend):
1394 request = _load_cert(
Lucia Lic6ba99d2021-11-08 22:06:11 +08001395 os.path.join("x509", "requests", "unsupported_extension.pem"),
Andre Caron6e721a92015-05-17 15:08:48 -04001396 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001397 backend,
Andre Caron6e721a92015-05-17 15:08:48 -04001398 )
1399 extensions = request.extensions
Paul Kehrer58ddc112015-12-30 20:19:00 -06001400 assert len(extensions) == 1
1401 assert extensions[0].oid == x509.ObjectIdentifier("1.2.3.4")
1402 assert extensions[0].value == x509.UnrecognizedExtension(
1403 x509.ObjectIdentifier("1.2.3.4"), b"value"
1404 )
Andre Caron6e721a92015-05-17 15:08:48 -04001405
1406 def test_request_basic_constraints(self, backend):
1407 request = _load_cert(
Lucia Lic6ba99d2021-11-08 22:06:11 +08001408 os.path.join("x509", "requests", "basic_constraints.pem"),
Andre Caron6e721a92015-05-17 15:08:48 -04001409 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001410 backend,
Andre Caron6e721a92015-05-17 15:08:48 -04001411 )
1412 extensions = request.extensions
1413 assert isinstance(extensions, x509.Extensions)
1414 assert list(extensions) == [
1415 x509.Extension(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001416 ExtensionOID.BASIC_CONSTRAINTS,
Andre Caron6e721a92015-05-17 15:08:48 -04001417 True,
Ian Cordasco0112b022015-06-16 17:51:18 -05001418 x509.BasicConstraints(ca=True, path_length=1),
Andre Caron6e721a92015-05-17 15:08:48 -04001419 ),
1420 ]
1421
Alex Gaynor37b82df2015-07-03 10:26:37 -04001422 def test_subject_alt_name(self, backend):
1423 request = _load_cert(
1424 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
1425 x509.load_pem_x509_csr,
1426 backend,
1427 )
1428 ext = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001429 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Alex Gaynor37b82df2015-07-03 10:26:37 -04001430 )
1431 assert list(ext.value) == [
Paul Kehrered321052017-10-11 08:11:44 +08001432 x509.DNSName(u"cryptography.io"),
1433 x509.DNSName(u"sub.cryptography.io"),
Alex Gaynor37b82df2015-07-03 10:26:37 -04001434 ]
1435
Andre Caronf27e4f42015-05-18 17:54:59 -04001436 def test_public_bytes_pem(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -04001437 # Load an existing CSR.
1438 request = _load_cert(
1439 os.path.join("x509", "requests", "rsa_sha1.pem"),
1440 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001441 backend,
Andre Caron476c5df2015-05-18 10:23:28 -04001442 )
1443
1444 # Encode it to PEM and load it back.
Lucia Lic6ba99d2021-11-08 22:06:11 +08001445 request = x509.load_pem_x509_csr(
1446 request.public_bytes(
1447 encoding=serialization.Encoding.PEM,
1448 ),
1449 backend,
1450 )
Andre Caron476c5df2015-05-18 10:23:28 -04001451
1452 # We should recover what we had to start with.
1453 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1454 public_key = request.public_key()
1455 assert isinstance(public_key, rsa.RSAPublicKey)
1456 subject = request.subject
1457 assert isinstance(subject, x509.Name)
1458 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +08001459 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
1460 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Texas"),
1461 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Austin"),
1462 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
1463 x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io"),
Andre Caron476c5df2015-05-18 10:23:28 -04001464 ]
1465
Andre Caronf27e4f42015-05-18 17:54:59 -04001466 def test_public_bytes_der(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -04001467 # Load an existing CSR.
1468 request = _load_cert(
1469 os.path.join("x509", "requests", "rsa_sha1.pem"),
1470 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001471 backend,
Andre Caron476c5df2015-05-18 10:23:28 -04001472 )
1473
1474 # Encode it to DER and load it back.
Lucia Lic6ba99d2021-11-08 22:06:11 +08001475 request = x509.load_der_x509_csr(
1476 request.public_bytes(
1477 encoding=serialization.Encoding.DER,
1478 ),
1479 backend,
1480 )
Andre Caron476c5df2015-05-18 10:23:28 -04001481
1482 # We should recover what we had to start with.
1483 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1484 public_key = request.public_key()
1485 assert isinstance(public_key, rsa.RSAPublicKey)
1486 subject = request.subject
1487 assert isinstance(subject, x509.Name)
1488 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +08001489 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
1490 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Texas"),
1491 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Austin"),
1492 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
1493 x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io"),
Andre Caron476c5df2015-05-18 10:23:28 -04001494 ]
1495
Paul Kehrerab209392015-12-01 14:50:31 -06001496 def test_signature(self, backend):
1497 request = _load_cert(
1498 os.path.join("x509", "requests", "rsa_sha1.pem"),
1499 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001500 backend,
Paul Kehrerab209392015-12-01 14:50:31 -06001501 )
1502 assert request.signature == binascii.unhexlify(
1503 b"8364c86ffbbfe0bfc9a21f831256658ca8989741b80576d36f08a934603a43b1"
1504 b"837246d00167a518abb1de7b51a1e5b7ebea14944800818b1a923c804f120a0d"
1505 b"624f6310ef79e8612755c2b01dcc7f59dfdbce0db3f2630f185f504b8c17af80"
1506 b"cbd364fa5fda68337153930948226cd4638287a0aed6524d3006885c19028a1e"
1507 b"e2f5a91d6e77dbaa0b49996ee0a0c60b55b61bd080a08bb34aa7f3e07e91f37f"
1508 b"6a11645be2d8654c1570dcda145ed7cc92017f7d53225d7f283f3459ec5bda41"
1509 b"cf6dd75d43676c543483385226b7e4fa29c8739f1b0eaf199613593991979862"
1510 b"e36181e8c4c270c354b7f52c128db1b70639823324c7ea24791b7bc3d7005f3b"
1511 )
1512
1513 def test_tbs_certrequest_bytes(self, backend):
1514 request = _load_cert(
1515 os.path.join("x509", "requests", "rsa_sha1.pem"),
1516 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001517 backend,
Paul Kehrerab209392015-12-01 14:50:31 -06001518 )
1519 assert request.tbs_certrequest_bytes == binascii.unhexlify(
1520 b"308201840201003057310b3009060355040613025553310e300c060355040813"
1521 b"055465786173310f300d0603550407130641757374696e310d300b060355040a"
1522 b"130450794341311830160603550403130f63727970746f6772617068792e696f"
1523 b"30820122300d06092a864886f70d01010105000382010f003082010a02820101"
1524 b"00a840a78460cb861066dfa3045a94ba6cf1b7ab9d24c761cffddcc2cb5e3f1d"
1525 b"c3e4be253e7039ef14fe9d6d2304f50d9f2e1584c51530ab75086f357138bff7"
1526 b"b854d067d1d5f384f1f2f2c39cc3b15415e2638554ef8402648ae3ef08336f22"
1527 b"b7ecc6d4331c2b21c3091a7f7a9518180754a646640b60419e4cc6f5c798110a"
1528 b"7f030a639fe87e33b4776dfcd993940ec776ab57a181ad8598857976dc303f9a"
1529 b"573ca619ab3fe596328e92806b828683edc17cc256b41948a2bfa8d047d2158d"
1530 b"3d8e069aa05fa85b3272abb1c4b4422b6366f3b70e642377b145cd6259e5d3e7"
1531 b"db048d51921e50766a37b1b130ee6b11f507d20a834001e8de16a92c14f2e964"
1532 b"a30203010001a000"
1533 )
Alex Gaynorb916fa92017-12-03 18:16:22 -06001534 request.public_key().verify(
Paul Kehrerab209392015-12-01 14:50:31 -06001535 request.signature,
Alex Gaynorb916fa92017-12-03 18:16:22 -06001536 request.tbs_certrequest_bytes,
Paul Kehrerab209392015-12-01 14:50:31 -06001537 padding.PKCS1v15(),
Lucia Lic6ba99d2021-11-08 22:06:11 +08001538 request.signature_hash_algorithm,
Paul Kehrerab209392015-12-01 14:50:31 -06001539 )
Paul Kehrerab209392015-12-01 14:50:31 -06001540
Andre Caronf27e4f42015-05-18 17:54:59 -04001541 def test_public_bytes_invalid_encoding(self, backend):
Andre Caron476c5df2015-05-18 10:23:28 -04001542 request = _load_cert(
1543 os.path.join("x509", "requests", "rsa_sha1.pem"),
1544 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001545 backend,
Andre Caron476c5df2015-05-18 10:23:28 -04001546 )
1547
1548 with pytest.raises(TypeError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08001549 request.public_bytes("NotAnEncoding")
Andre Caron476c5df2015-05-18 10:23:28 -04001550
Joern Heisslerfbda8ce2016-01-18 00:24:44 +01001551 def test_signature_invalid(self, backend):
Joern Heissler1bd77e22016-01-13 22:51:37 +01001552 request = _load_cert(
1553 os.path.join("x509", "requests", "invalid_signature.pem"),
1554 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001555 backend,
Joern Heissler1bd77e22016-01-13 22:51:37 +01001556 )
Joern Heisslerfbda8ce2016-01-18 00:24:44 +01001557 assert not request.is_signature_valid
Joern Heissler1bd77e22016-01-13 22:51:37 +01001558
Joern Heisslerfbda8ce2016-01-18 00:24:44 +01001559 def test_signature_valid(self, backend):
Joern Heissler1bd77e22016-01-13 22:51:37 +01001560 request = _load_cert(
1561 os.path.join("x509", "requests", "rsa_sha256.pem"),
1562 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001563 backend,
Joern Heissler1bd77e22016-01-13 22:51:37 +01001564 )
Joern Heisslerfbda8ce2016-01-18 00:24:44 +01001565 assert request.is_signature_valid
Joern Heissler1bd77e22016-01-13 22:51:37 +01001566
Andre Caronacb18972015-05-18 21:04:15 -04001567 @pytest.mark.parametrize(
1568 ("request_path", "loader_func", "encoding"),
1569 [
1570 (
1571 os.path.join("x509", "requests", "rsa_sha1.pem"),
1572 x509.load_pem_x509_csr,
1573 serialization.Encoding.PEM,
1574 ),
1575 (
1576 os.path.join("x509", "requests", "rsa_sha1.der"),
1577 x509.load_der_x509_csr,
1578 serialization.Encoding.DER,
1579 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08001580 ],
Andre Caronacb18972015-05-18 21:04:15 -04001581 )
Lucia Lic6ba99d2021-11-08 22:06:11 +08001582 def test_public_bytes_match(
1583 self, request_path, loader_func, encoding, backend
1584 ):
Andre Caronacb18972015-05-18 21:04:15 -04001585 request_bytes = load_vectors_from_file(
1586 request_path, lambda pemfile: pemfile.read(), mode="rb"
1587 )
1588 request = loader_func(request_bytes, backend)
1589 serialized = request.public_bytes(encoding)
1590 assert serialized == request_bytes
1591
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001592 def test_eq(self, backend):
1593 request1 = _load_cert(
1594 os.path.join("x509", "requests", "rsa_sha1.pem"),
1595 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001596 backend,
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001597 )
1598 request2 = _load_cert(
1599 os.path.join("x509", "requests", "rsa_sha1.pem"),
1600 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001601 backend,
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001602 )
1603
1604 assert request1 == request2
1605
1606 def test_ne(self, backend):
1607 request1 = _load_cert(
1608 os.path.join("x509", "requests", "rsa_sha1.pem"),
1609 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001610 backend,
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001611 )
1612 request2 = _load_cert(
Alex Gaynoreb2df542015-07-06 21:50:15 -04001613 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001614 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001615 backend,
Alex Gaynor70c8f8b2015-07-06 21:02:54 -04001616 )
1617
1618 assert request1 != request2
1619 assert request1 != object()
1620
Alex Gaynor978137d2015-07-08 20:59:16 -04001621 def test_hash(self, backend):
1622 request1 = _load_cert(
1623 os.path.join("x509", "requests", "rsa_sha1.pem"),
1624 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001625 backend,
Alex Gaynor978137d2015-07-08 20:59:16 -04001626 )
1627 request2 = _load_cert(
1628 os.path.join("x509", "requests", "rsa_sha1.pem"),
1629 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001630 backend,
Alex Gaynor978137d2015-07-08 20:59:16 -04001631 )
1632 request3 = _load_cert(
1633 os.path.join("x509", "requests", "san_rsa_sha1.pem"),
1634 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08001635 backend,
Alex Gaynor978137d2015-07-08 20:59:16 -04001636 )
1637
1638 assert hash(request1) == hash(request2)
1639 assert hash(request1) != hash(request3)
1640
Andre Caron9bbfcea2015-05-18 20:55:29 -04001641 def test_build_cert(self, backend):
Ian Cordascoe4e52a42015-07-19 10:15:37 -05001642 issuer_private_key = RSA_KEY_2048.private_key(backend)
1643 subject_private_key = RSA_KEY_2048.private_key(backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001644
Andre Caron9bbfcea2015-05-18 20:55:29 -04001645 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1646 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
Ian Cordascob3ed4842015-07-01 22:46:03 -05001647
Lucia Lic6ba99d2021-11-08 22:06:11 +08001648 builder = (
1649 x509.CertificateBuilder()
1650 .serial_number(777)
1651 .issuer_name(
1652 x509.Name(
1653 [
1654 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
1655 x509.NameAttribute(
1656 NameOID.STATE_OR_PROVINCE_NAME, u"Texas"
1657 ),
1658 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Austin"),
1659 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
1660 x509.NameAttribute(
1661 NameOID.COMMON_NAME, u"cryptography.io"
1662 ),
1663 ]
1664 )
1665 )
1666 .subject_name(
1667 x509.Name(
1668 [
1669 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
1670 x509.NameAttribute(
1671 NameOID.STATE_OR_PROVINCE_NAME, u"Texas"
1672 ),
1673 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Austin"),
1674 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
1675 x509.NameAttribute(
1676 NameOID.COMMON_NAME, u"cryptography.io"
1677 ),
1678 ]
1679 )
1680 )
1681 .public_key(subject_private_key.public_key())
1682 .add_extension(
1683 x509.BasicConstraints(ca=False, path_length=None),
1684 True,
1685 )
1686 .add_extension(
1687 x509.SubjectAlternativeName(
1688 [x509.DNSName(u"cryptography.io")]
1689 ),
1690 critical=False,
1691 )
1692 .not_valid_before(not_valid_before)
1693 .not_valid_after(not_valid_after)
Ian Cordascob3ed4842015-07-01 22:46:03 -05001694 )
1695
Paul Kehrer9add80e2015-08-03 17:53:14 +01001696 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Andre Caron9bbfcea2015-05-18 20:55:29 -04001697
1698 assert cert.version is x509.Version.v3
1699 assert cert.not_valid_before == not_valid_before
1700 assert cert.not_valid_after == not_valid_after
1701 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001702 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron9bbfcea2015-05-18 20:55:29 -04001703 )
1704 assert basic_constraints.value.ca is False
1705 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05001706 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05001707 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05001708 )
1709 assert list(subject_alternative_name.value) == [
Paul Kehrered321052017-10-11 08:11:44 +08001710 x509.DNSName(u"cryptography.io"),
Ian Cordasco47e94082015-08-02 11:34:47 -05001711 ]
Andre Caron9bbfcea2015-05-18 20:55:29 -04001712
Paul Kehrer72c92f52017-09-26 10:23:24 +08001713 def test_build_cert_private_type_encoding(self, backend):
1714 issuer_private_key = RSA_KEY_2048.private_key(backend)
1715 subject_private_key = RSA_KEY_2048.private_key(backend)
1716 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1717 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
Lucia Lic6ba99d2021-11-08 22:06:11 +08001718 name = x509.Name(
1719 [
1720 x509.NameAttribute(
1721 NameOID.STATE_OR_PROVINCE_NAME,
1722 u"Texas",
1723 _ASN1Type.PrintableString,
1724 ),
1725 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Austin"),
1726 x509.NameAttribute(
1727 NameOID.COMMON_NAME,
1728 u"cryptography.io",
1729 _ASN1Type.IA5String,
1730 ),
1731 ]
1732 )
1733 builder = (
1734 x509.CertificateBuilder()
1735 .serial_number(777)
1736 .issuer_name(name)
1737 .subject_name(name)
1738 .public_key(subject_private_key.public_key())
1739 .not_valid_before(not_valid_before)
1740 .not_valid_after(not_valid_after)
1741 )
Paul Kehrer72c92f52017-09-26 10:23:24 +08001742 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
1743
1744 for dn in (cert.subject, cert.issuer):
Lucia Lic6ba99d2021-11-08 22:06:11 +08001745 assert (
1746 dn.get_attributes_for_oid(NameOID.STATE_OR_PROVINCE_NAME)[
1747 0
1748 ]._type
1749 == _ASN1Type.PrintableString
1750 )
1751 assert (
1752 dn.get_attributes_for_oid(NameOID.STATE_OR_PROVINCE_NAME)[
1753 0
1754 ]._type
1755 == _ASN1Type.PrintableString
1756 )
1757 assert (
1758 dn.get_attributes_for_oid(NameOID.LOCALITY_NAME)[0]._type
1759 == _ASN1Type.UTF8String
1760 )
Paul Kehrer72c92f52017-09-26 10:23:24 +08001761
Paul Kehrer5a2bb542015-10-19 23:45:59 -05001762 def test_build_cert_printable_string_country_name(self, backend):
1763 issuer_private_key = RSA_KEY_2048.private_key(backend)
1764 subject_private_key = RSA_KEY_2048.private_key(backend)
1765
1766 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1767 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1768
Lucia Lic6ba99d2021-11-08 22:06:11 +08001769 builder = (
1770 x509.CertificateBuilder()
1771 .serial_number(777)
1772 .issuer_name(
1773 x509.Name(
1774 [
1775 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
1776 x509.NameAttribute(
1777 NameOID.JURISDICTION_COUNTRY_NAME, u"US"
1778 ),
1779 x509.NameAttribute(
1780 NameOID.STATE_OR_PROVINCE_NAME, u"Texas"
1781 ),
1782 ]
1783 )
1784 )
1785 .subject_name(
1786 x509.Name(
1787 [
1788 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
1789 x509.NameAttribute(
1790 NameOID.JURISDICTION_COUNTRY_NAME, u"US"
1791 ),
1792 x509.NameAttribute(
1793 NameOID.STATE_OR_PROVINCE_NAME, u"Texas"
1794 ),
1795 ]
1796 )
1797 )
1798 .public_key(subject_private_key.public_key())
1799 .not_valid_before(not_valid_before)
1800 .not_valid_after(not_valid_after)
Paul Kehrer5a2bb542015-10-19 23:45:59 -05001801 )
1802
1803 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
1804
Lucia Lic6ba99d2021-11-08 22:06:11 +08001805 parsed = _parse_cert(cert.public_bytes(serialization.Encoding.DER))
1806 subject = parsed.subject
1807 issuer = parsed.issuer
1808
1809 def read_next_rdn_value_tag(reader):
1810 # Assume each RDN has a single attribute.
1811 with reader.read_element(SET) as rdn:
1812 attribute = rdn.read_element(SEQUENCE)
1813
1814 with attribute:
1815 _ = attribute.read_element(OBJECT_IDENTIFIER)
1816 tag, value = attribute.read_any_element()
1817 return tag
Ofek Lev0e6a1292017-02-08 00:09:41 -05001818
1819 # Check that each value was encoded as an ASN.1 PRINTABLESTRING.
Lucia Lic6ba99d2021-11-08 22:06:11 +08001820 assert read_next_rdn_value_tag(subject) == PRINTABLE_STRING
1821 assert read_next_rdn_value_tag(issuer) == PRINTABLE_STRING
Alex Gaynor978a5e92017-05-25 21:11:09 -04001822 if (
1823 # This only works correctly in OpenSSL 1.1.0f+ and 1.0.2l+
Lucia Lic6ba99d2021-11-08 22:06:11 +08001824 backend._lib.CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER
Alex Gaynor978a5e92017-05-25 21:11:09 -04001825 ):
Lucia Lic6ba99d2021-11-08 22:06:11 +08001826 assert read_next_rdn_value_tag(subject) == PRINTABLE_STRING
1827 assert read_next_rdn_value_tag(issuer) == PRINTABLE_STRING
Paul Kehrer5a2bb542015-10-19 23:45:59 -05001828
Paul Kehrerf1ef3512014-11-26 17:36:05 -10001829
Ian Cordasco747a2172015-07-19 11:00:14 -05001830class TestCertificateBuilder(object):
Paul Kehrer25f19222015-08-04 23:05:09 +01001831 @pytest.mark.requires_backend_interface(interface=RSABackend)
1832 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrera03c3252015-08-09 10:59:29 -05001833 def test_checks_for_unsupported_extensions(self, backend):
1834 private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08001835 builder = (
1836 x509.CertificateBuilder()
1837 .subject_name(
1838 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
1839 )
1840 .issuer_name(
1841 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
1842 )
1843 .public_key(private_key.public_key())
1844 .serial_number(777)
1845 .not_valid_before(datetime.datetime(1999, 1, 1))
1846 .not_valid_after(datetime.datetime(2020, 1, 1))
1847 .add_extension(DummyExtension(), False)
Paul Kehrera03c3252015-08-09 10:59:29 -05001848 )
1849
1850 with pytest.raises(NotImplementedError):
1851 builder.sign(private_key, hashes.SHA1(), backend)
1852
Nick Bastin79d9e6a2015-12-13 15:43:46 -08001853 @pytest.mark.requires_backend_interface(interface=RSABackend)
1854 @pytest.mark.requires_backend_interface(interface=X509Backend)
1855 def test_encode_nonstandard_aia(self, backend):
1856 private_key = RSA_KEY_2048.private_key(backend)
1857
Lucia Lic6ba99d2021-11-08 22:06:11 +08001858 aia = x509.AuthorityInformationAccess(
1859 [
1860 x509.AccessDescription(
1861 x509.ObjectIdentifier("2.999.7"),
1862 x509.UniformResourceIdentifier(u"http://example.com"),
1863 ),
1864 ]
1865 )
Nick Bastin79d9e6a2015-12-13 15:43:46 -08001866
Lucia Lic6ba99d2021-11-08 22:06:11 +08001867 builder = (
1868 x509.CertificateBuilder()
1869 .subject_name(
1870 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
1871 )
1872 .issuer_name(
1873 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
1874 )
1875 .public_key(private_key.public_key())
1876 .serial_number(777)
1877 .not_valid_before(datetime.datetime(1999, 1, 1))
1878 .not_valid_after(datetime.datetime(2020, 1, 1))
1879 .add_extension(aia, False)
Nick Bastin79d9e6a2015-12-13 15:43:46 -08001880 )
1881
1882 builder.sign(private_key, hashes.SHA256(), backend)
1883
Paul Kehrer4662d442017-12-01 10:48:56 +08001884 @pytest.mark.requires_backend_interface(interface=RSABackend)
1885 @pytest.mark.requires_backend_interface(interface=X509Backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08001886 def test_encode_nonstandard_sia(self, backend):
1887 private_key = RSA_KEY_2048.private_key(backend)
1888
1889 sia = x509.SubjectInformationAccess(
1890 [
1891 x509.AccessDescription(
1892 x509.ObjectIdentifier("2.999.7"),
1893 x509.UniformResourceIdentifier(u"http://example.com"),
1894 ),
1895 ]
1896 )
1897
1898 builder = (
1899 x509.CertificateBuilder()
1900 .subject_name(
1901 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
1902 )
1903 .issuer_name(
1904 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
1905 )
1906 .public_key(private_key.public_key())
1907 .serial_number(777)
1908 .not_valid_before(datetime.datetime(2015, 1, 1))
1909 .not_valid_after(datetime.datetime(2040, 1, 1))
1910 .add_extension(sia, False)
1911 )
1912
1913 cert = builder.sign(private_key, hashes.SHA256(), backend)
1914 ext = cert.extensions.get_extension_for_oid(
1915 ExtensionOID.SUBJECT_INFORMATION_ACCESS
1916 )
1917 assert ext.value == sia
1918
1919 @pytest.mark.requires_backend_interface(interface=RSABackend)
1920 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer4662d442017-12-01 10:48:56 +08001921 def test_subject_dn_asn1_types(self, backend):
1922 private_key = RSA_KEY_2048.private_key(backend)
1923
Lucia Lic6ba99d2021-11-08 22:06:11 +08001924 name = x509.Name(
1925 [
1926 x509.NameAttribute(NameOID.COMMON_NAME, u"mysite.com"),
1927 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
1928 x509.NameAttribute(NameOID.LOCALITY_NAME, u"value"),
1929 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"value"),
1930 x509.NameAttribute(NameOID.STREET_ADDRESS, u"value"),
1931 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"value"),
1932 x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u"value"),
1933 x509.NameAttribute(NameOID.SERIAL_NUMBER, u"value"),
1934 x509.NameAttribute(NameOID.SURNAME, u"value"),
1935 x509.NameAttribute(NameOID.GIVEN_NAME, u"value"),
1936 x509.NameAttribute(NameOID.TITLE, u"value"),
1937 x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u"value"),
1938 x509.NameAttribute(NameOID.X500_UNIQUE_IDENTIFIER, u"value"),
1939 x509.NameAttribute(NameOID.DN_QUALIFIER, u"value"),
1940 x509.NameAttribute(NameOID.PSEUDONYM, u"value"),
1941 x509.NameAttribute(NameOID.USER_ID, u"value"),
1942 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u"value"),
1943 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u"value"),
1944 x509.NameAttribute(NameOID.JURISDICTION_COUNTRY_NAME, u"US"),
1945 x509.NameAttribute(
1946 NameOID.JURISDICTION_LOCALITY_NAME, u"value"
1947 ),
1948 x509.NameAttribute(
1949 NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME, u"value"
1950 ),
1951 x509.NameAttribute(NameOID.BUSINESS_CATEGORY, u"value"),
1952 x509.NameAttribute(NameOID.POSTAL_ADDRESS, u"value"),
1953 x509.NameAttribute(NameOID.POSTAL_CODE, u"value"),
1954 ]
1955 )
1956 cert = (
1957 x509.CertificateBuilder()
1958 .subject_name(name)
1959 .issuer_name(name)
1960 .public_key(private_key.public_key())
1961 .serial_number(777)
1962 .not_valid_before(datetime.datetime(1999, 1, 1))
1963 .not_valid_after(datetime.datetime(2020, 1, 1))
1964 .sign(private_key, hashes.SHA256(), backend)
1965 )
Paul Kehrer4662d442017-12-01 10:48:56 +08001966
1967 for dn in (cert.subject, cert.issuer):
1968 for oid, asn1_type in TestNameAttribute.EXPECTED_TYPES:
Lucia Lic6ba99d2021-11-08 22:06:11 +08001969 assert dn.get_attributes_for_oid(oid)[0]._type == asn1_type
Paul Kehrer4662d442017-12-01 10:48:56 +08001970
Paul Kehrer0cf36902016-12-05 07:12:43 -06001971 @pytest.mark.parametrize(
1972 ("not_valid_before", "not_valid_after"),
1973 [
Paul Kehrer767fa852019-01-21 22:36:25 -06001974 [datetime.datetime(1970, 2, 1), datetime.datetime(9999, 1, 1)],
1975 [datetime.datetime(1970, 2, 1), datetime.datetime(9999, 12, 31)],
Lucia Lic6ba99d2021-11-08 22:06:11 +08001976 ],
Paul Kehrer0cf36902016-12-05 07:12:43 -06001977 )
1978 @pytest.mark.requires_backend_interface(interface=RSABackend)
1979 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer767fa852019-01-21 22:36:25 -06001980 def test_extreme_times(self, not_valid_before, not_valid_after, backend):
Paul Kehrer0cf36902016-12-05 07:12:43 -06001981 private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08001982 builder = (
1983 x509.CertificateBuilder()
1984 .subject_name(
1985 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
1986 )
1987 .issuer_name(
1988 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
1989 )
1990 .public_key(private_key.public_key())
1991 .serial_number(777)
1992 .not_valid_before(not_valid_before)
1993 .not_valid_after(not_valid_after)
Paul Kehrer0cf36902016-12-05 07:12:43 -06001994 )
Paul Kehrer767fa852019-01-21 22:36:25 -06001995 cert = builder.sign(private_key, hashes.SHA256(), backend)
1996 assert cert.not_valid_before == not_valid_before
1997 assert cert.not_valid_after == not_valid_after
Lucia Lic6ba99d2021-11-08 22:06:11 +08001998 parsed = _parse_cert(cert.public_bytes(serialization.Encoding.DER))
1999 assert parsed.not_before_tag == UTC_TIME
2000 assert parsed.not_after_tag == GENERALIZED_TIME
Paul Kehrer0cf36902016-12-05 07:12:43 -06002001
Paul Kehrera03c3252015-08-09 10:59:29 -05002002 @pytest.mark.requires_backend_interface(interface=RSABackend)
2003 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer25f19222015-08-04 23:05:09 +01002004 def test_no_subject_name(self, backend):
2005 subject_private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002006 builder = (
2007 x509.CertificateBuilder()
2008 .serial_number(777)
2009 .issuer_name(
2010 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2011 )
2012 .public_key(subject_private_key.public_key())
2013 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2014 .not_valid_after(datetime.datetime(2030, 12, 31, 8, 30))
Paul Kehrer25f19222015-08-04 23:05:09 +01002015 )
2016 with pytest.raises(ValueError):
2017 builder.sign(subject_private_key, hashes.SHA256(), backend)
2018
2019 @pytest.mark.requires_backend_interface(interface=RSABackend)
2020 @pytest.mark.requires_backend_interface(interface=X509Backend)
2021 def test_no_issuer_name(self, backend):
2022 subject_private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002023 builder = (
2024 x509.CertificateBuilder()
2025 .serial_number(777)
2026 .subject_name(
2027 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2028 )
2029 .public_key(subject_private_key.public_key())
2030 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2031 .not_valid_after(datetime.datetime(2030, 12, 31, 8, 30))
Paul Kehrer25f19222015-08-04 23:05:09 +01002032 )
2033 with pytest.raises(ValueError):
2034 builder.sign(subject_private_key, hashes.SHA256(), backend)
2035
2036 @pytest.mark.requires_backend_interface(interface=RSABackend)
2037 @pytest.mark.requires_backend_interface(interface=X509Backend)
2038 def test_no_public_key(self, backend):
2039 subject_private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002040 builder = (
2041 x509.CertificateBuilder()
2042 .serial_number(777)
2043 .issuer_name(
2044 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2045 )
2046 .subject_name(
2047 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2048 )
2049 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2050 .not_valid_after(datetime.datetime(2030, 12, 31, 8, 30))
Paul Kehrer25f19222015-08-04 23:05:09 +01002051 )
2052 with pytest.raises(ValueError):
2053 builder.sign(subject_private_key, hashes.SHA256(), backend)
2054
2055 @pytest.mark.requires_backend_interface(interface=RSABackend)
2056 @pytest.mark.requires_backend_interface(interface=X509Backend)
2057 def test_no_not_valid_before(self, backend):
2058 subject_private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002059 builder = (
2060 x509.CertificateBuilder()
2061 .serial_number(777)
2062 .issuer_name(
2063 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2064 )
2065 .subject_name(
2066 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2067 )
2068 .public_key(subject_private_key.public_key())
2069 .not_valid_after(datetime.datetime(2030, 12, 31, 8, 30))
Paul Kehrer25f19222015-08-04 23:05:09 +01002070 )
2071 with pytest.raises(ValueError):
2072 builder.sign(subject_private_key, hashes.SHA256(), backend)
2073
2074 @pytest.mark.requires_backend_interface(interface=RSABackend)
2075 @pytest.mark.requires_backend_interface(interface=X509Backend)
2076 def test_no_not_valid_after(self, backend):
2077 subject_private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002078 builder = (
2079 x509.CertificateBuilder()
2080 .serial_number(777)
2081 .issuer_name(
2082 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2083 )
2084 .subject_name(
2085 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2086 )
2087 .public_key(subject_private_key.public_key())
2088 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
Paul Kehrer25f19222015-08-04 23:05:09 +01002089 )
2090 with pytest.raises(ValueError):
2091 builder.sign(subject_private_key, hashes.SHA256(), backend)
2092
2093 @pytest.mark.requires_backend_interface(interface=RSABackend)
2094 @pytest.mark.requires_backend_interface(interface=X509Backend)
2095 def test_no_serial_number(self, backend):
2096 subject_private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002097 builder = (
2098 x509.CertificateBuilder()
2099 .issuer_name(
2100 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2101 )
2102 .subject_name(
2103 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2104 )
2105 .public_key(subject_private_key.public_key())
2106 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2107 .not_valid_after(datetime.datetime(2030, 12, 31, 8, 30))
Paul Kehrer25f19222015-08-04 23:05:09 +01002108 )
2109 with pytest.raises(ValueError):
2110 builder.sign(subject_private_key, hashes.SHA256(), backend)
2111
Ian Cordasco747a2172015-07-19 11:00:14 -05002112 def test_issuer_name_must_be_a_name_type(self):
2113 builder = x509.CertificateBuilder()
2114
2115 with pytest.raises(TypeError):
2116 builder.issuer_name("subject")
2117
2118 with pytest.raises(TypeError):
2119 builder.issuer_name(object)
2120
2121 def test_issuer_name_may_only_be_set_once(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08002122 name = x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
Ian Cordasco747a2172015-07-19 11:00:14 -05002123 builder = x509.CertificateBuilder().issuer_name(name)
2124
2125 with pytest.raises(ValueError):
2126 builder.issuer_name(name)
2127
2128 def test_subject_name_must_be_a_name_type(self):
2129 builder = x509.CertificateBuilder()
2130
2131 with pytest.raises(TypeError):
2132 builder.subject_name("subject")
2133
2134 with pytest.raises(TypeError):
2135 builder.subject_name(object)
2136
2137 def test_subject_name_may_only_be_set_once(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08002138 name = x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
Ian Cordasco747a2172015-07-19 11:00:14 -05002139 builder = x509.CertificateBuilder().subject_name(name)
2140
2141 with pytest.raises(ValueError):
2142 builder.subject_name(name)
2143
Paul Kehrerf328b312015-12-13 21:34:03 -07002144 def test_not_valid_before_after_not_valid_after(self):
2145 builder = x509.CertificateBuilder()
2146
Lucia Lic6ba99d2021-11-08 22:06:11 +08002147 builder = builder.not_valid_after(datetime.datetime(2002, 1, 1, 12, 1))
Paul Kehrerf328b312015-12-13 21:34:03 -07002148 with pytest.raises(ValueError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08002149 builder.not_valid_before(datetime.datetime(2003, 1, 1, 12, 1))
Paul Kehrerf328b312015-12-13 21:34:03 -07002150
2151 def test_not_valid_after_before_not_valid_before(self):
2152 builder = x509.CertificateBuilder()
2153
2154 builder = builder.not_valid_before(
2155 datetime.datetime(2002, 1, 1, 12, 1)
2156 )
2157 with pytest.raises(ValueError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08002158 builder.not_valid_after(datetime.datetime(2001, 1, 1, 12, 1))
Paul Kehrerf328b312015-12-13 21:34:03 -07002159
Ian Cordasco747a2172015-07-19 11:00:14 -05002160 @pytest.mark.requires_backend_interface(interface=RSABackend)
2161 @pytest.mark.requires_backend_interface(interface=X509Backend)
2162 def test_public_key_must_be_public_key(self, backend):
2163 private_key = RSA_KEY_2048.private_key(backend)
2164 builder = x509.CertificateBuilder()
2165
2166 with pytest.raises(TypeError):
2167 builder.public_key(private_key)
2168
2169 @pytest.mark.requires_backend_interface(interface=RSABackend)
2170 @pytest.mark.requires_backend_interface(interface=X509Backend)
2171 def test_public_key_may_only_be_set_once(self, backend):
2172 private_key = RSA_KEY_2048.private_key(backend)
2173 public_key = private_key.public_key()
2174 builder = x509.CertificateBuilder().public_key(public_key)
2175
2176 with pytest.raises(ValueError):
2177 builder.public_key(public_key)
2178
2179 def test_serial_number_must_be_an_integer_type(self):
2180 with pytest.raises(TypeError):
2181 x509.CertificateBuilder().serial_number(10.0)
2182
Ian Cordascob4a155d2015-08-01 23:07:19 -05002183 def test_serial_number_must_be_non_negative(self):
2184 with pytest.raises(ValueError):
Коренберг Марк9e758302016-08-02 06:08:21 +05002185 x509.CertificateBuilder().serial_number(-1)
2186
2187 def test_serial_number_must_be_positive(self):
2188 with pytest.raises(ValueError):
2189 x509.CertificateBuilder().serial_number(0)
2190
2191 @pytest.mark.requires_backend_interface(interface=RSABackend)
2192 @pytest.mark.requires_backend_interface(interface=X509Backend)
2193 def test_minimal_serial_number(self, backend):
2194 subject_private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002195 builder = (
2196 x509.CertificateBuilder()
2197 .serial_number(1)
2198 .subject_name(
2199 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"RU")])
2200 )
2201 .issuer_name(
2202 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"RU")])
2203 )
2204 .public_key(subject_private_key.public_key())
2205 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2206 .not_valid_after(datetime.datetime(2030, 12, 31, 8, 30))
Коренберг Марк9e758302016-08-02 06:08:21 +05002207 )
2208 cert = builder.sign(subject_private_key, hashes.SHA256(), backend)
2209 assert cert.serial_number == 1
2210
2211 @pytest.mark.requires_backend_interface(interface=RSABackend)
2212 @pytest.mark.requires_backend_interface(interface=X509Backend)
2213 def test_biggest_serial_number(self, backend):
2214 subject_private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002215 builder = (
2216 x509.CertificateBuilder()
2217 .serial_number((1 << 159) - 1)
2218 .subject_name(
2219 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"RU")])
2220 )
2221 .issuer_name(
2222 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"RU")])
2223 )
2224 .public_key(subject_private_key.public_key())
2225 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2226 .not_valid_after(datetime.datetime(2030, 12, 31, 8, 30))
Коренберг Марк9e758302016-08-02 06:08:21 +05002227 )
2228 cert = builder.sign(subject_private_key, hashes.SHA256(), backend)
2229 assert cert.serial_number == (1 << 159) - 1
Ian Cordascob4a155d2015-08-01 23:07:19 -05002230
2231 def test_serial_number_must_be_less_than_160_bits_long(self):
2232 with pytest.raises(ValueError):
Коренберг Марк9e758302016-08-02 06:08:21 +05002233 x509.CertificateBuilder().serial_number(1 << 159)
Ian Cordascob4a155d2015-08-01 23:07:19 -05002234
Ian Cordasco747a2172015-07-19 11:00:14 -05002235 def test_serial_number_may_only_be_set_once(self):
2236 builder = x509.CertificateBuilder().serial_number(10)
2237
2238 with pytest.raises(ValueError):
2239 builder.serial_number(20)
2240
InvalidInterrupt8e66ca62016-08-16 19:39:31 -07002241 @pytest.mark.requires_backend_interface(interface=RSABackend)
2242 @pytest.mark.requires_backend_interface(interface=X509Backend)
2243 def test_aware_not_valid_after(self, backend):
2244 time = datetime.datetime(2012, 1, 16, 22, 43)
2245 tz = pytz.timezone("US/Pacific")
2246 time = tz.localize(time)
2247 utc_time = datetime.datetime(2012, 1, 17, 6, 43)
2248 private_key = RSA_KEY_2048.private_key(backend)
2249 cert_builder = x509.CertificateBuilder().not_valid_after(time)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002250 cert_builder = (
2251 cert_builder.subject_name(
2252 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2253 )
2254 .issuer_name(
2255 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2256 )
2257 .serial_number(1)
2258 .public_key(private_key.public_key())
2259 .not_valid_before(utc_time - datetime.timedelta(days=365))
InvalidInterrupt8e66ca62016-08-16 19:39:31 -07002260 )
2261
2262 cert = cert_builder.sign(private_key, hashes.SHA256(), backend)
2263 assert cert.not_valid_after == utc_time
2264
Paul Kehrer2e9c7df2019-01-22 06:59:06 -06002265 @pytest.mark.requires_backend_interface(interface=RSABackend)
2266 @pytest.mark.requires_backend_interface(interface=X509Backend)
2267 def test_earliest_time(self, backend):
2268 time = datetime.datetime(1950, 1, 1)
2269 private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002270 cert_builder = (
2271 x509.CertificateBuilder()
2272 .subject_name(
2273 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2274 )
2275 .issuer_name(
2276 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2277 )
2278 .serial_number(1)
2279 .public_key(private_key.public_key())
2280 .not_valid_before(time)
2281 .not_valid_after(time)
Paul Kehrer2e9c7df2019-01-22 06:59:06 -06002282 )
2283 cert = cert_builder.sign(private_key, hashes.SHA256(), backend)
2284 assert cert.not_valid_before == time
2285 assert cert.not_valid_after == time
Lucia Lic6ba99d2021-11-08 22:06:11 +08002286 parsed = _parse_cert(cert.public_bytes(serialization.Encoding.DER))
2287 assert parsed.not_before_tag == UTC_TIME
2288 assert parsed.not_after_tag == UTC_TIME
Paul Kehrer2e9c7df2019-01-22 06:59:06 -06002289
Ian Cordasco747a2172015-07-19 11:00:14 -05002290 def test_invalid_not_valid_after(self):
2291 with pytest.raises(TypeError):
2292 x509.CertificateBuilder().not_valid_after(104204304504)
2293
2294 with pytest.raises(TypeError):
2295 x509.CertificateBuilder().not_valid_after(datetime.time())
2296
Ian Cordascob4a155d2015-08-01 23:07:19 -05002297 with pytest.raises(ValueError):
2298 x509.CertificateBuilder().not_valid_after(
Paul Kehrer2e9c7df2019-01-22 06:59:06 -06002299 datetime.datetime(1940, 8, 10)
Ian Cordascob4a155d2015-08-01 23:07:19 -05002300 )
2301
Ian Cordasco747a2172015-07-19 11:00:14 -05002302 def test_not_valid_after_may_only_be_set_once(self):
2303 builder = x509.CertificateBuilder().not_valid_after(
2304 datetime.datetime.now()
2305 )
2306
2307 with pytest.raises(ValueError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08002308 builder.not_valid_after(datetime.datetime.now())
Ian Cordasco747a2172015-07-19 11:00:14 -05002309
InvalidInterrupt8e66ca62016-08-16 19:39:31 -07002310 @pytest.mark.requires_backend_interface(interface=RSABackend)
2311 @pytest.mark.requires_backend_interface(interface=X509Backend)
2312 def test_aware_not_valid_before(self, backend):
2313 time = datetime.datetime(2012, 1, 16, 22, 43)
2314 tz = pytz.timezone("US/Pacific")
2315 time = tz.localize(time)
2316 utc_time = datetime.datetime(2012, 1, 17, 6, 43)
2317 private_key = RSA_KEY_2048.private_key(backend)
2318 cert_builder = x509.CertificateBuilder().not_valid_before(time)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002319 cert_builder = (
2320 cert_builder.subject_name(
2321 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2322 )
2323 .issuer_name(
2324 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2325 )
2326 .serial_number(1)
2327 .public_key(private_key.public_key())
2328 .not_valid_after(utc_time + datetime.timedelta(days=366))
InvalidInterrupt8e66ca62016-08-16 19:39:31 -07002329 )
2330
2331 cert = cert_builder.sign(private_key, hashes.SHA256(), backend)
2332 assert cert.not_valid_before == utc_time
2333
Ian Cordasco747a2172015-07-19 11:00:14 -05002334 def test_invalid_not_valid_before(self):
2335 with pytest.raises(TypeError):
2336 x509.CertificateBuilder().not_valid_before(104204304504)
2337
2338 with pytest.raises(TypeError):
2339 x509.CertificateBuilder().not_valid_before(datetime.time())
2340
Ian Cordascob4a155d2015-08-01 23:07:19 -05002341 with pytest.raises(ValueError):
2342 x509.CertificateBuilder().not_valid_before(
Paul Kehrer2e9c7df2019-01-22 06:59:06 -06002343 datetime.datetime(1940, 8, 10)
Ian Cordascob4a155d2015-08-01 23:07:19 -05002344 )
2345
Ian Cordasco747a2172015-07-19 11:00:14 -05002346 def test_not_valid_before_may_only_be_set_once(self):
2347 builder = x509.CertificateBuilder().not_valid_before(
2348 datetime.datetime.now()
2349 )
2350
2351 with pytest.raises(ValueError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08002352 builder.not_valid_before(datetime.datetime.now())
Ian Cordasco747a2172015-07-19 11:00:14 -05002353
2354 def test_add_extension_checks_for_duplicates(self):
2355 builder = x509.CertificateBuilder().add_extension(
Lucia Lic6ba99d2021-11-08 22:06:11 +08002356 x509.BasicConstraints(ca=False, path_length=None),
2357 True,
Ian Cordasco747a2172015-07-19 11:00:14 -05002358 )
2359
2360 with pytest.raises(ValueError):
2361 builder.add_extension(
Lucia Lic6ba99d2021-11-08 22:06:11 +08002362 x509.BasicConstraints(ca=False, path_length=None),
2363 True,
Ian Cordasco747a2172015-07-19 11:00:14 -05002364 )
2365
Paul Kehrer08f950e2015-08-08 22:14:42 -05002366 def test_add_invalid_extension_type(self):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05002367 builder = x509.CertificateBuilder()
2368
Paul Kehrer08f950e2015-08-08 22:14:42 -05002369 with pytest.raises(TypeError):
Ian Cordasco9e0666e2015-07-20 11:42:51 -05002370 builder.add_extension(object(), False)
2371
Ian Cordascob77c7162015-07-20 21:22:33 -05002372 @pytest.mark.requires_backend_interface(interface=RSABackend)
2373 @pytest.mark.requires_backend_interface(interface=X509Backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002374 @pytest.mark.parametrize("algorithm", [object(), None])
2375 def test_sign_with_unsupported_hash(self, algorithm, backend):
Ian Cordascob77c7162015-07-20 21:22:33 -05002376 private_key = RSA_KEY_2048.private_key(backend)
2377 builder = x509.CertificateBuilder()
Lucia Lic6ba99d2021-11-08 22:06:11 +08002378 builder = (
2379 builder.subject_name(
2380 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2381 )
2382 .issuer_name(
2383 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2384 )
2385 .serial_number(1)
2386 .public_key(private_key.public_key())
2387 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2388 .not_valid_after(datetime.datetime(2032, 1, 1, 12, 1))
Paul Kehrer25f19222015-08-04 23:05:09 +01002389 )
Ian Cordascob77c7162015-07-20 21:22:33 -05002390
2391 with pytest.raises(TypeError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08002392 builder.sign(private_key, algorithm, backend)
2393
2394 @pytest.mark.supported(
2395 only_if=lambda backend: backend.ed25519_supported(),
2396 skip_message="Requires OpenSSL with Ed25519 support",
2397 )
2398 @pytest.mark.requires_backend_interface(interface=X509Backend)
2399 def test_sign_with_unsupported_hash_ed25519(self, backend):
2400 private_key = ed25519.Ed25519PrivateKey.generate()
2401 builder = (
2402 x509.CertificateBuilder()
2403 .subject_name(
2404 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2405 )
2406 .issuer_name(
2407 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2408 )
2409 .serial_number(1)
2410 .public_key(private_key.public_key())
2411 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2412 .not_valid_after(datetime.datetime(2032, 1, 1, 12, 1))
2413 )
2414
2415 with pytest.raises(ValueError):
2416 builder.sign(private_key, hashes.SHA256(), backend)
2417
2418 @pytest.mark.supported(
2419 only_if=lambda backend: backend.ed448_supported(),
2420 skip_message="Requires OpenSSL with Ed448 support",
2421 )
2422 @pytest.mark.requires_backend_interface(interface=X509Backend)
2423 def test_sign_with_unsupported_hash_ed448(self, backend):
2424 private_key = ed448.Ed448PrivateKey.generate()
2425 builder = (
2426 x509.CertificateBuilder()
2427 .subject_name(
2428 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2429 )
2430 .issuer_name(
2431 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2432 )
2433 .serial_number(1)
2434 .public_key(private_key.public_key())
2435 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2436 .not_valid_after(datetime.datetime(2032, 1, 1, 12, 1))
2437 )
2438
2439 with pytest.raises(ValueError):
2440 builder.sign(private_key, hashes.SHA256(), backend)
Ian Cordascob77c7162015-07-20 21:22:33 -05002441
Paul Kehrer784e3bc2017-06-30 19:49:53 -05002442 @pytest.mark.requires_backend_interface(interface=RSABackend)
2443 @pytest.mark.requires_backend_interface(interface=X509Backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002444 @pytest.mark.supported(
2445 only_if=lambda backend: backend.hash_supported(hashes.MD5()),
2446 skip_message="Requires OpenSSL with MD5 support",
2447 )
Paul Kehrer784e3bc2017-06-30 19:49:53 -05002448 def test_sign_rsa_with_md5(self, backend):
2449 private_key = RSA_KEY_2048.private_key(backend)
2450 builder = x509.CertificateBuilder()
Lucia Lic6ba99d2021-11-08 22:06:11 +08002451 builder = (
2452 builder.subject_name(
2453 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2454 )
2455 .issuer_name(
2456 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2457 )
2458 .serial_number(1)
2459 .public_key(private_key.public_key())
2460 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2461 .not_valid_after(datetime.datetime(2032, 1, 1, 12, 1))
Paul Kehrer784e3bc2017-06-30 19:49:53 -05002462 )
2463 cert = builder.sign(private_key, hashes.MD5(), backend)
2464 assert isinstance(cert.signature_hash_algorithm, hashes.MD5)
2465
2466 @pytest.mark.requires_backend_interface(interface=DSABackend)
2467 @pytest.mark.requires_backend_interface(interface=X509Backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002468 @pytest.mark.supported(
2469 only_if=lambda backend: backend.hash_supported(hashes.MD5()),
2470 skip_message="Requires OpenSSL with MD5 support",
2471 )
Paul Kehrer784e3bc2017-06-30 19:49:53 -05002472 def test_sign_dsa_with_md5(self, backend):
2473 private_key = DSA_KEY_2048.private_key(backend)
2474 builder = x509.CertificateBuilder()
Lucia Lic6ba99d2021-11-08 22:06:11 +08002475 builder = (
2476 builder.subject_name(
2477 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2478 )
2479 .issuer_name(
2480 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2481 )
2482 .serial_number(1)
2483 .public_key(private_key.public_key())
2484 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2485 .not_valid_after(datetime.datetime(2032, 1, 1, 12, 1))
Paul Kehrer784e3bc2017-06-30 19:49:53 -05002486 )
2487 with pytest.raises(ValueError):
2488 builder.sign(private_key, hashes.MD5(), backend)
2489
2490 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2491 @pytest.mark.requires_backend_interface(interface=X509Backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08002492 @pytest.mark.supported(
2493 only_if=lambda backend: backend.hash_supported(hashes.MD5()),
2494 skip_message="Requires OpenSSL with MD5 support",
2495 )
Paul Kehrer784e3bc2017-06-30 19:49:53 -05002496 def test_sign_ec_with_md5(self, backend):
2497 _skip_curve_unsupported(backend, ec.SECP256R1())
2498 private_key = EC_KEY_SECP256R1.private_key(backend)
2499 builder = x509.CertificateBuilder()
Lucia Lic6ba99d2021-11-08 22:06:11 +08002500 builder = (
2501 builder.subject_name(
2502 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2503 )
2504 .issuer_name(
2505 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2506 )
2507 .serial_number(1)
2508 .public_key(private_key.public_key())
2509 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
2510 .not_valid_after(datetime.datetime(2032, 1, 1, 12, 1))
Paul Kehrer784e3bc2017-06-30 19:49:53 -05002511 )
2512 with pytest.raises(ValueError):
2513 builder.sign(private_key, hashes.MD5(), backend)
2514
Ian Cordasco56561b12015-07-24 16:38:50 -05002515 @pytest.mark.requires_backend_interface(interface=DSABackend)
2516 @pytest.mark.requires_backend_interface(interface=X509Backend)
2517 def test_build_cert_with_dsa_private_key(self, backend):
Ian Cordasco56561b12015-07-24 16:38:50 -05002518 issuer_private_key = DSA_KEY_2048.private_key(backend)
2519 subject_private_key = DSA_KEY_2048.private_key(backend)
2520
2521 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2522 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2523
Lucia Lic6ba99d2021-11-08 22:06:11 +08002524 builder = (
2525 x509.CertificateBuilder()
2526 .serial_number(777)
2527 .issuer_name(
2528 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2529 )
2530 .subject_name(
2531 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2532 )
2533 .public_key(subject_private_key.public_key())
2534 .add_extension(
2535 x509.BasicConstraints(ca=False, path_length=None),
2536 True,
2537 )
2538 .add_extension(
2539 x509.SubjectAlternativeName(
2540 [x509.DNSName(u"cryptography.io")]
2541 ),
2542 critical=False,
2543 )
2544 .not_valid_before(not_valid_before)
2545 .not_valid_after(not_valid_after)
Ian Cordasco56561b12015-07-24 16:38:50 -05002546 )
2547
Paul Kehrer9add80e2015-08-03 17:53:14 +01002548 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05002549
2550 assert cert.version is x509.Version.v3
2551 assert cert.not_valid_before == not_valid_before
2552 assert cert.not_valid_after == not_valid_after
2553 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002554 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco56561b12015-07-24 16:38:50 -05002555 )
2556 assert basic_constraints.value.ca is False
2557 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05002558 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002559 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05002560 )
2561 assert list(subject_alternative_name.value) == [
Paul Kehrered321052017-10-11 08:11:44 +08002562 x509.DNSName(u"cryptography.io"),
Ian Cordasco47e94082015-08-02 11:34:47 -05002563 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05002564
2565 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2566 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco85fc4d52015-08-01 20:29:31 -05002567 def test_build_cert_with_ec_private_key(self, backend):
Ian Cordasco56561b12015-07-24 16:38:50 -05002568 _skip_curve_unsupported(backend, ec.SECP256R1())
2569 issuer_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
2570 subject_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
2571
2572 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2573 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2574
Lucia Lic6ba99d2021-11-08 22:06:11 +08002575 builder = (
2576 x509.CertificateBuilder()
2577 .serial_number(777)
2578 .issuer_name(
2579 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2580 )
2581 .subject_name(
2582 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2583 )
2584 .public_key(subject_private_key.public_key())
2585 .add_extension(
2586 x509.BasicConstraints(ca=False, path_length=None),
2587 True,
2588 )
2589 .add_extension(
2590 x509.SubjectAlternativeName(
2591 [x509.DNSName(u"cryptography.io")]
2592 ),
2593 critical=False,
2594 )
2595 .not_valid_before(not_valid_before)
2596 .not_valid_after(not_valid_after)
Ian Cordasco56561b12015-07-24 16:38:50 -05002597 )
2598
Paul Kehrer9add80e2015-08-03 17:53:14 +01002599 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
Ian Cordasco56561b12015-07-24 16:38:50 -05002600
2601 assert cert.version is x509.Version.v3
2602 assert cert.not_valid_before == not_valid_before
2603 assert cert.not_valid_after == not_valid_after
2604 basic_constraints = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002605 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco56561b12015-07-24 16:38:50 -05002606 )
2607 assert basic_constraints.value.ca is False
2608 assert basic_constraints.value.path_length is None
Ian Cordasco47e94082015-08-02 11:34:47 -05002609 subject_alternative_name = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05002610 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Ian Cordasco47e94082015-08-02 11:34:47 -05002611 )
2612 assert list(subject_alternative_name.value) == [
Paul Kehrered321052017-10-11 08:11:44 +08002613 x509.DNSName(u"cryptography.io"),
Ian Cordasco47e94082015-08-02 11:34:47 -05002614 ]
Ian Cordasco56561b12015-07-24 16:38:50 -05002615
Lucia Lic6ba99d2021-11-08 22:06:11 +08002616 @pytest.mark.supported(
2617 only_if=lambda backend: backend.ed25519_supported(),
2618 skip_message="Requires OpenSSL with Ed25519 support",
2619 )
2620 @pytest.mark.requires_backend_interface(interface=X509Backend)
2621 def test_build_cert_with_ed25519(self, backend):
2622 issuer_private_key = ed25519.Ed25519PrivateKey.generate()
2623 subject_private_key = ed25519.Ed25519PrivateKey.generate()
2624
2625 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2626 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2627
2628 builder = (
2629 x509.CertificateBuilder()
2630 .serial_number(777)
2631 .issuer_name(
2632 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2633 )
2634 .subject_name(
2635 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2636 )
2637 .public_key(subject_private_key.public_key())
2638 .add_extension(
2639 x509.BasicConstraints(ca=False, path_length=None),
2640 True,
2641 )
2642 .add_extension(
2643 x509.SubjectAlternativeName(
2644 [x509.DNSName(u"cryptography.io")]
2645 ),
2646 critical=False,
2647 )
2648 .not_valid_before(not_valid_before)
2649 .not_valid_after(not_valid_after)
2650 )
2651
2652 cert = builder.sign(issuer_private_key, None, backend)
2653 issuer_private_key.public_key().verify(
2654 cert.signature, cert.tbs_certificate_bytes
2655 )
2656 assert cert.signature_algorithm_oid == SignatureAlgorithmOID.ED25519
2657 assert cert.signature_hash_algorithm is None
2658 assert isinstance(cert.public_key(), ed25519.Ed25519PublicKey)
2659 assert cert.version is x509.Version.v3
2660 assert cert.not_valid_before == not_valid_before
2661 assert cert.not_valid_after == not_valid_after
2662 basic_constraints = cert.extensions.get_extension_for_oid(
2663 ExtensionOID.BASIC_CONSTRAINTS
2664 )
2665 assert basic_constraints.value.ca is False
2666 assert basic_constraints.value.path_length is None
2667 subject_alternative_name = cert.extensions.get_extension_for_oid(
2668 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
2669 )
2670 assert list(subject_alternative_name.value) == [
2671 x509.DNSName(u"cryptography.io"),
2672 ]
2673
2674 @pytest.mark.supported(
2675 only_if=lambda backend: backend.ed25519_supported(),
2676 skip_message="Requires OpenSSL with Ed25519 support",
2677 )
2678 @pytest.mark.requires_backend_interface(interface=X509Backend)
2679 @pytest.mark.requires_backend_interface(interface=RSABackend)
2680 def test_build_cert_with_public_ed25519_rsa_sig(self, backend):
2681 issuer_private_key = RSA_KEY_2048.private_key(backend)
2682 subject_private_key = ed25519.Ed25519PrivateKey.generate()
2683
2684 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2685 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2686
2687 builder = (
2688 x509.CertificateBuilder()
2689 .serial_number(777)
2690 .issuer_name(
2691 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2692 )
2693 .subject_name(
2694 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2695 )
2696 .public_key(subject_private_key.public_key())
2697 .not_valid_before(not_valid_before)
2698 .not_valid_after(not_valid_after)
2699 )
2700
2701 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2702 issuer_private_key.public_key().verify(
2703 cert.signature,
2704 cert.tbs_certificate_bytes,
2705 padding.PKCS1v15(),
2706 cert.signature_hash_algorithm,
2707 )
2708 assert cert.signature_algorithm_oid == (
2709 SignatureAlgorithmOID.RSA_WITH_SHA256
2710 )
2711 assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
2712 assert isinstance(cert.public_key(), ed25519.Ed25519PublicKey)
2713
2714 @pytest.mark.supported(
2715 only_if=lambda backend: backend.ed448_supported(),
2716 skip_message="Requires OpenSSL with Ed448 support",
2717 )
2718 @pytest.mark.requires_backend_interface(interface=X509Backend)
2719 def test_build_cert_with_ed448(self, backend):
2720 issuer_private_key = ed448.Ed448PrivateKey.generate()
2721 subject_private_key = ed448.Ed448PrivateKey.generate()
2722
2723 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2724 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2725
2726 builder = (
2727 x509.CertificateBuilder()
2728 .serial_number(777)
2729 .issuer_name(
2730 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2731 )
2732 .subject_name(
2733 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2734 )
2735 .public_key(subject_private_key.public_key())
2736 .add_extension(
2737 x509.BasicConstraints(ca=False, path_length=None),
2738 True,
2739 )
2740 .add_extension(
2741 x509.SubjectAlternativeName(
2742 [x509.DNSName(u"cryptography.io")]
2743 ),
2744 critical=False,
2745 )
2746 .not_valid_before(not_valid_before)
2747 .not_valid_after(not_valid_after)
2748 )
2749
2750 cert = builder.sign(issuer_private_key, None, backend)
2751 issuer_private_key.public_key().verify(
2752 cert.signature, cert.tbs_certificate_bytes
2753 )
2754 assert cert.signature_algorithm_oid == SignatureAlgorithmOID.ED448
2755 assert cert.signature_hash_algorithm is None
2756 assert isinstance(cert.public_key(), ed448.Ed448PublicKey)
2757 assert cert.version is x509.Version.v3
2758 assert cert.not_valid_before == not_valid_before
2759 assert cert.not_valid_after == not_valid_after
2760 basic_constraints = cert.extensions.get_extension_for_oid(
2761 ExtensionOID.BASIC_CONSTRAINTS
2762 )
2763 assert basic_constraints.value.ca is False
2764 assert basic_constraints.value.path_length is None
2765 subject_alternative_name = cert.extensions.get_extension_for_oid(
2766 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
2767 )
2768 assert list(subject_alternative_name.value) == [
2769 x509.DNSName(u"cryptography.io"),
2770 ]
2771
2772 @pytest.mark.supported(
2773 only_if=lambda backend: backend.ed448_supported(),
2774 skip_message="Requires OpenSSL with Ed448 support",
2775 )
2776 @pytest.mark.requires_backend_interface(interface=X509Backend)
2777 @pytest.mark.requires_backend_interface(interface=RSABackend)
2778 def test_build_cert_with_public_ed448_rsa_sig(self, backend):
2779 issuer_private_key = RSA_KEY_2048.private_key(backend)
2780 subject_private_key = ed448.Ed448PrivateKey.generate()
2781
2782 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2783 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2784
2785 builder = (
2786 x509.CertificateBuilder()
2787 .serial_number(777)
2788 .issuer_name(
2789 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2790 )
2791 .subject_name(
2792 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2793 )
2794 .public_key(subject_private_key.public_key())
2795 .not_valid_before(not_valid_before)
2796 .not_valid_after(not_valid_after)
2797 )
2798
2799 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
2800 issuer_private_key.public_key().verify(
2801 cert.signature,
2802 cert.tbs_certificate_bytes,
2803 padding.PKCS1v15(),
2804 cert.signature_hash_algorithm,
2805 )
2806 assert cert.signature_algorithm_oid == (
2807 SignatureAlgorithmOID.RSA_WITH_SHA256
2808 )
2809 assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
2810 assert isinstance(cert.public_key(), ed448.Ed448PublicKey)
2811
Ian Cordasco8690eff2015-07-24 16:42:58 -05002812 @pytest.mark.requires_backend_interface(interface=RSABackend)
2813 @pytest.mark.requires_backend_interface(interface=X509Backend)
Ian Cordasco19f5a492015-08-01 11:06:17 -05002814 def test_build_cert_with_rsa_key_too_small(self, backend):
Ian Cordasco8690eff2015-07-24 16:42:58 -05002815 issuer_private_key = RSA_KEY_512.private_key(backend)
2816 subject_private_key = RSA_KEY_512.private_key(backend)
2817
2818 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2819 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2820
Lucia Lic6ba99d2021-11-08 22:06:11 +08002821 builder = (
2822 x509.CertificateBuilder()
2823 .serial_number(777)
2824 .issuer_name(
2825 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2826 )
2827 .subject_name(
2828 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
2829 )
2830 .public_key(subject_private_key.public_key())
2831 .not_valid_before(not_valid_before)
2832 .not_valid_after(not_valid_after)
Ian Cordasco8690eff2015-07-24 16:42:58 -05002833 )
2834
Ian Cordasco19f5a492015-08-01 11:06:17 -05002835 with pytest.raises(ValueError):
Paul Kehrer9add80e2015-08-03 17:53:14 +01002836 builder.sign(issuer_private_key, hashes.SHA512(), backend)
Ian Cordasco8690eff2015-07-24 16:42:58 -05002837
Paul Kehrer2931b862017-09-22 10:07:10 +08002838 @pytest.mark.requires_backend_interface(interface=RSABackend)
2839 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrerdf387002015-07-27 15:19:57 +01002840 @pytest.mark.parametrize(
Paul Kehrer2931b862017-09-22 10:07:10 +08002841 "add_ext",
Paul Kehrerdf387002015-07-27 15:19:57 +01002842 [
Paul Kehrered321052017-10-11 08:11:44 +08002843 x509.SubjectAlternativeName(
Paul Kehrerd3f73e02017-10-11 09:48:40 +08002844 [
2845 # These examples exist to verify compatibility with
2846 # certificates that have utf8 encoded data in the ia5string
Lucia Lic6ba99d2021-11-08 22:06:11 +08002847 x509.DNSName._init_without_validation(u"a\xedt\xe1s.test"),
Paul Kehrerd3f73e02017-10-11 09:48:40 +08002848 x509.RFC822Name._init_without_validation(
Lucia Lic6ba99d2021-11-08 22:06:11 +08002849 u"test@a\xedt\xe1s.test"
Paul Kehrerd3f73e02017-10-11 09:48:40 +08002850 ),
Paul Kehrer1b43b512017-10-11 11:47:46 +08002851 x509.UniformResourceIdentifier._init_without_validation(
Lucia Lic6ba99d2021-11-08 22:06:11 +08002852 u"http://a\xedt\xe1s.test"
Paul Kehrer1b43b512017-10-11 11:47:46 +08002853 ),
Paul Kehrerd3f73e02017-10-11 09:48:40 +08002854 ]
Paul Kehrered321052017-10-11 08:11:44 +08002855 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08002856 x509.CertificatePolicies(
2857 [
2858 x509.PolicyInformation(
2859 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2860 [u"http://other.com/cps"],
2861 )
2862 ]
2863 ),
2864 x509.CertificatePolicies(
2865 [
2866 x509.PolicyInformation(
2867 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2868 None,
2869 )
2870 ]
2871 ),
2872 x509.CertificatePolicies(
2873 [
2874 x509.PolicyInformation(
2875 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2876 [
2877 u"http://example.com/cps",
2878 u"http://other.com/cps",
2879 x509.UserNotice(
2880 x509.NoticeReference(u"my org", [1, 2, 3, 4]),
2881 u"thing",
2882 ),
2883 ],
2884 )
2885 ]
2886 ),
2887 x509.CertificatePolicies(
2888 [
2889 x509.PolicyInformation(
2890 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2891 [
2892 u"http://example.com/cps",
2893 x509.UserNotice(
2894 x509.NoticeReference(
2895 u"UTF8\u2122'", [1, 2, 3, 4]
2896 ),
2897 u"We heart UTF8!\u2122",
2898 ),
2899 ],
2900 )
2901 ]
2902 ),
2903 x509.CertificatePolicies(
2904 [
2905 x509.PolicyInformation(
2906 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2907 [x509.UserNotice(None, u"thing")],
2908 )
2909 ]
2910 ),
2911 x509.CertificatePolicies(
2912 [
2913 x509.PolicyInformation(
2914 x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2915 [
2916 x509.UserNotice(
2917 x509.NoticeReference(u"my org", [1, 2, 3, 4]),
2918 None,
2919 )
2920 ],
2921 )
2922 ]
2923 ),
2924 x509.IssuerAlternativeName(
2925 [
2926 x509.DNSName(u"myissuer"),
2927 x509.RFC822Name(u"email@domain.com"),
2928 ]
2929 ),
2930 x509.ExtendedKeyUsage(
2931 [
2932 ExtendedKeyUsageOID.CLIENT_AUTH,
2933 ExtendedKeyUsageOID.SERVER_AUTH,
2934 ExtendedKeyUsageOID.CODE_SIGNING,
2935 ]
2936 ),
Paul Kehrer2931b862017-09-22 10:07:10 +08002937 x509.InhibitAnyPolicy(3),
2938 x509.TLSFeature([x509.TLSFeatureType.status_request]),
2939 x509.TLSFeature([x509.TLSFeatureType.status_request_v2]),
Lucia Lic6ba99d2021-11-08 22:06:11 +08002940 x509.TLSFeature(
2941 [
2942 x509.TLSFeatureType.status_request,
2943 x509.TLSFeatureType.status_request_v2,
2944 ]
2945 ),
Paul Kehrer3feeec82016-10-01 07:12:27 -05002946 x509.NameConstraints(
2947 permitted_subtrees=[
2948 x509.IPAddress(ipaddress.IPv4Network(u"192.168.0.0/24")),
2949 x509.IPAddress(ipaddress.IPv4Network(u"192.168.0.0/29")),
2950 x509.IPAddress(ipaddress.IPv4Network(u"127.0.0.1/32")),
2951 x509.IPAddress(ipaddress.IPv4Network(u"8.0.0.0/8")),
2952 x509.IPAddress(ipaddress.IPv4Network(u"0.0.0.0/0")),
2953 x509.IPAddress(
2954 ipaddress.IPv6Network(u"FF:0:0:0:0:0:0:0/96")
2955 ),
2956 x509.IPAddress(
2957 ipaddress.IPv6Network(u"FF:FF:0:0:0:0:0:0/128")
2958 ),
2959 ],
Lucia Lic6ba99d2021-11-08 22:06:11 +08002960 excluded_subtrees=[x509.DNSName(u"name.local")],
Paul Kehrer3feeec82016-10-01 07:12:27 -05002961 ),
2962 x509.NameConstraints(
2963 permitted_subtrees=[
2964 x509.IPAddress(ipaddress.IPv4Network(u"0.0.0.0/0")),
2965 ],
Lucia Lic6ba99d2021-11-08 22:06:11 +08002966 excluded_subtrees=None,
Paul Kehrer3feeec82016-10-01 07:12:27 -05002967 ),
2968 x509.NameConstraints(
2969 permitted_subtrees=None,
Lucia Lic6ba99d2021-11-08 22:06:11 +08002970 excluded_subtrees=[x509.DNSName(u"name.local")],
Paul Kehrer3feeec82016-10-01 07:12:27 -05002971 ),
Paul Kehrer2931b862017-09-22 10:07:10 +08002972 x509.PolicyConstraints(
Lucia Lic6ba99d2021-11-08 22:06:11 +08002973 require_explicit_policy=None, inhibit_policy_mapping=1
Paul Kehrer2931b862017-09-22 10:07:10 +08002974 ),
2975 x509.PolicyConstraints(
Lucia Lic6ba99d2021-11-08 22:06:11 +08002976 require_explicit_policy=3, inhibit_policy_mapping=1
Paul Kehrer2931b862017-09-22 10:07:10 +08002977 ),
2978 x509.PolicyConstraints(
Lucia Lic6ba99d2021-11-08 22:06:11 +08002979 require_explicit_policy=0, inhibit_policy_mapping=None
Paul Kehrer2931b862017-09-22 10:07:10 +08002980 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08002981 x509.CRLDistributionPoints(
2982 [
2983 x509.DistributionPoint(
2984 full_name=None,
2985 relative_name=x509.RelativeDistinguishedName(
2986 [
2987 x509.NameAttribute(
2988 NameOID.COMMON_NAME,
2989 u"indirect CRL for indirectCRL CA3",
2990 ),
2991 ]
Paul Kehrer2931b862017-09-22 10:07:10 +08002992 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08002993 reasons=None,
2994 crl_issuer=[
2995 x509.DirectoryName(
2996 x509.Name(
2997 [
2998 x509.NameAttribute(
2999 NameOID.COUNTRY_NAME, u"US"
3000 ),
3001 x509.NameAttribute(
3002 NameOID.ORGANIZATION_NAME,
3003 u"Test Certificates 2011",
3004 ),
3005 x509.NameAttribute(
3006 NameOID.ORGANIZATIONAL_UNIT_NAME,
3007 u"indirectCRL CA3 cRLIssuer",
3008 ),
3009 ]
3010 )
3011 )
3012 ],
3013 )
3014 ]
3015 ),
3016 x509.CRLDistributionPoints(
3017 [
3018 x509.DistributionPoint(
3019 full_name=[
3020 x509.DirectoryName(
3021 x509.Name(
3022 [
3023 x509.NameAttribute(
3024 NameOID.COUNTRY_NAME, u"US"
3025 ),
3026 ]
3027 )
3028 )
3029 ],
3030 relative_name=None,
3031 reasons=None,
3032 crl_issuer=[
3033 x509.DirectoryName(
3034 x509.Name(
3035 [
3036 x509.NameAttribute(
3037 NameOID.ORGANIZATION_NAME,
3038 u"cryptography Testing",
3039 ),
3040 ]
3041 )
3042 )
3043 ],
3044 )
3045 ]
3046 ),
3047 x509.CRLDistributionPoints(
3048 [
3049 x509.DistributionPoint(
3050 full_name=[
3051 x509.UniformResourceIdentifier(
3052 u"http://myhost.com/myca.crl"
Paul Kehrer2931b862017-09-22 10:07:10 +08003053 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08003054 x509.UniformResourceIdentifier(
3055 u"http://backup.myhost.com/myca.crl"
Paul Kehrer2931b862017-09-22 10:07:10 +08003056 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08003057 ],
3058 relative_name=None,
3059 reasons=frozenset(
3060 [
3061 x509.ReasonFlags.key_compromise,
3062 x509.ReasonFlags.ca_compromise,
3063 ]
Paul Kehrer2931b862017-09-22 10:07:10 +08003064 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08003065 crl_issuer=[
3066 x509.DirectoryName(
3067 x509.Name(
3068 [
3069 x509.NameAttribute(
3070 NameOID.COUNTRY_NAME, u"US"
3071 ),
3072 x509.NameAttribute(
3073 NameOID.COMMON_NAME,
3074 u"cryptography CA",
3075 ),
3076 ]
3077 )
3078 )
3079 ],
3080 )
3081 ]
3082 ),
3083 x509.CRLDistributionPoints(
3084 [
3085 x509.DistributionPoint(
3086 full_name=[
3087 x509.UniformResourceIdentifier(
3088 u"http://domain.com/some.crl"
3089 )
3090 ],
3091 relative_name=None,
3092 reasons=frozenset(
3093 [
3094 x509.ReasonFlags.key_compromise,
3095 x509.ReasonFlags.ca_compromise,
3096 x509.ReasonFlags.affiliation_changed,
3097 x509.ReasonFlags.superseded,
3098 x509.ReasonFlags.privilege_withdrawn,
3099 x509.ReasonFlags.cessation_of_operation,
3100 x509.ReasonFlags.aa_compromise,
3101 x509.ReasonFlags.certificate_hold,
3102 ]
Paul Kehrerb76bcf82017-09-24 08:44:12 +08003103 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08003104 crl_issuer=None,
3105 )
3106 ]
3107 ),
3108 x509.CRLDistributionPoints(
3109 [
3110 x509.DistributionPoint(
3111 full_name=None,
3112 relative_name=None,
3113 reasons=None,
3114 crl_issuer=[
3115 x509.DirectoryName(
3116 x509.Name(
3117 [
3118 x509.NameAttribute(
3119 NameOID.COMMON_NAME,
3120 u"cryptography CA",
3121 ),
3122 ]
3123 )
3124 )
3125 ],
3126 )
3127 ]
3128 ),
3129 x509.CRLDistributionPoints(
3130 [
3131 x509.DistributionPoint(
3132 full_name=[
3133 x509.UniformResourceIdentifier(
3134 u"http://domain.com/some.crl"
3135 )
3136 ],
3137 relative_name=None,
3138 reasons=frozenset([x509.ReasonFlags.aa_compromise]),
3139 crl_issuer=None,
3140 )
3141 ]
3142 ),
3143 x509.FreshestCRL(
3144 [
3145 x509.DistributionPoint(
3146 full_name=[
3147 x509.UniformResourceIdentifier(
3148 u"http://domain.com/some.crl"
3149 )
3150 ],
3151 relative_name=None,
3152 reasons=frozenset(
3153 [
3154 x509.ReasonFlags.key_compromise,
3155 x509.ReasonFlags.ca_compromise,
3156 x509.ReasonFlags.affiliation_changed,
3157 x509.ReasonFlags.superseded,
3158 x509.ReasonFlags.privilege_withdrawn,
3159 x509.ReasonFlags.cessation_of_operation,
3160 x509.ReasonFlags.aa_compromise,
3161 x509.ReasonFlags.certificate_hold,
3162 ]
Paul Kehrera84c5cd2018-12-01 12:26:54 +08003163 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08003164 crl_issuer=None,
3165 )
3166 ]
3167 ),
3168 x509.FreshestCRL(
3169 [
3170 x509.DistributionPoint(
3171 full_name=None,
3172 relative_name=x509.RelativeDistinguishedName(
3173 [
3174 x509.NameAttribute(
3175 NameOID.COMMON_NAME,
3176 u"indirect CRL for indirectCRL CA3",
3177 ),
3178 ]
Paul Kehrera84c5cd2018-12-01 12:26:54 +08003179 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08003180 reasons=None,
3181 crl_issuer=None,
3182 )
3183 ]
3184 ),
3185 x509.FreshestCRL(
3186 [
3187 x509.DistributionPoint(
3188 full_name=None,
3189 relative_name=x509.RelativeDistinguishedName(
3190 [
3191 x509.NameAttribute(
3192 NameOID.COMMON_NAME,
3193 u"indirect CRL for indirectCRL CA3",
3194 ),
3195 x509.NameAttribute(
3196 NameOID.COUNTRY_NAME, u"US"
3197 ),
3198 ]
3199 ),
3200 reasons=None,
3201 crl_issuer=None,
3202 )
3203 ]
3204 ),
3205 ],
Paul Kehrer3feeec82016-10-01 07:12:27 -05003206 )
Paul Kehrer2931b862017-09-22 10:07:10 +08003207 def test_ext(self, add_ext, backend):
Paul Kehrer5d669662017-09-11 09:16:34 +08003208 issuer_private_key = RSA_KEY_2048.private_key(backend)
3209 subject_private_key = RSA_KEY_2048.private_key(backend)
3210
3211 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
3212 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
3213
Lucia Lic6ba99d2021-11-08 22:06:11 +08003214 cert = (
3215 x509.CertificateBuilder()
3216 .subject_name(
3217 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3218 )
3219 .issuer_name(
3220 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3221 )
3222 .not_valid_before(not_valid_before)
3223 .not_valid_after(not_valid_after)
3224 .public_key(subject_private_key.public_key())
3225 .serial_number(123)
3226 .add_extension(add_ext, critical=False)
3227 .sign(issuer_private_key, hashes.SHA256(), backend)
3228 )
Paul Kehrer5d669662017-09-11 09:16:34 +08003229
Paul Kehrer2931b862017-09-22 10:07:10 +08003230 ext = cert.extensions.get_extension_for_class(type(add_ext))
Paul Kehrer5d669662017-09-11 09:16:34 +08003231 assert ext.critical is False
3232 assert ext.value == add_ext
3233
3234 @pytest.mark.requires_backend_interface(interface=RSABackend)
3235 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01003236 def test_key_usage(self, backend):
3237 issuer_private_key = RSA_KEY_2048.private_key(backend)
3238 subject_private_key = RSA_KEY_2048.private_key(backend)
3239
3240 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
3241 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
3242
Lucia Lic6ba99d2021-11-08 22:06:11 +08003243 cert = (
3244 x509.CertificateBuilder()
3245 .subject_name(
3246 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3247 )
3248 .issuer_name(
3249 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3250 )
3251 .not_valid_before(not_valid_before)
3252 .not_valid_after(not_valid_after)
3253 .public_key(subject_private_key.public_key())
3254 .serial_number(123)
3255 .add_extension(
3256 x509.KeyUsage(
3257 digital_signature=True,
3258 content_commitment=True,
3259 key_encipherment=False,
3260 data_encipherment=False,
3261 key_agreement=False,
3262 key_cert_sign=True,
3263 crl_sign=False,
3264 encipher_only=False,
3265 decipher_only=False,
3266 ),
3267 critical=False,
3268 )
3269 .sign(issuer_private_key, hashes.SHA256(), backend)
3270 )
Paul Kehrer2748d8a2015-08-03 17:50:03 +01003271
Paul Kehrerd44e4132015-08-10 19:13:13 -05003272 ext = cert.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrer2748d8a2015-08-03 17:50:03 +01003273 assert ext.critical is False
3274 assert ext.value == x509.KeyUsage(
3275 digital_signature=True,
3276 content_commitment=True,
3277 key_encipherment=False,
3278 data_encipherment=False,
3279 key_agreement=False,
3280 key_cert_sign=True,
3281 crl_sign=False,
3282 encipher_only=False,
Lucia Lic6ba99d2021-11-08 22:06:11 +08003283 decipher_only=False,
Paul Kehrer2748d8a2015-08-03 17:50:03 +01003284 )
3285
vicente.fiebig6b55c4e2015-10-01 18:24:58 -03003286 @pytest.mark.requires_backend_interface(interface=RSABackend)
3287 @pytest.mark.requires_backend_interface(interface=X509Backend)
3288 def test_build_ca_request_with_path_length_none(self, backend):
3289 private_key = RSA_KEY_2048.private_key(backend)
3290
Lucia Lic6ba99d2021-11-08 22:06:11 +08003291 request = (
3292 x509.CertificateSigningRequestBuilder()
3293 .subject_name(
3294 x509.Name(
3295 [x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA")]
3296 )
3297 )
3298 .add_extension(
3299 x509.BasicConstraints(ca=True, path_length=None), critical=True
3300 )
3301 .sign(private_key, hashes.SHA1(), backend)
3302 )
vicente.fiebig6b55c4e2015-10-01 18:24:58 -03003303
3304 loaded_request = x509.load_pem_x509_csr(
3305 request.public_bytes(encoding=serialization.Encoding.PEM), backend
3306 )
3307 subject = loaded_request.subject
3308 assert isinstance(subject, x509.Name)
3309 basic_constraints = request.extensions.get_extension_for_oid(
3310 ExtensionOID.BASIC_CONSTRAINTS
3311 )
3312 assert basic_constraints.value.path_length is None
3313
Alex Gaynor1e034632016-03-14 21:01:18 -04003314 @pytest.mark.parametrize(
Lucia Lic6ba99d2021-11-08 22:06:11 +08003315 "unrecognized",
3316 [
Alex Gaynor1e034632016-03-14 21:01:18 -04003317 x509.UnrecognizedExtension(
3318 x509.ObjectIdentifier("1.2.3.4.5"),
3319 b"abcdef",
3320 )
Lucia Lic6ba99d2021-11-08 22:06:11 +08003321 ],
Alex Gaynor1e034632016-03-14 21:01:18 -04003322 )
3323 @pytest.mark.requires_backend_interface(interface=RSABackend)
3324 @pytest.mark.requires_backend_interface(interface=X509Backend)
3325 def test_unrecognized_extension(self, backend, unrecognized):
3326 private_key = RSA_KEY_2048.private_key(backend)
3327
Lucia Lic6ba99d2021-11-08 22:06:11 +08003328 cert = (
3329 x509.CertificateBuilder()
3330 .subject_name(
3331 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US")])
3332 )
3333 .issuer_name(
3334 x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US")])
3335 )
3336 .not_valid_before(datetime.datetime(2002, 1, 1, 12, 1))
3337 .not_valid_after(datetime.datetime(2030, 12, 31, 8, 30))
3338 .public_key(private_key.public_key())
3339 .serial_number(123)
3340 .add_extension(unrecognized, critical=False)
3341 .sign(private_key, hashes.SHA256(), backend)
3342 )
Alex Gaynor1e034632016-03-14 21:01:18 -04003343
3344 ext = cert.extensions.get_extension_for_oid(unrecognized.oid)
3345
3346 assert ext.value == unrecognized
3347
Ian Cordasco747a2172015-07-19 11:00:14 -05003348
Andre Caron0ef595f2015-05-18 13:53:43 -04003349@pytest.mark.requires_backend_interface(interface=X509Backend)
3350class TestCertificateSigningRequestBuilder(object):
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003351 @pytest.mark.requires_backend_interface(interface=RSABackend)
Andre Caron0ef595f2015-05-18 13:53:43 -04003352 def test_sign_invalid_hash_algorithm(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05003353 private_key = RSA_KEY_2048.private_key(backend)
3354
Alex Gaynorba19c2e2015-06-27 00:07:09 -04003355 builder = x509.CertificateSigningRequestBuilder().subject_name(
3356 x509.Name([])
3357 )
Andre Caron0ef595f2015-05-18 13:53:43 -04003358 with pytest.raises(TypeError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08003359 builder.sign(private_key, "NotAHash", backend)
3360
3361 @pytest.mark.supported(
3362 only_if=lambda backend: backend.ed25519_supported(),
3363 skip_message="Requires OpenSSL with Ed25519 support",
3364 )
3365 @pytest.mark.requires_backend_interface(interface=X509Backend)
3366 def test_request_with_unsupported_hash_ed25519(self, backend):
3367 private_key = ed25519.Ed25519PrivateKey.generate()
3368 builder = x509.CertificateSigningRequestBuilder().subject_name(
3369 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3370 )
3371
3372 with pytest.raises(ValueError):
3373 builder.sign(private_key, hashes.SHA256(), backend)
3374
3375 @pytest.mark.supported(
3376 only_if=lambda backend: backend.ed448_supported(),
3377 skip_message="Requires OpenSSL with Ed448 support",
3378 )
3379 @pytest.mark.requires_backend_interface(interface=X509Backend)
3380 def test_request_with_unsupported_hash_ed448(self, backend):
3381 private_key = ed448.Ed448PrivateKey.generate()
3382 builder = x509.CertificateSigningRequestBuilder().subject_name(
3383 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3384 )
3385
3386 with pytest.raises(ValueError):
3387 builder.sign(private_key, hashes.SHA256(), backend)
Andre Caron0ef595f2015-05-18 13:53:43 -04003388
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003389 @pytest.mark.requires_backend_interface(interface=RSABackend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08003390 @pytest.mark.supported(
3391 only_if=lambda backend: backend.hash_supported(hashes.MD5()),
3392 skip_message="Requires OpenSSL with MD5 support",
3393 )
Paul Kehrer784e3bc2017-06-30 19:49:53 -05003394 def test_sign_rsa_with_md5(self, backend):
3395 private_key = RSA_KEY_2048.private_key(backend)
3396
3397 builder = x509.CertificateSigningRequestBuilder().subject_name(
Lucia Lic6ba99d2021-11-08 22:06:11 +08003398 x509.Name([x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA")])
Paul Kehrer784e3bc2017-06-30 19:49:53 -05003399 )
3400 request = builder.sign(private_key, hashes.MD5(), backend)
3401 assert isinstance(request.signature_hash_algorithm, hashes.MD5)
3402
3403 @pytest.mark.requires_backend_interface(interface=DSABackend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08003404 @pytest.mark.supported(
3405 only_if=lambda backend: backend.hash_supported(hashes.MD5()),
3406 skip_message="Requires OpenSSL with MD5 support",
3407 )
Paul Kehrer784e3bc2017-06-30 19:49:53 -05003408 def test_sign_dsa_with_md5(self, backend):
3409 private_key = DSA_KEY_2048.private_key(backend)
3410 builder = x509.CertificateSigningRequestBuilder().subject_name(
Lucia Lic6ba99d2021-11-08 22:06:11 +08003411 x509.Name([x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA")])
Paul Kehrer784e3bc2017-06-30 19:49:53 -05003412 )
3413 with pytest.raises(ValueError):
3414 builder.sign(private_key, hashes.MD5(), backend)
3415
3416 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08003417 @pytest.mark.supported(
3418 only_if=lambda backend: backend.hash_supported(hashes.MD5()),
3419 skip_message="Requires OpenSSL with MD5 support",
3420 )
Paul Kehrer784e3bc2017-06-30 19:49:53 -05003421 def test_sign_ec_with_md5(self, backend):
3422 _skip_curve_unsupported(backend, ec.SECP256R1())
3423 private_key = EC_KEY_SECP256R1.private_key(backend)
3424 builder = x509.CertificateSigningRequestBuilder().subject_name(
Lucia Lic6ba99d2021-11-08 22:06:11 +08003425 x509.Name([x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA")])
Paul Kehrer784e3bc2017-06-30 19:49:53 -05003426 )
3427 with pytest.raises(ValueError):
3428 builder.sign(private_key, hashes.MD5(), backend)
3429
3430 @pytest.mark.requires_backend_interface(interface=RSABackend)
Alex Gaynorba19c2e2015-06-27 00:07:09 -04003431 def test_no_subject_name(self, backend):
3432 private_key = RSA_KEY_2048.private_key(backend)
3433
3434 builder = x509.CertificateSigningRequestBuilder()
3435 with pytest.raises(ValueError):
3436 builder.sign(private_key, hashes.SHA256(), backend)
3437
3438 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003439 def test_build_ca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05003440 private_key = RSA_KEY_2048.private_key(backend)
3441
Lucia Lic6ba99d2021-11-08 22:06:11 +08003442 request = (
3443 x509.CertificateSigningRequestBuilder()
3444 .subject_name(
3445 x509.Name(
3446 [x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA")]
3447 )
3448 )
3449 .add_extension(
3450 x509.BasicConstraints(ca=True, path_length=2), critical=True
3451 )
3452 .sign(private_key, hashes.SHA1(), backend)
3453 )
Andre Caron0ef595f2015-05-18 13:53:43 -04003454
3455 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
3456 public_key = request.public_key()
3457 assert isinstance(public_key, rsa.RSAPublicKey)
3458 subject = request.subject
3459 assert isinstance(subject, x509.Name)
3460 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +08003461 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
Andre Caron0ef595f2015-05-18 13:53:43 -04003462 ]
3463 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05003464 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron0ef595f2015-05-18 13:53:43 -04003465 )
3466 assert basic_constraints.value.ca is True
3467 assert basic_constraints.value.path_length == 2
3468
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003469 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05003470 def test_build_ca_request_with_unicode(self, backend):
3471 private_key = RSA_KEY_2048.private_key(backend)
3472
Lucia Lic6ba99d2021-11-08 22:06:11 +08003473 request = (
3474 x509.CertificateSigningRequestBuilder()
3475 .subject_name(
3476 x509.Name(
3477 [
3478 x509.NameAttribute(
3479 NameOID.ORGANIZATION_NAME, u"PyCA\U0001f37a"
3480 ),
3481 ]
3482 )
3483 )
3484 .add_extension(
3485 x509.BasicConstraints(ca=True, path_length=2), critical=True
3486 )
3487 .sign(private_key, hashes.SHA1(), backend)
3488 )
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05003489
3490 loaded_request = x509.load_pem_x509_csr(
3491 request.public_bytes(encoding=serialization.Encoding.PEM), backend
3492 )
3493 subject = loaded_request.subject
3494 assert isinstance(subject, x509.Name)
3495 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +08003496 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA\U0001f37a"),
Ian Cordasco13cdc7b2015-06-24 21:45:55 -05003497 ]
3498
3499 @pytest.mark.requires_backend_interface(interface=RSABackend)
Paul Kehrer4662d442017-12-01 10:48:56 +08003500 def test_subject_dn_asn1_types(self, backend):
3501 private_key = RSA_KEY_2048.private_key(backend)
3502
Lucia Lic6ba99d2021-11-08 22:06:11 +08003503 request = (
3504 x509.CertificateSigningRequestBuilder()
3505 .subject_name(
3506 x509.Name(
3507 [
3508 x509.NameAttribute(NameOID.COMMON_NAME, u"mysite.com"),
3509 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
3510 x509.NameAttribute(NameOID.LOCALITY_NAME, u"value"),
3511 x509.NameAttribute(
3512 NameOID.STATE_OR_PROVINCE_NAME, u"value"
3513 ),
3514 x509.NameAttribute(NameOID.STREET_ADDRESS, u"value"),
3515 x509.NameAttribute(
3516 NameOID.ORGANIZATION_NAME, u"value"
3517 ),
3518 x509.NameAttribute(
3519 NameOID.ORGANIZATIONAL_UNIT_NAME, u"value"
3520 ),
3521 x509.NameAttribute(NameOID.SERIAL_NUMBER, u"value"),
3522 x509.NameAttribute(NameOID.SURNAME, u"value"),
3523 x509.NameAttribute(NameOID.GIVEN_NAME, u"value"),
3524 x509.NameAttribute(NameOID.TITLE, u"value"),
3525 x509.NameAttribute(
3526 NameOID.GENERATION_QUALIFIER, u"value"
3527 ),
3528 x509.NameAttribute(
3529 NameOID.X500_UNIQUE_IDENTIFIER, u"value"
3530 ),
3531 x509.NameAttribute(NameOID.DN_QUALIFIER, u"value"),
3532 x509.NameAttribute(NameOID.PSEUDONYM, u"value"),
3533 x509.NameAttribute(NameOID.USER_ID, u"value"),
3534 x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u"value"),
3535 x509.NameAttribute(NameOID.EMAIL_ADDRESS, u"value"),
3536 x509.NameAttribute(
3537 NameOID.JURISDICTION_COUNTRY_NAME, u"US"
3538 ),
3539 x509.NameAttribute(
3540 NameOID.JURISDICTION_LOCALITY_NAME, u"value"
3541 ),
3542 x509.NameAttribute(
3543 NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME,
3544 u"value",
3545 ),
3546 x509.NameAttribute(
3547 NameOID.BUSINESS_CATEGORY, u"value"
3548 ),
3549 x509.NameAttribute(NameOID.POSTAL_ADDRESS, u"value"),
3550 x509.NameAttribute(NameOID.POSTAL_CODE, u"value"),
3551 ]
3552 )
3553 )
3554 .sign(private_key, hashes.SHA256(), backend)
3555 )
Paul Kehrer4662d442017-12-01 10:48:56 +08003556 for oid, asn1_type in TestNameAttribute.EXPECTED_TYPES:
Lucia Lic6ba99d2021-11-08 22:06:11 +08003557 assert (
3558 request.subject.get_attributes_for_oid(oid)[0]._type
3559 == asn1_type
3560 )
Paul Kehrer4662d442017-12-01 10:48:56 +08003561
3562 @pytest.mark.requires_backend_interface(interface=RSABackend)
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10003563 def test_build_ca_request_with_multivalue_rdns(self, backend):
3564 private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08003565 subject = x509.Name(
3566 [
3567 x509.RelativeDistinguishedName(
3568 [
3569 x509.NameAttribute(NameOID.TITLE, u"Test"),
3570 x509.NameAttribute(NameOID.COMMON_NAME, u"Multivalue"),
3571 x509.NameAttribute(NameOID.SURNAME, u"RDNs"),
3572 ]
3573 ),
3574 x509.RelativeDistinguishedName(
3575 [x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA")]
3576 ),
3577 ]
3578 )
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10003579
Lucia Lic6ba99d2021-11-08 22:06:11 +08003580 request = (
3581 x509.CertificateSigningRequestBuilder()
3582 .subject_name(subject)
3583 .sign(private_key, hashes.SHA1(), backend)
3584 )
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10003585
3586 loaded_request = x509.load_pem_x509_csr(
3587 request.public_bytes(encoding=serialization.Encoding.PEM), backend
3588 )
3589 assert isinstance(loaded_request.subject, x509.Name)
3590 assert loaded_request.subject == subject
3591
3592 @pytest.mark.requires_backend_interface(interface=RSABackend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003593 def test_build_nonca_request_with_rsa(self, backend):
Ian Cordasco4d46eb72015-06-17 12:08:27 -05003594 private_key = RSA_KEY_2048.private_key(backend)
3595
Lucia Lic6ba99d2021-11-08 22:06:11 +08003596 request = (
3597 x509.CertificateSigningRequestBuilder()
3598 .subject_name(
3599 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3600 )
3601 .add_extension(
3602 x509.BasicConstraints(ca=False, path_length=None),
3603 critical=True,
3604 )
3605 .sign(private_key, hashes.SHA1(), backend)
3606 )
Andre Caron0ef595f2015-05-18 13:53:43 -04003607
3608 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
3609 public_key = request.public_key()
3610 assert isinstance(public_key, rsa.RSAPublicKey)
3611 subject = request.subject
3612 assert isinstance(subject, x509.Name)
3613 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +08003614 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Andre Caron0ef595f2015-05-18 13:53:43 -04003615 ]
3616 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05003617 ExtensionOID.BASIC_CONSTRAINTS
Andre Caron0ef595f2015-05-18 13:53:43 -04003618 )
3619 assert basic_constraints.value.ca is False
3620 assert basic_constraints.value.path_length is None
3621
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003622 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
3623 def test_build_ca_request_with_ec(self, backend):
Ian Cordasco8cdcdfc2015-06-24 22:00:26 -05003624 _skip_curve_unsupported(backend, ec.SECP256R1())
3625 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003626
Lucia Lic6ba99d2021-11-08 22:06:11 +08003627 request = (
3628 x509.CertificateSigningRequestBuilder()
3629 .subject_name(
3630 x509.Name(
3631 [
3632 x509.NameAttribute(
3633 NameOID.STATE_OR_PROVINCE_NAME, u"Texas"
3634 ),
3635 ]
3636 )
3637 )
3638 .add_extension(
3639 x509.BasicConstraints(ca=True, path_length=2), critical=True
3640 )
3641 .sign(private_key, hashes.SHA1(), backend)
3642 )
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003643
3644 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
3645 public_key = request.public_key()
3646 assert isinstance(public_key, ec.EllipticCurvePublicKey)
3647 subject = request.subject
3648 assert isinstance(subject, x509.Name)
3649 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +08003650 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Texas"),
3651 ]
3652 basic_constraints = request.extensions.get_extension_for_oid(
3653 ExtensionOID.BASIC_CONSTRAINTS
3654 )
3655 assert basic_constraints.value.ca is True
3656 assert basic_constraints.value.path_length == 2
3657
3658 @pytest.mark.supported(
3659 only_if=lambda backend: backend.ed25519_supported(),
3660 skip_message="Requires OpenSSL with Ed25519 support",
3661 )
3662 @pytest.mark.requires_backend_interface(interface=X509Backend)
3663 def test_build_ca_request_with_ed25519(self, backend):
3664 private_key = ed25519.Ed25519PrivateKey.generate()
3665
3666 request = (
3667 x509.CertificateSigningRequestBuilder()
3668 .subject_name(
3669 x509.Name(
3670 [
3671 x509.NameAttribute(
3672 NameOID.STATE_OR_PROVINCE_NAME, u"Texas"
3673 ),
3674 ]
3675 )
3676 )
3677 .add_extension(
3678 x509.BasicConstraints(ca=True, path_length=2), critical=True
3679 )
3680 .sign(private_key, None, backend)
3681 )
3682
3683 assert request.signature_hash_algorithm is None
3684 public_key = request.public_key()
3685 assert isinstance(public_key, ed25519.Ed25519PublicKey)
3686 subject = request.subject
3687 assert isinstance(subject, x509.Name)
3688 assert list(subject) == [
3689 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Texas"),
3690 ]
3691 basic_constraints = request.extensions.get_extension_for_oid(
3692 ExtensionOID.BASIC_CONSTRAINTS
3693 )
3694 assert basic_constraints.value.ca is True
3695 assert basic_constraints.value.path_length == 2
3696
3697 @pytest.mark.supported(
3698 only_if=lambda backend: backend.ed448_supported(),
3699 skip_message="Requires OpenSSL with Ed448 support",
3700 )
3701 @pytest.mark.requires_backend_interface(interface=X509Backend)
3702 def test_build_ca_request_with_ed448(self, backend):
3703 private_key = ed448.Ed448PrivateKey.generate()
3704
3705 request = (
3706 x509.CertificateSigningRequestBuilder()
3707 .subject_name(
3708 x509.Name(
3709 [
3710 x509.NameAttribute(
3711 NameOID.STATE_OR_PROVINCE_NAME, u"Texas"
3712 ),
3713 ]
3714 )
3715 )
3716 .add_extension(
3717 x509.BasicConstraints(ca=True, path_length=2), critical=True
3718 )
3719 .sign(private_key, None, backend)
3720 )
3721
3722 assert request.signature_hash_algorithm is None
3723 public_key = request.public_key()
3724 assert isinstance(public_key, ed448.Ed448PublicKey)
3725 subject = request.subject
3726 assert isinstance(subject, x509.Name)
3727 assert list(subject) == [
3728 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Texas"),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003729 ]
3730 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05003731 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003732 )
3733 assert basic_constraints.value.ca is True
3734 assert basic_constraints.value.path_length == 2
3735
3736 @pytest.mark.requires_backend_interface(interface=DSABackend)
3737 def test_build_ca_request_with_dsa(self, backend):
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003738 private_key = DSA_KEY_2048.private_key(backend)
3739
Lucia Lic6ba99d2021-11-08 22:06:11 +08003740 request = (
3741 x509.CertificateSigningRequestBuilder()
3742 .subject_name(
3743 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3744 )
3745 .add_extension(
3746 x509.BasicConstraints(ca=True, path_length=2), critical=True
3747 )
3748 .sign(private_key, hashes.SHA1(), backend)
3749 )
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003750
3751 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
3752 public_key = request.public_key()
3753 assert isinstance(public_key, dsa.DSAPublicKey)
3754 subject = request.subject
3755 assert isinstance(subject, x509.Name)
3756 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +08003757 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003758 ]
3759 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05003760 ExtensionOID.BASIC_CONSTRAINTS
Ian Cordasco8ed8edc2015-06-22 20:11:17 -05003761 )
3762 assert basic_constraints.value.ca is True
3763 assert basic_constraints.value.path_length == 2
3764
Paul Kehrerff917802015-06-26 17:29:04 -05003765 def test_add_duplicate_extension(self):
Andre Caronfc164c52015-05-31 17:36:18 -04003766 builder = x509.CertificateSigningRequestBuilder().add_extension(
Lucia Lic6ba99d2021-11-08 22:06:11 +08003767 x509.BasicConstraints(True, 2),
3768 critical=True,
Andre Caronfc164c52015-05-31 17:36:18 -04003769 )
Andre Caron0ef595f2015-05-18 13:53:43 -04003770 with pytest.raises(ValueError):
Andre Caron472fd692015-06-06 20:04:44 -04003771 builder.add_extension(
Lucia Lic6ba99d2021-11-08 22:06:11 +08003772 x509.BasicConstraints(True, 2),
3773 critical=True,
Andre Caron472fd692015-06-06 20:04:44 -04003774 )
Andre Caron0ef595f2015-05-18 13:53:43 -04003775
Paul Kehrerff917802015-06-26 17:29:04 -05003776 def test_set_invalid_subject(self):
Andre Caron0ef595f2015-05-18 13:53:43 -04003777 builder = x509.CertificateSigningRequestBuilder()
3778 with pytest.raises(TypeError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08003779 builder.subject_name("NotAName")
Andre Caron0ef595f2015-05-18 13:53:43 -04003780
Paul Kehrere59fd222015-08-08 22:50:19 -05003781 def test_add_invalid_extension_type(self):
Ian Cordasco34853f32015-06-21 10:50:53 -05003782 builder = x509.CertificateSigningRequestBuilder()
Andre Caron0ef595f2015-05-18 13:53:43 -04003783
Paul Kehrere59fd222015-08-08 22:50:19 -05003784 with pytest.raises(TypeError):
3785 builder.add_extension(object(), False)
3786
3787 def test_add_unsupported_extension(self, backend):
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05003788 private_key = RSA_KEY_2048.private_key(backend)
3789 builder = x509.CertificateSigningRequestBuilder()
Lucia Lic6ba99d2021-11-08 22:06:11 +08003790 builder = (
3791 builder.subject_name(
3792 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3793 )
3794 .add_extension(
3795 x509.SubjectAlternativeName(
3796 [x509.DNSName(u"cryptography.io")]
3797 ),
3798 critical=False,
3799 )
3800 .add_extension(DummyExtension(), False)
Paul Kehrerdce91f02015-07-23 20:31:12 +01003801 )
3802 with pytest.raises(NotImplementedError):
3803 builder.sign(private_key, hashes.SHA256(), backend)
3804
3805 def test_key_usage(self, backend):
3806 private_key = RSA_KEY_2048.private_key(backend)
3807 builder = x509.CertificateSigningRequestBuilder()
Lucia Lic6ba99d2021-11-08 22:06:11 +08003808 request = (
3809 builder.subject_name(
3810 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3811 )
3812 .add_extension(
3813 x509.KeyUsage(
3814 digital_signature=True,
3815 content_commitment=True,
3816 key_encipherment=False,
3817 data_encipherment=False,
3818 key_agreement=False,
3819 key_cert_sign=True,
3820 crl_sign=False,
3821 encipher_only=False,
3822 decipher_only=False,
3823 ),
3824 critical=False,
3825 )
3826 .sign(private_key, hashes.SHA256(), backend)
3827 )
Paul Kehrerdce91f02015-07-23 20:31:12 +01003828 assert len(request.extensions) == 1
Paul Kehrerd44e4132015-08-10 19:13:13 -05003829 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrerdce91f02015-07-23 20:31:12 +01003830 assert ext.critical is False
3831 assert ext.value == x509.KeyUsage(
3832 digital_signature=True,
3833 content_commitment=True,
3834 key_encipherment=False,
3835 data_encipherment=False,
3836 key_agreement=False,
3837 key_cert_sign=True,
3838 crl_sign=False,
3839 encipher_only=False,
Lucia Lic6ba99d2021-11-08 22:06:11 +08003840 decipher_only=False,
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05003841 )
Paul Kehrerdce91f02015-07-23 20:31:12 +01003842
3843 def test_key_usage_key_agreement_bit(self, backend):
3844 private_key = RSA_KEY_2048.private_key(backend)
3845 builder = x509.CertificateSigningRequestBuilder()
Lucia Lic6ba99d2021-11-08 22:06:11 +08003846 request = (
3847 builder.subject_name(
3848 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3849 )
3850 .add_extension(
3851 x509.KeyUsage(
3852 digital_signature=False,
3853 content_commitment=False,
3854 key_encipherment=False,
3855 data_encipherment=False,
3856 key_agreement=True,
3857 key_cert_sign=True,
3858 crl_sign=False,
3859 encipher_only=False,
3860 decipher_only=True,
3861 ),
3862 critical=False,
3863 )
3864 .sign(private_key, hashes.SHA256(), backend)
3865 )
Paul Kehrerdce91f02015-07-23 20:31:12 +01003866 assert len(request.extensions) == 1
Paul Kehrerd44e4132015-08-10 19:13:13 -05003867 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
Paul Kehrerdce91f02015-07-23 20:31:12 +01003868 assert ext.critical is False
3869 assert ext.value == x509.KeyUsage(
3870 digital_signature=False,
3871 content_commitment=False,
3872 key_encipherment=False,
3873 data_encipherment=False,
3874 key_agreement=True,
3875 key_cert_sign=True,
3876 crl_sign=False,
3877 encipher_only=False,
Lucia Lic6ba99d2021-11-08 22:06:11 +08003878 decipher_only=True,
Paul Kehrerdce91f02015-07-23 20:31:12 +01003879 )
Paul Kehrer7e2fbe62015-06-26 17:59:05 -05003880
Paul Kehrer8bfbace2015-07-23 19:10:28 +01003881 def test_add_two_extensions(self, backend):
3882 private_key = RSA_KEY_2048.private_key(backend)
3883 builder = x509.CertificateSigningRequestBuilder()
Lucia Lic6ba99d2021-11-08 22:06:11 +08003884 request = (
3885 builder.subject_name(
3886 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
3887 )
3888 .add_extension(
3889 x509.SubjectAlternativeName(
3890 [x509.DNSName(u"cryptography.io")]
3891 ),
3892 critical=False,
3893 )
3894 .add_extension(
3895 x509.BasicConstraints(ca=True, path_length=2), critical=True
3896 )
3897 .sign(private_key, hashes.SHA1(), backend)
3898 )
Paul Kehrer8bfbace2015-07-23 19:10:28 +01003899
3900 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
3901 public_key = request.public_key()
3902 assert isinstance(public_key, rsa.RSAPublicKey)
3903 basic_constraints = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05003904 ExtensionOID.BASIC_CONSTRAINTS
Paul Kehrer8bfbace2015-07-23 19:10:28 +01003905 )
3906 assert basic_constraints.value.ca is True
3907 assert basic_constraints.value.path_length == 2
3908 ext = request.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05003909 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
Paul Kehrer8bfbace2015-07-23 19:10:28 +01003910 )
Paul Kehrered321052017-10-11 08:11:44 +08003911 assert list(ext.value) == [x509.DNSName(u"cryptography.io")]
Paul Kehrerff917802015-06-26 17:29:04 -05003912
Lucia Lic6ba99d2021-11-08 22:06:11 +08003913 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
3914 def test_add_attributes(self, backend):
3915 _skip_curve_unsupported(backend, ec.SECP256R1())
3916 private_key = ec.generate_private_key(ec.SECP256R1(), backend)
3917 challenge_password = b"challenge me!"
3918 unstructured_name = b"no structure, for shame"
3919 locality = b"this shouldn't even be an X509 attribute"
3920
3921 request = (
3922 x509.CertificateSigningRequestBuilder()
3923 .subject_name(
3924 x509.Name(
3925 [
3926 x509.NameAttribute(
3927 NameOID.STATE_OR_PROVINCE_NAME, u"Texas"
3928 ),
3929 ]
3930 )
3931 )
3932 .add_attribute(
3933 x509.oid.AttributeOID.CHALLENGE_PASSWORD, challenge_password
3934 )
3935 .add_attribute(
3936 x509.oid.AttributeOID.UNSTRUCTURED_NAME, unstructured_name
3937 )
3938 .add_attribute(x509.oid.NameOID.LOCALITY_NAME, locality)
3939 .sign(private_key, hashes.SHA256(), backend)
3940 )
3941
3942 assert (
3943 request.get_attribute_for_oid(
3944 x509.oid.AttributeOID.CHALLENGE_PASSWORD
3945 )
3946 == challenge_password
3947 )
3948 assert (
3949 request.get_attribute_for_oid(
3950 x509.oid.AttributeOID.UNSTRUCTURED_NAME
3951 )
3952 == unstructured_name
3953 )
3954 assert (
3955 request.get_attribute_for_oid(x509.oid.NameOID.LOCALITY_NAME)
3956 == locality
3957 )
3958
3959 def test_add_attribute_bad_types(self, backend):
3960 request = x509.CertificateSigningRequestBuilder()
3961 with pytest.raises(TypeError):
3962 request.add_attribute(b"not an oid", b"val")
3963
3964 with pytest.raises(TypeError):
3965 request.add_attribute(
3966 x509.oid.AttributeOID.CHALLENGE_PASSWORD, 383
3967 )
3968
3969 def test_duplicate_attribute(self, backend):
3970 request = x509.CertificateSigningRequestBuilder().add_attribute(
3971 x509.oid.AttributeOID.CHALLENGE_PASSWORD, b"val"
3972 )
3973 with pytest.raises(ValueError):
3974 request.add_attribute(
3975 x509.oid.AttributeOID.CHALLENGE_PASSWORD, b"val2"
3976 )
3977
Andre Caron0ef595f2015-05-18 13:53:43 -04003978 def test_set_subject_twice(self):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10003979 builder = x509.CertificateSigningRequestBuilder()
3980 builder = builder.subject_name(
Lucia Lic6ba99d2021-11-08 22:06:11 +08003981 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
Paul Kehrer4903adc2014-12-13 16:57:50 -06003982 )
Paul Kehrer41120322014-12-02 18:31:14 -10003983 with pytest.raises(ValueError):
Paul Kehrera693cfd2014-11-27 07:47:58 -10003984 builder.subject_name(
Lucia Lic6ba99d2021-11-08 22:06:11 +08003985 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
Alex Gaynor32c57df2015-02-23 21:51:27 -08003986 )
Alex Gaynorfcadda62015-03-10 10:01:18 -04003987
Alex Gaynord3e84162015-06-28 10:14:55 -04003988 def test_subject_alt_names(self, backend):
3989 private_key = RSA_KEY_2048.private_key(backend)
3990
Lucia Lic6ba99d2021-11-08 22:06:11 +08003991 san = x509.SubjectAlternativeName(
3992 [
3993 x509.DNSName(u"example.com"),
3994 x509.DNSName(u"*.example.com"),
3995 x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
3996 x509.DirectoryName(
3997 x509.Name(
3998 [
3999 x509.NameAttribute(NameOID.COMMON_NAME, u"PyCA"),
4000 x509.NameAttribute(
4001 NameOID.ORGANIZATION_NAME,
4002 u"We heart UTF8!\u2122",
4003 ),
4004 ]
4005 )
4006 ),
4007 x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
4008 x509.IPAddress(ipaddress.ip_address(u"ff::")),
4009 x509.OtherName(
4010 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
4011 value=b"0\x03\x02\x01\x05",
4012 ),
4013 x509.RFC822Name(u"test@example.com"),
4014 x509.RFC822Name(u"email"),
4015 x509.RFC822Name(u"email@xn--eml-vla4c.com"),
4016 x509.UniformResourceIdentifier(
4017 u"https://xn--80ato2c.cryptography"
4018 ),
4019 x509.UniformResourceIdentifier(
4020 u"gopher://cryptography:70/some/path"
4021 ),
4022 ]
4023 )
Paul Kehrer9e66d102016-09-29 21:59:33 -05004024
Lucia Lic6ba99d2021-11-08 22:06:11 +08004025 csr = (
4026 x509.CertificateSigningRequestBuilder()
4027 .subject_name(
4028 x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, u"SAN")])
4029 )
4030 .add_extension(
4031 san,
4032 critical=False,
4033 )
4034 .sign(private_key, hashes.SHA256(), backend)
4035 )
Paul Kehrer9e66d102016-09-29 21:59:33 -05004036
4037 assert len(csr.extensions) == 1
4038 ext = csr.extensions.get_extension_for_oid(
4039 ExtensionOID.SUBJECT_ALTERNATIVE_NAME
4040 )
4041 assert not ext.critical
4042 assert ext.oid == ExtensionOID.SUBJECT_ALTERNATIVE_NAME
4043 assert ext.value == san
Alex Gaynord3e84162015-06-28 10:14:55 -04004044
Paul Kehrer500ed9d2015-07-10 20:51:36 -05004045 def test_invalid_asn1_othername(self, backend):
4046 private_key = RSA_KEY_2048.private_key(backend)
4047
Lucia Lic6ba99d2021-11-08 22:06:11 +08004048 builder = (
4049 x509.CertificateSigningRequestBuilder()
4050 .subject_name(
4051 x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, u"SAN")])
4052 )
4053 .add_extension(
4054 x509.SubjectAlternativeName(
4055 [
4056 x509.OtherName(
4057 type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
4058 value=b"\x01\x02\x01\x05",
4059 ),
4060 ]
Paul Kehrer500ed9d2015-07-10 20:51:36 -05004061 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08004062 critical=False,
4063 )
Paul Kehrer500ed9d2015-07-10 20:51:36 -05004064 )
4065 with pytest.raises(ValueError):
4066 builder.sign(private_key, hashes.SHA256(), backend)
4067
Alex Gaynord5f718c2015-07-05 11:19:38 -04004068 def test_subject_alt_name_unsupported_general_name(self, backend):
4069 private_key = RSA_KEY_2048.private_key(backend)
4070
Lucia Lic6ba99d2021-11-08 22:06:11 +08004071 builder = (
4072 x509.CertificateSigningRequestBuilder()
4073 .subject_name(
4074 x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, u"SAN")])
4075 )
4076 .add_extension(
4077 x509.SubjectAlternativeName([FakeGeneralName("")]),
4078 critical=False,
4079 )
Alex Gaynord5f718c2015-07-05 11:19:38 -04004080 )
4081
Paul Kehrer474a6472015-07-11 12:29:52 -05004082 with pytest.raises(ValueError):
Alex Gaynord5f718c2015-07-05 11:19:38 -04004083 builder.sign(private_key, hashes.SHA256(), backend)
4084
Paul Kehrer0b8f3272015-07-23 21:46:21 +01004085 def test_extended_key_usage(self, backend):
4086 private_key = RSA_KEY_2048.private_key(backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08004087 eku = x509.ExtendedKeyUsage(
4088 [
4089 ExtendedKeyUsageOID.CLIENT_AUTH,
4090 ExtendedKeyUsageOID.SERVER_AUTH,
4091 ExtendedKeyUsageOID.CODE_SIGNING,
4092 ]
4093 )
Paul Kehrer9e66d102016-09-29 21:59:33 -05004094 builder = x509.CertificateSigningRequestBuilder()
Lucia Lic6ba99d2021-11-08 22:06:11 +08004095 request = (
4096 builder.subject_name(
4097 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4098 )
4099 .add_extension(eku, critical=False)
4100 .sign(private_key, hashes.SHA256(), backend)
4101 )
Paul Kehrer9e66d102016-09-29 21:59:33 -05004102
4103 ext = request.extensions.get_extension_for_oid(
4104 ExtensionOID.EXTENDED_KEY_USAGE
4105 )
4106 assert ext.critical is False
4107 assert ext.value == eku
Paul Kehrer0b8f3272015-07-23 21:46:21 +01004108
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01004109 @pytest.mark.requires_backend_interface(interface=RSABackend)
4110 def test_rsa_key_too_small(self, backend):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004111 private_key = RSA_KEY_512.private_key(backend)
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01004112 builder = x509.CertificateSigningRequestBuilder()
4113 builder = builder.subject_name(
Lucia Lic6ba99d2021-11-08 22:06:11 +08004114 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01004115 )
4116
Lucia Lic6ba99d2021-11-08 22:06:11 +08004117 with pytest.raises(ValueError):
Paul Kehrer4e4a9ba2015-07-25 18:49:35 +01004118 builder.sign(private_key, hashes.SHA512(), backend)
4119
Paul Kehrer3b54ce22015-08-03 16:44:57 +01004120 @pytest.mark.requires_backend_interface(interface=RSABackend)
4121 @pytest.mark.requires_backend_interface(interface=X509Backend)
4122 def test_build_cert_with_aia(self, backend):
4123 issuer_private_key = RSA_KEY_2048.private_key(backend)
4124 subject_private_key = RSA_KEY_2048.private_key(backend)
4125
4126 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
4127 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
4128
Lucia Lic6ba99d2021-11-08 22:06:11 +08004129 aia = x509.AuthorityInformationAccess(
4130 [
4131 x509.AccessDescription(
4132 AuthorityInformationAccessOID.OCSP,
4133 x509.UniformResourceIdentifier(u"http://ocsp.domain.com"),
4134 ),
4135 x509.AccessDescription(
4136 AuthorityInformationAccessOID.CA_ISSUERS,
4137 x509.UniformResourceIdentifier(
4138 u"http://domain.com/ca.crt"
4139 ),
4140 ),
4141 ]
4142 )
Paul Kehrer3b54ce22015-08-03 16:44:57 +01004143
Lucia Lic6ba99d2021-11-08 22:06:11 +08004144 builder = (
4145 x509.CertificateBuilder()
4146 .serial_number(777)
4147 .issuer_name(
4148 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4149 )
4150 .subject_name(
4151 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4152 )
4153 .public_key(subject_private_key.public_key())
4154 .add_extension(aia, critical=False)
4155 .not_valid_before(not_valid_before)
4156 .not_valid_after(not_valid_after)
Paul Kehrer3b54ce22015-08-03 16:44:57 +01004157 )
4158
4159 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
4160
4161 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05004162 ExtensionOID.AUTHORITY_INFORMATION_ACCESS
Paul Kehrer3b54ce22015-08-03 16:44:57 +01004163 )
4164 assert ext.value == aia
4165
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01004166 @pytest.mark.requires_backend_interface(interface=RSABackend)
4167 @pytest.mark.requires_backend_interface(interface=X509Backend)
Lucia Lic6ba99d2021-11-08 22:06:11 +08004168 def test_build_cert_with_sia(self, backend):
4169 issuer_private_key = RSA_KEY_2048.private_key(backend)
4170 subject_private_key = RSA_KEY_2048.private_key(backend)
4171
4172 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
4173 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
4174
4175 sia = x509.SubjectInformationAccess(
4176 [
4177 x509.AccessDescription(
4178 SubjectInformationAccessOID.CA_REPOSITORY,
4179 x509.UniformResourceIdentifier(u"http://ca.domain.com"),
4180 ),
4181 ]
4182 )
4183
4184 builder = (
4185 x509.CertificateBuilder()
4186 .serial_number(777)
4187 .issuer_name(
4188 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4189 )
4190 .subject_name(
4191 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4192 )
4193 .public_key(subject_private_key.public_key())
4194 .add_extension(sia, critical=False)
4195 .not_valid_before(not_valid_before)
4196 .not_valid_after(not_valid_after)
4197 )
4198
4199 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
4200
4201 ext = cert.extensions.get_extension_for_oid(
4202 ExtensionOID.SUBJECT_INFORMATION_ACCESS
4203 )
4204 assert ext.value == sia
4205
4206 @pytest.mark.requires_backend_interface(interface=RSABackend)
4207 @pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01004208 def test_build_cert_with_ski(self, backend):
4209 issuer_private_key = RSA_KEY_2048.private_key(backend)
4210 subject_private_key = RSA_KEY_2048.private_key(backend)
4211
4212 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
4213 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
4214
4215 ski = x509.SubjectKeyIdentifier.from_public_key(
4216 subject_private_key.public_key()
4217 )
4218
Lucia Lic6ba99d2021-11-08 22:06:11 +08004219 builder = (
4220 x509.CertificateBuilder()
4221 .serial_number(777)
4222 .issuer_name(
4223 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4224 )
4225 .subject_name(
4226 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4227 )
4228 .public_key(subject_private_key.public_key())
4229 .add_extension(ski, critical=False)
4230 .not_valid_before(not_valid_before)
4231 .not_valid_after(not_valid_after)
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01004232 )
4233
4234 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
4235
4236 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05004237 ExtensionOID.SUBJECT_KEY_IDENTIFIER
Paul Kehrer2c9d6f12015-08-04 20:59:24 +01004238 )
4239 assert ext.value == ski
4240
Paul Kehrercbdc10b2015-08-05 21:24:59 +01004241 @pytest.mark.parametrize(
4242 "aki",
4243 [
4244 x509.AuthorityKeyIdentifier(
4245 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
4246 b"\xcbY",
4247 None,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004248 None,
Paul Kehrercbdc10b2015-08-05 21:24:59 +01004249 ),
4250 x509.AuthorityKeyIdentifier(
4251 b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
4252 b"\xcbY",
4253 [
4254 x509.DirectoryName(
Lucia Lic6ba99d2021-11-08 22:06:11 +08004255 x509.Name(
4256 [
4257 x509.NameAttribute(
4258 NameOID.ORGANIZATION_NAME, u"PyCA"
4259 ),
4260 x509.NameAttribute(
4261 NameOID.COMMON_NAME, u"cryptography CA"
4262 ),
4263 ]
4264 )
Paul Kehrercbdc10b2015-08-05 21:24:59 +01004265 )
4266 ],
Lucia Lic6ba99d2021-11-08 22:06:11 +08004267 333,
Paul Kehrercbdc10b2015-08-05 21:24:59 +01004268 ),
4269 x509.AuthorityKeyIdentifier(
4270 None,
4271 [
4272 x509.DirectoryName(
Lucia Lic6ba99d2021-11-08 22:06:11 +08004273 x509.Name(
4274 [
4275 x509.NameAttribute(
4276 NameOID.ORGANIZATION_NAME, u"PyCA"
4277 ),
4278 x509.NameAttribute(
4279 NameOID.COMMON_NAME, u"cryptography CA"
4280 ),
4281 ]
4282 )
Paul Kehrercbdc10b2015-08-05 21:24:59 +01004283 )
4284 ],
Lucia Lic6ba99d2021-11-08 22:06:11 +08004285 333,
Paul Kehrercbdc10b2015-08-05 21:24:59 +01004286 ),
Lucia Lic6ba99d2021-11-08 22:06:11 +08004287 ],
Paul Kehrercbdc10b2015-08-05 21:24:59 +01004288 )
4289 @pytest.mark.requires_backend_interface(interface=RSABackend)
4290 @pytest.mark.requires_backend_interface(interface=X509Backend)
4291 def test_build_cert_with_aki(self, aki, backend):
4292 issuer_private_key = RSA_KEY_2048.private_key(backend)
4293 subject_private_key = RSA_KEY_2048.private_key(backend)
4294
4295 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
4296 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
4297
Lucia Lic6ba99d2021-11-08 22:06:11 +08004298 builder = (
4299 x509.CertificateBuilder()
4300 .serial_number(777)
4301 .issuer_name(
4302 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4303 )
4304 .subject_name(
4305 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4306 )
4307 .public_key(subject_private_key.public_key())
4308 .add_extension(aki, critical=False)
4309 .not_valid_before(not_valid_before)
4310 .not_valid_after(not_valid_after)
Paul Kehrercbdc10b2015-08-05 21:24:59 +01004311 )
4312
4313 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
4314
4315 ext = cert.extensions.get_extension_for_oid(
Paul Kehrerd44e4132015-08-10 19:13:13 -05004316 ExtensionOID.AUTHORITY_KEY_IDENTIFIER
Paul Kehrercbdc10b2015-08-05 21:24:59 +01004317 )
4318 assert ext.value == aki
4319
Paul Kehrerf7d1b722015-08-06 18:49:45 +01004320 def test_ocsp_nocheck(self, backend):
4321 issuer_private_key = RSA_KEY_2048.private_key(backend)
4322 subject_private_key = RSA_KEY_2048.private_key(backend)
4323
4324 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
4325 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
4326
Lucia Lic6ba99d2021-11-08 22:06:11 +08004327 builder = (
4328 x509.CertificateBuilder()
4329 .serial_number(777)
4330 .issuer_name(
4331 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4332 )
4333 .subject_name(
4334 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
4335 )
4336 .public_key(subject_private_key.public_key())
4337 .add_extension(x509.OCSPNoCheck(), critical=False)
4338 .not_valid_before(not_valid_before)
4339 .not_valid_after(not_valid_after)
Paul Kehrerf7d1b722015-08-06 18:49:45 +01004340 )
4341
4342 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
4343
Lucia Lic6ba99d2021-11-08 22:06:11 +08004344 ext = cert.extensions.get_extension_for_oid(ExtensionOID.OCSP_NO_CHECK)
Paul Kehrerf7d1b722015-08-06 18:49:45 +01004345 assert isinstance(ext.value, x509.OCSPNoCheck)
4346
Alex Gaynord5f718c2015-07-05 11:19:38 -04004347
Paul Kehrerf1ef3512014-11-26 17:36:05 -10004348@pytest.mark.requires_backend_interface(interface=DSABackend)
4349@pytest.mark.requires_backend_interface(interface=X509Backend)
4350class TestDSACertificate(object):
4351 def test_load_dsa_cert(self, backend):
4352 cert = _load_cert(
4353 os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
4354 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004355 backend,
Paul Kehrerf1ef3512014-11-26 17:36:05 -10004356 )
Paul Kehrer8802a5b2015-02-13 12:06:57 -06004357 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
Paul Kehrerf1ef3512014-11-26 17:36:05 -10004358 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08004359 assert isinstance(public_key, dsa.DSAPublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04004360 num = public_key.public_numbers()
4361 assert num.y == int(
4362 "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94"
4363 "53b6656f13e543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2"
4364 "dea559f0b584c97a2b235b9b69b46bc6de1aed422a6f341832618bcaae2"
4365 "198aba388099dafb05ff0b5efecb3b0ae169a62e1c72022af50ae68af3b"
4366 "033c18e6eec1f7df4692c456ccafb79cc7e08da0a5786e9816ceda651d6"
4367 "1b4bb7b81c2783da97cea62df67af5e85991fdc13aff10fc60e06586386"
4368 "b96bb78d65750f542f86951e05a6d81baadbcd35a2e5cad4119923ae6a2"
4369 "002091a3d17017f93c52970113cdc119970b9074ca506eac91c3dd37632"
Lucia Lic6ba99d2021-11-08 22:06:11 +08004370 "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c",
4371 16,
Alex Gaynorece38722015-06-27 17:19:30 -04004372 )
4373 assert num.parameter_numbers.g == int(
4374 "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67"
4375 "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b"
4376 "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2"
4377 "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa"
4378 "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f"
4379 "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a"
4380 "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0"
4381 "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76"
Lucia Lic6ba99d2021-11-08 22:06:11 +08004382 "fa6247676a6d3ac945844a083509c6a1b436baca",
4383 16,
Alex Gaynorece38722015-06-27 17:19:30 -04004384 )
4385 assert num.parameter_numbers.p == int(
4386 "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3"
4387 "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330"
4388 "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e"
4389 "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a"
4390 "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4"
4391 "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2"
4392 "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93"
4393 "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d"
Lucia Lic6ba99d2021-11-08 22:06:11 +08004394 "833e36468f3907cfca788a3cb790f0341c8a31bf",
4395 16,
Alex Gaynorece38722015-06-27 17:19:30 -04004396 )
4397 assert num.parameter_numbers.q == int(
4398 "822ff5d234e073b901cf5941f58e1f538e71d40d", 16
4399 )
Paul Kehrerf1ef3512014-11-26 17:36:05 -10004400
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004401 def test_signature(self, backend):
4402 cert = _load_cert(
4403 os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
4404 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004405 backend,
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004406 )
4407 assert cert.signature == binascii.unhexlify(
4408 b"302c021425c4a84a936ab311ee017d3cbd9a3c650bb3ae4a02145d30c64b4326"
4409 b"86bdf925716b4ed059184396bcce"
4410 )
4411 r, s = decode_dss_signature(cert.signature)
4412 assert r == 215618264820276283222494627481362273536404860490
4413 assert s == 532023851299196869156027211159466197586787351758
4414
Paul Kehrerd2898052015-11-03 22:00:41 +09004415 def test_tbs_certificate_bytes(self, backend):
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004416 cert = _load_cert(
4417 os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
4418 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004419 backend,
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004420 )
Paul Kehrerd2898052015-11-03 22:00:41 +09004421 assert cert.tbs_certificate_bytes == binascii.unhexlify(
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004422 b"3082051aa003020102020900a37352e0b2142f86300906072a8648ce3804033"
4423 b"067310b3009060355040613025553310e300c06035504081305546578617331"
4424 b"0f300d0603550407130641757374696e3121301f060355040a1318496e74657"
4425 b"26e6574205769646769747320507479204c7464311430120603550403130b50"
4426 b"79434120445341204341301e170d3134313132373035313431375a170d31343"
4427 b"13232373035313431375a3067310b3009060355040613025553310e300c0603"
4428 b"55040813055465786173310f300d0603550407130641757374696e3121301f0"
4429 b"60355040a1318496e7465726e6574205769646769747320507479204c746431"
4430 b"1430120603550403130b50794341204453412043413082033a3082022d06072"
4431 b"a8648ce380401308202200282010100bfade6048e373cd4e48b677e878c8e5b"
4432 b"08c02102ae04eb2cb5c46a523a3af1c73d16b24f34a4964781ae7e50500e217"
4433 b"77754a670bd19a7420d633084e5556e33ca2c0e7d547ea5f46a07a01bf8669a"
4434 b"e3bdec042d9b2ae5e6ecf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736"
4435 b"857971444c25d0a33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e0"
4436 b"3e419fd4ca4e703313743d86caa885930f62ed5bf342d8165627681e9cc3244"
4437 b"ba72aa22148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56d"
4438 b"a93f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d8"
4439 b"33e36468f3907cfca788a3cb790f0341c8a31bf021500822ff5d234e073b901"
4440 b"cf5941f58e1f538e71d40d028201004b7ced71dc353965ecc10d441a9a06fc2"
4441 b"4943a32d66429dd5ef44d43e67d789d99770aec32c0415dc92970880872da45"
4442 b"fef8dd1e115a3e4801387ba6d755861f062fd3b6e9ea8e2641152339b828315"
4443 b"b1528ee6c7b79458d21f3db973f6fc303f9397174c2799dd2351282aa2d8842"
4444 b"c357a73495bbaac4932786414c55e60d73169f5761036fba29e9eebfb049f8a"
4445 b"3b1b7cee6f3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c"
4446 b"64130a1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425"
4447 b"c0b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76fa"
4448 b"6247676a6d3ac945844a083509c6a1b436baca0382010500028201004c08bfe"
4449 b"5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa9453b6656f13e"
4450 b"543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2dea559f0b584c97"
4451 b"a2b235b9b69b46bc6de1aed422a6f341832618bcaae2198aba388099dafb05f"
4452 b"f0b5efecb3b0ae169a62e1c72022af50ae68af3b033c18e6eec1f7df4692c45"
4453 b"6ccafb79cc7e08da0a5786e9816ceda651d61b4bb7b81c2783da97cea62df67"
4454 b"af5e85991fdc13aff10fc60e06586386b96bb78d65750f542f86951e05a6d81"
4455 b"baadbcd35a2e5cad4119923ae6a2002091a3d17017f93c52970113cdc119970"
4456 b"b9074ca506eac91c3dd376325df4af6b3911ef267d26623a5a1c5df4a6d13f1"
4457 b"ca381cc3081c9301d0603551d0e04160414a4fb887a13fcdeb303bbae9a1dec"
4458 b"a72f125a541b3081990603551d2304819130818e8014a4fb887a13fcdeb303b"
4459 b"bae9a1deca72f125a541ba16ba4693067310b3009060355040613025553310e"
4460 b"300c060355040813055465786173310f300d0603550407130641757374696e3"
4461 b"121301f060355040a1318496e7465726e657420576964676974732050747920"
4462 b"4c7464311430120603550403130b5079434120445341204341820900a37352e"
4463 b"0b2142f86300c0603551d13040530030101ff"
4464 )
Alex Gaynorb916fa92017-12-03 18:16:22 -06004465 cert.public_key().verify(
Lucia Lic6ba99d2021-11-08 22:06:11 +08004466 cert.signature,
4467 cert.tbs_certificate_bytes,
4468 cert.signature_hash_algorithm,
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004469 )
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004470
Paul Kehrerab209392015-12-01 14:50:31 -06004471
4472@pytest.mark.requires_backend_interface(interface=DSABackend)
4473@pytest.mark.requires_backend_interface(interface=X509Backend)
4474class TestDSACertificateRequest(object):
Paul Kehrer1effb6e2015-03-30 15:05:59 -05004475 @pytest.mark.parametrize(
4476 ("path", "loader_func"),
4477 [
4478 [
4479 os.path.join("x509", "requests", "dsa_sha1.pem"),
Lucia Lic6ba99d2021-11-08 22:06:11 +08004480 x509.load_pem_x509_csr,
Paul Kehrer1effb6e2015-03-30 15:05:59 -05004481 ],
4482 [
4483 os.path.join("x509", "requests", "dsa_sha1.der"),
Lucia Lic6ba99d2021-11-08 22:06:11 +08004484 x509.load_der_x509_csr,
Paul Kehrer1effb6e2015-03-30 15:05:59 -05004485 ],
Lucia Lic6ba99d2021-11-08 22:06:11 +08004486 ],
Paul Kehrer1effb6e2015-03-30 15:05:59 -05004487 )
4488 def test_load_dsa_request(self, path, loader_func, backend):
4489 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06004490 assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
4491 public_key = request.public_key()
4492 assert isinstance(public_key, dsa.DSAPublicKey)
4493 subject = request.subject
4494 assert isinstance(subject, x509.Name)
4495 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +08004496 x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io"),
4497 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
4498 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
4499 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Texas"),
4500 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Austin"),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06004501 ]
4502
Paul Kehrerab209392015-12-01 14:50:31 -06004503 def test_signature(self, backend):
4504 request = _load_cert(
4505 os.path.join("x509", "requests", "dsa_sha1.pem"),
4506 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004507 backend,
Paul Kehrerab209392015-12-01 14:50:31 -06004508 )
4509 assert request.signature == binascii.unhexlify(
4510 b"302c021461d58dc028d0110818a7d817d74235727c4acfdf0214097b52e198e"
4511 b"ce95de17273f0a924df23ce9d8188"
4512 )
4513
4514 def test_tbs_certrequest_bytes(self, backend):
4515 request = _load_cert(
4516 os.path.join("x509", "requests", "dsa_sha1.pem"),
4517 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004518 backend,
Paul Kehrerab209392015-12-01 14:50:31 -06004519 )
4520 assert request.tbs_certrequest_bytes == binascii.unhexlify(
4521 b"3082021802010030573118301606035504030c0f63727970746f677261706879"
4522 b"2e696f310d300b060355040a0c0450794341310b300906035504061302555331"
4523 b"0e300c06035504080c055465786173310f300d06035504070c0641757374696e"
4524 b"308201b63082012b06072a8648ce3804013082011e028181008d7fadbc09e284"
4525 b"aafa69154cea24177004909e519f8b35d685cde5b4ecdc9583e74d370a0f88ad"
4526 b"a98f026f27762fb3d5da7836f986dfcdb3589e5b925bea114defc03ef81dae30"
4527 b"c24bbc6df3d588e93427bba64203d4a5b1687b2b5e3b643d4c614976f89f95a3"
4528 b"8d3e4c89065fba97514c22c50adbbf289163a74b54859b35b7021500835de56b"
4529 b"d07cf7f82e2032fe78949aed117aa2ef0281801f717b5a07782fc2e4e68e311f"
4530 b"ea91a54edd36b86ac634d14f05a68a97eae9d2ef31fb1ef3de42c3d100df9ca6"
4531 b"4f5bdc2aec7bfdfb474cf831fea05853b5e059f2d24980a0ac463f1e818af352"
4532 b"3e3cb79a39d45fa92731897752842469cf8540b01491024eaafbce6018e8a1f4"
4533 b"658c343f4ba7c0b21e5376a21f4beb8491961e038184000281800713f07641f6"
4534 b"369bb5a9545274a2d4c01998367fb371bb9e13436363672ed68f82174c2de05c"
4535 b"8e839bc6de568dd50ba28d8d9d8719423aaec5557df10d773ab22d6d65cbb878"
4536 b"04a697bc8fd965b952f9f7e850edf13c8acdb5d753b6d10e59e0b5732e3c82ba"
4537 b"fa140342bc4a3bba16bd0681c8a6a2dbbb7efe6ce2b8463b170ba000"
4538 )
Alex Gaynorb916fa92017-12-03 18:16:22 -06004539 request.public_key().verify(
Paul Kehrerab209392015-12-01 14:50:31 -06004540 request.signature,
Alex Gaynorb916fa92017-12-03 18:16:22 -06004541 request.tbs_certrequest_bytes,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004542 request.signature_hash_algorithm,
Paul Kehrerab209392015-12-01 14:50:31 -06004543 )
Paul Kehrerab209392015-12-01 14:50:31 -06004544
Paul Kehrerf1ef3512014-11-26 17:36:05 -10004545
4546@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
4547@pytest.mark.requires_backend_interface(interface=X509Backend)
Paul Kehrere76cd272014-12-14 19:00:51 -06004548class TestECDSACertificate(object):
Paul Kehrerf1ef3512014-11-26 17:36:05 -10004549 def test_load_ecdsa_cert(self, backend):
4550 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrera693cfd2014-11-27 07:47:58 -10004551 cert = _load_cert(
Paul Kehrerf1ef3512014-11-26 17:36:05 -10004552 os.path.join("x509", "ecdsa_root.pem"),
Paul Kehrer41120322014-12-02 18:31:14 -10004553 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004554 backend,
Paul Kehrerf1ef3512014-11-26 17:36:05 -10004555 )
Paul Kehrer8802a5b2015-02-13 12:06:57 -06004556 assert isinstance(cert.signature_hash_algorithm, hashes.SHA384)
Paul Kehrerf1ef3512014-11-26 17:36:05 -10004557 public_key = cert.public_key()
Alex Gaynor32c57df2015-02-23 21:51:27 -08004558 assert isinstance(public_key, ec.EllipticCurvePublicKey)
Alex Gaynorece38722015-06-27 17:19:30 -04004559 num = public_key.public_numbers()
4560 assert num.x == int(
4561 "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f"
Lucia Lic6ba99d2021-11-08 22:06:11 +08004562 "6f0ccd00bba615b51467e9e2d9fee8e630c17",
4563 16,
Alex Gaynorece38722015-06-27 17:19:30 -04004564 )
4565 assert num.y == int(
4566 "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7"
Lucia Lic6ba99d2021-11-08 22:06:11 +08004567 "2deae88a7a16bb543ce67dc23ff031ca3e23e",
4568 16,
Alex Gaynorece38722015-06-27 17:19:30 -04004569 )
4570 assert isinstance(num.curve, ec.SECP384R1)
Paul Kehrer6c660a82014-12-12 11:50:44 -06004571
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004572 def test_signature(self, backend):
4573 cert = _load_cert(
4574 os.path.join("x509", "ecdsa_root.pem"),
4575 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004576 backend,
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004577 )
4578 assert cert.signature == binascii.unhexlify(
4579 b"3065023100adbcf26c3f124ad12d39c30a099773f488368c8827bbe6888d5085"
4580 b"a763f99e32de66930ff1ccb1098fdd6cabfa6b7fa0023039665bc2648db89e50"
4581 b"dca8d549a2edc7dcd1497f1701b8c8868f4e8c882ba89aa98ac5d100bdf854e2"
4582 b"9ae55b7cb32717"
4583 )
4584 r, s = decode_dss_signature(cert.signature)
4585 assert r == int(
4586 "adbcf26c3f124ad12d39c30a099773f488368c8827bbe6888d5085a763f99e32"
4587 "de66930ff1ccb1098fdd6cabfa6b7fa0",
Lucia Lic6ba99d2021-11-08 22:06:11 +08004588 16,
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004589 )
4590 assert s == int(
4591 "39665bc2648db89e50dca8d549a2edc7dcd1497f1701b8c8868f4e8c882ba89a"
4592 "a98ac5d100bdf854e29ae55b7cb32717",
Lucia Lic6ba99d2021-11-08 22:06:11 +08004593 16,
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004594 )
4595
Paul Kehrerd2898052015-11-03 22:00:41 +09004596 def test_tbs_certificate_bytes(self, backend):
Paul Kehreraa74abb2015-11-03 15:45:43 +09004597 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004598 cert = _load_cert(
4599 os.path.join("x509", "ecdsa_root.pem"),
4600 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004601 backend,
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004602 )
Paul Kehrerd2898052015-11-03 22:00:41 +09004603 assert cert.tbs_certificate_bytes == binascii.unhexlify(
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004604 b"308201c5a0030201020210055556bcf25ea43535c3a40fd5ab4572300a06082"
4605 b"a8648ce3d0403033061310b300906035504061302555331153013060355040a"
4606 b"130c446967694365727420496e6331193017060355040b13107777772e64696"
4607 b"769636572742e636f6d3120301e06035504031317446967694365727420476c"
4608 b"6f62616c20526f6f74204733301e170d3133303830313132303030305a170d3"
4609 b"338303131353132303030305a3061310b300906035504061302555331153013"
4610 b"060355040a130c446967694365727420496e6331193017060355040b1310777"
4611 b"7772e64696769636572742e636f6d3120301e06035504031317446967694365"
4612 b"727420476c6f62616c20526f6f742047333076301006072a8648ce3d0201060"
4613 b"52b8104002203620004dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34"
4614 b"eadec69bbcd095f6f0ccd00bba615b51467e9e2d9fee8e630c17ec0770f5cf8"
4615 b"42e40839ce83f416d3badd3a4145936789d0343ee10136c72deae88a7a16bb5"
4616 b"43ce67dc23ff031ca3e23ea3423040300f0603551d130101ff040530030101f"
4617 b"f300e0603551d0f0101ff040403020186301d0603551d0e04160414b3db48a4"
4618 b"f9a1c5d8ae3641cc1163696229bc4bc6"
4619 )
Alex Gaynorb916fa92017-12-03 18:16:22 -06004620 cert.public_key().verify(
Lucia Lic6ba99d2021-11-08 22:06:11 +08004621 cert.signature,
4622 cert.tbs_certificate_bytes,
4623 ec.ECDSA(cert.signature_hash_algorithm),
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004624 )
Paul Kehrerd91e7c12015-10-01 16:50:42 -05004625
Paul Kehrer6c660a82014-12-12 11:50:44 -06004626 def test_load_ecdsa_no_named_curve(self, backend):
4627 _skip_curve_unsupported(backend, ec.SECP256R1())
4628 cert = _load_cert(
4629 os.path.join("x509", "custom", "ec_no_named_curve.pem"),
4630 x509.load_pem_x509_certificate,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004631 backend,
Paul Kehrer6c660a82014-12-12 11:50:44 -06004632 )
4633 with pytest.raises(NotImplementedError):
4634 cert.public_key()
Paul Kehrer912d3fb2015-01-29 11:19:22 -06004635
Paul Kehrerab209392015-12-01 14:50:31 -06004636
4637@pytest.mark.requires_backend_interface(interface=X509Backend)
4638@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
4639class TestECDSACertificateRequest(object):
Paul Kehrer1effb6e2015-03-30 15:05:59 -05004640 @pytest.mark.parametrize(
4641 ("path", "loader_func"),
4642 [
4643 [
4644 os.path.join("x509", "requests", "ec_sha256.pem"),
Lucia Lic6ba99d2021-11-08 22:06:11 +08004645 x509.load_pem_x509_csr,
Paul Kehrer1effb6e2015-03-30 15:05:59 -05004646 ],
4647 [
4648 os.path.join("x509", "requests", "ec_sha256.der"),
Lucia Lic6ba99d2021-11-08 22:06:11 +08004649 x509.load_der_x509_csr,
Paul Kehrer1effb6e2015-03-30 15:05:59 -05004650 ],
Lucia Lic6ba99d2021-11-08 22:06:11 +08004651 ],
Paul Kehrer1effb6e2015-03-30 15:05:59 -05004652 )
4653 def test_load_ecdsa_certificate_request(self, path, loader_func, backend):
Paul Kehrerdc480ad2015-02-23 12:14:54 -06004654 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrer1effb6e2015-03-30 15:05:59 -05004655 request = _load_cert(path, loader_func, backend)
Paul Kehrerdc480ad2015-02-23 12:14:54 -06004656 assert isinstance(request.signature_hash_algorithm, hashes.SHA256)
4657 public_key = request.public_key()
4658 assert isinstance(public_key, ec.EllipticCurvePublicKey)
4659 subject = request.subject
4660 assert isinstance(subject, x509.Name)
4661 assert list(subject) == [
Lucia Lic6ba99d2021-11-08 22:06:11 +08004662 x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io"),
4663 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
4664 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
4665 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"Texas"),
4666 x509.NameAttribute(NameOID.LOCALITY_NAME, u"Austin"),
Paul Kehrerdc480ad2015-02-23 12:14:54 -06004667 ]
4668
Paul Kehrerab209392015-12-01 14:50:31 -06004669 def test_signature(self, backend):
Paul Kehrerf3893732015-12-03 22:53:46 -06004670 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrerab209392015-12-01 14:50:31 -06004671 request = _load_cert(
4672 os.path.join("x509", "requests", "ec_sha256.pem"),
4673 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004674 backend,
Paul Kehrerab209392015-12-01 14:50:31 -06004675 )
4676 assert request.signature == binascii.unhexlify(
4677 b"306502302c1a9f7de8c1787332d2307a886b476a59f172b9b0e250262f3238b1"
4678 b"b45ee112bb6eb35b0fb56a123b9296eb212dffc302310094cf440c95c52827d5"
4679 b"56ae6d76500e3008255d47c29f7ee782ed7558e51bfd76aa45df6d999ed5c463"
4680 b"347fe2382d1751"
4681 )
4682
4683 def test_tbs_certrequest_bytes(self, backend):
Paul Kehrerf3893732015-12-03 22:53:46 -06004684 _skip_curve_unsupported(backend, ec.SECP384R1())
Paul Kehrerab209392015-12-01 14:50:31 -06004685 request = _load_cert(
4686 os.path.join("x509", "requests", "ec_sha256.pem"),
4687 x509.load_pem_x509_csr,
Lucia Lic6ba99d2021-11-08 22:06:11 +08004688 backend,
Paul Kehrerab209392015-12-01 14:50:31 -06004689 )
4690 assert request.tbs_certrequest_bytes == binascii.unhexlify(
4691 b"3081d602010030573118301606035504030c0f63727970746f6772617068792"
4692 b"e696f310d300b060355040a0c0450794341310b300906035504061302555331"
4693 b"0e300c06035504080c055465786173310f300d06035504070c0641757374696"
4694 b"e3076301006072a8648ce3d020106052b8104002203620004de19b514c0b3c3"
4695 b"ae9b398ea3e26b5e816bdcf9102cad8f12fe02f9e4c9248724b39297ed7582e"
4696 b"04d8b32a551038d09086803a6d3fb91a1a1167ec02158b00efad39c9396462f"
4697 b"accff0ffaf7155812909d3726bd59fde001cff4bb9b2f5af8cbaa000"
4698 )
Alex Gaynorb916fa92017-12-03 18:16:22 -06004699 request.public_key().verify(
Lucia Lic6ba99d2021-11-08 22:06:11 +08004700 request.signature,
4701 request.tbs_certrequest_bytes,
4702 ec.ECDSA(request.signature_hash_algorithm),
Paul Kehrerab209392015-12-01 14:50:31 -06004703 )
Paul Kehrerab209392015-12-01 14:50:31 -06004704
Paul Kehrer912d3fb2015-01-29 11:19:22 -06004705
Alex Gaynor96605fc2015-10-10 09:03:07 -04004706@pytest.mark.requires_backend_interface(interface=X509Backend)
4707class TestOtherCertificate(object):
4708 def test_unsupported_subject_public_key_info(self, backend):
4709 cert = _load_cert(
4710 os.path.join(
4711 "x509", "custom", "unsupported_subject_public_key_info.pem"
4712 ),
4713 x509.load_pem_x509_certificate,
4714 backend,
4715 )
4716
4717 with pytest.raises(ValueError):
4718 cert.public_key()
4719
Joshua Crowgey25f2b4e2018-04-03 16:24:06 -07004720 def test_bad_time_in_validity(self, backend):
4721 cert = _load_cert(
Lucia Lic6ba99d2021-11-08 22:06:11 +08004722 os.path.join("x509", "badasn1time.pem"),
Joshua Crowgey25f2b4e2018-04-03 16:24:06 -07004723 x509.load_pem_x509_certificate,
4724 backend,
4725 )
4726
Lucia Lic6ba99d2021-11-08 22:06:11 +08004727 with pytest.raises(ValueError, match="19020701025736Z"):
Joshua Crowgey25f2b4e2018-04-03 16:24:06 -07004728 cert.not_valid_after
4729
Alex Gaynor96605fc2015-10-10 09:03:07 -04004730
Paul Kehrer806bfb22015-02-02 17:05:24 -06004731class TestNameAttribute(object):
Paul Kehrer4662d442017-12-01 10:48:56 +08004732 EXPECTED_TYPES = [
4733 (NameOID.COMMON_NAME, _ASN1Type.UTF8String),
4734 (NameOID.COUNTRY_NAME, _ASN1Type.PrintableString),
4735 (NameOID.LOCALITY_NAME, _ASN1Type.UTF8String),
4736 (NameOID.STATE_OR_PROVINCE_NAME, _ASN1Type.UTF8String),
4737 (NameOID.STREET_ADDRESS, _ASN1Type.UTF8String),
4738 (NameOID.ORGANIZATION_NAME, _ASN1Type.UTF8String),
4739 (NameOID.ORGANIZATIONAL_UNIT_NAME, _ASN1Type.UTF8String),
4740 (NameOID.SERIAL_NUMBER, _ASN1Type.PrintableString),
4741 (NameOID.SURNAME, _ASN1Type.UTF8String),
4742 (NameOID.GIVEN_NAME, _ASN1Type.UTF8String),
4743 (NameOID.TITLE, _ASN1Type.UTF8String),
4744 (NameOID.GENERATION_QUALIFIER, _ASN1Type.UTF8String),
4745 (NameOID.X500_UNIQUE_IDENTIFIER, _ASN1Type.UTF8String),
4746 (NameOID.DN_QUALIFIER, _ASN1Type.PrintableString),
4747 (NameOID.PSEUDONYM, _ASN1Type.UTF8String),
4748 (NameOID.USER_ID, _ASN1Type.UTF8String),
4749 (NameOID.DOMAIN_COMPONENT, _ASN1Type.IA5String),
4750 (NameOID.EMAIL_ADDRESS, _ASN1Type.IA5String),
4751 (NameOID.JURISDICTION_COUNTRY_NAME, _ASN1Type.PrintableString),
4752 (NameOID.JURISDICTION_LOCALITY_NAME, _ASN1Type.UTF8String),
Lucia Lic6ba99d2021-11-08 22:06:11 +08004753 (NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME, _ASN1Type.UTF8String),
Paul Kehrer4662d442017-12-01 10:48:56 +08004754 (NameOID.BUSINESS_CATEGORY, _ASN1Type.UTF8String),
4755 (NameOID.POSTAL_ADDRESS, _ASN1Type.UTF8String),
4756 (NameOID.POSTAL_CODE, _ASN1Type.UTF8String),
4757 ]
4758
4759 def test_default_types(self):
4760 for oid, asn1_type in TestNameAttribute.EXPECTED_TYPES:
4761 na = x509.NameAttribute(oid, u"US")
4762 assert na._type == asn1_type
4763
4764 def test_alternate_type(self):
4765 na2 = x509.NameAttribute(
4766 NameOID.COMMON_NAME, u"common", _ASN1Type.IA5String
4767 )
4768 assert na2._type == _ASN1Type.IA5String
4769
Alex Gaynora56ff412015-02-10 17:26:32 -05004770 def test_init_bad_oid(self):
4771 with pytest.raises(TypeError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004772 x509.NameAttribute(None, u"value")
Alex Gaynora56ff412015-02-10 17:26:32 -05004773
Ian Cordasco7618fbe2015-06-16 19:12:17 -05004774 def test_init_bad_value(self):
4775 with pytest.raises(TypeError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004776 x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), b"bytes")
4777
4778 def test_init_none_value(self):
4779 with pytest.raises(TypeError):
4780 x509.NameAttribute(NameOID.ORGANIZATION_NAME, None)
Ian Cordasco7618fbe2015-06-16 19:12:17 -05004781
Paul Kehrer641149c2016-03-06 19:10:56 -04304782 def test_init_bad_country_code_value(self):
4783 with pytest.raises(ValueError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004784 x509.NameAttribute(NameOID.COUNTRY_NAME, u"United States")
Paul Kehrer641149c2016-03-06 19:10:56 -04304785
4786 # unicode string of length 2, but > 2 bytes
4787 with pytest.raises(ValueError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004788 x509.NameAttribute(NameOID.COUNTRY_NAME, u"\U0001F37A\U0001F37A")
Paul Kehrer312ed092017-06-19 01:00:42 -10004789
Paul Kehrer72c92f52017-09-26 10:23:24 +08004790 def test_invalid_type(self):
4791 with pytest.raises(TypeError):
4792 x509.NameAttribute(NameOID.COMMON_NAME, u"common", "notanenum")
4793
Paul Kehrer912d3fb2015-01-29 11:19:22 -06004794 def test_eq(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06004795 assert x509.NameAttribute(
Lucia Lic6ba99d2021-11-08 22:06:11 +08004796 x509.ObjectIdentifier("2.999.1"), u"value"
4797 ) == x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value")
Paul Kehrer912d3fb2015-01-29 11:19:22 -06004798
4799 def test_ne(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06004800 assert x509.NameAttribute(
Lucia Lic6ba99d2021-11-08 22:06:11 +08004801 x509.ObjectIdentifier("2.5.4.3"), u"value"
4802 ) != x509.NameAttribute(x509.ObjectIdentifier("2.5.4.5"), u"value")
Paul Kehrer806bfb22015-02-02 17:05:24 -06004803 assert x509.NameAttribute(
Lucia Lic6ba99d2021-11-08 22:06:11 +08004804 x509.ObjectIdentifier("2.999.1"), u"value"
4805 ) != x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value2")
4806 assert (
4807 x509.NameAttribute(x509.ObjectIdentifier("2.999.2"), u"value")
4808 != object()
Paul Kehrer912d3fb2015-01-29 11:19:22 -06004809 )
Paul Kehrer912d3fb2015-01-29 11:19:22 -06004810
Paul Kehrera498be82015-02-12 15:00:56 -06004811 def test_repr(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004812 na = x509.NameAttribute(x509.ObjectIdentifier("2.5.4.3"), u"value")
Eric Brown50bad372018-05-14 20:47:57 -07004813 if not six.PY2:
Ian Cordascoa908d692015-06-16 21:35:24 -05004814 assert repr(na) == (
4815 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
4816 "nName)>, value='value')>"
4817 )
4818 else:
4819 assert repr(na) == (
4820 "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
4821 "nName)>, value=u'value')>"
4822 )
Paul Kehrera498be82015-02-12 15:00:56 -06004823
Marti Raudseppc3d38b52018-12-08 03:26:07 +02004824 def test_distinugished_name(self):
4825 # Escaping
4826 na = x509.NameAttribute(NameOID.COMMON_NAME, u'James "Jim" Smith, III')
Lucia Lic6ba99d2021-11-08 22:06:11 +08004827 assert na.rfc4514_string() == r"CN=James \"Jim\" Smith\, III"
4828 na = x509.NameAttribute(NameOID.USER_ID, u"# escape+,;\0this ")
4829 assert na.rfc4514_string() == r"UID=\# escape\+\,\;\00this\ "
Marti Raudseppc3d38b52018-12-08 03:26:07 +02004830
4831 # Nonstandard attribute OID
Lucia Lic6ba99d2021-11-08 22:06:11 +08004832 na = x509.NameAttribute(NameOID.EMAIL_ADDRESS, u"somebody@example.com")
4833 assert (
4834 na.rfc4514_string() == "1.2.840.113549.1.9.1=somebody@example.com"
4835 )
4836
4837 def test_empty_value(self):
4838 na = x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"")
4839 assert na.rfc4514_string() == r"ST="
Marti Raudseppc3d38b52018-12-08 03:26:07 +02004840
Paul Kehrer912d3fb2015-01-29 11:19:22 -06004841
Fraser Tweedale02467dd2016-11-07 15:54:04 +10004842class TestRelativeDistinguishedName(object):
4843 def test_init_empty(self):
4844 with pytest.raises(ValueError):
4845 x509.RelativeDistinguishedName([])
4846
4847 def test_init_not_nameattribute(self):
4848 with pytest.raises(TypeError):
4849 x509.RelativeDistinguishedName(["not-a-NameAttribute"])
4850
4851 def test_init_duplicate_attribute(self):
Marti Raudsepp9e1873a2018-07-09 16:11:18 +03004852 with pytest.raises(ValueError):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004853 x509.RelativeDistinguishedName(
4854 [
4855 x509.NameAttribute(
4856 x509.ObjectIdentifier("2.999.1"), u"val1"
4857 ),
4858 x509.NameAttribute(
4859 x509.ObjectIdentifier("2.999.1"), u"val1"
4860 ),
4861 ]
4862 )
Fraser Tweedale02467dd2016-11-07 15:54:04 +10004863
4864 def test_hash(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004865 rdn1 = x509.RelativeDistinguishedName(
4866 [
4867 x509.NameAttribute(
4868 x509.ObjectIdentifier("2.999.1"), u"value1"
4869 ),
4870 x509.NameAttribute(
4871 x509.ObjectIdentifier("2.999.2"), u"value2"
4872 ),
4873 ]
4874 )
4875 rdn2 = x509.RelativeDistinguishedName(
4876 [
4877 x509.NameAttribute(
4878 x509.ObjectIdentifier("2.999.2"), u"value2"
4879 ),
4880 x509.NameAttribute(
4881 x509.ObjectIdentifier("2.999.1"), u"value1"
4882 ),
4883 ]
4884 )
4885 rdn3 = x509.RelativeDistinguishedName(
4886 [
4887 x509.NameAttribute(
4888 x509.ObjectIdentifier("2.999.1"), u"value1"
4889 ),
4890 x509.NameAttribute(
4891 x509.ObjectIdentifier("2.999.2"), u"value3"
4892 ),
4893 ]
4894 )
Fraser Tweedale02467dd2016-11-07 15:54:04 +10004895 assert hash(rdn1) == hash(rdn2)
4896 assert hash(rdn1) != hash(rdn3)
4897
4898 def test_eq(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004899 rdn1 = x509.RelativeDistinguishedName(
4900 [
4901 x509.NameAttribute(
4902 x509.ObjectIdentifier("2.999.1"), u"value1"
4903 ),
4904 x509.NameAttribute(
4905 x509.ObjectIdentifier("2.999.2"), u"value2"
4906 ),
4907 ]
4908 )
4909 rdn2 = x509.RelativeDistinguishedName(
4910 [
4911 x509.NameAttribute(
4912 x509.ObjectIdentifier("2.999.2"), u"value2"
4913 ),
4914 x509.NameAttribute(
4915 x509.ObjectIdentifier("2.999.1"), u"value1"
4916 ),
4917 ]
4918 )
Fraser Tweedale02467dd2016-11-07 15:54:04 +10004919 assert rdn1 == rdn2
4920
4921 def test_ne(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004922 rdn1 = x509.RelativeDistinguishedName(
4923 [
4924 x509.NameAttribute(
4925 x509.ObjectIdentifier("2.999.1"), u"value1"
4926 ),
4927 x509.NameAttribute(
4928 x509.ObjectIdentifier("2.999.2"), u"value2"
4929 ),
4930 ]
4931 )
4932 rdn2 = x509.RelativeDistinguishedName(
4933 [
4934 x509.NameAttribute(
4935 x509.ObjectIdentifier("2.999.1"), u"value1"
4936 ),
4937 x509.NameAttribute(
4938 x509.ObjectIdentifier("2.999.2"), u"value3"
4939 ),
4940 ]
4941 )
Fraser Tweedale02467dd2016-11-07 15:54:04 +10004942 assert rdn1 != rdn2
4943 assert rdn1 != object()
4944
4945 def test_iter_input(self):
Marti Raudsepp9e1873a2018-07-09 16:11:18 +03004946 # Order must be preserved too
Fraser Tweedale02467dd2016-11-07 15:54:04 +10004947 attrs = [
Lucia Lic6ba99d2021-11-08 22:06:11 +08004948 x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1"),
4949 x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value2"),
4950 x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value3"),
Fraser Tweedale02467dd2016-11-07 15:54:04 +10004951 ]
4952 rdn = x509.RelativeDistinguishedName(iter(attrs))
4953 assert list(rdn) == attrs
4954 assert list(rdn) == attrs
4955
4956 def test_get_attributes_for_oid(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004957 oid = x509.ObjectIdentifier("2.999.1")
4958 attr = x509.NameAttribute(oid, u"value1")
Fraser Tweedale02467dd2016-11-07 15:54:04 +10004959 rdn = x509.RelativeDistinguishedName([attr])
4960 assert rdn.get_attributes_for_oid(oid) == [attr]
Lucia Lic6ba99d2021-11-08 22:06:11 +08004961 assert rdn.get_attributes_for_oid(x509.ObjectIdentifier("1.2.3")) == []
Fraser Tweedale02467dd2016-11-07 15:54:04 +10004962
4963
Paul Kehrer912d3fb2015-01-29 11:19:22 -06004964class TestObjectIdentifier(object):
4965 def test_eq(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004966 oid1 = x509.ObjectIdentifier("2.999.1")
4967 oid2 = x509.ObjectIdentifier("2.999.1")
Paul Kehrer912d3fb2015-01-29 11:19:22 -06004968 assert oid1 == oid2
4969
4970 def test_ne(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08004971 oid1 = x509.ObjectIdentifier("2.999.1")
4972 assert oid1 != x509.ObjectIdentifier("2.999.2")
Paul Kehrer912d3fb2015-01-29 11:19:22 -06004973 assert oid1 != object()
4974
4975 def test_repr(self):
Paul Kehrer806bfb22015-02-02 17:05:24 -06004976 oid = x509.ObjectIdentifier("2.5.4.3")
4977 assert repr(oid) == "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>"
Nick Bastin6721fb82015-12-14 12:26:24 -08004978 oid = x509.ObjectIdentifier("2.999.1")
4979 assert repr(oid) == "<ObjectIdentifier(oid=2.999.1, name=Unknown OID)>"
Paul Kehrer719d5362015-01-01 20:03:52 -06004980
Brendan McCollam1b3b3ce2015-08-25 10:55:44 -05004981 def test_name_property(self):
4982 oid = x509.ObjectIdentifier("2.5.4.3")
Lucia Lic6ba99d2021-11-08 22:06:11 +08004983 assert oid._name == "commonName"
Nick Bastin6721fb82015-12-14 12:26:24 -08004984 oid = x509.ObjectIdentifier("2.999.1")
Lucia Lic6ba99d2021-11-08 22:06:11 +08004985 assert oid._name == "Unknown OID"
Brendan McCollam1b3b3ce2015-08-25 10:55:44 -05004986
Nick Bastinf9c30b32015-12-17 05:28:49 -08004987 def test_too_short(self):
4988 with pytest.raises(ValueError):
4989 x509.ObjectIdentifier("1")
4990
Nick Bastin6721fb82015-12-14 12:26:24 -08004991 def test_invalid_input(self):
4992 with pytest.raises(ValueError):
4993 x509.ObjectIdentifier("notavalidform")
4994
4995 def test_invalid_node1(self):
4996 with pytest.raises(ValueError):
4997 x509.ObjectIdentifier("7.1.37")
4998
4999 def test_invalid_node2(self):
5000 with pytest.raises(ValueError):
5001 x509.ObjectIdentifier("1.50.200")
5002
5003 def test_valid(self):
5004 x509.ObjectIdentifier("0.35.200")
5005 x509.ObjectIdentifier("1.39.999")
5006 x509.ObjectIdentifier("2.5.29.3")
5007 x509.ObjectIdentifier("2.999.37.5.22.8")
5008 x509.ObjectIdentifier("2.25.305821105408246119474742976030998643995")
5009
Paul Kehrer719d5362015-01-01 20:03:52 -06005010
5011class TestName(object):
5012 def test_eq(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08005013 ava1 = x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1")
5014 ava2 = x509.NameAttribute(x509.ObjectIdentifier("2.999.2"), u"value2")
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10005015 name1 = x509.Name([ava1, ava2])
Lucia Lic6ba99d2021-11-08 22:06:11 +08005016 name2 = x509.Name(
5017 [
5018 x509.RelativeDistinguishedName([ava1]),
5019 x509.RelativeDistinguishedName([ava2]),
5020 ]
5021 )
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10005022 name3 = x509.Name([x509.RelativeDistinguishedName([ava1, ava2])])
5023 name4 = x509.Name([x509.RelativeDistinguishedName([ava2, ava1])])
Paul Kehrer719d5362015-01-01 20:03:52 -06005024 assert name1 == name2
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10005025 assert name3 == name4
Paul Kehrer719d5362015-01-01 20:03:52 -06005026
5027 def test_ne(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08005028 ava1 = x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1")
5029 ava2 = x509.NameAttribute(x509.ObjectIdentifier("2.999.2"), u"value2")
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10005030 name1 = x509.Name([ava1, ava2])
5031 name2 = x509.Name([ava2, ava1])
5032 name3 = x509.Name([x509.RelativeDistinguishedName([ava1, ava2])])
Paul Kehrer719d5362015-01-01 20:03:52 -06005033 assert name1 != name2
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10005034 assert name1 != name3
Paul Kehrer719d5362015-01-01 20:03:52 -06005035 assert name1 != object()
Paul Kehrer1fb35c92015-04-11 15:42:54 -04005036
Alex Gaynor1aecec72015-10-24 19:26:02 -04005037 def test_hash(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08005038 ava1 = x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1")
5039 ava2 = x509.NameAttribute(x509.ObjectIdentifier("2.999.2"), u"value2")
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10005040 name1 = x509.Name([ava1, ava2])
Lucia Lic6ba99d2021-11-08 22:06:11 +08005041 name2 = x509.Name(
5042 [
5043 x509.RelativeDistinguishedName([ava1]),
5044 x509.RelativeDistinguishedName([ava2]),
5045 ]
5046 )
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10005047 name3 = x509.Name([ava2, ava1])
5048 name4 = x509.Name([x509.RelativeDistinguishedName([ava1, ava2])])
5049 name5 = x509.Name([x509.RelativeDistinguishedName([ava2, ava1])])
Alex Gaynor9442fa92015-10-24 18:32:10 -04005050 assert hash(name1) == hash(name2)
5051 assert hash(name1) != hash(name3)
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10005052 assert hash(name1) != hash(name4)
5053 assert hash(name4) == hash(name5)
Alex Gaynor9442fa92015-10-24 18:32:10 -04005054
Marti40f19992016-08-26 04:26:31 +03005055 def test_iter_input(self):
5056 attrs = [
Lucia Lic6ba99d2021-11-08 22:06:11 +08005057 x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1")
Marti40f19992016-08-26 04:26:31 +03005058 ]
5059 name = x509.Name(iter(attrs))
5060 assert list(name) == attrs
5061 assert list(name) == attrs
5062
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10005063 def test_rdns(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08005064 rdn1 = x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1")
5065 rdn2 = x509.NameAttribute(x509.ObjectIdentifier("2.999.2"), u"value2")
Fraser Tweedale01ee6f52016-11-12 01:28:56 +10005066 name1 = x509.Name([rdn1, rdn2])
5067 assert name1.rdns == [
5068 x509.RelativeDistinguishedName([rdn1]),
5069 x509.RelativeDistinguishedName([rdn2]),
5070 ]
5071 name2 = x509.Name([x509.RelativeDistinguishedName([rdn1, rdn2])])
5072 assert name2.rdns == [x509.RelativeDistinguishedName([rdn1, rdn2])]
5073
Lucia Lic6ba99d2021-11-08 22:06:11 +08005074 @pytest.mark.parametrize(
5075 ("common_name", "org_name", "expected_repr"),
5076 [
5077 (
5078 u"cryptography.io",
5079 u"PyCA",
5080 "<Name(CN=cryptography.io,O=PyCA)>",
5081 ),
5082 (
5083 u"Certificación",
5084 u"Certificación",
5085 "<Name(CN=Certificación,O=Certificación)>",
5086 ),
5087 ],
5088 )
5089 def test_repr(self, common_name, org_name, expected_repr):
5090 name = x509.Name(
5091 [
5092 x509.NameAttribute(NameOID.COMMON_NAME, common_name),
5093 x509.NameAttribute(NameOID.ORGANIZATION_NAME, org_name),
5094 ]
5095 )
Paul Kehrer1fb35c92015-04-11 15:42:54 -04005096
Lucia Lic6ba99d2021-11-08 22:06:11 +08005097 assert repr(name) == expected_repr
Marti Raudseppc3d38b52018-12-08 03:26:07 +02005098
5099 def test_rfc4514_string(self):
Lucia Lic6ba99d2021-11-08 22:06:11 +08005100 n = x509.Name(
5101 [
5102 x509.RelativeDistinguishedName(
5103 [x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u"net")]
5104 ),
5105 x509.RelativeDistinguishedName(
5106 [x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u"example")]
5107 ),
5108 x509.RelativeDistinguishedName(
5109 [
5110 x509.NameAttribute(
5111 NameOID.ORGANIZATIONAL_UNIT_NAME, u"Sales"
5112 ),
5113 x509.NameAttribute(NameOID.COMMON_NAME, u"J. Smith"),
5114 ]
5115 ),
5116 ]
5117 )
5118 assert n.rfc4514_string() == "OU=Sales+CN=J. Smith,DC=example,DC=net"
5119
5120 def test_rfc4514_string_empty_values(self):
5121 n = x509.Name(
5122 [
5123 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
5124 x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u""),
5125 x509.NameAttribute(NameOID.LOCALITY_NAME, u""),
5126 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
5127 x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io"),
5128 ]
5129 )
5130 assert n.rfc4514_string() == "CN=cryptography.io,O=PyCA,L=,ST=,C=US"
Marti40f19992016-08-26 04:26:31 +03005131
5132 def test_not_nameattribute(self):
5133 with pytest.raises(TypeError):
5134 x509.Name(["not-a-NameAttribute"])
Paul Kehrer8b89bcc2016-09-03 11:31:43 -05005135
Paul Kehrer3a15b032016-11-13 14:30:11 -08005136 @pytest.mark.requires_backend_interface(interface=X509Backend)
5137 def test_bytes(self, backend):
Lucia Lic6ba99d2021-11-08 22:06:11 +08005138 name = x509.Name(
5139 [
5140 x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io"),
5141 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
5142 ]
5143 )
Paul Kehrer3a15b032016-11-13 14:30:11 -08005144 assert name.public_bytes(backend) == binascii.unhexlify(
5145 b"30293118301606035504030c0f63727970746f6772617068792e696f310d300"
5146 b"b060355040a0c0450794341"
5147 )
5148
Paul Kehrer20ae2c82018-07-10 04:55:02 +05305149 @pytest.mark.requires_backend_interface(interface=X509Backend)
5150 def test_bmpstring_bytes(self, backend):
5151 # For this test we need an odd length string. BMPString is UCS-2
5152 # encoded so it will always be even length and OpenSSL will error if
5153 # you pass an odd length string without encoding it properly first.
Lucia Lic6ba99d2021-11-08 22:06:11 +08005154 name = x509.Name(
5155 [
5156 x509.NameAttribute(
5157 NameOID.COMMON_NAME,
5158 u"cryptography.io",
5159 _ASN1Type.BMPString,
5160 ),
5161 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
5162 ]
5163 )
Paul Kehrer20ae2c82018-07-10 04:55:02 +05305164 assert name.public_bytes(backend) == binascii.unhexlify(
5165 b"30383127302506035504031e1e00630072007900700074006f00670072006100"
5166 b"7000680079002e0069006f310d300b060355040a0c0450794341"
5167 )
5168
Lucia Lic6ba99d2021-11-08 22:06:11 +08005169 @pytest.mark.requires_backend_interface(interface=X509Backend)
5170 def test_universalstring_bytes(self, backend):
5171 # UniversalString is UCS-4
5172 name = x509.Name(
5173 [
5174 x509.NameAttribute(
5175 NameOID.COMMON_NAME,
5176 u"cryptography.io",
5177 _ASN1Type.UniversalString,
5178 ),
5179 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"),
5180 ]
5181 )
5182 assert name.public_bytes(backend) == binascii.unhexlify(
5183 b"30563145304306035504031c3c00000063000000720000007900000070000000"
5184 b"740000006f000000670000007200000061000000700000006800000079000000"
5185 b"2e000000690000006f310d300b060355040a0c0450794341"
5186 )
5187
5188
5189@pytest.mark.supported(
5190 only_if=lambda backend: backend.ed25519_supported(),
5191 skip_message="Requires OpenSSL with Ed25519 support",
5192)
5193@pytest.mark.requires_backend_interface(interface=X509Backend)
5194class TestEd25519Certificate(object):
5195 def test_load_pem_cert(self, backend):
5196 cert = _load_cert(
5197 os.path.join("x509", "ed25519", "root-ed25519.pem"),
5198 x509.load_pem_x509_certificate,
5199 backend,
5200 )
5201 # self-signed, so this will work
5202 cert.public_key().verify(cert.signature, cert.tbs_certificate_bytes)
5203 assert isinstance(cert, x509.Certificate)
5204 assert cert.serial_number == 9579446940964433301
5205 assert cert.signature_hash_algorithm is None
5206 assert cert.signature_algorithm_oid == SignatureAlgorithmOID.ED25519
5207
5208 def test_deepcopy(self, backend):
5209 cert = _load_cert(
5210 os.path.join("x509", "ed25519", "root-ed25519.pem"),
5211 x509.load_pem_x509_certificate,
5212 backend,
5213 )
5214 assert copy.deepcopy(cert) is cert
5215
5216
5217@pytest.mark.supported(
5218 only_if=lambda backend: backend.ed448_supported(),
5219 skip_message="Requires OpenSSL with Ed448 support",
5220)
5221@pytest.mark.requires_backend_interface(interface=X509Backend)
5222class TestEd448Certificate(object):
5223 def test_load_pem_cert(self, backend):
5224 cert = _load_cert(
5225 os.path.join("x509", "ed448", "root-ed448.pem"),
5226 x509.load_pem_x509_certificate,
5227 backend,
5228 )
5229 # self-signed, so this will work
5230 cert.public_key().verify(cert.signature, cert.tbs_certificate_bytes)
5231 assert isinstance(cert, x509.Certificate)
5232 assert cert.serial_number == 448
5233 assert cert.signature_hash_algorithm is None
5234 assert cert.signature_algorithm_oid == SignatureAlgorithmOID.ED448
5235
5236
5237@pytest.mark.requires_backend_interface(interface=X509Backend)
5238class TestSignatureRejection(object):
5239 """Test if signing rejects DH keys properly."""
5240
5241 def load_key(self, backend):
5242 vector = load_vectors_from_file(
5243 os.path.join("asymmetric", "DH", "rfc3526.txt"),
5244 load_nist_vectors,
5245 )[1]
5246 p = int_from_bytes(binascii.unhexlify(vector["p"]), "big")
5247 params = dh.DHParameterNumbers(p, int(vector["g"]))
5248 param = params.parameters(backend)
5249 return param.generate_private_key()
5250
5251 def test_crt_signing_check(self, backend):
5252 issuer_private_key = self.load_key(backend)
5253 public_key = RSA_KEY_2048.private_key(backend).public_key()
5254 not_valid_before = datetime.datetime(2020, 1, 1, 1, 1)
5255 not_valid_after = datetime.datetime(2050, 12, 31, 8, 30)
5256 builder = (
5257 x509.CertificateBuilder()
5258 .serial_number(777)
5259 .issuer_name(
5260 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
5261 )
5262 .subject_name(
5263 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
5264 )
5265 .public_key(public_key)
5266 .not_valid_before(not_valid_before)
5267 .not_valid_after(not_valid_after)
5268 )
5269
5270 with pytest.raises(TypeError):
5271 builder.sign(issuer_private_key, hashes.SHA256(), backend)
5272
5273 def test_csr_signing_check(self, backend):
5274 private_key = self.load_key(backend)
5275 builder = x509.CertificateSigningRequestBuilder().subject_name(
5276 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")])
5277 )
5278
5279 with pytest.raises(TypeError):
5280 builder.sign(private_key, hashes.SHA256(), backend)
5281
5282 def test_crl_signing_check(self, backend):
5283 private_key = self.load_key(backend)
5284 last_time = datetime.datetime.utcnow().replace(microsecond=0)
5285 next_time = last_time
5286 builder = (
5287 x509.CertificateRevocationListBuilder()
5288 .issuer_name(
5289 x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, u"CA")])
5290 )
5291 .last_update(last_time)
5292 .next_update(next_time)
5293 )
5294
5295 with pytest.raises(TypeError):
5296 builder.sign(private_key, hashes.SHA256(), backend)
5297
Paul Kehrer8b89bcc2016-09-03 11:31:43 -05005298
5299def test_random_serial_number(monkeypatch):
5300 sample_data = os.urandom(20)
5301
5302 def notrandom(size):
5303 assert size == len(sample_data)
5304 return sample_data
5305
5306 monkeypatch.setattr(os, "urandom", notrandom)
5307
5308 serial_number = x509.random_serial_number()
5309
Lucia Lic6ba99d2021-11-08 22:06:11 +08005310 assert serial_number == utils.int_from_bytes(sample_data, "big") >> 1
Alex Gaynor31034a02017-10-11 22:01:29 -04005311 assert serial_number.bit_length() < 160