1# -*- coding: utf-8 -*- 2# 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 8import binascii 9import collections 10import copy 11import datetime 12import ipaddress 13import os 14 15import pytest 16 17import pytz 18 19import six 20 21from cryptography import utils, x509 22from cryptography.exceptions import UnsupportedAlgorithm 23from 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) 36from cryptography.hazmat.backends.interfaces import ( 37 DSABackend, 38 EllipticCurveBackend, 39 RSABackend, 40 X509Backend, 41) 42from cryptography.hazmat.primitives import hashes, serialization 43from cryptography.hazmat.primitives.asymmetric import ( 44 dh, 45 dsa, 46 ec, 47 ed25519, 48 ed448, 49 padding, 50 rsa, 51) 52from cryptography.hazmat.primitives.asymmetric.utils import ( 53 decode_dss_signature, 54) 55from cryptography.utils import int_from_bytes 56from cryptography.x509.name import _ASN1Type 57from cryptography.x509.oid import ( 58 AuthorityInformationAccessOID, 59 ExtendedKeyUsageOID, 60 ExtensionOID, 61 NameOID, 62 SignatureAlgorithmOID, 63 SubjectInformationAccessOID, 64) 65 66from ..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 70from ..utils import load_nist_vectors, load_vectors_from_file 71 72 73@utils.register_interface(x509.ExtensionType) 74class DummyExtension(object): 75 oid = x509.ObjectIdentifier("1.2.3.4") 76 77 78@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 86def _load_cert(filename, loader, backend): 87 cert = load_vectors_from_file( 88 filename=filename, 89 loader=lambda pemfile: loader(pemfile.read(), backend), 90 mode="rb", 91 ) 92 return cert 93 94 95ParsedCertificate = 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 141@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, 147 backend, 148 ) 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) 154 assert ( 155 crl.signature_algorithm_oid 156 == SignatureAlgorithmOID.RSA_WITH_SHA256 157 ) 158 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, 163 backend, 164 ) 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, 185 backend, 186 ) 187 188 with pytest.raises(UnsupportedAlgorithm): 189 crl.signature_hash_algorithm() 190 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, 195 backend, 196 ) 197 198 assert isinstance(crl.issuer, x509.Name) 199 assert list(crl.issuer) == [ 200 x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"), 201 x509.NameAttribute( 202 x509.OID_ORGANIZATION_NAME, u"Test Certificates 2011" 203 ), 204 x509.NameAttribute(x509.OID_COMMON_NAME, u"Good CA"), 205 ] 206 assert crl.issuer.get_attributes_for_oid(x509.OID_COMMON_NAME) == [ 207 x509.NameAttribute(x509.OID_COMMON_NAME, u"Good CA") 208 ] 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, 214 backend, 215 ) 216 217 crl2 = _load_cert( 218 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"), 219 x509.load_der_x509_crl, 220 backend, 221 ) 222 223 crl3 = _load_cert( 224 os.path.join("x509", "custom", "crl_all_reasons.pem"), 225 x509.load_pem_x509_crl, 226 backend, 227 ) 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, 237 backend, 238 ) 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 246 def test_revoked_cert_retrieval(self, backend): 247 crl = _load_cert( 248 os.path.join("x509", "custom", "crl_all_reasons.pem"), 249 x509.load_pem_x509_crl, 250 backend, 251 ) 252 253 for r in crl: 254 assert isinstance(r, x509.RevokedCertificate) 255 256 # Check that len() works for CRLs. 257 assert len(crl) == 12 258 259 def test_get_revoked_certificate_by_serial_number(self, backend): 260 crl = _load_cert( 261 os.path.join( 262 "x509", "PKITS_data", "crls", "LongSerialNumberCACRL.crl" 263 ), 264 x509.load_der_x509_crl, 265 backend, 266 ) 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 272 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 276 PyPy does gc at its own pace, so it will only be reliable on CPython. 277 """ 278 revoked = _load_cert( 279 os.path.join("x509", "custom", "crl_all_reasons.pem"), 280 x509.load_pem_x509_crl, 281 backend, 282 )[11] 283 assert revoked.revocation_date == datetime.datetime(2015, 1, 1, 0, 0) 284 assert revoked.serial_number == 11 285 286 def test_extensions(self, backend): 287 crl = _load_cert( 288 os.path.join("x509", "custom", "crl_ian_aia_aki.pem"), 289 x509.load_pem_x509_crl, 290 backend, 291 ) 292 293 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 ) 299 aia = crl.extensions.get_extension_for_class( 300 x509.AuthorityInformationAccess 301 ) 302 ian = crl.extensions.get_extension_for_class( 303 x509.IssuerAlternativeName 304 ) 305 assert crl_number.value == x509.CRLNumber(1) 306 assert crl_number.critical is False 307 assert aki.value == x509.AuthorityKeyIdentifier( 308 key_identifier=(b"yu\xbb\x84:\xcb,\xdez\t\xbe1\x1bC\xbc\x1c*MSX"), 309 authority_cert_issuer=None, 310 authority_cert_serial_number=None, 311 ) 312 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 ) 323 324 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, 328 backend, 329 ) 330 331 dci = crl.extensions.get_extension_for_oid( 332 ExtensionOID.DELTA_CRL_INDICATOR 333 ) 334 assert dci.value == x509.DeltaCRLIndicator(12345678901234567890) 335 assert dci.critical is True 336 337 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, 341 backend, 342 ) 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 356 def test_tbs_certlist_bytes(self, backend): 357 crl = _load_cert( 358 os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"), 359 x509.load_der_x509_crl, 360 backend, 361 ) 362 363 ca_cert = _load_cert( 364 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"), 365 x509.load_der_x509_certificate, 366 backend, 367 ) 368 369 ca_cert.public_key().verify( 370 crl.signature, 371 crl.tbs_certlist_bytes, 372 padding.PKCS1v15(), 373 crl.signature_hash_algorithm, 374 ) 375 376 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, 380 backend, 381 ) 382 383 # Encode it to PEM and load it back. 384 crl = x509.load_pem_x509_crl( 385 crl.public_bytes( 386 encoding=serialization.Encoding.PEM, 387 ), 388 backend, 389 ) 390 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, 399 backend, 400 ) 401 402 # Encode it to DER and load it back. 403 crl = x509.load_der_x509_crl( 404 crl.public_bytes( 405 encoding=serialization.Encoding.DER, 406 ), 407 backend, 408 ) 409 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 414 @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 ), 427 ], 428 ) 429 def test_public_bytes_match( 430 self, cert_path, loader_func, encoding, backend 431 ): 432 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 439 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, 443 backend, 444 ) 445 446 with pytest.raises(TypeError): 447 crl.public_bytes("NotAnEncoding") 448 449 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, 453 backend, 454 ) 455 crt = _load_cert( 456 os.path.join("x509", "custom", "invalid_signature.pem"), 457 x509.load_pem_x509_certificate, 458 backend, 459 ) 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, 467 backend, 468 ) 469 crt = _load_cert( 470 os.path.join("x509", "custom", "valid_signature.pem"), 471 x509.load_pem_x509_certificate, 472 backend, 473 ) 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, 481 backend, 482 ) 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 490 491@pytest.mark.requires_backend_interface(interface=X509Backend) 492class TestRevokedCertificate(object): 493 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, 497 backend, 498 ) 499 500 for i, rev in enumerate(crl): 501 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, 513 backend, 514 ) 515 516 exp_issuer = [ 517 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 ) 527 ] 528 529 # First revoked cert doesn't have extensions, test if it is handled 530 # correctly. 531 rev0 = crl[0] 532 # 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) 537 with pytest.raises(x509.ExtensionNotFound): 538 rev0.extensions.get_extension_for_oid(x509.OID_CERTIFICATE_ISSUER) 539 with pytest.raises(x509.ExtensionNotFound): 540 rev0.extensions.get_extension_for_oid(x509.OID_INVALIDITY_DATE) 541 542 # Test manual retrieval of extension values. 543 rev1 = crl[1] 544 assert isinstance(rev1.extensions, x509.Extensions) 545 546 reason = rev1.extensions.get_extension_for_class(x509.CRLReason).value 547 assert reason == x509.CRLReason(x509.ReasonFlags.unspecified) 548 549 issuer = rev1.extensions.get_extension_for_class( 550 x509.CertificateIssuer 551 ).value 552 assert issuer == x509.CertificateIssuer(exp_issuer) 553 554 date = rev1.extensions.get_extension_for_class( 555 x509.InvalidityDate 556 ).value 557 assert date == x509.InvalidityDate(datetime.datetime(2015, 1, 1, 0, 0)) 558 559 # Check if all reason flags can be found in the CRL. 560 flags = set(x509.ReasonFlags) 561 for rev in crl: 562 try: 563 r = rev.extensions.get_extension_for_class(x509.CRLReason) 564 except x509.ExtensionNotFound: 565 # Not all revoked certs have a reason extension. 566 pass 567 else: 568 flags.discard(r.value.reason) 569 570 assert len(flags) == 0 571 572 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, 576 backend, 577 ) 578 assert len(crl) == 0 579 580 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, 584 backend, 585 ) 586 587 with pytest.raises(x509.DuplicateExtension): 588 crl[0].extensions 589 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, 596 backend, 597 ) 598 599 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" 603 604 def test_unsupported_reason(self, backend): 605 crl = _load_cert( 606 os.path.join("x509", "custom", "crl_unsupported_reason.pem"), 607 x509.load_pem_x509_crl, 608 backend, 609 ) 610 611 with pytest.raises(ValueError): 612 crl[0].extensions 613 614 def test_invalid_cert_issuer_ext(self, backend): 615 crl = _load_cert( 616 os.path.join( 617 "x509", "custom", "crl_inval_cert_issuer_entry_ext.pem" 618 ), 619 x509.load_pem_x509_crl, 620 backend, 621 ) 622 623 with pytest.raises(ValueError): 624 crl[0].extensions 625 626 def test_indexing(self, backend): 627 crl = _load_cert( 628 os.path.join("x509", "custom", "crl_all_reasons.pem"), 629 x509.load_pem_x509_crl, 630 backend, 631 ) 632 633 with pytest.raises(IndexError): 634 crl[-13] 635 with pytest.raises(IndexError): 636 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 642 643 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) 647 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) 660 ) 661 for i in [2, 500, 3, 49, 7, 1]: 662 revoked_cert = ( 663 x509.RevokedCertificateBuilder() 664 .serial_number(i) 665 .revocation_date(datetime.datetime(2012, 1, 1, 1, 1)) 666 .build(backend) 667 ) 668 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 678 679@pytest.mark.requires_backend_interface(interface=RSABackend) 680@pytest.mark.requires_backend_interface(interface=X509Backend) 681class TestRSACertificate(object): 682 def test_load_pem_cert(self, backend): 683 cert = _load_cert( 684 os.path.join("x509", "custom", "post2000utctime.pem"), 685 x509.load_pem_x509_certificate, 686 backend, 687 ) 688 assert isinstance(cert, x509.Certificate) 689 assert cert.serial_number == 11559813051657483483 690 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1())) 691 assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8" 692 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1) 693 assert ( 694 cert.signature_algorithm_oid == SignatureAlgorithmOID.RSA_WITH_SHA1 695 ) 696 697 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 705 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, 709 backend, 710 ) 711 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1) 712 assert ( 713 cert.signature_algorithm_oid 714 == SignatureAlgorithmOID._RSA_WITH_SHA1 715 ) 716 717 def test_load_der_cert(self, backend): 718 cert = _load_cert( 719 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"), 720 x509.load_der_x509_certificate, 721 backend, 722 ) 723 assert isinstance(cert, x509.Certificate) 724 assert cert.serial_number == 2 725 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1())) 726 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d" 727 assert isinstance(cert.signature_hash_algorithm, hashes.SHA256) 728 729 def test_signature(self, backend): 730 cert = _load_cert( 731 os.path.join("x509", "custom", "post2000utctime.pem"), 732 x509.load_pem_x509_certificate, 733 backend, 734 ) 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 748 def test_tbs_certificate_bytes(self, backend): 749 cert = _load_cert( 750 os.path.join("x509", "custom", "post2000utctime.pem"), 751 x509.load_pem_x509_certificate, 752 backend, 753 ) 754 assert cert.tbs_certificate_bytes == binascii.unhexlify( 755 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 ) 780 cert.public_key().verify( 781 cert.signature, 782 cert.tbs_certificate_bytes, 783 padding.PKCS1v15(), 784 cert.signature_hash_algorithm, 785 ) 786 787 def test_issuer(self, backend): 788 cert = _load_cert( 789 os.path.join( 790 "x509", 791 "PKITS_data", 792 "certs", 793 "Validpre2000UTCnotBeforeDateTest3EE.crt", 794 ), 795 x509.load_der_x509_certificate, 796 backend, 797 ) 798 issuer = cert.issuer 799 assert isinstance(issuer, x509.Name) 800 assert list(issuer) == [ 801 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"), 802 x509.NameAttribute( 803 NameOID.ORGANIZATION_NAME, u"Test Certificates 2011" 804 ), 805 x509.NameAttribute(NameOID.COMMON_NAME, u"Good CA"), 806 ] 807 assert issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [ 808 x509.NameAttribute(NameOID.COMMON_NAME, u"Good CA") 809 ] 810 811 def test_all_issuer_name_types(self, backend): 812 cert = _load_cert( 813 os.path.join("x509", "custom", "all_supported_names.pem"), 814 x509.load_pem_x509_certificate, 815 backend, 816 ) 817 issuer = cert.issuer 818 819 assert isinstance(issuer, x509.Name) 820 assert list(issuer) == [ 821 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"), 851 ] 852 853 def test_subject(self, backend): 854 cert = _load_cert( 855 os.path.join( 856 "x509", 857 "PKITS_data", 858 "certs", 859 "Validpre2000UTCnotBeforeDateTest3EE.crt", 860 ), 861 x509.load_der_x509_certificate, 862 backend, 863 ) 864 subject = cert.subject 865 assert isinstance(subject, x509.Name) 866 assert list(subject) == [ 867 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"), 868 x509.NameAttribute( 869 NameOID.ORGANIZATION_NAME, u"Test Certificates 2011" 870 ), 871 x509.NameAttribute( 872 NameOID.COMMON_NAME, 873 u"Valid pre2000 UTC notBefore Date EE Certificate Test3", 874 ), 875 ] 876 assert subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [ 877 x509.NameAttribute( 878 NameOID.COMMON_NAME, 879 u"Valid pre2000 UTC notBefore Date EE Certificate Test3", 880 ) 881 ] 882 883 def test_unicode_name(self, backend): 884 cert = _load_cert( 885 os.path.join("x509", "custom", "utf8_common_name.pem"), 886 x509.load_pem_x509_certificate, 887 backend, 888 ) 889 assert cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [ 890 x509.NameAttribute(NameOID.COMMON_NAME, u"We heart UTF8!\u2122") 891 ] 892 assert cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [ 893 x509.NameAttribute(NameOID.COMMON_NAME, u"We heart UTF8!\u2122") 894 ] 895 896 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, 900 backend, 901 ) 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 == [ 909 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", 916 ] 917 918 def test_all_subject_name_types(self, backend): 919 cert = _load_cert( 920 os.path.join("x509", "custom", "all_supported_names.pem"), 921 x509.load_pem_x509_certificate, 922 backend, 923 ) 924 subject = cert.subject 925 assert isinstance(subject, x509.Name) 926 assert list(subject) == [ 927 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"), 937 x509.NameAttribute( 938 NameOID.ORGANIZATIONAL_UNIT_NAME, u"Engineering 0" 939 ), 940 x509.NameAttribute( 941 NameOID.ORGANIZATIONAL_UNIT_NAME, u"Engineering 1" 942 ), 943 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"), 961 ] 962 963 def test_load_good_ca_cert(self, backend): 964 cert = _load_cert( 965 os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"), 966 x509.load_der_x509_certificate, 967 backend, 968 ) 969 970 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) 972 assert cert.serial_number == 2 973 public_key = cert.public_key() 974 assert isinstance(public_key, rsa.RSAPublicKey) 975 assert cert.version is x509.Version.v3 976 fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1())) 977 assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d" 978 979 def test_utc_pre_2000_not_before_cert(self, backend): 980 cert = _load_cert( 981 os.path.join( 982 "x509", 983 "PKITS_data", 984 "certs", 985 "Validpre2000UTCnotBeforeDateTest3EE.crt", 986 ), 987 x509.load_der_x509_certificate, 988 backend, 989 ) 990 991 assert cert.not_valid_before == datetime.datetime(1950, 1, 1, 12, 1) 992 993 def test_pre_2000_utc_not_after_cert(self, backend): 994 cert = _load_cert( 995 os.path.join( 996 "x509", 997 "PKITS_data", 998 "certs", 999 "Invalidpre2000UTCEEnotAfterDateTest7EE.crt", 1000 ), 1001 x509.load_der_x509_certificate, 1002 backend, 1003 ) 1004 1005 assert cert.not_valid_after == datetime.datetime(1999, 1, 1, 12, 1) 1006 1007 def test_post_2000_utc_cert(self, backend): 1008 cert = _load_cert( 1009 os.path.join("x509", "custom", "post2000utctime.pem"), 1010 x509.load_pem_x509_certificate, 1011 backend, 1012 ) 1013 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 ) 1019 1020 def test_generalized_time_not_before_cert(self, backend): 1021 cert = _load_cert( 1022 os.path.join( 1023 "x509", 1024 "PKITS_data", 1025 "certs", 1026 "ValidGeneralizedTimenotBeforeDateTest4EE.crt", 1027 ), 1028 x509.load_der_x509_certificate, 1029 backend, 1030 ) 1031 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) 1033 assert cert.version is x509.Version.v3 1034 1035 def test_generalized_time_not_after_cert(self, backend): 1036 cert = _load_cert( 1037 os.path.join( 1038 "x509", 1039 "PKITS_data", 1040 "certs", 1041 "ValidGeneralizedTimenotAfterDateTest8EE.crt", 1042 ), 1043 x509.load_der_x509_certificate, 1044 backend, 1045 ) 1046 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) 1048 assert cert.version is x509.Version.v3 1049 1050 def test_invalid_version_cert(self, backend): 1051 with pytest.raises(x509.InvalidVersion) as exc: 1052 _load_cert( 1053 os.path.join("x509", "custom", "invalid_version.pem"), 1054 x509.load_pem_x509_certificate, 1055 backend, 1056 ) 1057 1058 assert exc.value.parsed_version == 7 1059 1060 def test_eq(self, backend): 1061 cert = _load_cert( 1062 os.path.join("x509", "custom", "post2000utctime.pem"), 1063 x509.load_pem_x509_certificate, 1064 backend, 1065 ) 1066 cert2 = _load_cert( 1067 os.path.join("x509", "custom", "post2000utctime.pem"), 1068 x509.load_pem_x509_certificate, 1069 backend, 1070 ) 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, 1077 backend, 1078 ) 1079 cert2 = _load_cert( 1080 os.path.join( 1081 "x509", 1082 "PKITS_data", 1083 "certs", 1084 "ValidGeneralizedTimenotAfterDateTest8EE.crt", 1085 ), 1086 x509.load_der_x509_certificate, 1087 backend, 1088 ) 1089 assert cert != cert2 1090 assert cert != object() 1091 1092 def test_hash(self, backend): 1093 cert1 = _load_cert( 1094 os.path.join("x509", "custom", "post2000utctime.pem"), 1095 x509.load_pem_x509_certificate, 1096 backend, 1097 ) 1098 cert2 = _load_cert( 1099 os.path.join("x509", "custom", "post2000utctime.pem"), 1100 x509.load_pem_x509_certificate, 1101 backend, 1102 ) 1103 cert3 = _load_cert( 1104 os.path.join( 1105 "x509", 1106 "PKITS_data", 1107 "certs", 1108 "ValidGeneralizedTimenotAfterDateTest8EE.crt", 1109 ), 1110 x509.load_der_x509_certificate, 1111 backend, 1112 ) 1113 1114 assert hash(cert1) == hash(cert2) 1115 assert hash(cert1) != hash(cert3) 1116 1117 def test_version_1_cert(self, backend): 1118 cert = _load_cert( 1119 os.path.join("x509", "v1_cert.pem"), 1120 x509.load_pem_x509_certificate, 1121 backend, 1122 ) 1123 assert cert.version is x509.Version.v1 1124 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) 1132 1133 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, 1137 backend, 1138 ) 1139 with pytest.raises(UnsupportedAlgorithm): 1140 cert.signature_hash_algorithm 1141 1142 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, 1147 backend, 1148 ) 1149 1150 # Encode it to PEM and load it back. 1151 cert = x509.load_pem_x509_certificate( 1152 cert.public_bytes( 1153 encoding=serialization.Encoding.PEM, 1154 ), 1155 backend, 1156 ) 1157 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) 1161 assert cert.serial_number == 2 1162 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, 1173 backend, 1174 ) 1175 1176 # Encode it to DER and load it back. 1177 cert = x509.load_der_x509_certificate( 1178 cert.public_bytes( 1179 encoding=serialization.Encoding.DER, 1180 ), 1181 backend, 1182 ) 1183 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) 1187 assert cert.serial_number == 2 1188 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, 1198 backend, 1199 ) 1200 1201 with pytest.raises(TypeError): 1202 cert.public_bytes("NotAnEncoding") 1203 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 ), 1217 ], 1218 ) 1219 def test_public_bytes_match( 1220 self, cert_path, loader_func, encoding, backend 1221 ): 1222 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 1229 def test_certificate_repr(self, backend): 1230 cert = _load_cert( 1231 os.path.join("x509", "cryptography.io.pem"), 1232 x509.load_pem_x509_certificate, 1233 backend, 1234 ) 1235 assert repr(cert) == ( 1236 "<Certificate(subject=<Name(OU=GT48742965,OU=See www.rapidssl.com" 1237 "/resources/cps (c)14,OU=Domain Control Validated - RapidSSL(R)," 1238 "CN=www.cryptography.io)>, ...)>" 1239 ) 1240 1241 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, 1245 backend, 1246 ) 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 1253 1254@pytest.mark.requires_backend_interface(interface=RSABackend) 1255@pytest.mark.requires_backend_interface(interface=X509Backend) 1256class TestRSACertificateRequest(object): 1257 @pytest.mark.parametrize( 1258 ("path", "loader_func"), 1259 [ 1260 [ 1261 os.path.join("x509", "requests", "rsa_sha1.pem"), 1262 x509.load_pem_x509_csr, 1263 ], 1264 [ 1265 os.path.join("x509", "requests", "rsa_sha1.der"), 1266 x509.load_der_x509_csr, 1267 ], 1268 ], 1269 ) 1270 def test_load_rsa_certificate_request(self, path, loader_func, backend): 1271 request = _load_cert(path, loader_func, backend) 1272 assert isinstance(request.signature_hash_algorithm, hashes.SHA1) 1273 assert ( 1274 request.signature_algorithm_oid 1275 == SignatureAlgorithmOID.RSA_WITH_SHA1 1276 ) 1277 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) == [ 1282 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"), 1287 ] 1288 extensions = request.extensions 1289 assert isinstance(extensions, x509.Extensions) 1290 assert list(extensions) == [] 1291 1292 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 1353 @pytest.mark.parametrize( 1354 "loader_func", [x509.load_pem_x509_csr, x509.load_der_x509_csr] 1355 ) 1356 def test_invalid_certificate_request(self, loader_func, backend): 1357 with pytest.raises(ValueError): 1358 loader_func(b"notacsr", backend) 1359 1360 def test_unsupported_signature_hash_algorithm_request(self, backend): 1361 request = _load_cert( 1362 os.path.join("x509", "requests", "rsa_md4.pem"), 1363 x509.load_pem_x509_csr, 1364 backend, 1365 ) 1366 with pytest.raises(UnsupportedAlgorithm): 1367 request.signature_hash_algorithm 1368 1369 def test_duplicate_extension(self, backend): 1370 request = _load_cert( 1371 os.path.join("x509", "requests", "two_basic_constraints.pem"), 1372 x509.load_pem_x509_csr, 1373 backend, 1374 ) 1375 with pytest.raises(x509.DuplicateExtension) as exc: 1376 request.extensions 1377 1378 assert exc.value.oid == ExtensionOID.BASIC_CONSTRAINTS 1379 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, 1386 backend, 1387 ) 1388 ext = request.extensions.get_extension_for_oid( 1389 x509.ObjectIdentifier("1.2.3.4") 1390 ) 1391 assert ext.value.value == b"value" 1392 1393 def test_unsupported_extension(self, backend): 1394 request = _load_cert( 1395 os.path.join("x509", "requests", "unsupported_extension.pem"), 1396 x509.load_pem_x509_csr, 1397 backend, 1398 ) 1399 extensions = request.extensions 1400 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 ) 1405 1406 def test_request_basic_constraints(self, backend): 1407 request = _load_cert( 1408 os.path.join("x509", "requests", "basic_constraints.pem"), 1409 x509.load_pem_x509_csr, 1410 backend, 1411 ) 1412 extensions = request.extensions 1413 assert isinstance(extensions, x509.Extensions) 1414 assert list(extensions) == [ 1415 x509.Extension( 1416 ExtensionOID.BASIC_CONSTRAINTS, 1417 True, 1418 x509.BasicConstraints(ca=True, path_length=1), 1419 ), 1420 ] 1421 1422 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( 1429 ExtensionOID.SUBJECT_ALTERNATIVE_NAME 1430 ) 1431 assert list(ext.value) == [ 1432 x509.DNSName(u"cryptography.io"), 1433 x509.DNSName(u"sub.cryptography.io"), 1434 ] 1435 1436 def test_public_bytes_pem(self, backend): 1437 # Load an existing CSR. 1438 request = _load_cert( 1439 os.path.join("x509", "requests", "rsa_sha1.pem"), 1440 x509.load_pem_x509_csr, 1441 backend, 1442 ) 1443 1444 # Encode it to PEM and load it back. 1445 request = x509.load_pem_x509_csr( 1446 request.public_bytes( 1447 encoding=serialization.Encoding.PEM, 1448 ), 1449 backend, 1450 ) 1451 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) == [ 1459 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"), 1464 ] 1465 1466 def test_public_bytes_der(self, backend): 1467 # Load an existing CSR. 1468 request = _load_cert( 1469 os.path.join("x509", "requests", "rsa_sha1.pem"), 1470 x509.load_pem_x509_csr, 1471 backend, 1472 ) 1473 1474 # Encode it to DER and load it back. 1475 request = x509.load_der_x509_csr( 1476 request.public_bytes( 1477 encoding=serialization.Encoding.DER, 1478 ), 1479 backend, 1480 ) 1481 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) == [ 1489 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"), 1494 ] 1495 1496 def test_signature(self, backend): 1497 request = _load_cert( 1498 os.path.join("x509", "requests", "rsa_sha1.pem"), 1499 x509.load_pem_x509_csr, 1500 backend, 1501 ) 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, 1517 backend, 1518 ) 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 ) 1534 request.public_key().verify( 1535 request.signature, 1536 request.tbs_certrequest_bytes, 1537 padding.PKCS1v15(), 1538 request.signature_hash_algorithm, 1539 ) 1540 1541 def test_public_bytes_invalid_encoding(self, backend): 1542 request = _load_cert( 1543 os.path.join("x509", "requests", "rsa_sha1.pem"), 1544 x509.load_pem_x509_csr, 1545 backend, 1546 ) 1547 1548 with pytest.raises(TypeError): 1549 request.public_bytes("NotAnEncoding") 1550 1551 def test_signature_invalid(self, backend): 1552 request = _load_cert( 1553 os.path.join("x509", "requests", "invalid_signature.pem"), 1554 x509.load_pem_x509_csr, 1555 backend, 1556 ) 1557 assert not request.is_signature_valid 1558 1559 def test_signature_valid(self, backend): 1560 request = _load_cert( 1561 os.path.join("x509", "requests", "rsa_sha256.pem"), 1562 x509.load_pem_x509_csr, 1563 backend, 1564 ) 1565 assert request.is_signature_valid 1566 1567 @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 ), 1580 ], 1581 ) 1582 def test_public_bytes_match( 1583 self, request_path, loader_func, encoding, backend 1584 ): 1585 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 1592 def test_eq(self, backend): 1593 request1 = _load_cert( 1594 os.path.join("x509", "requests", "rsa_sha1.pem"), 1595 x509.load_pem_x509_csr, 1596 backend, 1597 ) 1598 request2 = _load_cert( 1599 os.path.join("x509", "requests", "rsa_sha1.pem"), 1600 x509.load_pem_x509_csr, 1601 backend, 1602 ) 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, 1610 backend, 1611 ) 1612 request2 = _load_cert( 1613 os.path.join("x509", "requests", "san_rsa_sha1.pem"), 1614 x509.load_pem_x509_csr, 1615 backend, 1616 ) 1617 1618 assert request1 != request2 1619 assert request1 != object() 1620 1621 def test_hash(self, backend): 1622 request1 = _load_cert( 1623 os.path.join("x509", "requests", "rsa_sha1.pem"), 1624 x509.load_pem_x509_csr, 1625 backend, 1626 ) 1627 request2 = _load_cert( 1628 os.path.join("x509", "requests", "rsa_sha1.pem"), 1629 x509.load_pem_x509_csr, 1630 backend, 1631 ) 1632 request3 = _load_cert( 1633 os.path.join("x509", "requests", "san_rsa_sha1.pem"), 1634 x509.load_pem_x509_csr, 1635 backend, 1636 ) 1637 1638 assert hash(request1) == hash(request2) 1639 assert hash(request1) != hash(request3) 1640 1641 def test_build_cert(self, backend): 1642 issuer_private_key = RSA_KEY_2048.private_key(backend) 1643 subject_private_key = RSA_KEY_2048.private_key(backend) 1644 1645 not_valid_before = datetime.datetime(2002, 1, 1, 12, 1) 1646 not_valid_after = datetime.datetime(2030, 12, 31, 8, 30) 1647 1648 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) 1694 ) 1695 1696 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend) 1697 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( 1702 ExtensionOID.BASIC_CONSTRAINTS 1703 ) 1704 assert basic_constraints.value.ca is False 1705 assert basic_constraints.value.path_length is None 1706 subject_alternative_name = cert.extensions.get_extension_for_oid( 1707 ExtensionOID.SUBJECT_ALTERNATIVE_NAME 1708 ) 1709 assert list(subject_alternative_name.value) == [ 1710 x509.DNSName(u"cryptography.io"), 1711 ] 1712 1713 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) 1718 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 ) 1742 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend) 1743 1744 for dn in (cert.subject, cert.issuer): 1745 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 ) 1761 1762 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 1769 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) 1801 ) 1802 1803 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend) 1804 1805 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 1818 1819 # Check that each value was encoded as an ASN.1 PRINTABLESTRING. 1820 assert read_next_rdn_value_tag(subject) == PRINTABLE_STRING 1821 assert read_next_rdn_value_tag(issuer) == PRINTABLE_STRING 1822 if ( 1823 # This only works correctly in OpenSSL 1.1.0f+ and 1.0.2l+ 1824 backend._lib.CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER 1825 ): 1826 assert read_next_rdn_value_tag(subject) == PRINTABLE_STRING 1827 assert read_next_rdn_value_tag(issuer) == PRINTABLE_STRING 1828 1829 1830class TestCertificateBuilder(object): 1831 @pytest.mark.requires_backend_interface(interface=RSABackend) 1832 @pytest.mark.requires_backend_interface(interface=X509Backend) 1833 def test_checks_for_unsupported_extensions(self, backend): 1834 private_key = RSA_KEY_2048.private_key(backend) 1835 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) 1848 ) 1849 1850 with pytest.raises(NotImplementedError): 1851 builder.sign(private_key, hashes.SHA1(), backend) 1852 1853 @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 1858 aia = x509.AuthorityInformationAccess( 1859 [ 1860 x509.AccessDescription( 1861 x509.ObjectIdentifier("2.999.7"), 1862 x509.UniformResourceIdentifier(u"http://example.com"), 1863 ), 1864 ] 1865 ) 1866 1867 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) 1880 ) 1881 1882 builder.sign(private_key, hashes.SHA256(), backend) 1883 1884 @pytest.mark.requires_backend_interface(interface=RSABackend) 1885 @pytest.mark.requires_backend_interface(interface=X509Backend) 1886 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) 1921 def test_subject_dn_asn1_types(self, backend): 1922 private_key = RSA_KEY_2048.private_key(backend) 1923 1924 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 ) 1966 1967 for dn in (cert.subject, cert.issuer): 1968 for oid, asn1_type in TestNameAttribute.EXPECTED_TYPES: 1969 assert dn.get_attributes_for_oid(oid)[0]._type == asn1_type 1970 1971 @pytest.mark.parametrize( 1972 ("not_valid_before", "not_valid_after"), 1973 [ 1974 [datetime.datetime(1970, 2, 1), datetime.datetime(9999, 1, 1)], 1975 [datetime.datetime(1970, 2, 1), datetime.datetime(9999, 12, 31)], 1976 ], 1977 ) 1978 @pytest.mark.requires_backend_interface(interface=RSABackend) 1979 @pytest.mark.requires_backend_interface(interface=X509Backend) 1980 def test_extreme_times(self, not_valid_before, not_valid_after, backend): 1981 private_key = RSA_KEY_2048.private_key(backend) 1982 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) 1994 ) 1995 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 1998 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 2001 2002 @pytest.mark.requires_backend_interface(interface=RSABackend) 2003 @pytest.mark.requires_backend_interface(interface=X509Backend) 2004 def test_no_subject_name(self, backend): 2005 subject_private_key = RSA_KEY_2048.private_key(backend) 2006 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)) 2015 ) 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) 2023 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)) 2032 ) 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) 2040 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)) 2051 ) 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) 2059 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)) 2070 ) 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) 2078 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)) 2089 ) 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) 2097 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)) 2108 ) 2109 with pytest.raises(ValueError): 2110 builder.sign(subject_private_key, hashes.SHA256(), backend) 2111 2112 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): 2122 name = x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")]) 2123 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): 2138 name = x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")]) 2139 builder = x509.CertificateBuilder().subject_name(name) 2140 2141 with pytest.raises(ValueError): 2142 builder.subject_name(name) 2143 2144 def test_not_valid_before_after_not_valid_after(self): 2145 builder = x509.CertificateBuilder() 2146 2147 builder = builder.not_valid_after(datetime.datetime(2002, 1, 1, 12, 1)) 2148 with pytest.raises(ValueError): 2149 builder.not_valid_before(datetime.datetime(2003, 1, 1, 12, 1)) 2150 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): 2158 builder.not_valid_after(datetime.datetime(2001, 1, 1, 12, 1)) 2159 2160 @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 2183 def test_serial_number_must_be_non_negative(self): 2184 with pytest.raises(ValueError): 2185 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) 2195 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)) 2207 ) 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) 2215 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)) 2227 ) 2228 cert = builder.sign(subject_private_key, hashes.SHA256(), backend) 2229 assert cert.serial_number == (1 << 159) - 1 2230 2231 def test_serial_number_must_be_less_than_160_bits_long(self): 2232 with pytest.raises(ValueError): 2233 x509.CertificateBuilder().serial_number(1 << 159) 2234 2235 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 2241 @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) 2250 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)) 2260 ) 2261 2262 cert = cert_builder.sign(private_key, hashes.SHA256(), backend) 2263 assert cert.not_valid_after == utc_time 2264 2265 @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) 2270 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) 2282 ) 2283 cert = cert_builder.sign(private_key, hashes.SHA256(), backend) 2284 assert cert.not_valid_before == time 2285 assert cert.not_valid_after == time 2286 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 2289 2290 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 2297 with pytest.raises(ValueError): 2298 x509.CertificateBuilder().not_valid_after( 2299 datetime.datetime(1940, 8, 10) 2300 ) 2301 2302 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): 2308 builder.not_valid_after(datetime.datetime.now()) 2309 2310 @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) 2319 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)) 2329 ) 2330 2331 cert = cert_builder.sign(private_key, hashes.SHA256(), backend) 2332 assert cert.not_valid_before == utc_time 2333 2334 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 2341 with pytest.raises(ValueError): 2342 x509.CertificateBuilder().not_valid_before( 2343 datetime.datetime(1940, 8, 10) 2344 ) 2345 2346 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): 2352 builder.not_valid_before(datetime.datetime.now()) 2353 2354 def test_add_extension_checks_for_duplicates(self): 2355 builder = x509.CertificateBuilder().add_extension( 2356 x509.BasicConstraints(ca=False, path_length=None), 2357 True, 2358 ) 2359 2360 with pytest.raises(ValueError): 2361 builder.add_extension( 2362 x509.BasicConstraints(ca=False, path_length=None), 2363 True, 2364 ) 2365 2366 def test_add_invalid_extension_type(self): 2367 builder = x509.CertificateBuilder() 2368 2369 with pytest.raises(TypeError): 2370 builder.add_extension(object(), False) 2371 2372 @pytest.mark.requires_backend_interface(interface=RSABackend) 2373 @pytest.mark.requires_backend_interface(interface=X509Backend) 2374 @pytest.mark.parametrize("algorithm", [object(), None]) 2375 def test_sign_with_unsupported_hash(self, algorithm, backend): 2376 private_key = RSA_KEY_2048.private_key(backend) 2377 builder = x509.CertificateBuilder() 2378 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)) 2389 ) 2390 2391 with pytest.raises(TypeError): 2392 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) 2441 2442 @pytest.mark.requires_backend_interface(interface=RSABackend) 2443 @pytest.mark.requires_backend_interface(interface=X509Backend) 2444 @pytest.mark.supported( 2445 only_if=lambda backend: backend.hash_supported(hashes.MD5()), 2446 skip_message="Requires OpenSSL with MD5 support", 2447 ) 2448 def test_sign_rsa_with_md5(self, backend): 2449 private_key = RSA_KEY_2048.private_key(backend) 2450 builder = x509.CertificateBuilder() 2451 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)) 2462 ) 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) 2468 @pytest.mark.supported( 2469 only_if=lambda backend: backend.hash_supported(hashes.MD5()), 2470 skip_message="Requires OpenSSL with MD5 support", 2471 ) 2472 def test_sign_dsa_with_md5(self, backend): 2473 private_key = DSA_KEY_2048.private_key(backend) 2474 builder = x509.CertificateBuilder() 2475 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)) 2486 ) 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) 2492 @pytest.mark.supported( 2493 only_if=lambda backend: backend.hash_supported(hashes.MD5()), 2494 skip_message="Requires OpenSSL with MD5 support", 2495 ) 2496 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() 2500 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)) 2511 ) 2512 with pytest.raises(ValueError): 2513 builder.sign(private_key, hashes.MD5(), backend) 2514 2515 @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): 2518 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 2524 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) 2546 ) 2547 2548 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend) 2549 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( 2554 ExtensionOID.BASIC_CONSTRAINTS 2555 ) 2556 assert basic_constraints.value.ca is False 2557 assert basic_constraints.value.path_length is None 2558 subject_alternative_name = cert.extensions.get_extension_for_oid( 2559 ExtensionOID.SUBJECT_ALTERNATIVE_NAME 2560 ) 2561 assert list(subject_alternative_name.value) == [ 2562 x509.DNSName(u"cryptography.io"), 2563 ] 2564 2565 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) 2566 @pytest.mark.requires_backend_interface(interface=X509Backend) 2567 def test_build_cert_with_ec_private_key(self, backend): 2568 _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 2575 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) 2597 ) 2598 2599 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend) 2600 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( 2605 ExtensionOID.BASIC_CONSTRAINTS 2606 ) 2607 assert basic_constraints.value.ca is False 2608 assert basic_constraints.value.path_length is None 2609 subject_alternative_name = cert.extensions.get_extension_for_oid( 2610 ExtensionOID.SUBJECT_ALTERNATIVE_NAME 2611 ) 2612 assert list(subject_alternative_name.value) == [ 2613 x509.DNSName(u"cryptography.io"), 2614 ] 2615 2616 @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 2812 @pytest.mark.requires_backend_interface(interface=RSABackend) 2813 @pytest.mark.requires_backend_interface(interface=X509Backend) 2814 def test_build_cert_with_rsa_key_too_small(self, backend): 2815 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 2821 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) 2833 ) 2834 2835 with pytest.raises(ValueError): 2836 builder.sign(issuer_private_key, hashes.SHA512(), backend) 2837 2838 @pytest.mark.requires_backend_interface(interface=RSABackend) 2839 @pytest.mark.requires_backend_interface(interface=X509Backend) 2840 @pytest.mark.parametrize( 2841 "add_ext", 2842 [ 2843 x509.SubjectAlternativeName( 2844 [ 2845 # These examples exist to verify compatibility with 2846 # certificates that have utf8 encoded data in the ia5string 2847 x509.DNSName._init_without_validation(u"a\xedt\xe1s.test"), 2848 x509.RFC822Name._init_without_validation( 2849 u"test@a\xedt\xe1s.test" 2850 ), 2851 x509.UniformResourceIdentifier._init_without_validation( 2852 u"http://a\xedt\xe1s.test" 2853 ), 2854 ] 2855 ), 2856 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 ), 2937 x509.InhibitAnyPolicy(3), 2938 x509.TLSFeature([x509.TLSFeatureType.status_request]), 2939 x509.TLSFeature([x509.TLSFeatureType.status_request_v2]), 2940 x509.TLSFeature( 2941 [ 2942 x509.TLSFeatureType.status_request, 2943 x509.TLSFeatureType.status_request_v2, 2944 ] 2945 ), 2946 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 ], 2960 excluded_subtrees=[x509.DNSName(u"name.local")], 2961 ), 2962 x509.NameConstraints( 2963 permitted_subtrees=[ 2964 x509.IPAddress(ipaddress.IPv4Network(u"0.0.0.0/0")), 2965 ], 2966 excluded_subtrees=None, 2967 ), 2968 x509.NameConstraints( 2969 permitted_subtrees=None, 2970 excluded_subtrees=[x509.DNSName(u"name.local")], 2971 ), 2972 x509.PolicyConstraints( 2973 require_explicit_policy=None, inhibit_policy_mapping=1 2974 ), 2975 x509.PolicyConstraints( 2976 require_explicit_policy=3, inhibit_policy_mapping=1 2977 ), 2978 x509.PolicyConstraints( 2979 require_explicit_policy=0, inhibit_policy_mapping=None 2980 ), 2981 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 ] 2992 ), 2993 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" 3053 ), 3054 x509.UniformResourceIdentifier( 3055 u"http://backup.myhost.com/myca.crl" 3056 ), 3057 ], 3058 relative_name=None, 3059 reasons=frozenset( 3060 [ 3061 x509.ReasonFlags.key_compromise, 3062 x509.ReasonFlags.ca_compromise, 3063 ] 3064 ), 3065 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 ] 3103 ), 3104 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 ] 3163 ), 3164 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 ] 3179 ), 3180 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 ], 3206 ) 3207 def test_ext(self, add_ext, backend): 3208 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 3214 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 ) 3229 3230 ext = cert.extensions.get_extension_for_class(type(add_ext)) 3231 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) 3236 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 3243 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 ) 3271 3272 ext = cert.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE) 3273 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, 3283 decipher_only=False, 3284 ) 3285 3286 @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 3291 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 ) 3303 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 3314 @pytest.mark.parametrize( 3315 "unrecognized", 3316 [ 3317 x509.UnrecognizedExtension( 3318 x509.ObjectIdentifier("1.2.3.4.5"), 3319 b"abcdef", 3320 ) 3321 ], 3322 ) 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 3328 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 ) 3343 3344 ext = cert.extensions.get_extension_for_oid(unrecognized.oid) 3345 3346 assert ext.value == unrecognized 3347 3348 3349@pytest.mark.requires_backend_interface(interface=X509Backend) 3350class TestCertificateSigningRequestBuilder(object): 3351 @pytest.mark.requires_backend_interface(interface=RSABackend) 3352 def test_sign_invalid_hash_algorithm(self, backend): 3353 private_key = RSA_KEY_2048.private_key(backend) 3354 3355 builder = x509.CertificateSigningRequestBuilder().subject_name( 3356 x509.Name([]) 3357 ) 3358 with pytest.raises(TypeError): 3359 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) 3388 3389 @pytest.mark.requires_backend_interface(interface=RSABackend) 3390 @pytest.mark.supported( 3391 only_if=lambda backend: backend.hash_supported(hashes.MD5()), 3392 skip_message="Requires OpenSSL with MD5 support", 3393 ) 3394 def test_sign_rsa_with_md5(self, backend): 3395 private_key = RSA_KEY_2048.private_key(backend) 3396 3397 builder = x509.CertificateSigningRequestBuilder().subject_name( 3398 x509.Name([x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA")]) 3399 ) 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) 3404 @pytest.mark.supported( 3405 only_if=lambda backend: backend.hash_supported(hashes.MD5()), 3406 skip_message="Requires OpenSSL with MD5 support", 3407 ) 3408 def test_sign_dsa_with_md5(self, backend): 3409 private_key = DSA_KEY_2048.private_key(backend) 3410 builder = x509.CertificateSigningRequestBuilder().subject_name( 3411 x509.Name([x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA")]) 3412 ) 3413 with pytest.raises(ValueError): 3414 builder.sign(private_key, hashes.MD5(), backend) 3415 3416 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) 3417 @pytest.mark.supported( 3418 only_if=lambda backend: backend.hash_supported(hashes.MD5()), 3419 skip_message="Requires OpenSSL with MD5 support", 3420 ) 3421 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( 3425 x509.Name([x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA")]) 3426 ) 3427 with pytest.raises(ValueError): 3428 builder.sign(private_key, hashes.MD5(), backend) 3429 3430 @pytest.mark.requires_backend_interface(interface=RSABackend) 3431 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) 3439 def test_build_ca_request_with_rsa(self, backend): 3440 private_key = RSA_KEY_2048.private_key(backend) 3441 3442 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 ) 3454 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) == [ 3461 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"), 3462 ] 3463 basic_constraints = request.extensions.get_extension_for_oid( 3464 ExtensionOID.BASIC_CONSTRAINTS 3465 ) 3466 assert basic_constraints.value.ca is True 3467 assert basic_constraints.value.path_length == 2 3468 3469 @pytest.mark.requires_backend_interface(interface=RSABackend) 3470 def test_build_ca_request_with_unicode(self, backend): 3471 private_key = RSA_KEY_2048.private_key(backend) 3472 3473 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 ) 3489 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) == [ 3496 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA\U0001f37a"), 3497 ] 3498 3499 @pytest.mark.requires_backend_interface(interface=RSABackend) 3500 def test_subject_dn_asn1_types(self, backend): 3501 private_key = RSA_KEY_2048.private_key(backend) 3502 3503 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 ) 3556 for oid, asn1_type in TestNameAttribute.EXPECTED_TYPES: 3557 assert ( 3558 request.subject.get_attributes_for_oid(oid)[0]._type 3559 == asn1_type 3560 ) 3561 3562 @pytest.mark.requires_backend_interface(interface=RSABackend) 3563 def test_build_ca_request_with_multivalue_rdns(self, backend): 3564 private_key = RSA_KEY_2048.private_key(backend) 3565 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 ) 3579 3580 request = ( 3581 x509.CertificateSigningRequestBuilder() 3582 .subject_name(subject) 3583 .sign(private_key, hashes.SHA1(), backend) 3584 ) 3585 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) 3593 def test_build_nonca_request_with_rsa(self, backend): 3594 private_key = RSA_KEY_2048.private_key(backend) 3595 3596 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 ) 3607 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) == [ 3614 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"), 3615 ] 3616 basic_constraints = request.extensions.get_extension_for_oid( 3617 ExtensionOID.BASIC_CONSTRAINTS 3618 ) 3619 assert basic_constraints.value.ca is False 3620 assert basic_constraints.value.path_length is None 3621 3622 @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) 3623 def test_build_ca_request_with_ec(self, backend): 3624 _skip_curve_unsupported(backend, ec.SECP256R1()) 3625 private_key = ec.generate_private_key(ec.SECP256R1(), backend) 3626 3627 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 ) 3643 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) == [ 3650 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"), 3729 ] 3730 basic_constraints = request.extensions.get_extension_for_oid( 3731 ExtensionOID.BASIC_CONSTRAINTS 3732 ) 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): 3738 private_key = DSA_KEY_2048.private_key(backend) 3739 3740 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 ) 3750 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) == [ 3757 x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"), 3758 ] 3759 basic_constraints = request.extensions.get_extension_for_oid( 3760 ExtensionOID.BASIC_CONSTRAINTS 3761 ) 3762 assert basic_constraints.value.ca is True 3763 assert basic_constraints.value.path_length == 2 3764 3765 def test_add_duplicate_extension(self): 3766 builder = x509.CertificateSigningRequestBuilder().add_extension( 3767 x509.BasicConstraints(True, 2), 3768 critical=True, 3769 ) 3770 with pytest.raises(ValueError): 3771 builder.add_extension( 3772 x509.BasicConstraints(True, 2), 3773 critical=True, 3774 ) 3775 3776 def test_set_invalid_subject(self): 3777 builder = x509.CertificateSigningRequestBuilder() 3778 with pytest.raises(TypeError): 3779 builder.subject_name("NotAName") 3780 3781 def test_add_invalid_extension_type(self): 3782 builder = x509.CertificateSigningRequestBuilder() 3783 3784 with pytest.raises(TypeError): 3785 builder.add_extension(object(), False) 3786 3787 def test_add_unsupported_extension(self, backend): 3788 private_key = RSA_KEY_2048.private_key(backend) 3789 builder = x509.CertificateSigningRequestBuilder() 3790 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) 3801 ) 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() 3808 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 ) 3828 assert len(request.extensions) == 1 3829 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE) 3830 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, 3840 decipher_only=False, 3841 ) 3842 3843 def test_key_usage_key_agreement_bit(self, backend): 3844 private_key = RSA_KEY_2048.private_key(backend) 3845 builder = x509.CertificateSigningRequestBuilder() 3846 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 ) 3866 assert len(request.extensions) == 1 3867 ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE) 3868 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, 3878 decipher_only=True, 3879 ) 3880 3881 def test_add_two_extensions(self, backend): 3882 private_key = RSA_KEY_2048.private_key(backend) 3883 builder = x509.CertificateSigningRequestBuilder() 3884 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 ) 3899 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( 3904 ExtensionOID.BASIC_CONSTRAINTS 3905 ) 3906 assert basic_constraints.value.ca is True 3907 assert basic_constraints.value.path_length == 2 3908 ext = request.extensions.get_extension_for_oid( 3909 ExtensionOID.SUBJECT_ALTERNATIVE_NAME 3910 ) 3911 assert list(ext.value) == [x509.DNSName(u"cryptography.io")] 3912 3913 @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 3978 def test_set_subject_twice(self): 3979 builder = x509.CertificateSigningRequestBuilder() 3980 builder = builder.subject_name( 3981 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")]) 3982 ) 3983 with pytest.raises(ValueError): 3984 builder.subject_name( 3985 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")]) 3986 ) 3987 3988 def test_subject_alt_names(self, backend): 3989 private_key = RSA_KEY_2048.private_key(backend) 3990 3991 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 ) 4024 4025 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 ) 4036 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 4044 4045 def test_invalid_asn1_othername(self, backend): 4046 private_key = RSA_KEY_2048.private_key(backend) 4047 4048 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 ] 4061 ), 4062 critical=False, 4063 ) 4064 ) 4065 with pytest.raises(ValueError): 4066 builder.sign(private_key, hashes.SHA256(), backend) 4067 4068 def test_subject_alt_name_unsupported_general_name(self, backend): 4069 private_key = RSA_KEY_2048.private_key(backend) 4070 4071 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 ) 4080 ) 4081 4082 with pytest.raises(ValueError): 4083 builder.sign(private_key, hashes.SHA256(), backend) 4084 4085 def test_extended_key_usage(self, backend): 4086 private_key = RSA_KEY_2048.private_key(backend) 4087 eku = x509.ExtendedKeyUsage( 4088 [ 4089 ExtendedKeyUsageOID.CLIENT_AUTH, 4090 ExtendedKeyUsageOID.SERVER_AUTH, 4091 ExtendedKeyUsageOID.CODE_SIGNING, 4092 ] 4093 ) 4094 builder = x509.CertificateSigningRequestBuilder() 4095 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 ) 4102 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 4108 4109 @pytest.mark.requires_backend_interface(interface=RSABackend) 4110 def test_rsa_key_too_small(self, backend): 4111 private_key = RSA_KEY_512.private_key(backend) 4112 builder = x509.CertificateSigningRequestBuilder() 4113 builder = builder.subject_name( 4114 x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u"US")]) 4115 ) 4116 4117 with pytest.raises(ValueError): 4118 builder.sign(private_key, hashes.SHA512(), backend) 4119 4120 @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 4129 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 ) 4143 4144 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) 4157 ) 4158 4159 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend) 4160 4161 ext = cert.extensions.get_extension_for_oid( 4162 ExtensionOID.AUTHORITY_INFORMATION_ACCESS 4163 ) 4164 assert ext.value == aia 4165 4166 @pytest.mark.requires_backend_interface(interface=RSABackend) 4167 @pytest.mark.requires_backend_interface(interface=X509Backend) 4168 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) 4208 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 4219 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) 4232 ) 4233 4234 cert = builder.sign(issuer_private_key, hashes.SHA1(), backend) 4235 4236 ext = cert.extensions.get_extension_for_oid( 4237 ExtensionOID.SUBJECT_KEY_IDENTIFIER 4238 ) 4239 assert ext.value == ski 4240 4241 @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, 4248 None, 4249 ), 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( 4255 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 ) 4265 ) 4266 ], 4267 333, 4268 ), 4269 x509.AuthorityKeyIdentifier( 4270 None, 4271 [ 4272 x509.DirectoryName( 4273 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 ) 4283 ) 4284 ], 4285 333, 4286 ), 4287 ], 4288 ) 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 4298 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) 4311 ) 4312 4313 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend) 4314 4315 ext = cert.extensions.get_extension_for_oid( 4316 ExtensionOID.AUTHORITY_KEY_IDENTIFIER 4317 ) 4318 assert ext.value == aki 4319 4320 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 4327 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) 4340 ) 4341 4342 cert = builder.sign(issuer_private_key, hashes.SHA256(), backend) 4343 4344 ext = cert.extensions.get_extension_for_oid(ExtensionOID.OCSP_NO_CHECK) 4345 assert isinstance(ext.value, x509.OCSPNoCheck) 4346 4347 4348@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, 4355 backend, 4356 ) 4357 assert isinstance(cert.signature_hash_algorithm, hashes.SHA1) 4358 public_key = cert.public_key() 4359 assert isinstance(public_key, dsa.DSAPublicKey) 4360 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" 4370 "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c", 4371 16, 4372 ) 4373 assert num.parameter_numbers.g == int( 4374 "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67" 4375 "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b" 4376 "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2" 4377 "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa" 4378 "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f" 4379 "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a" 4380 "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0" 4381 "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76" 4382 "fa6247676a6d3ac945844a083509c6a1b436baca", 4383 16, 4384 ) 4385 assert num.parameter_numbers.p == int( 4386 "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3" 4387 "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330" 4388 "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e" 4389 "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a" 4390 "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4" 4391 "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2" 4392 "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93" 4393 "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d" 4394 "833e36468f3907cfca788a3cb790f0341c8a31bf", 4395 16, 4396 ) 4397 assert num.parameter_numbers.q == int( 4398 "822ff5d234e073b901cf5941f58e1f538e71d40d", 16 4399 ) 4400 4401 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, 4405 backend, 4406 ) 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 4415 def test_tbs_certificate_bytes(self, backend): 4416 cert = _load_cert( 4417 os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"), 4418 x509.load_pem_x509_certificate, 4419 backend, 4420 ) 4421 assert cert.tbs_certificate_bytes == binascii.unhexlify( 4422 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 ) 4465 cert.public_key().verify( 4466 cert.signature, 4467 cert.tbs_certificate_bytes, 4468 cert.signature_hash_algorithm, 4469 ) 4470 4471 4472@pytest.mark.requires_backend_interface(interface=DSABackend) 4473@pytest.mark.requires_backend_interface(interface=X509Backend) 4474class TestDSACertificateRequest(object): 4475 @pytest.mark.parametrize( 4476 ("path", "loader_func"), 4477 [ 4478 [ 4479 os.path.join("x509", "requests", "dsa_sha1.pem"), 4480 x509.load_pem_x509_csr, 4481 ], 4482 [ 4483 os.path.join("x509", "requests", "dsa_sha1.der"), 4484 x509.load_der_x509_csr, 4485 ], 4486 ], 4487 ) 4488 def test_load_dsa_request(self, path, loader_func, backend): 4489 request = _load_cert(path, loader_func, backend) 4490 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) == [ 4496 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"), 4501 ] 4502 4503 def test_signature(self, backend): 4504 request = _load_cert( 4505 os.path.join("x509", "requests", "dsa_sha1.pem"), 4506 x509.load_pem_x509_csr, 4507 backend, 4508 ) 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, 4518 backend, 4519 ) 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 ) 4539 request.public_key().verify( 4540 request.signature, 4541 request.tbs_certrequest_bytes, 4542 request.signature_hash_algorithm, 4543 ) 4544 4545 4546@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) 4547@pytest.mark.requires_backend_interface(interface=X509Backend) 4548class TestECDSACertificate(object): 4549 def test_load_ecdsa_cert(self, backend): 4550 _skip_curve_unsupported(backend, ec.SECP384R1()) 4551 cert = _load_cert( 4552 os.path.join("x509", "ecdsa_root.pem"), 4553 x509.load_pem_x509_certificate, 4554 backend, 4555 ) 4556 assert isinstance(cert.signature_hash_algorithm, hashes.SHA384) 4557 public_key = cert.public_key() 4558 assert isinstance(public_key, ec.EllipticCurvePublicKey) 4559 num = public_key.public_numbers() 4560 assert num.x == int( 4561 "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f" 4562 "6f0ccd00bba615b51467e9e2d9fee8e630c17", 4563 16, 4564 ) 4565 assert num.y == int( 4566 "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7" 4567 "2deae88a7a16bb543ce67dc23ff031ca3e23e", 4568 16, 4569 ) 4570 assert isinstance(num.curve, ec.SECP384R1) 4571 4572 def test_signature(self, backend): 4573 cert = _load_cert( 4574 os.path.join("x509", "ecdsa_root.pem"), 4575 x509.load_pem_x509_certificate, 4576 backend, 4577 ) 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", 4588 16, 4589 ) 4590 assert s == int( 4591 "39665bc2648db89e50dca8d549a2edc7dcd1497f1701b8c8868f4e8c882ba89a" 4592 "a98ac5d100bdf854e29ae55b7cb32717", 4593 16, 4594 ) 4595 4596 def test_tbs_certificate_bytes(self, backend): 4597 _skip_curve_unsupported(backend, ec.SECP384R1()) 4598 cert = _load_cert( 4599 os.path.join("x509", "ecdsa_root.pem"), 4600 x509.load_pem_x509_certificate, 4601 backend, 4602 ) 4603 assert cert.tbs_certificate_bytes == binascii.unhexlify( 4604 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 ) 4620 cert.public_key().verify( 4621 cert.signature, 4622 cert.tbs_certificate_bytes, 4623 ec.ECDSA(cert.signature_hash_algorithm), 4624 ) 4625 4626 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, 4631 backend, 4632 ) 4633 with pytest.raises(NotImplementedError): 4634 cert.public_key() 4635 4636 4637@pytest.mark.requires_backend_interface(interface=X509Backend) 4638@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) 4639class TestECDSACertificateRequest(object): 4640 @pytest.mark.parametrize( 4641 ("path", "loader_func"), 4642 [ 4643 [ 4644 os.path.join("x509", "requests", "ec_sha256.pem"), 4645 x509.load_pem_x509_csr, 4646 ], 4647 [ 4648 os.path.join("x509", "requests", "ec_sha256.der"), 4649 x509.load_der_x509_csr, 4650 ], 4651 ], 4652 ) 4653 def test_load_ecdsa_certificate_request(self, path, loader_func, backend): 4654 _skip_curve_unsupported(backend, ec.SECP384R1()) 4655 request = _load_cert(path, loader_func, backend) 4656 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) == [ 4662 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"), 4667 ] 4668 4669 def test_signature(self, backend): 4670 _skip_curve_unsupported(backend, ec.SECP384R1()) 4671 request = _load_cert( 4672 os.path.join("x509", "requests", "ec_sha256.pem"), 4673 x509.load_pem_x509_csr, 4674 backend, 4675 ) 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): 4684 _skip_curve_unsupported(backend, ec.SECP384R1()) 4685 request = _load_cert( 4686 os.path.join("x509", "requests", "ec_sha256.pem"), 4687 x509.load_pem_x509_csr, 4688 backend, 4689 ) 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 ) 4699 request.public_key().verify( 4700 request.signature, 4701 request.tbs_certrequest_bytes, 4702 ec.ECDSA(request.signature_hash_algorithm), 4703 ) 4704 4705 4706@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 4720 def test_bad_time_in_validity(self, backend): 4721 cert = _load_cert( 4722 os.path.join("x509", "badasn1time.pem"), 4723 x509.load_pem_x509_certificate, 4724 backend, 4725 ) 4726 4727 with pytest.raises(ValueError, match="19020701025736Z"): 4728 cert.not_valid_after 4729 4730 4731class TestNameAttribute(object): 4732 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), 4753 (NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME, _ASN1Type.UTF8String), 4754 (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 4770 def test_init_bad_oid(self): 4771 with pytest.raises(TypeError): 4772 x509.NameAttribute(None, u"value") 4773 4774 def test_init_bad_value(self): 4775 with pytest.raises(TypeError): 4776 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) 4781 4782 def test_init_bad_country_code_value(self): 4783 with pytest.raises(ValueError): 4784 x509.NameAttribute(NameOID.COUNTRY_NAME, u"United States") 4785 4786 # unicode string of length 2, but > 2 bytes 4787 with pytest.raises(ValueError): 4788 x509.NameAttribute(NameOID.COUNTRY_NAME, u"\U0001F37A\U0001F37A") 4789 4790 def test_invalid_type(self): 4791 with pytest.raises(TypeError): 4792 x509.NameAttribute(NameOID.COMMON_NAME, u"common", "notanenum") 4793 4794 def test_eq(self): 4795 assert x509.NameAttribute( 4796 x509.ObjectIdentifier("2.999.1"), u"value" 4797 ) == x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value") 4798 4799 def test_ne(self): 4800 assert x509.NameAttribute( 4801 x509.ObjectIdentifier("2.5.4.3"), u"value" 4802 ) != x509.NameAttribute(x509.ObjectIdentifier("2.5.4.5"), u"value") 4803 assert x509.NameAttribute( 4804 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() 4809 ) 4810 4811 def test_repr(self): 4812 na = x509.NameAttribute(x509.ObjectIdentifier("2.5.4.3"), u"value") 4813 if not six.PY2: 4814 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 ) 4823 4824 def test_distinugished_name(self): 4825 # Escaping 4826 na = x509.NameAttribute(NameOID.COMMON_NAME, u'James "Jim" Smith, III') 4827 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\ " 4830 4831 # Nonstandard attribute OID 4832 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=" 4840 4841 4842class 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): 4852 with pytest.raises(ValueError): 4853 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 ) 4863 4864 def test_hash(self): 4865 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 ) 4895 assert hash(rdn1) == hash(rdn2) 4896 assert hash(rdn1) != hash(rdn3) 4897 4898 def test_eq(self): 4899 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 ) 4919 assert rdn1 == rdn2 4920 4921 def test_ne(self): 4922 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 ) 4942 assert rdn1 != rdn2 4943 assert rdn1 != object() 4944 4945 def test_iter_input(self): 4946 # Order must be preserved too 4947 attrs = [ 4948 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"), 4951 ] 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): 4957 oid = x509.ObjectIdentifier("2.999.1") 4958 attr = x509.NameAttribute(oid, u"value1") 4959 rdn = x509.RelativeDistinguishedName([attr]) 4960 assert rdn.get_attributes_for_oid(oid) == [attr] 4961 assert rdn.get_attributes_for_oid(x509.ObjectIdentifier("1.2.3")) == [] 4962 4963 4964class TestObjectIdentifier(object): 4965 def test_eq(self): 4966 oid1 = x509.ObjectIdentifier("2.999.1") 4967 oid2 = x509.ObjectIdentifier("2.999.1") 4968 assert oid1 == oid2 4969 4970 def test_ne(self): 4971 oid1 = x509.ObjectIdentifier("2.999.1") 4972 assert oid1 != x509.ObjectIdentifier("2.999.2") 4973 assert oid1 != object() 4974 4975 def test_repr(self): 4976 oid = x509.ObjectIdentifier("2.5.4.3") 4977 assert repr(oid) == "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>" 4978 oid = x509.ObjectIdentifier("2.999.1") 4979 assert repr(oid) == "<ObjectIdentifier(oid=2.999.1, name=Unknown OID)>" 4980 4981 def test_name_property(self): 4982 oid = x509.ObjectIdentifier("2.5.4.3") 4983 assert oid._name == "commonName" 4984 oid = x509.ObjectIdentifier("2.999.1") 4985 assert oid._name == "Unknown OID" 4986 4987 def test_too_short(self): 4988 with pytest.raises(ValueError): 4989 x509.ObjectIdentifier("1") 4990 4991 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 5010 5011class TestName(object): 5012 def test_eq(self): 5013 ava1 = x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1") 5014 ava2 = x509.NameAttribute(x509.ObjectIdentifier("2.999.2"), u"value2") 5015 name1 = x509.Name([ava1, ava2]) 5016 name2 = x509.Name( 5017 [ 5018 x509.RelativeDistinguishedName([ava1]), 5019 x509.RelativeDistinguishedName([ava2]), 5020 ] 5021 ) 5022 name3 = x509.Name([x509.RelativeDistinguishedName([ava1, ava2])]) 5023 name4 = x509.Name([x509.RelativeDistinguishedName([ava2, ava1])]) 5024 assert name1 == name2 5025 assert name3 == name4 5026 5027 def test_ne(self): 5028 ava1 = x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1") 5029 ava2 = x509.NameAttribute(x509.ObjectIdentifier("2.999.2"), u"value2") 5030 name1 = x509.Name([ava1, ava2]) 5031 name2 = x509.Name([ava2, ava1]) 5032 name3 = x509.Name([x509.RelativeDistinguishedName([ava1, ava2])]) 5033 assert name1 != name2 5034 assert name1 != name3 5035 assert name1 != object() 5036 5037 def test_hash(self): 5038 ava1 = x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1") 5039 ava2 = x509.NameAttribute(x509.ObjectIdentifier("2.999.2"), u"value2") 5040 name1 = x509.Name([ava1, ava2]) 5041 name2 = x509.Name( 5042 [ 5043 x509.RelativeDistinguishedName([ava1]), 5044 x509.RelativeDistinguishedName([ava2]), 5045 ] 5046 ) 5047 name3 = x509.Name([ava2, ava1]) 5048 name4 = x509.Name([x509.RelativeDistinguishedName([ava1, ava2])]) 5049 name5 = x509.Name([x509.RelativeDistinguishedName([ava2, ava1])]) 5050 assert hash(name1) == hash(name2) 5051 assert hash(name1) != hash(name3) 5052 assert hash(name1) != hash(name4) 5053 assert hash(name4) == hash(name5) 5054 5055 def test_iter_input(self): 5056 attrs = [ 5057 x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1") 5058 ] 5059 name = x509.Name(iter(attrs)) 5060 assert list(name) == attrs 5061 assert list(name) == attrs 5062 5063 def test_rdns(self): 5064 rdn1 = x509.NameAttribute(x509.ObjectIdentifier("2.999.1"), u"value1") 5065 rdn2 = x509.NameAttribute(x509.ObjectIdentifier("2.999.2"), u"value2") 5066 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 5074 @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 ) 5096 5097 assert repr(name) == expected_repr 5098 5099 def test_rfc4514_string(self): 5100 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" 5131 5132 def test_not_nameattribute(self): 5133 with pytest.raises(TypeError): 5134 x509.Name(["not-a-NameAttribute"]) 5135 5136 @pytest.mark.requires_backend_interface(interface=X509Backend) 5137 def test_bytes(self, backend): 5138 name = x509.Name( 5139 [ 5140 x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io"), 5141 x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"PyCA"), 5142 ] 5143 ) 5144 assert name.public_bytes(backend) == binascii.unhexlify( 5145 b"30293118301606035504030c0f63727970746f6772617068792e696f310d300" 5146 b"b060355040a0c0450794341" 5147 ) 5148 5149 @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. 5154 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 ) 5164 assert name.public_bytes(backend) == binascii.unhexlify( 5165 b"30383127302506035504031e1e00630072007900700074006f00670072006100" 5166 b"7000680079002e0069006f310d300b060355040a0c0450794341" 5167 ) 5168 5169 @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 5298 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 5310 assert serial_number == utils.int_from_bytes(sample_data, "big") >> 1 5311 assert serial_number.bit_length() < 160 5312