• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
4
5from __future__ import absolute_import, division, print_function
6
7import binascii
8import datetime
9import ipaddress
10import os
11
12from asn1crypto.x509 import Certificate
13
14import pytest
15
16import pytz
17
18import six
19
20from cryptography import utils, x509
21from cryptography.exceptions import UnsupportedAlgorithm
22from cryptography.hazmat.backends.interfaces import (
23    DSABackend, EllipticCurveBackend, RSABackend, X509Backend
24)
25from cryptography.hazmat.primitives import hashes, serialization
26from cryptography.hazmat.primitives.asymmetric import dsa, ec, padding, rsa
27from cryptography.hazmat.primitives.asymmetric.utils import (
28    decode_dss_signature
29)
30from cryptography.x509.name import _ASN1Type
31from cryptography.x509.oid import (
32    AuthorityInformationAccessOID, ExtendedKeyUsageOID, ExtensionOID,
33    NameOID, SignatureAlgorithmOID
34)
35
36from ..hazmat.primitives.fixtures_dsa import DSA_KEY_2048
37from ..hazmat.primitives.fixtures_ec import EC_KEY_SECP256R1
38from ..hazmat.primitives.fixtures_rsa import RSA_KEY_2048, RSA_KEY_512
39from ..hazmat.primitives.test_ec import _skip_curve_unsupported
40from ..utils import load_vectors_from_file
41
42
43@utils.register_interface(x509.ExtensionType)
44class DummyExtension(object):
45    oid = x509.ObjectIdentifier("1.2.3.4")
46
47
48@utils.register_interface(x509.GeneralName)
49class FakeGeneralName(object):
50    def __init__(self, value):
51        self._value = value
52
53    value = utils.read_only_property("_value")
54
55
56def _load_cert(filename, loader, backend):
57    cert = load_vectors_from_file(
58        filename=filename,
59        loader=lambda pemfile: loader(pemfile.read(), backend),
60        mode="rb"
61    )
62    return cert
63
64
65@pytest.mark.requires_backend_interface(interface=X509Backend)
66class TestCertificateRevocationList(object):
67    def test_load_pem_crl(self, backend):
68        crl = _load_cert(
69            os.path.join("x509", "custom", "crl_all_reasons.pem"),
70            x509.load_pem_x509_crl,
71            backend
72        )
73
74        assert isinstance(crl, x509.CertificateRevocationList)
75        fingerprint = binascii.hexlify(crl.fingerprint(hashes.SHA1()))
76        assert fingerprint == b"3234b0cb4c0cedf6423724b736729dcfc9e441ef"
77        assert isinstance(crl.signature_hash_algorithm, hashes.SHA256)
78        assert (
79            crl.signature_algorithm_oid ==
80            SignatureAlgorithmOID.RSA_WITH_SHA256
81        )
82
83    def test_load_der_crl(self, backend):
84        crl = _load_cert(
85            os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
86            x509.load_der_x509_crl,
87            backend
88        )
89
90        assert isinstance(crl, x509.CertificateRevocationList)
91        fingerprint = binascii.hexlify(crl.fingerprint(hashes.SHA1()))
92        assert fingerprint == b"dd3db63c50f4c4a13e090f14053227cb1011a5ad"
93        assert isinstance(crl.signature_hash_algorithm, hashes.SHA256)
94
95    def test_invalid_pem(self, backend):
96        with pytest.raises(ValueError):
97            x509.load_pem_x509_crl(b"notacrl", backend)
98
99    def test_invalid_der(self, backend):
100        with pytest.raises(ValueError):
101            x509.load_der_x509_crl(b"notacrl", backend)
102
103    def test_unknown_signature_algorithm(self, backend):
104        crl = _load_cert(
105            os.path.join(
106                "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
107            ),
108            x509.load_pem_x509_crl,
109            backend
110        )
111
112        with pytest.raises(UnsupportedAlgorithm):
113                crl.signature_hash_algorithm()
114
115    def test_issuer(self, backend):
116        crl = _load_cert(
117            os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
118            x509.load_der_x509_crl,
119            backend
120        )
121
122        assert isinstance(crl.issuer, x509.Name)
123        assert list(crl.issuer) == [
124            x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US'),
125            x509.NameAttribute(
126                x509.OID_ORGANIZATION_NAME, u'Test Certificates 2011'
127            ),
128            x509.NameAttribute(x509.OID_COMMON_NAME, u'Good CA')
129        ]
130        assert crl.issuer.get_attributes_for_oid(x509.OID_COMMON_NAME) == [
131            x509.NameAttribute(x509.OID_COMMON_NAME, u'Good CA')
132        ]
133
134    def test_equality(self, backend):
135        crl1 = _load_cert(
136            os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
137            x509.load_der_x509_crl,
138            backend
139        )
140
141        crl2 = _load_cert(
142            os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
143            x509.load_der_x509_crl,
144            backend
145        )
146
147        crl3 = _load_cert(
148            os.path.join("x509", "custom", "crl_all_reasons.pem"),
149            x509.load_pem_x509_crl,
150            backend
151        )
152
153        assert crl1 == crl2
154        assert crl1 != crl3
155        assert crl1 != object()
156
157    def test_update_dates(self, backend):
158        crl = _load_cert(
159            os.path.join("x509", "custom", "crl_all_reasons.pem"),
160            x509.load_pem_x509_crl,
161            backend
162        )
163
164        assert isinstance(crl.next_update, datetime.datetime)
165        assert isinstance(crl.last_update, datetime.datetime)
166
167        assert crl.next_update.isoformat() == "2016-01-01T00:00:00"
168        assert crl.last_update.isoformat() == "2015-01-01T00:00:00"
169
170    def test_revoked_cert_retrieval(self, backend):
171        crl = _load_cert(
172            os.path.join("x509", "custom", "crl_all_reasons.pem"),
173            x509.load_pem_x509_crl,
174            backend
175        )
176
177        for r in crl:
178            assert isinstance(r, x509.RevokedCertificate)
179
180        # Check that len() works for CRLs.
181        assert len(crl) == 12
182
183    def test_get_revoked_certificate_by_serial_number(self, backend):
184        crl = _load_cert(
185            os.path.join(
186                "x509", "PKITS_data", "crls", "LongSerialNumberCACRL.crl"),
187            x509.load_der_x509_crl,
188            backend
189        )
190        serial_number = 725064303890588110203033396814564464046290047507
191        revoked = crl.get_revoked_certificate_by_serial_number(serial_number)
192        assert revoked.serial_number == serial_number
193        assert crl.get_revoked_certificate_by_serial_number(500) is None
194
195    def test_revoked_cert_retrieval_retain_only_revoked(self, backend):
196        """
197        This test attempts to trigger the crash condition described in
198        https://github.com/pyca/cryptography/issues/2557
199        PyPy does gc at its own pace, so it will only be reliable on CPython.
200        """
201        revoked = _load_cert(
202            os.path.join("x509", "custom", "crl_all_reasons.pem"),
203            x509.load_pem_x509_crl,
204            backend
205        )[11]
206        assert revoked.revocation_date == datetime.datetime(2015, 1, 1, 0, 0)
207        assert revoked.serial_number == 11
208
209    def test_extensions(self, backend):
210        crl = _load_cert(
211            os.path.join("x509", "custom", "crl_ian_aia_aki.pem"),
212            x509.load_pem_x509_crl,
213            backend
214        )
215
216        crl_number = crl.extensions.get_extension_for_oid(
217            ExtensionOID.CRL_NUMBER
218        )
219        aki = crl.extensions.get_extension_for_class(
220            x509.AuthorityKeyIdentifier
221        )
222        aia = crl.extensions.get_extension_for_class(
223            x509.AuthorityInformationAccess
224        )
225        ian = crl.extensions.get_extension_for_class(
226            x509.IssuerAlternativeName
227        )
228        assert crl_number.value == x509.CRLNumber(1)
229        assert crl_number.critical is False
230        assert aki.value == x509.AuthorityKeyIdentifier(
231            key_identifier=(
232                b'yu\xbb\x84:\xcb,\xdez\t\xbe1\x1bC\xbc\x1c*MSX'
233            ),
234            authority_cert_issuer=None,
235            authority_cert_serial_number=None
236        )
237        assert aia.value == x509.AuthorityInformationAccess([
238            x509.AccessDescription(
239                AuthorityInformationAccessOID.CA_ISSUERS,
240                x509.DNSName(u"cryptography.io")
241            )
242        ])
243        assert ian.value == x509.IssuerAlternativeName([
244            x509.UniformResourceIdentifier(u"https://cryptography.io"),
245        ])
246
247    def test_delta_crl_indicator(self, backend):
248        crl = _load_cert(
249            os.path.join("x509", "custom", "crl_delta_crl_indicator.pem"),
250            x509.load_pem_x509_crl,
251            backend
252        )
253
254        dci = crl.extensions.get_extension_for_oid(
255            ExtensionOID.DELTA_CRL_INDICATOR
256        )
257        assert dci.value == x509.DeltaCRLIndicator(12345678901234567890)
258        assert dci.critical is False
259
260    def test_signature(self, backend):
261        crl = _load_cert(
262            os.path.join("x509", "custom", "crl_all_reasons.pem"),
263            x509.load_pem_x509_crl,
264            backend
265        )
266
267        assert crl.signature == binascii.unhexlify(
268            b"536a5a0794f68267361e7bc2f19167a3e667a2ab141535616855d8deb2ba1af"
269            b"9fd4546b1fe76b454eb436af7b28229fedff4634dfc9dd92254266219ae0ea8"
270            b"75d9ff972e9a2da23d5945f073da18c50a4265bfed9ca16586347800ef49dd1"
271            b"6856d7265f4f3c498a57f04dc04404e2bd2e2ada1f5697057aacef779a18371"
272            b"c621edc9a5c2b8ec1716e8fa22feeb7fcec0ce9156c8d344aa6ae8d1a5d99d0"
273            b"9386df36307df3b63c83908f4a61a0ff604c1e292ad63b349d1082ddd7ae1b7"
274            b"c178bba995523ec6999310c54da5706549797bfb1230f5593ba7b4353dade4f"
275            b"d2be13a57580a6eb20b5c4083f000abac3bf32cd8b75f23e4c8f4b3a79e1e2d"
276            b"58a472b0"
277        )
278
279    def test_tbs_certlist_bytes(self, backend):
280        crl = _load_cert(
281            os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
282            x509.load_der_x509_crl,
283            backend
284        )
285
286        ca_cert = _load_cert(
287            os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
288            x509.load_der_x509_certificate,
289            backend
290        )
291
292        ca_cert.public_key().verify(
293            crl.signature, crl.tbs_certlist_bytes,
294            padding.PKCS1v15(), crl.signature_hash_algorithm
295        )
296
297    def test_public_bytes_pem(self, backend):
298        crl = _load_cert(
299            os.path.join("x509", "custom", "crl_empty.pem"),
300            x509.load_pem_x509_crl,
301            backend
302        )
303
304        # Encode it to PEM and load it back.
305        crl = x509.load_pem_x509_crl(crl.public_bytes(
306            encoding=serialization.Encoding.PEM,
307        ), backend)
308
309        assert len(crl) == 0
310        assert crl.last_update == datetime.datetime(2015, 12, 20, 23, 44, 47)
311        assert crl.next_update == datetime.datetime(2015, 12, 28, 0, 44, 47)
312
313    def test_public_bytes_der(self, backend):
314        crl = _load_cert(
315            os.path.join("x509", "custom", "crl_all_reasons.pem"),
316            x509.load_pem_x509_crl,
317            backend
318        )
319
320        # Encode it to DER and load it back.
321        crl = x509.load_der_x509_crl(crl.public_bytes(
322            encoding=serialization.Encoding.DER,
323        ), backend)
324
325        assert len(crl) == 12
326        assert crl.last_update == datetime.datetime(2015, 1, 1, 0, 0, 0)
327        assert crl.next_update == datetime.datetime(2016, 1, 1, 0, 0, 0)
328
329    @pytest.mark.parametrize(
330        ("cert_path", "loader_func", "encoding"),
331        [
332            (
333                os.path.join("x509", "custom", "crl_all_reasons.pem"),
334                x509.load_pem_x509_crl,
335                serialization.Encoding.PEM,
336            ),
337            (
338                os.path.join("x509", "PKITS_data", "crls", "GoodCACRL.crl"),
339                x509.load_der_x509_crl,
340                serialization.Encoding.DER,
341            ),
342        ]
343    )
344    def test_public_bytes_match(self, cert_path, loader_func, encoding,
345                                backend):
346        crl_bytes = load_vectors_from_file(
347            cert_path, lambda pemfile: pemfile.read(), mode="rb"
348        )
349        crl = loader_func(crl_bytes, backend)
350        serialized = crl.public_bytes(encoding)
351        assert serialized == crl_bytes
352
353    def test_public_bytes_invalid_encoding(self, backend):
354        crl = _load_cert(
355            os.path.join("x509", "custom", "crl_empty.pem"),
356            x509.load_pem_x509_crl,
357            backend
358        )
359
360        with pytest.raises(TypeError):
361            crl.public_bytes('NotAnEncoding')
362
363    def test_verify_bad(self, backend):
364        crl = _load_cert(
365            os.path.join("x509", "custom", "invalid_signature.pem"),
366            x509.load_pem_x509_crl,
367            backend
368        )
369        crt = _load_cert(
370            os.path.join("x509", "custom", "invalid_signature.pem"),
371            x509.load_pem_x509_certificate,
372            backend
373        )
374
375        assert not crl.is_signature_valid(crt.public_key())
376
377    def test_verify_good(self, backend):
378        crl = _load_cert(
379            os.path.join("x509", "custom", "valid_signature.pem"),
380            x509.load_pem_x509_crl,
381            backend
382        )
383        crt = _load_cert(
384            os.path.join("x509", "custom", "valid_signature.pem"),
385            x509.load_pem_x509_certificate,
386            backend
387        )
388
389        assert crl.is_signature_valid(crt.public_key())
390
391    def test_verify_argument_must_be_a_public_key(self, backend):
392        crl = _load_cert(
393            os.path.join("x509", "custom", "valid_signature.pem"),
394            x509.load_pem_x509_crl,
395            backend
396        )
397
398        with pytest.raises(TypeError):
399            crl.is_signature_valid("not a public key")
400
401        with pytest.raises(TypeError):
402            crl.is_signature_valid(object)
403
404
405@pytest.mark.requires_backend_interface(interface=X509Backend)
406class TestRevokedCertificate(object):
407    def test_revoked_basics(self, backend):
408        crl = _load_cert(
409            os.path.join("x509", "custom", "crl_all_reasons.pem"),
410            x509.load_pem_x509_crl,
411            backend
412        )
413
414        for i, rev in enumerate(crl):
415            assert isinstance(rev, x509.RevokedCertificate)
416            assert isinstance(rev.serial_number, int)
417            assert isinstance(rev.revocation_date, datetime.datetime)
418            assert isinstance(rev.extensions, x509.Extensions)
419
420            assert rev.serial_number == i
421            assert rev.revocation_date.isoformat() == "2015-01-01T00:00:00"
422
423    def test_revoked_extensions(self, backend):
424        crl = _load_cert(
425            os.path.join("x509", "custom", "crl_all_reasons.pem"),
426            x509.load_pem_x509_crl,
427            backend
428        )
429
430        exp_issuer = [
431            x509.DirectoryName(x509.Name([
432                x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
433                x509.NameAttribute(x509.OID_COMMON_NAME, u"cryptography.io"),
434            ]))
435        ]
436
437        # First revoked cert doesn't have extensions, test if it is handled
438        # correctly.
439        rev0 = crl[0]
440        # It should return an empty Extensions object.
441        assert isinstance(rev0.extensions, x509.Extensions)
442        assert len(rev0.extensions) == 0
443        with pytest.raises(x509.ExtensionNotFound):
444            rev0.extensions.get_extension_for_oid(x509.OID_CRL_REASON)
445        with pytest.raises(x509.ExtensionNotFound):
446            rev0.extensions.get_extension_for_oid(x509.OID_CERTIFICATE_ISSUER)
447        with pytest.raises(x509.ExtensionNotFound):
448            rev0.extensions.get_extension_for_oid(x509.OID_INVALIDITY_DATE)
449
450        # Test manual retrieval of extension values.
451        rev1 = crl[1]
452        assert isinstance(rev1.extensions, x509.Extensions)
453
454        reason = rev1.extensions.get_extension_for_class(
455            x509.CRLReason).value
456        assert reason == x509.CRLReason(x509.ReasonFlags.unspecified)
457
458        issuer = rev1.extensions.get_extension_for_class(
459            x509.CertificateIssuer).value
460        assert issuer == x509.CertificateIssuer(exp_issuer)
461
462        date = rev1.extensions.get_extension_for_class(
463            x509.InvalidityDate).value
464        assert date == x509.InvalidityDate(datetime.datetime(2015, 1, 1, 0, 0))
465
466        # Check if all reason flags can be found in the CRL.
467        flags = set(x509.ReasonFlags)
468        for rev in crl:
469            try:
470                r = rev.extensions.get_extension_for_class(x509.CRLReason)
471            except x509.ExtensionNotFound:
472                # Not all revoked certs have a reason extension.
473                pass
474            else:
475                flags.discard(r.value.reason)
476
477        assert len(flags) == 0
478
479    def test_no_revoked_certs(self, backend):
480        crl = _load_cert(
481            os.path.join("x509", "custom", "crl_empty.pem"),
482            x509.load_pem_x509_crl,
483            backend
484        )
485        assert len(crl) == 0
486
487    def test_duplicate_entry_ext(self, backend):
488        crl = _load_cert(
489            os.path.join("x509", "custom", "crl_dup_entry_ext.pem"),
490            x509.load_pem_x509_crl,
491            backend
492        )
493
494        with pytest.raises(x509.DuplicateExtension):
495            crl[0].extensions
496
497    def test_unsupported_crit_entry_ext(self, backend):
498        crl = _load_cert(
499            os.path.join(
500                "x509", "custom", "crl_md2_unknown_crit_entry_ext.pem"
501            ),
502            x509.load_pem_x509_crl,
503            backend
504        )
505
506        ext = crl[0].extensions.get_extension_for_oid(
507            x509.ObjectIdentifier("1.2.3.4")
508        )
509        assert ext.value.value == b"\n\x01\x00"
510
511    def test_unsupported_reason(self, backend):
512        crl = _load_cert(
513            os.path.join(
514                "x509", "custom", "crl_unsupported_reason.pem"
515            ),
516            x509.load_pem_x509_crl,
517            backend
518        )
519
520        with pytest.raises(ValueError):
521            crl[0].extensions
522
523    def test_invalid_cert_issuer_ext(self, backend):
524        crl = _load_cert(
525            os.path.join(
526                "x509", "custom", "crl_inval_cert_issuer_entry_ext.pem"
527            ),
528            x509.load_pem_x509_crl,
529            backend
530        )
531
532        with pytest.raises(ValueError):
533            crl[0].extensions
534
535    def test_indexing(self, backend):
536        crl = _load_cert(
537            os.path.join("x509", "custom", "crl_all_reasons.pem"),
538            x509.load_pem_x509_crl,
539            backend
540        )
541
542        with pytest.raises(IndexError):
543            crl[-13]
544        with pytest.raises(IndexError):
545            crl[12]
546
547        assert crl[-1].serial_number == crl[11].serial_number
548        assert len(crl[2:4]) == 2
549        assert crl[2:4][0].serial_number == crl[2].serial_number
550        assert crl[2:4][1].serial_number == crl[3].serial_number
551
552    def test_get_revoked_certificate_doesnt_reorder(self, backend):
553        private_key = RSA_KEY_2048.private_key(backend)
554        last_update = datetime.datetime(2002, 1, 1, 12, 1)
555        next_update = datetime.datetime(2030, 1, 1, 12, 1)
556        builder = x509.CertificateRevocationListBuilder().issuer_name(
557            x509.Name([
558                x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io CA")
559            ])
560        ).last_update(
561            last_update
562        ).next_update(
563            next_update
564        )
565        for i in [2, 500, 3, 49, 7, 1]:
566            revoked_cert = x509.RevokedCertificateBuilder().serial_number(
567                i
568            ).revocation_date(
569                datetime.datetime(2012, 1, 1, 1, 1)
570            ).build(backend)
571            builder = builder.add_revoked_certificate(revoked_cert)
572        crl = builder.sign(private_key, hashes.SHA256(), backend)
573        assert crl[0].serial_number == 2
574        assert crl[2].serial_number == 3
575        # make sure get_revoked_certificate_by_serial_number doesn't affect
576        # ordering after being invoked
577        crl.get_revoked_certificate_by_serial_number(500)
578        assert crl[0].serial_number == 2
579        assert crl[2].serial_number == 3
580
581
582@pytest.mark.requires_backend_interface(interface=RSABackend)
583@pytest.mark.requires_backend_interface(interface=X509Backend)
584class TestRSACertificate(object):
585    def test_load_pem_cert(self, backend):
586        cert = _load_cert(
587            os.path.join("x509", "custom", "post2000utctime.pem"),
588            x509.load_pem_x509_certificate,
589            backend
590        )
591        assert isinstance(cert, x509.Certificate)
592        assert cert.serial_number == 11559813051657483483
593        fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
594        assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8"
595        assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
596        assert (
597            cert.signature_algorithm_oid == SignatureAlgorithmOID.RSA_WITH_SHA1
598        )
599
600    def test_alternate_rsa_with_sha1_oid(self, backend):
601        cert = _load_cert(
602            os.path.join("x509", "alternate-rsa-sha1-oid.pem"),
603            x509.load_pem_x509_certificate,
604            backend
605        )
606        assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
607        assert (
608            cert.signature_algorithm_oid ==
609            SignatureAlgorithmOID._RSA_WITH_SHA1
610        )
611
612    def test_cert_serial_number(self, backend):
613        cert = _load_cert(
614            os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
615            x509.load_der_x509_certificate,
616            backend
617        )
618
619        with pytest.warns(utils.CryptographyDeprecationWarning):
620            assert cert.serial == 2
621            assert cert.serial_number == 2
622
623    def test_cert_serial_warning(self, backend):
624        cert = _load_cert(
625            os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
626            x509.load_der_x509_certificate,
627            backend
628        )
629
630        with pytest.warns(utils.CryptographyDeprecationWarning):
631            cert.serial
632
633    def test_load_der_cert(self, backend):
634        cert = _load_cert(
635            os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
636            x509.load_der_x509_certificate,
637            backend
638        )
639        assert isinstance(cert, x509.Certificate)
640        assert cert.serial_number == 2
641        fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
642        assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
643        assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
644
645    def test_signature(self, backend):
646        cert = _load_cert(
647            os.path.join("x509", "custom", "post2000utctime.pem"),
648            x509.load_pem_x509_certificate,
649            backend
650        )
651        assert cert.signature == binascii.unhexlify(
652            b"8e0f72fcbebe4755abcaf76c8ce0bae17cde4db16291638e1b1ce04a93cdb4c"
653            b"44a3486070986c5a880c14fdf8497e7d289b2630ccb21d24a3d1aa1b2d87482"
654            b"07f3a1e16ccdf8daa8a7ea1a33d49774f513edf09270bd8e665b6300a10f003"
655            b"66a59076905eb63cf10a81a0ca78a6ef3127f6cb2f6fb7f947fce22a30d8004"
656            b"8c243ba2c1a54c425fe12310e8a737638f4920354d4cce25cbd9dea25e6a2fe"
657            b"0d8579a5c8d929b9275be221975479f3f75075bcacf09526523b5fd67f7683f"
658            b"3cda420fabb1e9e6fc26bc0649cf61bb051d6932fac37066bb16f55903dfe78"
659            b"53dc5e505e2a10fbba4f9e93a0d3b53b7fa34b05d7ba6eef869bfc34b8e514f"
660            b"d5419f75"
661        )
662        assert len(cert.signature) == cert.public_key().key_size // 8
663
664    def test_tbs_certificate_bytes(self, backend):
665        cert = _load_cert(
666            os.path.join("x509", "custom", "post2000utctime.pem"),
667            x509.load_pem_x509_certificate,
668            backend
669        )
670        assert cert.tbs_certificate_bytes == binascii.unhexlify(
671            b"308202d8a003020102020900a06cb4b955f7f4db300d06092a864886f70d010"
672            b"10505003058310b3009060355040613024155311330110603550408130a536f"
673            b"6d652d53746174653121301f060355040a1318496e7465726e6574205769646"
674            b"769747320507479204c74643111300f0603550403130848656c6c6f20434130"
675            b"1e170d3134313132363231343132305a170d3134313232363231343132305a3"
676            b"058310b3009060355040613024155311330110603550408130a536f6d652d53"
677            b"746174653121301f060355040a1318496e7465726e657420576964676974732"
678            b"0507479204c74643111300f0603550403130848656c6c6f2043413082012230"
679            b"0d06092a864886f70d01010105000382010f003082010a0282010100b03af70"
680            b"2059e27f1e2284b56bbb26c039153bf81f295b73a49132990645ede4d2da0a9"
681            b"13c42e7d38d3589a00d3940d194f6e6d877c2ef812da22a275e83d8be786467"
682            b"48b4e7f23d10e873fd72f57a13dec732fc56ab138b1bb308399bb412cd73921"
683            b"4ef714e1976e09603405e2556299a05522510ac4574db5e9cb2cf5f99e8f48c"
684            b"1696ab3ea2d6d2ddab7d4e1b317188b76a572977f6ece0a4ad396f0150e7d8b"
685            b"1a9986c0cb90527ec26ca56e2914c270d2a198b632fa8a2fda55079d3d39864"
686            b"b6fb96ddbe331cacb3cb8783a8494ccccd886a3525078847ca01ca5f803e892"
687            b"14403e8a4b5499539c0b86f7a0daa45b204a8e079d8a5b03db7ba1ba3d7011a"
688            b"70203010001a381bc3081b9301d0603551d0e04160414d8e89dc777e4472656"
689            b"f1864695a9f66b7b0400ae3081890603551d23048181307f8014d8e89dc777e"
690            b"4472656f1864695a9f66b7b0400aea15ca45a3058310b300906035504061302"
691            b"4155311330110603550408130a536f6d652d53746174653121301f060355040"
692            b"a1318496e7465726e6574205769646769747320507479204c74643111300f06"
693            b"03550403130848656c6c6f204341820900a06cb4b955f7f4db300c0603551d1"
694            b"3040530030101ff"
695        )
696        cert.public_key().verify(
697            cert.signature, cert.tbs_certificate_bytes,
698            padding.PKCS1v15(), cert.signature_hash_algorithm
699        )
700
701    def test_issuer(self, backend):
702        cert = _load_cert(
703            os.path.join(
704                "x509", "PKITS_data", "certs",
705                "Validpre2000UTCnotBeforeDateTest3EE.crt"
706            ),
707            x509.load_der_x509_certificate,
708            backend
709        )
710        issuer = cert.issuer
711        assert isinstance(issuer, x509.Name)
712        assert list(issuer) == [
713            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
714            x509.NameAttribute(
715                NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
716            ),
717            x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
718        ]
719        assert issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
720            x509.NameAttribute(NameOID.COMMON_NAME, u'Good CA')
721        ]
722
723    def test_all_issuer_name_types(self, backend):
724        cert = _load_cert(
725            os.path.join(
726                "x509", "custom",
727                "all_supported_names.pem"
728            ),
729            x509.load_pem_x509_certificate,
730            backend
731        )
732        issuer = cert.issuer
733
734        assert isinstance(issuer, x509.Name)
735        assert list(issuer) == [
736            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
737            x509.NameAttribute(NameOID.COUNTRY_NAME, u'CA'),
738            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
739            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Illinois'),
740            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Chicago'),
741            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
742            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Zero, LLC'),
743            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'One, LLC'),
744            x509.NameAttribute(NameOID.COMMON_NAME, u'common name 0'),
745            x509.NameAttribute(NameOID.COMMON_NAME, u'common name 1'),
746            x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 0'),
747            x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'OU 1'),
748            x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier0'),
749            x509.NameAttribute(NameOID.DN_QUALIFIER, u'dnQualifier1'),
750            x509.NameAttribute(NameOID.SERIAL_NUMBER, u'123'),
751            x509.NameAttribute(NameOID.SERIAL_NUMBER, u'456'),
752            x509.NameAttribute(NameOID.TITLE, u'Title 0'),
753            x509.NameAttribute(NameOID.TITLE, u'Title 1'),
754            x509.NameAttribute(NameOID.SURNAME, u'Surname 0'),
755            x509.NameAttribute(NameOID.SURNAME, u'Surname 1'),
756            x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 0'),
757            x509.NameAttribute(NameOID.GIVEN_NAME, u'Given Name 1'),
758            x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 0'),
759            x509.NameAttribute(NameOID.PSEUDONYM, u'Incognito 1'),
760            x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Last Gen'),
761            x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Next Gen'),
762            x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc0'),
763            x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc1'),
764            x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test0@test.local'),
765            x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test1@test.local'),
766        ]
767
768    def test_subject(self, backend):
769        cert = _load_cert(
770            os.path.join(
771                "x509", "PKITS_data", "certs",
772                "Validpre2000UTCnotBeforeDateTest3EE.crt"
773            ),
774            x509.load_der_x509_certificate,
775            backend
776        )
777        subject = cert.subject
778        assert isinstance(subject, x509.Name)
779        assert list(subject) == [
780            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
781            x509.NameAttribute(
782                NameOID.ORGANIZATION_NAME, u'Test Certificates 2011'
783            ),
784            x509.NameAttribute(
785                NameOID.COMMON_NAME,
786                u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
787            )
788        ]
789        assert subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
790            x509.NameAttribute(
791                NameOID.COMMON_NAME,
792                u'Valid pre2000 UTC notBefore Date EE Certificate Test3'
793            )
794        ]
795
796    def test_unicode_name(self, backend):
797        cert = _load_cert(
798            os.path.join(
799                "x509", "custom",
800                "utf8_common_name.pem"
801            ),
802            x509.load_pem_x509_certificate,
803            backend
804        )
805        assert cert.subject.get_attributes_for_oid(NameOID.COMMON_NAME) == [
806            x509.NameAttribute(
807                NameOID.COMMON_NAME,
808                u'We heart UTF8!\u2122'
809            )
810        ]
811        assert cert.issuer.get_attributes_for_oid(NameOID.COMMON_NAME) == [
812            x509.NameAttribute(
813                NameOID.COMMON_NAME,
814                u'We heart UTF8!\u2122'
815            )
816        ]
817
818    def test_non_ascii_dns_name(self, backend):
819        cert = _load_cert(
820            os.path.join("x509", "utf8-dnsname.pem"),
821            x509.load_pem_x509_certificate,
822            backend
823        )
824        san = cert.extensions.get_extension_for_class(
825            x509.SubjectAlternativeName
826        ).value
827
828        names = san.get_values_for_type(x509.DNSName)
829
830        assert names == [
831            u'partner.biztositas.hu', u'biztositas.hu', u'*.biztositas.hu',
832            u'biztos\xedt\xe1s.hu', u'*.biztos\xedt\xe1s.hu',
833            u'xn--biztosts-fza2j.hu', u'*.xn--biztosts-fza2j.hu'
834        ]
835
836    def test_all_subject_name_types(self, backend):
837        cert = _load_cert(
838            os.path.join(
839                "x509", "custom",
840                "all_supported_names.pem"
841            ),
842            x509.load_pem_x509_certificate,
843            backend
844        )
845        subject = cert.subject
846        assert isinstance(subject, x509.Name)
847        assert list(subject) == [
848            x509.NameAttribute(NameOID.COUNTRY_NAME, u'AU'),
849            x509.NameAttribute(NameOID.COUNTRY_NAME, u'DE'),
850            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'California'),
851            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'New York'),
852            x509.NameAttribute(NameOID.LOCALITY_NAME, u'San Francisco'),
853            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Ithaca'),
854            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org Zero, LLC'),
855            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'Org One, LLC'),
856            x509.NameAttribute(NameOID.COMMON_NAME, u'CN 0'),
857            x509.NameAttribute(NameOID.COMMON_NAME, u'CN 1'),
858            x509.NameAttribute(
859                NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 0'
860            ),
861            x509.NameAttribute(
862                NameOID.ORGANIZATIONAL_UNIT_NAME, u'Engineering 1'
863            ),
864            x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified0'),
865            x509.NameAttribute(NameOID.DN_QUALIFIER, u'qualified1'),
866            x509.NameAttribute(NameOID.SERIAL_NUMBER, u'789'),
867            x509.NameAttribute(NameOID.SERIAL_NUMBER, u'012'),
868            x509.NameAttribute(NameOID.TITLE, u'Title IX'),
869            x509.NameAttribute(NameOID.TITLE, u'Title X'),
870            x509.NameAttribute(NameOID.SURNAME, u'Last 0'),
871            x509.NameAttribute(NameOID.SURNAME, u'Last 1'),
872            x509.NameAttribute(NameOID.GIVEN_NAME, u'First 0'),
873            x509.NameAttribute(NameOID.GIVEN_NAME, u'First 1'),
874            x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 0'),
875            x509.NameAttribute(NameOID.PSEUDONYM, u'Guy Incognito 1'),
876            x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'32X'),
877            x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u'Dreamcast'),
878            x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc2'),
879            x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'dc3'),
880            x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test2@test.local'),
881            x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'test3@test.local'),
882        ]
883
884    def test_load_good_ca_cert(self, backend):
885        cert = _load_cert(
886            os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
887            x509.load_der_x509_certificate,
888            backend
889        )
890
891        assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
892        assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
893        assert cert.serial_number == 2
894        public_key = cert.public_key()
895        assert isinstance(public_key, rsa.RSAPublicKey)
896        assert cert.version is x509.Version.v3
897        fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
898        assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
899
900    def test_utc_pre_2000_not_before_cert(self, backend):
901        cert = _load_cert(
902            os.path.join(
903                "x509", "PKITS_data", "certs",
904                "Validpre2000UTCnotBeforeDateTest3EE.crt"
905            ),
906            x509.load_der_x509_certificate,
907            backend
908        )
909
910        assert cert.not_valid_before == datetime.datetime(1950, 1, 1, 12, 1)
911
912    def test_pre_2000_utc_not_after_cert(self, backend):
913        cert = _load_cert(
914            os.path.join(
915                "x509", "PKITS_data", "certs",
916                "Invalidpre2000UTCEEnotAfterDateTest7EE.crt"
917            ),
918            x509.load_der_x509_certificate,
919            backend
920        )
921
922        assert cert.not_valid_after == datetime.datetime(1999, 1, 1, 12, 1)
923
924    def test_post_2000_utc_cert(self, backend):
925        cert = _load_cert(
926            os.path.join("x509", "custom", "post2000utctime.pem"),
927            x509.load_pem_x509_certificate,
928            backend
929        )
930        assert cert.not_valid_before == datetime.datetime(
931            2014, 11, 26, 21, 41, 20
932        )
933        assert cert.not_valid_after == datetime.datetime(
934            2014, 12, 26, 21, 41, 20
935        )
936
937    def test_generalized_time_not_before_cert(self, backend):
938        cert = _load_cert(
939            os.path.join(
940                "x509", "PKITS_data", "certs",
941                "ValidGeneralizedTimenotBeforeDateTest4EE.crt"
942            ),
943            x509.load_der_x509_certificate,
944            backend
945        )
946        assert cert.not_valid_before == datetime.datetime(2002, 1, 1, 12, 1)
947        assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
948        assert cert.version is x509.Version.v3
949
950    def test_generalized_time_not_after_cert(self, backend):
951        cert = _load_cert(
952            os.path.join(
953                "x509", "PKITS_data", "certs",
954                "ValidGeneralizedTimenotAfterDateTest8EE.crt"
955            ),
956            x509.load_der_x509_certificate,
957            backend
958        )
959        assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
960        assert cert.not_valid_after == datetime.datetime(2050, 1, 1, 12, 1)
961        assert cert.version is x509.Version.v3
962
963    def test_invalid_version_cert(self, backend):
964        cert = _load_cert(
965            os.path.join("x509", "custom", "invalid_version.pem"),
966            x509.load_pem_x509_certificate,
967            backend
968        )
969        with pytest.raises(x509.InvalidVersion) as exc:
970            cert.version
971
972        assert exc.value.parsed_version == 7
973
974    def test_eq(self, backend):
975        cert = _load_cert(
976            os.path.join("x509", "custom", "post2000utctime.pem"),
977            x509.load_pem_x509_certificate,
978            backend
979        )
980        cert2 = _load_cert(
981            os.path.join("x509", "custom", "post2000utctime.pem"),
982            x509.load_pem_x509_certificate,
983            backend
984        )
985        assert cert == cert2
986
987    def test_ne(self, backend):
988        cert = _load_cert(
989            os.path.join("x509", "custom", "post2000utctime.pem"),
990            x509.load_pem_x509_certificate,
991            backend
992        )
993        cert2 = _load_cert(
994            os.path.join(
995                "x509", "PKITS_data", "certs",
996                "ValidGeneralizedTimenotAfterDateTest8EE.crt"
997            ),
998            x509.load_der_x509_certificate,
999            backend
1000        )
1001        assert cert != cert2
1002        assert cert != object()
1003
1004    def test_hash(self, backend):
1005        cert1 = _load_cert(
1006            os.path.join("x509", "custom", "post2000utctime.pem"),
1007            x509.load_pem_x509_certificate,
1008            backend
1009        )
1010        cert2 = _load_cert(
1011            os.path.join("x509", "custom", "post2000utctime.pem"),
1012            x509.load_pem_x509_certificate,
1013            backend
1014        )
1015        cert3 = _load_cert(
1016            os.path.join(
1017                "x509", "PKITS_data", "certs",
1018                "ValidGeneralizedTimenotAfterDateTest8EE.crt"
1019            ),
1020            x509.load_der_x509_certificate,
1021            backend
1022        )
1023
1024        assert hash(cert1) == hash(cert2)
1025        assert hash(cert1) != hash(cert3)
1026
1027    def test_version_1_cert(self, backend):
1028        cert = _load_cert(
1029            os.path.join("x509", "v1_cert.pem"),
1030            x509.load_pem_x509_certificate,
1031            backend
1032        )
1033        assert cert.version is x509.Version.v1
1034
1035    def test_invalid_pem(self, backend):
1036        with pytest.raises(ValueError):
1037            x509.load_pem_x509_certificate(b"notacert", backend)
1038
1039    def test_invalid_der(self, backend):
1040        with pytest.raises(ValueError):
1041            x509.load_der_x509_certificate(b"notacert", backend)
1042
1043    def test_unsupported_signature_hash_algorithm_cert(self, backend):
1044        cert = _load_cert(
1045            os.path.join("x509", "verisign_md2_root.pem"),
1046            x509.load_pem_x509_certificate,
1047            backend
1048        )
1049        with pytest.raises(UnsupportedAlgorithm):
1050            cert.signature_hash_algorithm
1051
1052    def test_public_bytes_pem(self, backend):
1053        # Load an existing certificate.
1054        cert = _load_cert(
1055            os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
1056            x509.load_der_x509_certificate,
1057            backend
1058        )
1059
1060        # Encode it to PEM and load it back.
1061        cert = x509.load_pem_x509_certificate(cert.public_bytes(
1062            encoding=serialization.Encoding.PEM,
1063        ), backend)
1064
1065        # We should recover what we had to start with.
1066        assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
1067        assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
1068        assert cert.serial_number == 2
1069        public_key = cert.public_key()
1070        assert isinstance(public_key, rsa.RSAPublicKey)
1071        assert cert.version is x509.Version.v3
1072        fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
1073        assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
1074
1075    def test_public_bytes_der(self, backend):
1076        # Load an existing certificate.
1077        cert = _load_cert(
1078            os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
1079            x509.load_der_x509_certificate,
1080            backend
1081        )
1082
1083        # Encode it to DER and load it back.
1084        cert = x509.load_der_x509_certificate(cert.public_bytes(
1085            encoding=serialization.Encoding.DER,
1086        ), backend)
1087
1088        # We should recover what we had to start with.
1089        assert cert.not_valid_before == datetime.datetime(2010, 1, 1, 8, 30)
1090        assert cert.not_valid_after == datetime.datetime(2030, 12, 31, 8, 30)
1091        assert cert.serial_number == 2
1092        public_key = cert.public_key()
1093        assert isinstance(public_key, rsa.RSAPublicKey)
1094        assert cert.version is x509.Version.v3
1095        fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
1096        assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
1097
1098    def test_public_bytes_invalid_encoding(self, backend):
1099        cert = _load_cert(
1100            os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
1101            x509.load_der_x509_certificate,
1102            backend
1103        )
1104
1105        with pytest.raises(TypeError):
1106            cert.public_bytes('NotAnEncoding')
1107
1108    @pytest.mark.parametrize(
1109        ("cert_path", "loader_func", "encoding"),
1110        [
1111            (
1112                os.path.join("x509", "v1_cert.pem"),
1113                x509.load_pem_x509_certificate,
1114                serialization.Encoding.PEM,
1115            ),
1116            (
1117                os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),
1118                x509.load_der_x509_certificate,
1119                serialization.Encoding.DER,
1120            ),
1121        ]
1122    )
1123    def test_public_bytes_match(self, cert_path, loader_func, encoding,
1124                                backend):
1125        cert_bytes = load_vectors_from_file(
1126            cert_path, lambda pemfile: pemfile.read(), mode="rb"
1127        )
1128        cert = loader_func(cert_bytes, backend)
1129        serialized = cert.public_bytes(encoding)
1130        assert serialized == cert_bytes
1131
1132    def test_certificate_repr(self, backend):
1133        cert = _load_cert(
1134            os.path.join(
1135                "x509", "cryptography.io.pem"
1136            ),
1137            x509.load_pem_x509_certificate,
1138            backend
1139        )
1140        assert repr(cert) == (
1141            "<Certificate(subject=<Name(OU=GT48742965,OU=See www.rapidssl.com"
1142            "/resources/cps (c)14,OU=Domain Control Validated - RapidSSL(R),"
1143            "CN=www.cryptography.io)>, ...)>"
1144        )
1145
1146    def test_parse_tls_feature_extension(self, backend):
1147        cert = _load_cert(
1148            os.path.join("x509", "tls-feature-ocsp-staple.pem"),
1149            x509.load_pem_x509_certificate,
1150            backend
1151        )
1152        ext = cert.extensions.get_extension_for_class(x509.TLSFeature)
1153        assert ext.critical is False
1154        assert ext.value == x509.TLSFeature(
1155            [x509.TLSFeatureType.status_request]
1156        )
1157
1158
1159@pytest.mark.requires_backend_interface(interface=RSABackend)
1160@pytest.mark.requires_backend_interface(interface=X509Backend)
1161class TestRSACertificateRequest(object):
1162    @pytest.mark.parametrize(
1163        ("path", "loader_func"),
1164        [
1165            [
1166                os.path.join("x509", "requests", "rsa_sha1.pem"),
1167                x509.load_pem_x509_csr
1168            ],
1169            [
1170                os.path.join("x509", "requests", "rsa_sha1.der"),
1171                x509.load_der_x509_csr
1172            ],
1173        ]
1174    )
1175    def test_load_rsa_certificate_request(self, path, loader_func, backend):
1176        request = _load_cert(path, loader_func, backend)
1177        assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1178        assert (
1179            request.signature_algorithm_oid ==
1180            SignatureAlgorithmOID.RSA_WITH_SHA1
1181        )
1182        public_key = request.public_key()
1183        assert isinstance(public_key, rsa.RSAPublicKey)
1184        subject = request.subject
1185        assert isinstance(subject, x509.Name)
1186        assert list(subject) == [
1187            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1188            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1189            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1190            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1191            x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
1192        ]
1193        extensions = request.extensions
1194        assert isinstance(extensions, x509.Extensions)
1195        assert list(extensions) == []
1196
1197    @pytest.mark.parametrize(
1198        "loader_func",
1199        [x509.load_pem_x509_csr, x509.load_der_x509_csr]
1200    )
1201    def test_invalid_certificate_request(self, loader_func, backend):
1202        with pytest.raises(ValueError):
1203            loader_func(b"notacsr", backend)
1204
1205    def test_unsupported_signature_hash_algorithm_request(self, backend):
1206        request = _load_cert(
1207            os.path.join("x509", "requests", "rsa_md4.pem"),
1208            x509.load_pem_x509_csr,
1209            backend
1210        )
1211        with pytest.raises(UnsupportedAlgorithm):
1212            request.signature_hash_algorithm
1213
1214    def test_duplicate_extension(self, backend):
1215        request = _load_cert(
1216            os.path.join(
1217                "x509", "requests", "two_basic_constraints.pem"
1218            ),
1219            x509.load_pem_x509_csr,
1220            backend
1221        )
1222        with pytest.raises(x509.DuplicateExtension) as exc:
1223            request.extensions
1224
1225        assert exc.value.oid == ExtensionOID.BASIC_CONSTRAINTS
1226
1227    def test_unsupported_critical_extension(self, backend):
1228        request = _load_cert(
1229            os.path.join(
1230                "x509", "requests", "unsupported_extension_critical.pem"
1231            ),
1232            x509.load_pem_x509_csr,
1233            backend
1234        )
1235        ext = request.extensions.get_extension_for_oid(
1236            x509.ObjectIdentifier('1.2.3.4')
1237        )
1238        assert ext.value.value == b"value"
1239
1240    def test_unsupported_extension(self, backend):
1241        request = _load_cert(
1242            os.path.join(
1243                "x509", "requests", "unsupported_extension.pem"
1244            ),
1245            x509.load_pem_x509_csr,
1246            backend
1247        )
1248        extensions = request.extensions
1249        assert len(extensions) == 1
1250        assert extensions[0].oid == x509.ObjectIdentifier("1.2.3.4")
1251        assert extensions[0].value == x509.UnrecognizedExtension(
1252            x509.ObjectIdentifier("1.2.3.4"), b"value"
1253        )
1254
1255    def test_request_basic_constraints(self, backend):
1256        request = _load_cert(
1257            os.path.join(
1258                "x509", "requests", "basic_constraints.pem"
1259            ),
1260            x509.load_pem_x509_csr,
1261            backend
1262        )
1263        extensions = request.extensions
1264        assert isinstance(extensions, x509.Extensions)
1265        assert list(extensions) == [
1266            x509.Extension(
1267                ExtensionOID.BASIC_CONSTRAINTS,
1268                True,
1269                x509.BasicConstraints(ca=True, path_length=1),
1270            ),
1271        ]
1272
1273    def test_subject_alt_name(self, backend):
1274        request = _load_cert(
1275            os.path.join("x509", "requests", "san_rsa_sha1.pem"),
1276            x509.load_pem_x509_csr,
1277            backend,
1278        )
1279        ext = request.extensions.get_extension_for_oid(
1280            ExtensionOID.SUBJECT_ALTERNATIVE_NAME
1281        )
1282        assert list(ext.value) == [
1283            x509.DNSName(u"cryptography.io"),
1284            x509.DNSName(u"sub.cryptography.io"),
1285        ]
1286
1287    def test_public_bytes_pem(self, backend):
1288        # Load an existing CSR.
1289        request = _load_cert(
1290            os.path.join("x509", "requests", "rsa_sha1.pem"),
1291            x509.load_pem_x509_csr,
1292            backend
1293        )
1294
1295        # Encode it to PEM and load it back.
1296        request = x509.load_pem_x509_csr(request.public_bytes(
1297            encoding=serialization.Encoding.PEM,
1298        ), backend)
1299
1300        # We should recover what we had to start with.
1301        assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1302        public_key = request.public_key()
1303        assert isinstance(public_key, rsa.RSAPublicKey)
1304        subject = request.subject
1305        assert isinstance(subject, x509.Name)
1306        assert list(subject) == [
1307            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1308            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1309            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1310            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1311            x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
1312        ]
1313
1314    def test_public_bytes_der(self, backend):
1315        # Load an existing CSR.
1316        request = _load_cert(
1317            os.path.join("x509", "requests", "rsa_sha1.pem"),
1318            x509.load_pem_x509_csr,
1319            backend
1320        )
1321
1322        # Encode it to DER and load it back.
1323        request = x509.load_der_x509_csr(request.public_bytes(
1324            encoding=serialization.Encoding.DER,
1325        ), backend)
1326
1327        # We should recover what we had to start with.
1328        assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
1329        public_key = request.public_key()
1330        assert isinstance(public_key, rsa.RSAPublicKey)
1331        subject = request.subject
1332        assert isinstance(subject, x509.Name)
1333        assert list(subject) == [
1334            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1335            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1336            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1337            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1338            x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
1339        ]
1340
1341    def test_signature(self, backend):
1342        request = _load_cert(
1343            os.path.join("x509", "requests", "rsa_sha1.pem"),
1344            x509.load_pem_x509_csr,
1345            backend
1346        )
1347        assert request.signature == binascii.unhexlify(
1348            b"8364c86ffbbfe0bfc9a21f831256658ca8989741b80576d36f08a934603a43b1"
1349            b"837246d00167a518abb1de7b51a1e5b7ebea14944800818b1a923c804f120a0d"
1350            b"624f6310ef79e8612755c2b01dcc7f59dfdbce0db3f2630f185f504b8c17af80"
1351            b"cbd364fa5fda68337153930948226cd4638287a0aed6524d3006885c19028a1e"
1352            b"e2f5a91d6e77dbaa0b49996ee0a0c60b55b61bd080a08bb34aa7f3e07e91f37f"
1353            b"6a11645be2d8654c1570dcda145ed7cc92017f7d53225d7f283f3459ec5bda41"
1354            b"cf6dd75d43676c543483385226b7e4fa29c8739f1b0eaf199613593991979862"
1355            b"e36181e8c4c270c354b7f52c128db1b70639823324c7ea24791b7bc3d7005f3b"
1356        )
1357
1358    def test_tbs_certrequest_bytes(self, backend):
1359        request = _load_cert(
1360            os.path.join("x509", "requests", "rsa_sha1.pem"),
1361            x509.load_pem_x509_csr,
1362            backend
1363        )
1364        assert request.tbs_certrequest_bytes == binascii.unhexlify(
1365            b"308201840201003057310b3009060355040613025553310e300c060355040813"
1366            b"055465786173310f300d0603550407130641757374696e310d300b060355040a"
1367            b"130450794341311830160603550403130f63727970746f6772617068792e696f"
1368            b"30820122300d06092a864886f70d01010105000382010f003082010a02820101"
1369            b"00a840a78460cb861066dfa3045a94ba6cf1b7ab9d24c761cffddcc2cb5e3f1d"
1370            b"c3e4be253e7039ef14fe9d6d2304f50d9f2e1584c51530ab75086f357138bff7"
1371            b"b854d067d1d5f384f1f2f2c39cc3b15415e2638554ef8402648ae3ef08336f22"
1372            b"b7ecc6d4331c2b21c3091a7f7a9518180754a646640b60419e4cc6f5c798110a"
1373            b"7f030a639fe87e33b4776dfcd993940ec776ab57a181ad8598857976dc303f9a"
1374            b"573ca619ab3fe596328e92806b828683edc17cc256b41948a2bfa8d047d2158d"
1375            b"3d8e069aa05fa85b3272abb1c4b4422b6366f3b70e642377b145cd6259e5d3e7"
1376            b"db048d51921e50766a37b1b130ee6b11f507d20a834001e8de16a92c14f2e964"
1377            b"a30203010001a000"
1378        )
1379        request.public_key().verify(
1380            request.signature,
1381            request.tbs_certrequest_bytes,
1382            padding.PKCS1v15(),
1383            request.signature_hash_algorithm
1384        )
1385
1386    def test_public_bytes_invalid_encoding(self, backend):
1387        request = _load_cert(
1388            os.path.join("x509", "requests", "rsa_sha1.pem"),
1389            x509.load_pem_x509_csr,
1390            backend
1391        )
1392
1393        with pytest.raises(TypeError):
1394            request.public_bytes('NotAnEncoding')
1395
1396    def test_signature_invalid(self, backend):
1397        request = _load_cert(
1398            os.path.join("x509", "requests", "invalid_signature.pem"),
1399            x509.load_pem_x509_csr,
1400            backend
1401        )
1402        assert not request.is_signature_valid
1403
1404    def test_signature_valid(self, backend):
1405        request = _load_cert(
1406            os.path.join("x509", "requests", "rsa_sha256.pem"),
1407            x509.load_pem_x509_csr,
1408            backend
1409        )
1410        assert request.is_signature_valid
1411
1412    @pytest.mark.parametrize(
1413        ("request_path", "loader_func", "encoding"),
1414        [
1415            (
1416                os.path.join("x509", "requests", "rsa_sha1.pem"),
1417                x509.load_pem_x509_csr,
1418                serialization.Encoding.PEM,
1419            ),
1420            (
1421                os.path.join("x509", "requests", "rsa_sha1.der"),
1422                x509.load_der_x509_csr,
1423                serialization.Encoding.DER,
1424            ),
1425        ]
1426    )
1427    def test_public_bytes_match(self, request_path, loader_func, encoding,
1428                                backend):
1429        request_bytes = load_vectors_from_file(
1430            request_path, lambda pemfile: pemfile.read(), mode="rb"
1431        )
1432        request = loader_func(request_bytes, backend)
1433        serialized = request.public_bytes(encoding)
1434        assert serialized == request_bytes
1435
1436    def test_eq(self, backend):
1437        request1 = _load_cert(
1438            os.path.join("x509", "requests", "rsa_sha1.pem"),
1439            x509.load_pem_x509_csr,
1440            backend
1441        )
1442        request2 = _load_cert(
1443            os.path.join("x509", "requests", "rsa_sha1.pem"),
1444            x509.load_pem_x509_csr,
1445            backend
1446        )
1447
1448        assert request1 == request2
1449
1450    def test_ne(self, backend):
1451        request1 = _load_cert(
1452            os.path.join("x509", "requests", "rsa_sha1.pem"),
1453            x509.load_pem_x509_csr,
1454            backend
1455        )
1456        request2 = _load_cert(
1457            os.path.join("x509", "requests", "san_rsa_sha1.pem"),
1458            x509.load_pem_x509_csr,
1459            backend
1460        )
1461
1462        assert request1 != request2
1463        assert request1 != object()
1464
1465    def test_hash(self, backend):
1466        request1 = _load_cert(
1467            os.path.join("x509", "requests", "rsa_sha1.pem"),
1468            x509.load_pem_x509_csr,
1469            backend
1470        )
1471        request2 = _load_cert(
1472            os.path.join("x509", "requests", "rsa_sha1.pem"),
1473            x509.load_pem_x509_csr,
1474            backend
1475        )
1476        request3 = _load_cert(
1477            os.path.join("x509", "requests", "san_rsa_sha1.pem"),
1478            x509.load_pem_x509_csr,
1479            backend
1480        )
1481
1482        assert hash(request1) == hash(request2)
1483        assert hash(request1) != hash(request3)
1484
1485    def test_build_cert(self, backend):
1486        issuer_private_key = RSA_KEY_2048.private_key(backend)
1487        subject_private_key = RSA_KEY_2048.private_key(backend)
1488
1489        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1490        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1491
1492        builder = x509.CertificateBuilder().serial_number(
1493            777
1494        ).issuer_name(x509.Name([
1495            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1496            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1497            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1498            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1499            x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
1500        ])).subject_name(x509.Name([
1501            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1502            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1503            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1504            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
1505            x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
1506        ])).public_key(
1507            subject_private_key.public_key()
1508        ).add_extension(
1509            x509.BasicConstraints(ca=False, path_length=None), True,
1510        ).add_extension(
1511            x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
1512            critical=False,
1513        ).not_valid_before(
1514            not_valid_before
1515        ).not_valid_after(
1516            not_valid_after
1517        )
1518
1519        cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
1520
1521        assert cert.version is x509.Version.v3
1522        assert cert.not_valid_before == not_valid_before
1523        assert cert.not_valid_after == not_valid_after
1524        basic_constraints = cert.extensions.get_extension_for_oid(
1525            ExtensionOID.BASIC_CONSTRAINTS
1526        )
1527        assert basic_constraints.value.ca is False
1528        assert basic_constraints.value.path_length is None
1529        subject_alternative_name = cert.extensions.get_extension_for_oid(
1530            ExtensionOID.SUBJECT_ALTERNATIVE_NAME
1531        )
1532        assert list(subject_alternative_name.value) == [
1533            x509.DNSName(u"cryptography.io"),
1534        ]
1535
1536    def test_build_cert_private_type_encoding(self, backend):
1537        issuer_private_key = RSA_KEY_2048.private_key(backend)
1538        subject_private_key = RSA_KEY_2048.private_key(backend)
1539        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1540        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1541        name = x509.Name([
1542            x509.NameAttribute(
1543                NameOID.STATE_OR_PROVINCE_NAME, u'Texas',
1544                _ASN1Type.PrintableString),
1545            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
1546            x509.NameAttribute(
1547                NameOID.COMMON_NAME, u'cryptography.io', _ASN1Type.IA5String),
1548        ])
1549        builder = x509.CertificateBuilder().serial_number(
1550            777
1551        ).issuer_name(
1552            name
1553        ).subject_name(
1554            name
1555        ).public_key(
1556            subject_private_key.public_key()
1557        ).not_valid_before(
1558            not_valid_before
1559        ).not_valid_after(not_valid_after)
1560        cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
1561
1562        for dn in (cert.subject, cert.issuer):
1563            assert dn.get_attributes_for_oid(
1564                NameOID.STATE_OR_PROVINCE_NAME
1565            )[0]._type == _ASN1Type.PrintableString
1566            assert dn.get_attributes_for_oid(
1567                NameOID.STATE_OR_PROVINCE_NAME
1568            )[0]._type == _ASN1Type.PrintableString
1569            assert dn.get_attributes_for_oid(
1570                NameOID.LOCALITY_NAME
1571            )[0]._type == _ASN1Type.UTF8String
1572
1573    def test_build_cert_printable_string_country_name(self, backend):
1574        issuer_private_key = RSA_KEY_2048.private_key(backend)
1575        subject_private_key = RSA_KEY_2048.private_key(backend)
1576
1577        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
1578        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
1579
1580        builder = x509.CertificateBuilder().serial_number(
1581            777
1582        ).issuer_name(x509.Name([
1583            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1584            x509.NameAttribute(NameOID.JURISDICTION_COUNTRY_NAME, u'US'),
1585            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1586        ])).subject_name(x509.Name([
1587            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1588            x509.NameAttribute(NameOID.JURISDICTION_COUNTRY_NAME, u'US'),
1589            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
1590        ])).public_key(
1591            subject_private_key.public_key()
1592        ).not_valid_before(
1593            not_valid_before
1594        ).not_valid_after(
1595            not_valid_after
1596        )
1597
1598        cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
1599
1600        parsed = Certificate.load(
1601            cert.public_bytes(serialization.Encoding.DER))
1602
1603        # Check that each value was encoded as an ASN.1 PRINTABLESTRING.
1604        assert parsed.subject.chosen[0][0]['value'].chosen.tag == 19
1605        assert parsed.issuer.chosen[0][0]['value'].chosen.tag == 19
1606        if (
1607            # This only works correctly in OpenSSL 1.1.0f+ and 1.0.2l+
1608            backend._lib.CRYPTOGRAPHY_OPENSSL_110F_OR_GREATER or (
1609                backend._lib.CRYPTOGRAPHY_OPENSSL_102L_OR_GREATER and
1610                not backend._lib.CRYPTOGRAPHY_OPENSSL_110_OR_GREATER
1611            )
1612        ):
1613            assert parsed.subject.chosen[1][0]['value'].chosen.tag == 19
1614            assert parsed.issuer.chosen[1][0]['value'].chosen.tag == 19
1615
1616
1617class TestCertificateBuilder(object):
1618    @pytest.mark.requires_backend_interface(interface=RSABackend)
1619    @pytest.mark.requires_backend_interface(interface=X509Backend)
1620    def test_checks_for_unsupported_extensions(self, backend):
1621        private_key = RSA_KEY_2048.private_key(backend)
1622        builder = x509.CertificateBuilder().subject_name(x509.Name([
1623            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1624        ])).issuer_name(x509.Name([
1625            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1626        ])).public_key(
1627            private_key.public_key()
1628        ).serial_number(
1629            777
1630        ).not_valid_before(
1631            datetime.datetime(1999, 1, 1)
1632        ).not_valid_after(
1633            datetime.datetime(2020, 1, 1)
1634        ).add_extension(
1635            DummyExtension(), False
1636        )
1637
1638        with pytest.raises(NotImplementedError):
1639            builder.sign(private_key, hashes.SHA1(), backend)
1640
1641    @pytest.mark.requires_backend_interface(interface=RSABackend)
1642    @pytest.mark.requires_backend_interface(interface=X509Backend)
1643    def test_encode_nonstandard_aia(self, backend):
1644        private_key = RSA_KEY_2048.private_key(backend)
1645
1646        aia = x509.AuthorityInformationAccess([
1647            x509.AccessDescription(
1648                x509.ObjectIdentifier("2.999.7"),
1649                x509.UniformResourceIdentifier(u"http://example.com")
1650            ),
1651        ])
1652
1653        builder = x509.CertificateBuilder().subject_name(x509.Name([
1654            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1655        ])).issuer_name(x509.Name([
1656            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1657        ])).public_key(
1658            private_key.public_key()
1659        ).serial_number(
1660            777
1661        ).not_valid_before(
1662            datetime.datetime(1999, 1, 1)
1663        ).not_valid_after(
1664            datetime.datetime(2020, 1, 1)
1665        ).add_extension(
1666            aia, False
1667        )
1668
1669        builder.sign(private_key, hashes.SHA256(), backend)
1670
1671    @pytest.mark.requires_backend_interface(interface=RSABackend)
1672    @pytest.mark.requires_backend_interface(interface=X509Backend)
1673    def test_subject_dn_asn1_types(self, backend):
1674        private_key = RSA_KEY_2048.private_key(backend)
1675
1676        name = x509.Name([
1677            x509.NameAttribute(NameOID.COMMON_NAME, u"mysite.com"),
1678            x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
1679            x509.NameAttribute(NameOID.LOCALITY_NAME, u"value"),
1680            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"value"),
1681            x509.NameAttribute(NameOID.STREET_ADDRESS, u"value"),
1682            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"value"),
1683            x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u"value"),
1684            x509.NameAttribute(NameOID.SERIAL_NUMBER, u"value"),
1685            x509.NameAttribute(NameOID.SURNAME, u"value"),
1686            x509.NameAttribute(NameOID.GIVEN_NAME, u"value"),
1687            x509.NameAttribute(NameOID.TITLE, u"value"),
1688            x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u"value"),
1689            x509.NameAttribute(NameOID.X500_UNIQUE_IDENTIFIER, u"value"),
1690            x509.NameAttribute(NameOID.DN_QUALIFIER, u"value"),
1691            x509.NameAttribute(NameOID.PSEUDONYM, u"value"),
1692            x509.NameAttribute(NameOID.USER_ID, u"value"),
1693            x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u"value"),
1694            x509.NameAttribute(NameOID.EMAIL_ADDRESS, u"value"),
1695            x509.NameAttribute(NameOID.JURISDICTION_COUNTRY_NAME, u"US"),
1696            x509.NameAttribute(NameOID.JURISDICTION_LOCALITY_NAME, u"value"),
1697            x509.NameAttribute(
1698                NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME, u"value"
1699            ),
1700            x509.NameAttribute(NameOID.BUSINESS_CATEGORY, u"value"),
1701            x509.NameAttribute(NameOID.POSTAL_ADDRESS, u"value"),
1702            x509.NameAttribute(NameOID.POSTAL_CODE, u"value"),
1703        ])
1704        cert = x509.CertificateBuilder().subject_name(
1705            name
1706        ).issuer_name(
1707            name
1708        ).public_key(
1709            private_key.public_key()
1710        ).serial_number(
1711            777
1712        ).not_valid_before(
1713            datetime.datetime(1999, 1, 1)
1714        ).not_valid_after(
1715            datetime.datetime(2020, 1, 1)
1716        ).sign(private_key, hashes.SHA256(), backend)
1717
1718        for dn in (cert.subject, cert.issuer):
1719            for oid, asn1_type in TestNameAttribute.EXPECTED_TYPES:
1720                assert dn.get_attributes_for_oid(
1721                    oid
1722                )[0]._type == asn1_type
1723
1724    @pytest.mark.parametrize(
1725        ("not_valid_before", "not_valid_after"),
1726        [
1727            [datetime.datetime(1970, 2, 1), datetime.datetime(9999, 1, 1)],
1728            [datetime.datetime(1970, 2, 1), datetime.datetime(9999, 12, 31)],
1729        ]
1730    )
1731    @pytest.mark.requires_backend_interface(interface=RSABackend)
1732    @pytest.mark.requires_backend_interface(interface=X509Backend)
1733    def test_extreme_times(self, not_valid_before, not_valid_after, backend):
1734        private_key = RSA_KEY_2048.private_key(backend)
1735        builder = x509.CertificateBuilder().subject_name(x509.Name([
1736            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1737        ])).issuer_name(x509.Name([
1738            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1739        ])).public_key(
1740            private_key.public_key()
1741        ).serial_number(
1742            777
1743        ).not_valid_before(
1744            not_valid_before
1745        ).not_valid_after(
1746            not_valid_after
1747        )
1748        cert = builder.sign(private_key, hashes.SHA256(), backend)
1749        assert cert.not_valid_before == not_valid_before
1750        assert cert.not_valid_after == not_valid_after
1751        parsed = Certificate.load(
1752            cert.public_bytes(serialization.Encoding.DER)
1753        )
1754        not_before = parsed['tbs_certificate']['validity']['not_before']
1755        not_after = parsed['tbs_certificate']['validity']['not_after']
1756        assert not_before.chosen.tag == 23  # UTCTime
1757        assert not_after.chosen.tag == 24  # GeneralizedTime
1758
1759    @pytest.mark.requires_backend_interface(interface=RSABackend)
1760    @pytest.mark.requires_backend_interface(interface=X509Backend)
1761    def test_no_subject_name(self, backend):
1762        subject_private_key = RSA_KEY_2048.private_key(backend)
1763        builder = x509.CertificateBuilder().serial_number(
1764            777
1765        ).issuer_name(x509.Name([
1766            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1767        ])).public_key(
1768            subject_private_key.public_key()
1769        ).not_valid_before(
1770            datetime.datetime(2002, 1, 1, 12, 1)
1771        ).not_valid_after(
1772            datetime.datetime(2030, 12, 31, 8, 30)
1773        )
1774        with pytest.raises(ValueError):
1775            builder.sign(subject_private_key, hashes.SHA256(), backend)
1776
1777    @pytest.mark.requires_backend_interface(interface=RSABackend)
1778    @pytest.mark.requires_backend_interface(interface=X509Backend)
1779    def test_no_issuer_name(self, backend):
1780        subject_private_key = RSA_KEY_2048.private_key(backend)
1781        builder = x509.CertificateBuilder().serial_number(
1782            777
1783        ).subject_name(x509.Name([
1784            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1785        ])).public_key(
1786            subject_private_key.public_key()
1787        ).not_valid_before(
1788            datetime.datetime(2002, 1, 1, 12, 1)
1789        ).not_valid_after(
1790            datetime.datetime(2030, 12, 31, 8, 30)
1791        )
1792        with pytest.raises(ValueError):
1793            builder.sign(subject_private_key, hashes.SHA256(), backend)
1794
1795    @pytest.mark.requires_backend_interface(interface=RSABackend)
1796    @pytest.mark.requires_backend_interface(interface=X509Backend)
1797    def test_no_public_key(self, backend):
1798        subject_private_key = RSA_KEY_2048.private_key(backend)
1799        builder = x509.CertificateBuilder().serial_number(
1800            777
1801        ).issuer_name(x509.Name([
1802            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1803        ])).subject_name(x509.Name([
1804            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1805        ])).not_valid_before(
1806            datetime.datetime(2002, 1, 1, 12, 1)
1807        ).not_valid_after(
1808            datetime.datetime(2030, 12, 31, 8, 30)
1809        )
1810        with pytest.raises(ValueError):
1811            builder.sign(subject_private_key, hashes.SHA256(), backend)
1812
1813    @pytest.mark.requires_backend_interface(interface=RSABackend)
1814    @pytest.mark.requires_backend_interface(interface=X509Backend)
1815    def test_no_not_valid_before(self, backend):
1816        subject_private_key = RSA_KEY_2048.private_key(backend)
1817        builder = x509.CertificateBuilder().serial_number(
1818            777
1819        ).issuer_name(x509.Name([
1820            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1821        ])).subject_name(x509.Name([
1822            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1823        ])).public_key(
1824            subject_private_key.public_key()
1825        ).not_valid_after(
1826            datetime.datetime(2030, 12, 31, 8, 30)
1827        )
1828        with pytest.raises(ValueError):
1829            builder.sign(subject_private_key, hashes.SHA256(), backend)
1830
1831    @pytest.mark.requires_backend_interface(interface=RSABackend)
1832    @pytest.mark.requires_backend_interface(interface=X509Backend)
1833    def test_no_not_valid_after(self, backend):
1834        subject_private_key = RSA_KEY_2048.private_key(backend)
1835        builder = x509.CertificateBuilder().serial_number(
1836            777
1837        ).issuer_name(x509.Name([
1838            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1839        ])).subject_name(x509.Name([
1840            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1841        ])).public_key(
1842            subject_private_key.public_key()
1843        ).not_valid_before(
1844            datetime.datetime(2002, 1, 1, 12, 1)
1845        )
1846        with pytest.raises(ValueError):
1847            builder.sign(subject_private_key, hashes.SHA256(), backend)
1848
1849    @pytest.mark.requires_backend_interface(interface=RSABackend)
1850    @pytest.mark.requires_backend_interface(interface=X509Backend)
1851    def test_no_serial_number(self, backend):
1852        subject_private_key = RSA_KEY_2048.private_key(backend)
1853        builder = x509.CertificateBuilder().issuer_name(x509.Name([
1854            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1855        ])).subject_name(x509.Name([
1856            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1857        ])).public_key(
1858            subject_private_key.public_key()
1859        ).not_valid_before(
1860            datetime.datetime(2002, 1, 1, 12, 1)
1861        ).not_valid_after(
1862            datetime.datetime(2030, 12, 31, 8, 30)
1863        )
1864        with pytest.raises(ValueError):
1865            builder.sign(subject_private_key, hashes.SHA256(), backend)
1866
1867    def test_issuer_name_must_be_a_name_type(self):
1868        builder = x509.CertificateBuilder()
1869
1870        with pytest.raises(TypeError):
1871            builder.issuer_name("subject")
1872
1873        with pytest.raises(TypeError):
1874            builder.issuer_name(object)
1875
1876    def test_issuer_name_may_only_be_set_once(self):
1877        name = x509.Name([
1878            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1879        ])
1880        builder = x509.CertificateBuilder().issuer_name(name)
1881
1882        with pytest.raises(ValueError):
1883            builder.issuer_name(name)
1884
1885    def test_subject_name_must_be_a_name_type(self):
1886        builder = x509.CertificateBuilder()
1887
1888        with pytest.raises(TypeError):
1889            builder.subject_name("subject")
1890
1891        with pytest.raises(TypeError):
1892            builder.subject_name(object)
1893
1894    def test_subject_name_may_only_be_set_once(self):
1895        name = x509.Name([
1896            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
1897        ])
1898        builder = x509.CertificateBuilder().subject_name(name)
1899
1900        with pytest.raises(ValueError):
1901            builder.subject_name(name)
1902
1903    def test_not_valid_before_after_not_valid_after(self):
1904        builder = x509.CertificateBuilder()
1905
1906        builder = builder.not_valid_after(
1907            datetime.datetime(2002, 1, 1, 12, 1)
1908        )
1909        with pytest.raises(ValueError):
1910            builder.not_valid_before(
1911                datetime.datetime(2003, 1, 1, 12, 1)
1912            )
1913
1914    def test_not_valid_after_before_not_valid_before(self):
1915        builder = x509.CertificateBuilder()
1916
1917        builder = builder.not_valid_before(
1918            datetime.datetime(2002, 1, 1, 12, 1)
1919        )
1920        with pytest.raises(ValueError):
1921            builder.not_valid_after(
1922                datetime.datetime(2001, 1, 1, 12, 1)
1923            )
1924
1925    @pytest.mark.requires_backend_interface(interface=RSABackend)
1926    @pytest.mark.requires_backend_interface(interface=X509Backend)
1927    def test_public_key_must_be_public_key(self, backend):
1928        private_key = RSA_KEY_2048.private_key(backend)
1929        builder = x509.CertificateBuilder()
1930
1931        with pytest.raises(TypeError):
1932            builder.public_key(private_key)
1933
1934    @pytest.mark.requires_backend_interface(interface=RSABackend)
1935    @pytest.mark.requires_backend_interface(interface=X509Backend)
1936    def test_public_key_may_only_be_set_once(self, backend):
1937        private_key = RSA_KEY_2048.private_key(backend)
1938        public_key = private_key.public_key()
1939        builder = x509.CertificateBuilder().public_key(public_key)
1940
1941        with pytest.raises(ValueError):
1942            builder.public_key(public_key)
1943
1944    def test_serial_number_must_be_an_integer_type(self):
1945        with pytest.raises(TypeError):
1946            x509.CertificateBuilder().serial_number(10.0)
1947
1948    def test_serial_number_must_be_non_negative(self):
1949        with pytest.raises(ValueError):
1950            x509.CertificateBuilder().serial_number(-1)
1951
1952    def test_serial_number_must_be_positive(self):
1953        with pytest.raises(ValueError):
1954            x509.CertificateBuilder().serial_number(0)
1955
1956    @pytest.mark.requires_backend_interface(interface=RSABackend)
1957    @pytest.mark.requires_backend_interface(interface=X509Backend)
1958    def test_minimal_serial_number(self, backend):
1959        subject_private_key = RSA_KEY_2048.private_key(backend)
1960        builder = x509.CertificateBuilder().serial_number(
1961            1
1962        ).subject_name(x509.Name([
1963            x509.NameAttribute(NameOID.COUNTRY_NAME, u'RU'),
1964        ])).issuer_name(x509.Name([
1965            x509.NameAttribute(NameOID.COUNTRY_NAME, u'RU'),
1966        ])).public_key(
1967            subject_private_key.public_key()
1968        ).not_valid_before(
1969            datetime.datetime(2002, 1, 1, 12, 1)
1970        ).not_valid_after(
1971            datetime.datetime(2030, 12, 31, 8, 30)
1972        )
1973        cert = builder.sign(subject_private_key, hashes.SHA256(), backend)
1974        assert cert.serial_number == 1
1975
1976    @pytest.mark.requires_backend_interface(interface=RSABackend)
1977    @pytest.mark.requires_backend_interface(interface=X509Backend)
1978    def test_biggest_serial_number(self, backend):
1979        subject_private_key = RSA_KEY_2048.private_key(backend)
1980        builder = x509.CertificateBuilder().serial_number(
1981            (1 << 159) - 1
1982        ).subject_name(x509.Name([
1983            x509.NameAttribute(NameOID.COUNTRY_NAME, u'RU'),
1984        ])).issuer_name(x509.Name([
1985            x509.NameAttribute(NameOID.COUNTRY_NAME, u'RU'),
1986        ])).public_key(
1987            subject_private_key.public_key()
1988        ).not_valid_before(
1989            datetime.datetime(2002, 1, 1, 12, 1)
1990        ).not_valid_after(
1991            datetime.datetime(2030, 12, 31, 8, 30)
1992        )
1993        cert = builder.sign(subject_private_key, hashes.SHA256(), backend)
1994        assert cert.serial_number == (1 << 159) - 1
1995
1996    def test_serial_number_must_be_less_than_160_bits_long(self):
1997        with pytest.raises(ValueError):
1998            x509.CertificateBuilder().serial_number(1 << 159)
1999
2000    def test_serial_number_may_only_be_set_once(self):
2001        builder = x509.CertificateBuilder().serial_number(10)
2002
2003        with pytest.raises(ValueError):
2004            builder.serial_number(20)
2005
2006    @pytest.mark.requires_backend_interface(interface=RSABackend)
2007    @pytest.mark.requires_backend_interface(interface=X509Backend)
2008    def test_aware_not_valid_after(self, backend):
2009        time = datetime.datetime(2012, 1, 16, 22, 43)
2010        tz = pytz.timezone("US/Pacific")
2011        time = tz.localize(time)
2012        utc_time = datetime.datetime(2012, 1, 17, 6, 43)
2013        private_key = RSA_KEY_2048.private_key(backend)
2014        cert_builder = x509.CertificateBuilder().not_valid_after(time)
2015        cert_builder = cert_builder.subject_name(
2016            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2017        ).issuer_name(
2018            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2019        ).serial_number(
2020            1
2021        ).public_key(
2022            private_key.public_key()
2023        ).not_valid_before(
2024            utc_time - datetime.timedelta(days=365)
2025        )
2026
2027        cert = cert_builder.sign(private_key, hashes.SHA256(), backend)
2028        assert cert.not_valid_after == utc_time
2029
2030    @pytest.mark.requires_backend_interface(interface=RSABackend)
2031    @pytest.mark.requires_backend_interface(interface=X509Backend)
2032    def test_earliest_time(self, backend):
2033        time = datetime.datetime(1950, 1, 1)
2034        private_key = RSA_KEY_2048.private_key(backend)
2035        cert_builder = x509.CertificateBuilder().subject_name(
2036            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2037        ).issuer_name(
2038            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2039        ).serial_number(
2040            1
2041        ).public_key(
2042            private_key.public_key()
2043        ).not_valid_before(
2044            time
2045        ).not_valid_after(
2046            time
2047        )
2048        cert = cert_builder.sign(private_key, hashes.SHA256(), backend)
2049        assert cert.not_valid_before == time
2050        assert cert.not_valid_after == time
2051        parsed = Certificate.load(
2052            cert.public_bytes(serialization.Encoding.DER)
2053        )
2054        not_before = parsed['tbs_certificate']['validity']['not_before']
2055        not_after = parsed['tbs_certificate']['validity']['not_after']
2056        assert not_before.chosen.tag == 23  # UTCTime
2057        assert not_after.chosen.tag == 23  # UTCTime
2058
2059    def test_invalid_not_valid_after(self):
2060        with pytest.raises(TypeError):
2061            x509.CertificateBuilder().not_valid_after(104204304504)
2062
2063        with pytest.raises(TypeError):
2064            x509.CertificateBuilder().not_valid_after(datetime.time())
2065
2066        with pytest.raises(ValueError):
2067            x509.CertificateBuilder().not_valid_after(
2068                datetime.datetime(1940, 8, 10)
2069            )
2070
2071    def test_not_valid_after_may_only_be_set_once(self):
2072        builder = x509.CertificateBuilder().not_valid_after(
2073            datetime.datetime.now()
2074        )
2075
2076        with pytest.raises(ValueError):
2077            builder.not_valid_after(
2078                datetime.datetime.now()
2079            )
2080
2081    @pytest.mark.requires_backend_interface(interface=RSABackend)
2082    @pytest.mark.requires_backend_interface(interface=X509Backend)
2083    def test_aware_not_valid_before(self, backend):
2084        time = datetime.datetime(2012, 1, 16, 22, 43)
2085        tz = pytz.timezone("US/Pacific")
2086        time = tz.localize(time)
2087        utc_time = datetime.datetime(2012, 1, 17, 6, 43)
2088        private_key = RSA_KEY_2048.private_key(backend)
2089        cert_builder = x509.CertificateBuilder().not_valid_before(time)
2090        cert_builder = cert_builder.subject_name(
2091            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2092        ).issuer_name(
2093            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2094        ).serial_number(
2095            1
2096        ).public_key(
2097            private_key.public_key()
2098        ).not_valid_after(
2099            utc_time + datetime.timedelta(days=366)
2100        )
2101
2102        cert = cert_builder.sign(private_key, hashes.SHA256(), backend)
2103        assert cert.not_valid_before == utc_time
2104
2105    def test_invalid_not_valid_before(self):
2106        with pytest.raises(TypeError):
2107            x509.CertificateBuilder().not_valid_before(104204304504)
2108
2109        with pytest.raises(TypeError):
2110            x509.CertificateBuilder().not_valid_before(datetime.time())
2111
2112        with pytest.raises(ValueError):
2113            x509.CertificateBuilder().not_valid_before(
2114                datetime.datetime(1940, 8, 10)
2115            )
2116
2117    def test_not_valid_before_may_only_be_set_once(self):
2118        builder = x509.CertificateBuilder().not_valid_before(
2119            datetime.datetime.now()
2120        )
2121
2122        with pytest.raises(ValueError):
2123            builder.not_valid_before(
2124                datetime.datetime.now()
2125            )
2126
2127    def test_add_extension_checks_for_duplicates(self):
2128        builder = x509.CertificateBuilder().add_extension(
2129            x509.BasicConstraints(ca=False, path_length=None), True,
2130        )
2131
2132        with pytest.raises(ValueError):
2133            builder.add_extension(
2134                x509.BasicConstraints(ca=False, path_length=None), True,
2135            )
2136
2137    def test_add_invalid_extension_type(self):
2138        builder = x509.CertificateBuilder()
2139
2140        with pytest.raises(TypeError):
2141            builder.add_extension(object(), False)
2142
2143    @pytest.mark.requires_backend_interface(interface=RSABackend)
2144    @pytest.mark.requires_backend_interface(interface=X509Backend)
2145    def test_sign_with_unsupported_hash(self, backend):
2146        private_key = RSA_KEY_2048.private_key(backend)
2147        builder = x509.CertificateBuilder()
2148        builder = builder.subject_name(
2149            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2150        ).issuer_name(
2151            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2152        ).serial_number(
2153            1
2154        ).public_key(
2155            private_key.public_key()
2156        ).not_valid_before(
2157            datetime.datetime(2002, 1, 1, 12, 1)
2158        ).not_valid_after(
2159            datetime.datetime(2032, 1, 1, 12, 1)
2160        )
2161
2162        with pytest.raises(TypeError):
2163            builder.sign(private_key, object(), backend)
2164
2165    @pytest.mark.requires_backend_interface(interface=RSABackend)
2166    @pytest.mark.requires_backend_interface(interface=X509Backend)
2167    def test_sign_rsa_with_md5(self, backend):
2168        private_key = RSA_KEY_2048.private_key(backend)
2169        builder = x509.CertificateBuilder()
2170        builder = builder.subject_name(
2171            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2172        ).issuer_name(
2173            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2174        ).serial_number(
2175            1
2176        ).public_key(
2177            private_key.public_key()
2178        ).not_valid_before(
2179            datetime.datetime(2002, 1, 1, 12, 1)
2180        ).not_valid_after(
2181            datetime.datetime(2032, 1, 1, 12, 1)
2182        )
2183        cert = builder.sign(private_key, hashes.MD5(), backend)
2184        assert isinstance(cert.signature_hash_algorithm, hashes.MD5)
2185
2186    @pytest.mark.requires_backend_interface(interface=DSABackend)
2187    @pytest.mark.requires_backend_interface(interface=X509Backend)
2188    def test_sign_dsa_with_md5(self, backend):
2189        private_key = DSA_KEY_2048.private_key(backend)
2190        builder = x509.CertificateBuilder()
2191        builder = builder.subject_name(
2192            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2193        ).issuer_name(
2194            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2195        ).serial_number(
2196            1
2197        ).public_key(
2198            private_key.public_key()
2199        ).not_valid_before(
2200            datetime.datetime(2002, 1, 1, 12, 1)
2201        ).not_valid_after(
2202            datetime.datetime(2032, 1, 1, 12, 1)
2203        )
2204        with pytest.raises(ValueError):
2205            builder.sign(private_key, hashes.MD5(), backend)
2206
2207    @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2208    @pytest.mark.requires_backend_interface(interface=X509Backend)
2209    def test_sign_ec_with_md5(self, backend):
2210        _skip_curve_unsupported(backend, ec.SECP256R1())
2211        private_key = EC_KEY_SECP256R1.private_key(backend)
2212        builder = x509.CertificateBuilder()
2213        builder = builder.subject_name(
2214            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2215        ).issuer_name(
2216            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2217        ).serial_number(
2218            1
2219        ).public_key(
2220            private_key.public_key()
2221        ).not_valid_before(
2222            datetime.datetime(2002, 1, 1, 12, 1)
2223        ).not_valid_after(
2224            datetime.datetime(2032, 1, 1, 12, 1)
2225        )
2226        with pytest.raises(ValueError):
2227            builder.sign(private_key, hashes.MD5(), backend)
2228
2229    @pytest.mark.requires_backend_interface(interface=DSABackend)
2230    @pytest.mark.requires_backend_interface(interface=X509Backend)
2231    def test_build_cert_with_dsa_private_key(self, backend):
2232        issuer_private_key = DSA_KEY_2048.private_key(backend)
2233        subject_private_key = DSA_KEY_2048.private_key(backend)
2234
2235        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2236        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2237
2238        builder = x509.CertificateBuilder().serial_number(
2239            777
2240        ).issuer_name(x509.Name([
2241            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2242        ])).subject_name(x509.Name([
2243            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2244        ])).public_key(
2245            subject_private_key.public_key()
2246        ).add_extension(
2247            x509.BasicConstraints(ca=False, path_length=None), True,
2248        ).add_extension(
2249            x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
2250            critical=False,
2251        ).not_valid_before(
2252            not_valid_before
2253        ).not_valid_after(
2254            not_valid_after
2255        )
2256
2257        cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2258
2259        assert cert.version is x509.Version.v3
2260        assert cert.not_valid_before == not_valid_before
2261        assert cert.not_valid_after == not_valid_after
2262        basic_constraints = cert.extensions.get_extension_for_oid(
2263            ExtensionOID.BASIC_CONSTRAINTS
2264        )
2265        assert basic_constraints.value.ca is False
2266        assert basic_constraints.value.path_length is None
2267        subject_alternative_name = cert.extensions.get_extension_for_oid(
2268            ExtensionOID.SUBJECT_ALTERNATIVE_NAME
2269        )
2270        assert list(subject_alternative_name.value) == [
2271            x509.DNSName(u"cryptography.io"),
2272        ]
2273
2274    @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2275    @pytest.mark.requires_backend_interface(interface=X509Backend)
2276    def test_build_cert_with_ec_private_key(self, backend):
2277        _skip_curve_unsupported(backend, ec.SECP256R1())
2278        issuer_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
2279        subject_private_key = ec.generate_private_key(ec.SECP256R1(), backend)
2280
2281        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2282        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2283
2284        builder = x509.CertificateBuilder().serial_number(
2285            777
2286        ).issuer_name(x509.Name([
2287            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2288        ])).subject_name(x509.Name([
2289            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2290        ])).public_key(
2291            subject_private_key.public_key()
2292        ).add_extension(
2293            x509.BasicConstraints(ca=False, path_length=None), True,
2294        ).add_extension(
2295            x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
2296            critical=False,
2297        ).not_valid_before(
2298            not_valid_before
2299        ).not_valid_after(
2300            not_valid_after
2301        )
2302
2303        cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
2304
2305        assert cert.version is x509.Version.v3
2306        assert cert.not_valid_before == not_valid_before
2307        assert cert.not_valid_after == not_valid_after
2308        basic_constraints = cert.extensions.get_extension_for_oid(
2309            ExtensionOID.BASIC_CONSTRAINTS
2310        )
2311        assert basic_constraints.value.ca is False
2312        assert basic_constraints.value.path_length is None
2313        subject_alternative_name = cert.extensions.get_extension_for_oid(
2314            ExtensionOID.SUBJECT_ALTERNATIVE_NAME
2315        )
2316        assert list(subject_alternative_name.value) == [
2317            x509.DNSName(u"cryptography.io"),
2318        ]
2319
2320    @pytest.mark.requires_backend_interface(interface=RSABackend)
2321    @pytest.mark.requires_backend_interface(interface=X509Backend)
2322    def test_build_cert_with_rsa_key_too_small(self, backend):
2323        issuer_private_key = RSA_KEY_512.private_key(backend)
2324        subject_private_key = RSA_KEY_512.private_key(backend)
2325
2326        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2327        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2328
2329        builder = x509.CertificateBuilder().serial_number(
2330            777
2331        ).issuer_name(x509.Name([
2332            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2333        ])).subject_name(x509.Name([
2334            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2335        ])).public_key(
2336            subject_private_key.public_key()
2337        ).not_valid_before(
2338            not_valid_before
2339        ).not_valid_after(
2340            not_valid_after
2341        )
2342
2343        with pytest.raises(ValueError):
2344            builder.sign(issuer_private_key, hashes.SHA512(), backend)
2345
2346    @pytest.mark.requires_backend_interface(interface=RSABackend)
2347    @pytest.mark.requires_backend_interface(interface=X509Backend)
2348    @pytest.mark.parametrize(
2349        "add_ext",
2350        [
2351            x509.SubjectAlternativeName(
2352                [
2353                    # These examples exist to verify compatibility with
2354                    # certificates that have utf8 encoded data in the ia5string
2355                    x509.DNSName._init_without_validation(u'a\xedt\xe1s.test'),
2356                    x509.RFC822Name._init_without_validation(
2357                        u'test@a\xedt\xe1s.test'
2358                    ),
2359                    x509.UniformResourceIdentifier._init_without_validation(
2360                        u'http://a\xedt\xe1s.test'
2361                    ),
2362                ]
2363            ),
2364            x509.CertificatePolicies([
2365                x509.PolicyInformation(
2366                    x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2367                    [u"http://other.com/cps"]
2368                )
2369            ]),
2370            x509.CertificatePolicies([
2371                x509.PolicyInformation(
2372                    x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2373                    None
2374                )
2375            ]),
2376            x509.CertificatePolicies([
2377                x509.PolicyInformation(
2378                    x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2379                    [
2380                        u"http://example.com/cps",
2381                        u"http://other.com/cps",
2382                        x509.UserNotice(
2383                            x509.NoticeReference(u"my org", [1, 2, 3, 4]),
2384                            u"thing"
2385                        )
2386                    ]
2387                )
2388            ]),
2389            x509.CertificatePolicies([
2390                x509.PolicyInformation(
2391                    x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2392                    [
2393                        u"http://example.com/cps",
2394                        x509.UserNotice(
2395                            x509.NoticeReference(u"UTF8\u2122'", [1, 2, 3, 4]),
2396                            u"We heart UTF8!\u2122"
2397                        )
2398                    ]
2399                )
2400            ]),
2401            x509.CertificatePolicies([
2402                x509.PolicyInformation(
2403                    x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2404                    [x509.UserNotice(None, u"thing")]
2405                )
2406            ]),
2407            x509.CertificatePolicies([
2408                x509.PolicyInformation(
2409                    x509.ObjectIdentifier("2.16.840.1.12345.1.2.3.4.1"),
2410                    [
2411                        x509.UserNotice(
2412                            x509.NoticeReference(u"my org", [1, 2, 3, 4]),
2413                            None
2414                        )
2415                    ]
2416                )
2417            ]),
2418            x509.IssuerAlternativeName([
2419                x509.DNSName(u"myissuer"),
2420                x509.RFC822Name(u"email@domain.com"),
2421            ]),
2422            x509.ExtendedKeyUsage([
2423                ExtendedKeyUsageOID.CLIENT_AUTH,
2424                ExtendedKeyUsageOID.SERVER_AUTH,
2425                ExtendedKeyUsageOID.CODE_SIGNING,
2426            ]),
2427            x509.InhibitAnyPolicy(3),
2428            x509.TLSFeature([x509.TLSFeatureType.status_request]),
2429            x509.TLSFeature([x509.TLSFeatureType.status_request_v2]),
2430            x509.TLSFeature([
2431                x509.TLSFeatureType.status_request,
2432                x509.TLSFeatureType.status_request_v2
2433            ]),
2434            x509.NameConstraints(
2435                permitted_subtrees=[
2436                    x509.IPAddress(ipaddress.IPv4Network(u"192.168.0.0/24")),
2437                    x509.IPAddress(ipaddress.IPv4Network(u"192.168.0.0/29")),
2438                    x509.IPAddress(ipaddress.IPv4Network(u"127.0.0.1/32")),
2439                    x509.IPAddress(ipaddress.IPv4Network(u"8.0.0.0/8")),
2440                    x509.IPAddress(ipaddress.IPv4Network(u"0.0.0.0/0")),
2441                    x509.IPAddress(
2442                        ipaddress.IPv6Network(u"FF:0:0:0:0:0:0:0/96")
2443                    ),
2444                    x509.IPAddress(
2445                        ipaddress.IPv6Network(u"FF:FF:0:0:0:0:0:0/128")
2446                    ),
2447                ],
2448                excluded_subtrees=[x509.DNSName(u"name.local")]
2449            ),
2450            x509.NameConstraints(
2451                permitted_subtrees=[
2452                    x509.IPAddress(ipaddress.IPv4Network(u"0.0.0.0/0")),
2453                ],
2454                excluded_subtrees=None
2455            ),
2456            x509.NameConstraints(
2457                permitted_subtrees=None,
2458                excluded_subtrees=[x509.DNSName(u"name.local")]
2459            ),
2460            x509.PolicyConstraints(
2461                require_explicit_policy=None,
2462                inhibit_policy_mapping=1
2463            ),
2464            x509.PolicyConstraints(
2465                require_explicit_policy=3,
2466                inhibit_policy_mapping=1
2467            ),
2468            x509.PolicyConstraints(
2469                require_explicit_policy=0,
2470                inhibit_policy_mapping=None
2471            ),
2472            x509.CRLDistributionPoints([
2473                x509.DistributionPoint(
2474                    full_name=None,
2475                    relative_name=x509.RelativeDistinguishedName([
2476                        x509.NameAttribute(
2477                            NameOID.COMMON_NAME,
2478                            u"indirect CRL for indirectCRL CA3"
2479                        ),
2480                    ]),
2481                    reasons=None,
2482                    crl_issuer=[x509.DirectoryName(
2483                        x509.Name([
2484                            x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
2485                            x509.NameAttribute(
2486                                NameOID.ORGANIZATION_NAME,
2487                                u"Test Certificates 2011"
2488                            ),
2489                            x509.NameAttribute(
2490                                NameOID.ORGANIZATIONAL_UNIT_NAME,
2491                                u"indirectCRL CA3 cRLIssuer"
2492                            ),
2493                        ])
2494                    )],
2495                )
2496            ]),
2497            x509.CRLDistributionPoints([
2498                x509.DistributionPoint(
2499                    full_name=[x509.DirectoryName(
2500                        x509.Name([
2501                            x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
2502                        ])
2503                    )],
2504                    relative_name=None,
2505                    reasons=None,
2506                    crl_issuer=[x509.DirectoryName(
2507                        x509.Name([
2508                            x509.NameAttribute(
2509                                NameOID.ORGANIZATION_NAME,
2510                                u"cryptography Testing"
2511                            ),
2512                        ])
2513                    )],
2514                )
2515            ]),
2516            x509.CRLDistributionPoints([
2517                x509.DistributionPoint(
2518                    full_name=[
2519                        x509.UniformResourceIdentifier(
2520                            u"http://myhost.com/myca.crl"
2521                        ),
2522                        x509.UniformResourceIdentifier(
2523                            u"http://backup.myhost.com/myca.crl"
2524                        )
2525                    ],
2526                    relative_name=None,
2527                    reasons=frozenset([
2528                        x509.ReasonFlags.key_compromise,
2529                        x509.ReasonFlags.ca_compromise
2530                    ]),
2531                    crl_issuer=[x509.DirectoryName(
2532                        x509.Name([
2533                            x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
2534                            x509.NameAttribute(
2535                                NameOID.COMMON_NAME, u"cryptography CA"
2536                            ),
2537                        ])
2538                    )],
2539                )
2540            ]),
2541            x509.CRLDistributionPoints([
2542                x509.DistributionPoint(
2543                    full_name=[x509.UniformResourceIdentifier(
2544                        u"http://domain.com/some.crl"
2545                    )],
2546                    relative_name=None,
2547                    reasons=frozenset([
2548                        x509.ReasonFlags.key_compromise,
2549                        x509.ReasonFlags.ca_compromise,
2550                        x509.ReasonFlags.affiliation_changed,
2551                        x509.ReasonFlags.superseded,
2552                        x509.ReasonFlags.privilege_withdrawn,
2553                        x509.ReasonFlags.cessation_of_operation,
2554                        x509.ReasonFlags.aa_compromise,
2555                        x509.ReasonFlags.certificate_hold,
2556                    ]),
2557                    crl_issuer=None
2558                )
2559            ]),
2560            x509.CRLDistributionPoints([
2561                x509.DistributionPoint(
2562                    full_name=None,
2563                    relative_name=None,
2564                    reasons=None,
2565                    crl_issuer=[x509.DirectoryName(
2566                        x509.Name([
2567                            x509.NameAttribute(
2568                                NameOID.COMMON_NAME, u"cryptography CA"
2569                            ),
2570                        ])
2571                    )],
2572                )
2573            ]),
2574            x509.CRLDistributionPoints([
2575                x509.DistributionPoint(
2576                    full_name=[x509.UniformResourceIdentifier(
2577                        u"http://domain.com/some.crl"
2578                    )],
2579                    relative_name=None,
2580                    reasons=frozenset([x509.ReasonFlags.aa_compromise]),
2581                    crl_issuer=None
2582                )
2583            ]),
2584            x509.FreshestCRL([
2585                x509.DistributionPoint(
2586                    full_name=[x509.UniformResourceIdentifier(
2587                        u"http://domain.com/some.crl"
2588                    )],
2589                    relative_name=None,
2590                    reasons=frozenset([
2591                        x509.ReasonFlags.key_compromise,
2592                        x509.ReasonFlags.ca_compromise,
2593                        x509.ReasonFlags.affiliation_changed,
2594                        x509.ReasonFlags.superseded,
2595                        x509.ReasonFlags.privilege_withdrawn,
2596                        x509.ReasonFlags.cessation_of_operation,
2597                        x509.ReasonFlags.aa_compromise,
2598                        x509.ReasonFlags.certificate_hold,
2599                    ]),
2600                    crl_issuer=None
2601                )
2602            ]),
2603            x509.FreshestCRL([
2604                x509.DistributionPoint(
2605                    full_name=None,
2606                    relative_name=x509.RelativeDistinguishedName([
2607                        x509.NameAttribute(
2608                            NameOID.COMMON_NAME,
2609                            u"indirect CRL for indirectCRL CA3"
2610                        ),
2611                    ]),
2612                    reasons=None,
2613                    crl_issuer=None,
2614                )
2615            ]),
2616            x509.FreshestCRL([
2617                x509.DistributionPoint(
2618                    full_name=None,
2619                    relative_name=x509.RelativeDistinguishedName([
2620                        x509.NameAttribute(
2621                            NameOID.COMMON_NAME,
2622                            u"indirect CRL for indirectCRL CA3"
2623                        ),
2624                        x509.NameAttribute(
2625                            NameOID.COUNTRY_NAME,
2626                            u"US"
2627                        ),
2628                    ]),
2629                    reasons=None,
2630                    crl_issuer=None,
2631                )
2632            ]),
2633        ]
2634    )
2635    def test_ext(self, add_ext, backend):
2636        issuer_private_key = RSA_KEY_2048.private_key(backend)
2637        subject_private_key = RSA_KEY_2048.private_key(backend)
2638
2639        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2640        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2641
2642        cert = x509.CertificateBuilder().subject_name(
2643            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2644        ).issuer_name(
2645            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2646        ).not_valid_before(
2647            not_valid_before
2648        ).not_valid_after(
2649            not_valid_after
2650        ).public_key(
2651            subject_private_key.public_key()
2652        ).serial_number(
2653            123
2654        ).add_extension(
2655            add_ext, critical=False
2656        ).sign(issuer_private_key, hashes.SHA256(), backend)
2657
2658        ext = cert.extensions.get_extension_for_class(type(add_ext))
2659        assert ext.critical is False
2660        assert ext.value == add_ext
2661
2662    @pytest.mark.requires_backend_interface(interface=RSABackend)
2663    @pytest.mark.requires_backend_interface(interface=X509Backend)
2664    def test_key_usage(self, backend):
2665        issuer_private_key = RSA_KEY_2048.private_key(backend)
2666        subject_private_key = RSA_KEY_2048.private_key(backend)
2667
2668        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
2669        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
2670
2671        cert = x509.CertificateBuilder().subject_name(
2672            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2673        ).issuer_name(
2674            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
2675        ).not_valid_before(
2676            not_valid_before
2677        ).not_valid_after(
2678            not_valid_after
2679        ).public_key(
2680            subject_private_key.public_key()
2681        ).serial_number(
2682            123
2683        ).add_extension(
2684            x509.KeyUsage(
2685                digital_signature=True,
2686                content_commitment=True,
2687                key_encipherment=False,
2688                data_encipherment=False,
2689                key_agreement=False,
2690                key_cert_sign=True,
2691                crl_sign=False,
2692                encipher_only=False,
2693                decipher_only=False
2694            ),
2695            critical=False
2696        ).sign(issuer_private_key, hashes.SHA256(), backend)
2697
2698        ext = cert.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
2699        assert ext.critical is False
2700        assert ext.value == x509.KeyUsage(
2701            digital_signature=True,
2702            content_commitment=True,
2703            key_encipherment=False,
2704            data_encipherment=False,
2705            key_agreement=False,
2706            key_cert_sign=True,
2707            crl_sign=False,
2708            encipher_only=False,
2709            decipher_only=False
2710        )
2711
2712    @pytest.mark.requires_backend_interface(interface=RSABackend)
2713    @pytest.mark.requires_backend_interface(interface=X509Backend)
2714    def test_build_ca_request_with_path_length_none(self, backend):
2715        private_key = RSA_KEY_2048.private_key(backend)
2716
2717        request = x509.CertificateSigningRequestBuilder().subject_name(
2718            x509.Name([
2719                x509.NameAttribute(NameOID.ORGANIZATION_NAME,
2720                                   u'PyCA'),
2721            ])
2722        ).add_extension(
2723            x509.BasicConstraints(ca=True, path_length=None), critical=True
2724        ).sign(private_key, hashes.SHA1(), backend)
2725
2726        loaded_request = x509.load_pem_x509_csr(
2727            request.public_bytes(encoding=serialization.Encoding.PEM), backend
2728        )
2729        subject = loaded_request.subject
2730        assert isinstance(subject, x509.Name)
2731        basic_constraints = request.extensions.get_extension_for_oid(
2732            ExtensionOID.BASIC_CONSTRAINTS
2733        )
2734        assert basic_constraints.value.path_length is None
2735
2736    @pytest.mark.parametrize(
2737        "unrecognized", [
2738            x509.UnrecognizedExtension(
2739                x509.ObjectIdentifier("1.2.3.4.5"),
2740                b"abcdef",
2741            )
2742        ]
2743    )
2744    @pytest.mark.requires_backend_interface(interface=RSABackend)
2745    @pytest.mark.requires_backend_interface(interface=X509Backend)
2746    def test_unrecognized_extension(self, backend, unrecognized):
2747        private_key = RSA_KEY_2048.private_key(backend)
2748
2749        cert = x509.CertificateBuilder().subject_name(
2750            x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
2751        ).issuer_name(
2752            x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
2753        ).not_valid_before(
2754            datetime.datetime(2002, 1, 1, 12, 1)
2755        ).not_valid_after(
2756            datetime.datetime(2030, 12, 31, 8, 30)
2757        ).public_key(
2758            private_key.public_key()
2759        ).serial_number(
2760            123
2761        ).add_extension(
2762            unrecognized, critical=False
2763        ).sign(private_key, hashes.SHA256(), backend)
2764
2765        ext = cert.extensions.get_extension_for_oid(unrecognized.oid)
2766
2767        assert ext.value == unrecognized
2768
2769
2770@pytest.mark.requires_backend_interface(interface=X509Backend)
2771class TestCertificateSigningRequestBuilder(object):
2772    @pytest.mark.requires_backend_interface(interface=RSABackend)
2773    def test_sign_invalid_hash_algorithm(self, backend):
2774        private_key = RSA_KEY_2048.private_key(backend)
2775
2776        builder = x509.CertificateSigningRequestBuilder().subject_name(
2777            x509.Name([])
2778        )
2779        with pytest.raises(TypeError):
2780            builder.sign(private_key, 'NotAHash', backend)
2781
2782    @pytest.mark.requires_backend_interface(interface=RSABackend)
2783    def test_sign_rsa_with_md5(self, backend):
2784        private_key = RSA_KEY_2048.private_key(backend)
2785
2786        builder = x509.CertificateSigningRequestBuilder().subject_name(
2787            x509.Name([
2788                x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2789            ])
2790        )
2791        request = builder.sign(private_key, hashes.MD5(), backend)
2792        assert isinstance(request.signature_hash_algorithm, hashes.MD5)
2793
2794    @pytest.mark.requires_backend_interface(interface=DSABackend)
2795    def test_sign_dsa_with_md5(self, backend):
2796        private_key = DSA_KEY_2048.private_key(backend)
2797        builder = x509.CertificateSigningRequestBuilder().subject_name(
2798            x509.Name([
2799                x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2800            ])
2801        )
2802        with pytest.raises(ValueError):
2803            builder.sign(private_key, hashes.MD5(), backend)
2804
2805    @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2806    def test_sign_ec_with_md5(self, backend):
2807        _skip_curve_unsupported(backend, ec.SECP256R1())
2808        private_key = EC_KEY_SECP256R1.private_key(backend)
2809        builder = x509.CertificateSigningRequestBuilder().subject_name(
2810            x509.Name([
2811                x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2812            ])
2813        )
2814        with pytest.raises(ValueError):
2815            builder.sign(private_key, hashes.MD5(), backend)
2816
2817    @pytest.mark.requires_backend_interface(interface=RSABackend)
2818    def test_no_subject_name(self, backend):
2819        private_key = RSA_KEY_2048.private_key(backend)
2820
2821        builder = x509.CertificateSigningRequestBuilder()
2822        with pytest.raises(ValueError):
2823            builder.sign(private_key, hashes.SHA256(), backend)
2824
2825    @pytest.mark.requires_backend_interface(interface=RSABackend)
2826    def test_build_ca_request_with_rsa(self, backend):
2827        private_key = RSA_KEY_2048.private_key(backend)
2828
2829        request = x509.CertificateSigningRequestBuilder().subject_name(
2830            x509.Name([
2831                x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2832            ])
2833        ).add_extension(
2834            x509.BasicConstraints(ca=True, path_length=2), critical=True
2835        ).sign(private_key, hashes.SHA1(), backend)
2836
2837        assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2838        public_key = request.public_key()
2839        assert isinstance(public_key, rsa.RSAPublicKey)
2840        subject = request.subject
2841        assert isinstance(subject, x509.Name)
2842        assert list(subject) == [
2843            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
2844        ]
2845        basic_constraints = request.extensions.get_extension_for_oid(
2846            ExtensionOID.BASIC_CONSTRAINTS
2847        )
2848        assert basic_constraints.value.ca is True
2849        assert basic_constraints.value.path_length == 2
2850
2851    @pytest.mark.requires_backend_interface(interface=RSABackend)
2852    def test_build_ca_request_with_unicode(self, backend):
2853        private_key = RSA_KEY_2048.private_key(backend)
2854
2855        request = x509.CertificateSigningRequestBuilder().subject_name(
2856            x509.Name([
2857                x509.NameAttribute(NameOID.ORGANIZATION_NAME,
2858                                   u'PyCA\U0001f37a'),
2859            ])
2860        ).add_extension(
2861            x509.BasicConstraints(ca=True, path_length=2), critical=True
2862        ).sign(private_key, hashes.SHA1(), backend)
2863
2864        loaded_request = x509.load_pem_x509_csr(
2865            request.public_bytes(encoding=serialization.Encoding.PEM), backend
2866        )
2867        subject = loaded_request.subject
2868        assert isinstance(subject, x509.Name)
2869        assert list(subject) == [
2870            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA\U0001f37a'),
2871        ]
2872
2873    @pytest.mark.requires_backend_interface(interface=RSABackend)
2874    def test_subject_dn_asn1_types(self, backend):
2875        private_key = RSA_KEY_2048.private_key(backend)
2876
2877        request = x509.CertificateSigningRequestBuilder().subject_name(
2878            x509.Name([
2879                x509.NameAttribute(NameOID.COMMON_NAME, u"mysite.com"),
2880                x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
2881                x509.NameAttribute(NameOID.LOCALITY_NAME, u"value"),
2882                x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"value"),
2883                x509.NameAttribute(NameOID.STREET_ADDRESS, u"value"),
2884                x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"value"),
2885                x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u"value"),
2886                x509.NameAttribute(NameOID.SERIAL_NUMBER, u"value"),
2887                x509.NameAttribute(NameOID.SURNAME, u"value"),
2888                x509.NameAttribute(NameOID.GIVEN_NAME, u"value"),
2889                x509.NameAttribute(NameOID.TITLE, u"value"),
2890                x509.NameAttribute(NameOID.GENERATION_QUALIFIER, u"value"),
2891                x509.NameAttribute(NameOID.X500_UNIQUE_IDENTIFIER, u"value"),
2892                x509.NameAttribute(NameOID.DN_QUALIFIER, u"value"),
2893                x509.NameAttribute(NameOID.PSEUDONYM, u"value"),
2894                x509.NameAttribute(NameOID.USER_ID, u"value"),
2895                x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u"value"),
2896                x509.NameAttribute(NameOID.EMAIL_ADDRESS, u"value"),
2897                x509.NameAttribute(NameOID.JURISDICTION_COUNTRY_NAME, u"US"),
2898                x509.NameAttribute(
2899                    NameOID.JURISDICTION_LOCALITY_NAME, u"value"
2900                ),
2901                x509.NameAttribute(
2902                    NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME, u"value"
2903                ),
2904                x509.NameAttribute(NameOID.BUSINESS_CATEGORY, u"value"),
2905                x509.NameAttribute(NameOID.POSTAL_ADDRESS, u"value"),
2906                x509.NameAttribute(NameOID.POSTAL_CODE, u"value"),
2907            ])
2908        ).sign(private_key, hashes.SHA256(), backend)
2909        for oid, asn1_type in TestNameAttribute.EXPECTED_TYPES:
2910            assert request.subject.get_attributes_for_oid(
2911                oid
2912            )[0]._type == asn1_type
2913
2914    @pytest.mark.requires_backend_interface(interface=RSABackend)
2915    def test_build_ca_request_with_multivalue_rdns(self, backend):
2916        private_key = RSA_KEY_2048.private_key(backend)
2917        subject = x509.Name([
2918            x509.RelativeDistinguishedName([
2919                x509.NameAttribute(NameOID.TITLE, u'Test'),
2920                x509.NameAttribute(NameOID.COMMON_NAME, u'Multivalue'),
2921                x509.NameAttribute(NameOID.SURNAME, u'RDNs'),
2922            ]),
2923            x509.RelativeDistinguishedName([
2924                x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA')
2925            ]),
2926        ])
2927
2928        request = x509.CertificateSigningRequestBuilder().subject_name(
2929            subject
2930        ).sign(private_key, hashes.SHA1(), backend)
2931
2932        loaded_request = x509.load_pem_x509_csr(
2933            request.public_bytes(encoding=serialization.Encoding.PEM), backend
2934        )
2935        assert isinstance(loaded_request.subject, x509.Name)
2936        assert loaded_request.subject == subject
2937
2938    @pytest.mark.requires_backend_interface(interface=RSABackend)
2939    def test_build_nonca_request_with_rsa(self, backend):
2940        private_key = RSA_KEY_2048.private_key(backend)
2941
2942        request = x509.CertificateSigningRequestBuilder().subject_name(
2943            x509.Name([
2944                x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2945            ])
2946        ).add_extension(
2947            x509.BasicConstraints(ca=False, path_length=None), critical=True,
2948        ).sign(private_key, hashes.SHA1(), backend)
2949
2950        assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2951        public_key = request.public_key()
2952        assert isinstance(public_key, rsa.RSAPublicKey)
2953        subject = request.subject
2954        assert isinstance(subject, x509.Name)
2955        assert list(subject) == [
2956            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2957        ]
2958        basic_constraints = request.extensions.get_extension_for_oid(
2959            ExtensionOID.BASIC_CONSTRAINTS
2960        )
2961        assert basic_constraints.value.ca is False
2962        assert basic_constraints.value.path_length is None
2963
2964    @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
2965    def test_build_ca_request_with_ec(self, backend):
2966        _skip_curve_unsupported(backend, ec.SECP256R1())
2967        private_key = ec.generate_private_key(ec.SECP256R1(), backend)
2968
2969        request = x509.CertificateSigningRequestBuilder().subject_name(
2970            x509.Name([
2971                x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2972            ])
2973        ).add_extension(
2974            x509.BasicConstraints(ca=True, path_length=2), critical=True
2975        ).sign(private_key, hashes.SHA1(), backend)
2976
2977        assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
2978        public_key = request.public_key()
2979        assert isinstance(public_key, ec.EllipticCurvePublicKey)
2980        subject = request.subject
2981        assert isinstance(subject, x509.Name)
2982        assert list(subject) == [
2983            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
2984        ]
2985        basic_constraints = request.extensions.get_extension_for_oid(
2986            ExtensionOID.BASIC_CONSTRAINTS
2987        )
2988        assert basic_constraints.value.ca is True
2989        assert basic_constraints.value.path_length == 2
2990
2991    @pytest.mark.requires_backend_interface(interface=DSABackend)
2992    def test_build_ca_request_with_dsa(self, backend):
2993        private_key = DSA_KEY_2048.private_key(backend)
2994
2995        request = x509.CertificateSigningRequestBuilder().subject_name(
2996            x509.Name([
2997                x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
2998            ])
2999        ).add_extension(
3000            x509.BasicConstraints(ca=True, path_length=2), critical=True
3001        ).sign(private_key, hashes.SHA1(), backend)
3002
3003        assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
3004        public_key = request.public_key()
3005        assert isinstance(public_key, dsa.DSAPublicKey)
3006        subject = request.subject
3007        assert isinstance(subject, x509.Name)
3008        assert list(subject) == [
3009            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3010        ]
3011        basic_constraints = request.extensions.get_extension_for_oid(
3012            ExtensionOID.BASIC_CONSTRAINTS
3013        )
3014        assert basic_constraints.value.ca is True
3015        assert basic_constraints.value.path_length == 2
3016
3017    def test_add_duplicate_extension(self):
3018        builder = x509.CertificateSigningRequestBuilder().add_extension(
3019            x509.BasicConstraints(True, 2), critical=True,
3020        )
3021        with pytest.raises(ValueError):
3022            builder.add_extension(
3023                x509.BasicConstraints(True, 2), critical=True,
3024            )
3025
3026    def test_set_invalid_subject(self):
3027        builder = x509.CertificateSigningRequestBuilder()
3028        with pytest.raises(TypeError):
3029            builder.subject_name('NotAName')
3030
3031    def test_add_invalid_extension_type(self):
3032        builder = x509.CertificateSigningRequestBuilder()
3033
3034        with pytest.raises(TypeError):
3035            builder.add_extension(object(), False)
3036
3037    def test_add_unsupported_extension(self, backend):
3038        private_key = RSA_KEY_2048.private_key(backend)
3039        builder = x509.CertificateSigningRequestBuilder()
3040        builder = builder.subject_name(
3041            x509.Name([
3042                x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3043            ])
3044        ).add_extension(
3045            x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
3046            critical=False,
3047        ).add_extension(
3048            DummyExtension(), False
3049        )
3050        with pytest.raises(NotImplementedError):
3051            builder.sign(private_key, hashes.SHA256(), backend)
3052
3053    def test_key_usage(self, backend):
3054        private_key = RSA_KEY_2048.private_key(backend)
3055        builder = x509.CertificateSigningRequestBuilder()
3056        request = builder.subject_name(
3057            x509.Name([
3058                x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3059            ])
3060        ).add_extension(
3061            x509.KeyUsage(
3062                digital_signature=True,
3063                content_commitment=True,
3064                key_encipherment=False,
3065                data_encipherment=False,
3066                key_agreement=False,
3067                key_cert_sign=True,
3068                crl_sign=False,
3069                encipher_only=False,
3070                decipher_only=False
3071            ),
3072            critical=False
3073        ).sign(private_key, hashes.SHA256(), backend)
3074        assert len(request.extensions) == 1
3075        ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
3076        assert ext.critical is False
3077        assert ext.value == x509.KeyUsage(
3078            digital_signature=True,
3079            content_commitment=True,
3080            key_encipherment=False,
3081            data_encipherment=False,
3082            key_agreement=False,
3083            key_cert_sign=True,
3084            crl_sign=False,
3085            encipher_only=False,
3086            decipher_only=False
3087        )
3088
3089    def test_key_usage_key_agreement_bit(self, backend):
3090        private_key = RSA_KEY_2048.private_key(backend)
3091        builder = x509.CertificateSigningRequestBuilder()
3092        request = builder.subject_name(
3093            x509.Name([
3094                x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3095            ])
3096        ).add_extension(
3097            x509.KeyUsage(
3098                digital_signature=False,
3099                content_commitment=False,
3100                key_encipherment=False,
3101                data_encipherment=False,
3102                key_agreement=True,
3103                key_cert_sign=True,
3104                crl_sign=False,
3105                encipher_only=False,
3106                decipher_only=True
3107            ),
3108            critical=False
3109        ).sign(private_key, hashes.SHA256(), backend)
3110        assert len(request.extensions) == 1
3111        ext = request.extensions.get_extension_for_oid(ExtensionOID.KEY_USAGE)
3112        assert ext.critical is False
3113        assert ext.value == x509.KeyUsage(
3114            digital_signature=False,
3115            content_commitment=False,
3116            key_encipherment=False,
3117            data_encipherment=False,
3118            key_agreement=True,
3119            key_cert_sign=True,
3120            crl_sign=False,
3121            encipher_only=False,
3122            decipher_only=True
3123        )
3124
3125    def test_add_two_extensions(self, backend):
3126        private_key = RSA_KEY_2048.private_key(backend)
3127        builder = x509.CertificateSigningRequestBuilder()
3128        request = builder.subject_name(
3129            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
3130        ).add_extension(
3131            x509.SubjectAlternativeName([x509.DNSName(u"cryptography.io")]),
3132            critical=False,
3133        ).add_extension(
3134            x509.BasicConstraints(ca=True, path_length=2), critical=True
3135        ).sign(private_key, hashes.SHA1(), backend)
3136
3137        assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
3138        public_key = request.public_key()
3139        assert isinstance(public_key, rsa.RSAPublicKey)
3140        basic_constraints = request.extensions.get_extension_for_oid(
3141            ExtensionOID.BASIC_CONSTRAINTS
3142        )
3143        assert basic_constraints.value.ca is True
3144        assert basic_constraints.value.path_length == 2
3145        ext = request.extensions.get_extension_for_oid(
3146            ExtensionOID.SUBJECT_ALTERNATIVE_NAME
3147        )
3148        assert list(ext.value) == [x509.DNSName(u"cryptography.io")]
3149
3150    def test_set_subject_twice(self):
3151        builder = x509.CertificateSigningRequestBuilder()
3152        builder = builder.subject_name(
3153            x509.Name([
3154                x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3155            ])
3156        )
3157        with pytest.raises(ValueError):
3158            builder.subject_name(
3159                x509.Name([
3160                    x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3161                ])
3162            )
3163
3164    def test_subject_alt_names(self, backend):
3165        private_key = RSA_KEY_2048.private_key(backend)
3166
3167        san = x509.SubjectAlternativeName([
3168            x509.DNSName(u"example.com"),
3169            x509.DNSName(u"*.example.com"),
3170            x509.RegisteredID(x509.ObjectIdentifier("1.2.3.4.5.6.7")),
3171            x509.DirectoryName(x509.Name([
3172                x509.NameAttribute(NameOID.COMMON_NAME, u'PyCA'),
3173                x509.NameAttribute(
3174                    NameOID.ORGANIZATION_NAME, u'We heart UTF8!\u2122'
3175                )
3176            ])),
3177            x509.IPAddress(ipaddress.ip_address(u"127.0.0.1")),
3178            x509.IPAddress(ipaddress.ip_address(u"ff::")),
3179            x509.OtherName(
3180                type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
3181                value=b"0\x03\x02\x01\x05"
3182            ),
3183            x509.RFC822Name(u"test@example.com"),
3184            x509.RFC822Name(u"email"),
3185            x509.RFC822Name(u"email@xn--eml-vla4c.com"),
3186            x509.UniformResourceIdentifier(
3187                u"https://xn--80ato2c.cryptography"
3188            ),
3189            x509.UniformResourceIdentifier(
3190                u"gopher://cryptography:70/some/path"
3191            ),
3192        ])
3193
3194        csr = x509.CertificateSigningRequestBuilder().subject_name(
3195            x509.Name([
3196                x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
3197            ])
3198        ).add_extension(
3199            san,
3200            critical=False,
3201        ).sign(private_key, hashes.SHA256(), backend)
3202
3203        assert len(csr.extensions) == 1
3204        ext = csr.extensions.get_extension_for_oid(
3205            ExtensionOID.SUBJECT_ALTERNATIVE_NAME
3206        )
3207        assert not ext.critical
3208        assert ext.oid == ExtensionOID.SUBJECT_ALTERNATIVE_NAME
3209        assert ext.value == san
3210
3211    def test_invalid_asn1_othername(self, backend):
3212        private_key = RSA_KEY_2048.private_key(backend)
3213
3214        builder = x509.CertificateSigningRequestBuilder().subject_name(
3215            x509.Name([
3216                x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
3217            ])
3218        ).add_extension(
3219            x509.SubjectAlternativeName([
3220                x509.OtherName(
3221                    type_id=x509.ObjectIdentifier("1.2.3.3.3.3"),
3222                    value=b"\x01\x02\x01\x05"
3223                ),
3224            ]),
3225            critical=False,
3226        )
3227        with pytest.raises(ValueError):
3228            builder.sign(private_key, hashes.SHA256(), backend)
3229
3230    def test_subject_alt_name_unsupported_general_name(self, backend):
3231        private_key = RSA_KEY_2048.private_key(backend)
3232
3233        builder = x509.CertificateSigningRequestBuilder().subject_name(
3234            x509.Name([
3235                x509.NameAttribute(NameOID.COMMON_NAME, u"SAN"),
3236            ])
3237        ).add_extension(
3238            x509.SubjectAlternativeName([FakeGeneralName("")]),
3239            critical=False,
3240        )
3241
3242        with pytest.raises(ValueError):
3243            builder.sign(private_key, hashes.SHA256(), backend)
3244
3245    def test_extended_key_usage(self, backend):
3246        private_key = RSA_KEY_2048.private_key(backend)
3247        eku = x509.ExtendedKeyUsage([
3248            ExtendedKeyUsageOID.CLIENT_AUTH,
3249            ExtendedKeyUsageOID.SERVER_AUTH,
3250            ExtendedKeyUsageOID.CODE_SIGNING,
3251        ])
3252        builder = x509.CertificateSigningRequestBuilder()
3253        request = builder.subject_name(
3254            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
3255        ).add_extension(
3256            eku, critical=False
3257        ).sign(private_key, hashes.SHA256(), backend)
3258
3259        ext = request.extensions.get_extension_for_oid(
3260            ExtensionOID.EXTENDED_KEY_USAGE
3261        )
3262        assert ext.critical is False
3263        assert ext.value == eku
3264
3265    @pytest.mark.requires_backend_interface(interface=RSABackend)
3266    def test_rsa_key_too_small(self, backend):
3267        private_key = rsa.generate_private_key(65537, 512, backend)
3268        builder = x509.CertificateSigningRequestBuilder()
3269        builder = builder.subject_name(
3270            x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')])
3271        )
3272
3273        with pytest.raises(ValueError) as exc:
3274            builder.sign(private_key, hashes.SHA512(), backend)
3275
3276        assert str(exc.value) == "Digest too big for RSA key"
3277
3278    @pytest.mark.requires_backend_interface(interface=RSABackend)
3279    @pytest.mark.requires_backend_interface(interface=X509Backend)
3280    def test_build_cert_with_aia(self, backend):
3281        issuer_private_key = RSA_KEY_2048.private_key(backend)
3282        subject_private_key = RSA_KEY_2048.private_key(backend)
3283
3284        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
3285        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
3286
3287        aia = x509.AuthorityInformationAccess([
3288            x509.AccessDescription(
3289                AuthorityInformationAccessOID.OCSP,
3290                x509.UniformResourceIdentifier(u"http://ocsp.domain.com")
3291            ),
3292            x509.AccessDescription(
3293                AuthorityInformationAccessOID.CA_ISSUERS,
3294                x509.UniformResourceIdentifier(u"http://domain.com/ca.crt")
3295            )
3296        ])
3297
3298        builder = x509.CertificateBuilder().serial_number(
3299            777
3300        ).issuer_name(x509.Name([
3301            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3302        ])).subject_name(x509.Name([
3303            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3304        ])).public_key(
3305            subject_private_key.public_key()
3306        ).add_extension(
3307            aia, critical=False
3308        ).not_valid_before(
3309            not_valid_before
3310        ).not_valid_after(
3311            not_valid_after
3312        )
3313
3314        cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
3315
3316        ext = cert.extensions.get_extension_for_oid(
3317            ExtensionOID.AUTHORITY_INFORMATION_ACCESS
3318        )
3319        assert ext.value == aia
3320
3321    @pytest.mark.requires_backend_interface(interface=RSABackend)
3322    @pytest.mark.requires_backend_interface(interface=X509Backend)
3323    def test_build_cert_with_ski(self, backend):
3324        issuer_private_key = RSA_KEY_2048.private_key(backend)
3325        subject_private_key = RSA_KEY_2048.private_key(backend)
3326
3327        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
3328        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
3329
3330        ski = x509.SubjectKeyIdentifier.from_public_key(
3331            subject_private_key.public_key()
3332        )
3333
3334        builder = x509.CertificateBuilder().serial_number(
3335            777
3336        ).issuer_name(x509.Name([
3337            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3338        ])).subject_name(x509.Name([
3339            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3340        ])).public_key(
3341            subject_private_key.public_key()
3342        ).add_extension(
3343            ski, critical=False
3344        ).not_valid_before(
3345            not_valid_before
3346        ).not_valid_after(
3347            not_valid_after
3348        )
3349
3350        cert = builder.sign(issuer_private_key, hashes.SHA1(), backend)
3351
3352        ext = cert.extensions.get_extension_for_oid(
3353            ExtensionOID.SUBJECT_KEY_IDENTIFIER
3354        )
3355        assert ext.value == ski
3356
3357    @pytest.mark.parametrize(
3358        "aki",
3359        [
3360            x509.AuthorityKeyIdentifier(
3361                b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
3362                b"\xcbY",
3363                None,
3364                None
3365            ),
3366            x509.AuthorityKeyIdentifier(
3367                b"\xc3\x9c\xf3\xfc\xd3F\x084\xbb\xceF\x7f\xa0|[\xf3\xe2\x08"
3368                b"\xcbY",
3369                [
3370                    x509.DirectoryName(
3371                        x509.Name([
3372                            x509.NameAttribute(
3373                                NameOID.ORGANIZATION_NAME, u"PyCA"
3374                            ),
3375                            x509.NameAttribute(
3376                                NameOID.COMMON_NAME, u"cryptography CA"
3377                            )
3378                        ])
3379                    )
3380                ],
3381                333
3382            ),
3383            x509.AuthorityKeyIdentifier(
3384                None,
3385                [
3386                    x509.DirectoryName(
3387                        x509.Name([
3388                            x509.NameAttribute(
3389                                NameOID.ORGANIZATION_NAME, u"PyCA"
3390                            ),
3391                            x509.NameAttribute(
3392                                NameOID.COMMON_NAME, u"cryptography CA"
3393                            )
3394                        ])
3395                    )
3396                ],
3397                333
3398            ),
3399        ]
3400    )
3401    @pytest.mark.requires_backend_interface(interface=RSABackend)
3402    @pytest.mark.requires_backend_interface(interface=X509Backend)
3403    def test_build_cert_with_aki(self, aki, backend):
3404        issuer_private_key = RSA_KEY_2048.private_key(backend)
3405        subject_private_key = RSA_KEY_2048.private_key(backend)
3406
3407        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
3408        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
3409
3410        builder = x509.CertificateBuilder().serial_number(
3411            777
3412        ).issuer_name(x509.Name([
3413            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3414        ])).subject_name(x509.Name([
3415            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3416        ])).public_key(
3417            subject_private_key.public_key()
3418        ).add_extension(
3419            aki, critical=False
3420        ).not_valid_before(
3421            not_valid_before
3422        ).not_valid_after(
3423            not_valid_after
3424        )
3425
3426        cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
3427
3428        ext = cert.extensions.get_extension_for_oid(
3429            ExtensionOID.AUTHORITY_KEY_IDENTIFIER
3430        )
3431        assert ext.value == aki
3432
3433    def test_ocsp_nocheck(self, backend):
3434        issuer_private_key = RSA_KEY_2048.private_key(backend)
3435        subject_private_key = RSA_KEY_2048.private_key(backend)
3436
3437        not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
3438        not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
3439
3440        builder = x509.CertificateBuilder().serial_number(
3441            777
3442        ).issuer_name(x509.Name([
3443            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3444        ])).subject_name(x509.Name([
3445            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3446        ])).public_key(
3447            subject_private_key.public_key()
3448        ).add_extension(
3449            x509.OCSPNoCheck(), critical=False
3450        ).not_valid_before(
3451            not_valid_before
3452        ).not_valid_after(
3453            not_valid_after
3454        )
3455
3456        cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
3457
3458        ext = cert.extensions.get_extension_for_oid(
3459            ExtensionOID.OCSP_NO_CHECK
3460        )
3461        assert isinstance(ext.value, x509.OCSPNoCheck)
3462
3463
3464@pytest.mark.requires_backend_interface(interface=DSABackend)
3465@pytest.mark.requires_backend_interface(interface=X509Backend)
3466class TestDSACertificate(object):
3467    def test_load_dsa_cert(self, backend):
3468        cert = _load_cert(
3469            os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
3470            x509.load_pem_x509_certificate,
3471            backend
3472        )
3473        assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
3474        public_key = cert.public_key()
3475        assert isinstance(public_key, dsa.DSAPublicKey)
3476        num = public_key.public_numbers()
3477        assert num.y == int(
3478            "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94"
3479            "53b6656f13e543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2"
3480            "dea559f0b584c97a2b235b9b69b46bc6de1aed422a6f341832618bcaae2"
3481            "198aba388099dafb05ff0b5efecb3b0ae169a62e1c72022af50ae68af3b"
3482            "033c18e6eec1f7df4692c456ccafb79cc7e08da0a5786e9816ceda651d6"
3483            "1b4bb7b81c2783da97cea62df67af5e85991fdc13aff10fc60e06586386"
3484            "b96bb78d65750f542f86951e05a6d81baadbcd35a2e5cad4119923ae6a2"
3485            "002091a3d17017f93c52970113cdc119970b9074ca506eac91c3dd37632"
3486            "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c", 16
3487        )
3488        assert num.parameter_numbers.g == int(
3489            "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67"
3490            "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b"
3491            "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2"
3492            "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa"
3493            "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f"
3494            "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a"
3495            "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0"
3496            "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76"
3497            "fa6247676a6d3ac945844a083509c6a1b436baca", 16
3498        )
3499        assert num.parameter_numbers.p == int(
3500            "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3"
3501            "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330"
3502            "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e"
3503            "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a"
3504            "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4"
3505            "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2"
3506            "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93"
3507            "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d"
3508            "833e36468f3907cfca788a3cb790f0341c8a31bf", 16
3509        )
3510        assert num.parameter_numbers.q == int(
3511            "822ff5d234e073b901cf5941f58e1f538e71d40d", 16
3512        )
3513
3514    def test_signature(self, backend):
3515        cert = _load_cert(
3516            os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
3517            x509.load_pem_x509_certificate,
3518            backend
3519        )
3520        assert cert.signature == binascii.unhexlify(
3521            b"302c021425c4a84a936ab311ee017d3cbd9a3c650bb3ae4a02145d30c64b4326"
3522            b"86bdf925716b4ed059184396bcce"
3523        )
3524        r, s = decode_dss_signature(cert.signature)
3525        assert r == 215618264820276283222494627481362273536404860490
3526        assert s == 532023851299196869156027211159466197586787351758
3527
3528    def test_tbs_certificate_bytes(self, backend):
3529        cert = _load_cert(
3530            os.path.join("x509", "custom", "dsa_selfsigned_ca.pem"),
3531            x509.load_pem_x509_certificate,
3532            backend
3533        )
3534        assert cert.tbs_certificate_bytes == binascii.unhexlify(
3535            b"3082051aa003020102020900a37352e0b2142f86300906072a8648ce3804033"
3536            b"067310b3009060355040613025553310e300c06035504081305546578617331"
3537            b"0f300d0603550407130641757374696e3121301f060355040a1318496e74657"
3538            b"26e6574205769646769747320507479204c7464311430120603550403130b50"
3539            b"79434120445341204341301e170d3134313132373035313431375a170d31343"
3540            b"13232373035313431375a3067310b3009060355040613025553310e300c0603"
3541            b"55040813055465786173310f300d0603550407130641757374696e3121301f0"
3542            b"60355040a1318496e7465726e6574205769646769747320507479204c746431"
3543            b"1430120603550403130b50794341204453412043413082033a3082022d06072"
3544            b"a8648ce380401308202200282010100bfade6048e373cd4e48b677e878c8e5b"
3545            b"08c02102ae04eb2cb5c46a523a3af1c73d16b24f34a4964781ae7e50500e217"
3546            b"77754a670bd19a7420d633084e5556e33ca2c0e7d547ea5f46a07a01bf8669a"
3547            b"e3bdec042d9b2ae5e6ecf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736"
3548            b"857971444c25d0a33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e0"
3549            b"3e419fd4ca4e703313743d86caa885930f62ed5bf342d8165627681e9cc3244"
3550            b"ba72aa22148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56d"
3551            b"a93f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d8"
3552            b"33e36468f3907cfca788a3cb790f0341c8a31bf021500822ff5d234e073b901"
3553            b"cf5941f58e1f538e71d40d028201004b7ced71dc353965ecc10d441a9a06fc2"
3554            b"4943a32d66429dd5ef44d43e67d789d99770aec32c0415dc92970880872da45"
3555            b"fef8dd1e115a3e4801387ba6d755861f062fd3b6e9ea8e2641152339b828315"
3556            b"b1528ee6c7b79458d21f3db973f6fc303f9397174c2799dd2351282aa2d8842"
3557            b"c357a73495bbaac4932786414c55e60d73169f5761036fba29e9eebfb049f8a"
3558            b"3b1b7cee6f3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c"
3559            b"64130a1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425"
3560            b"c0b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76fa"
3561            b"6247676a6d3ac945844a083509c6a1b436baca0382010500028201004c08bfe"
3562            b"5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa9453b6656f13e"
3563            b"543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2dea559f0b584c97"
3564            b"a2b235b9b69b46bc6de1aed422a6f341832618bcaae2198aba388099dafb05f"
3565            b"f0b5efecb3b0ae169a62e1c72022af50ae68af3b033c18e6eec1f7df4692c45"
3566            b"6ccafb79cc7e08da0a5786e9816ceda651d61b4bb7b81c2783da97cea62df67"
3567            b"af5e85991fdc13aff10fc60e06586386b96bb78d65750f542f86951e05a6d81"
3568            b"baadbcd35a2e5cad4119923ae6a2002091a3d17017f93c52970113cdc119970"
3569            b"b9074ca506eac91c3dd376325df4af6b3911ef267d26623a5a1c5df4a6d13f1"
3570            b"ca381cc3081c9301d0603551d0e04160414a4fb887a13fcdeb303bbae9a1dec"
3571            b"a72f125a541b3081990603551d2304819130818e8014a4fb887a13fcdeb303b"
3572            b"bae9a1deca72f125a541ba16ba4693067310b3009060355040613025553310e"
3573            b"300c060355040813055465786173310f300d0603550407130641757374696e3"
3574            b"121301f060355040a1318496e7465726e657420576964676974732050747920"
3575            b"4c7464311430120603550403130b5079434120445341204341820900a37352e"
3576            b"0b2142f86300c0603551d13040530030101ff"
3577        )
3578        cert.public_key().verify(
3579            cert.signature, cert.tbs_certificate_bytes,
3580            cert.signature_hash_algorithm
3581        )
3582
3583
3584@pytest.mark.requires_backend_interface(interface=DSABackend)
3585@pytest.mark.requires_backend_interface(interface=X509Backend)
3586class TestDSACertificateRequest(object):
3587    @pytest.mark.parametrize(
3588        ("path", "loader_func"),
3589        [
3590            [
3591                os.path.join("x509", "requests", "dsa_sha1.pem"),
3592                x509.load_pem_x509_csr
3593            ],
3594            [
3595                os.path.join("x509", "requests", "dsa_sha1.der"),
3596                x509.load_der_x509_csr
3597            ],
3598        ]
3599    )
3600    def test_load_dsa_request(self, path, loader_func, backend):
3601        request = _load_cert(path, loader_func, backend)
3602        assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
3603        public_key = request.public_key()
3604        assert isinstance(public_key, dsa.DSAPublicKey)
3605        subject = request.subject
3606        assert isinstance(subject, x509.Name)
3607        assert list(subject) == [
3608            x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
3609            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
3610            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3611            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
3612            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
3613        ]
3614
3615    def test_signature(self, backend):
3616        request = _load_cert(
3617            os.path.join("x509", "requests", "dsa_sha1.pem"),
3618            x509.load_pem_x509_csr,
3619            backend
3620        )
3621        assert request.signature == binascii.unhexlify(
3622            b"302c021461d58dc028d0110818a7d817d74235727c4acfdf0214097b52e198e"
3623            b"ce95de17273f0a924df23ce9d8188"
3624        )
3625
3626    def test_tbs_certrequest_bytes(self, backend):
3627        request = _load_cert(
3628            os.path.join("x509", "requests", "dsa_sha1.pem"),
3629            x509.load_pem_x509_csr,
3630            backend
3631        )
3632        assert request.tbs_certrequest_bytes == binascii.unhexlify(
3633            b"3082021802010030573118301606035504030c0f63727970746f677261706879"
3634            b"2e696f310d300b060355040a0c0450794341310b300906035504061302555331"
3635            b"0e300c06035504080c055465786173310f300d06035504070c0641757374696e"
3636            b"308201b63082012b06072a8648ce3804013082011e028181008d7fadbc09e284"
3637            b"aafa69154cea24177004909e519f8b35d685cde5b4ecdc9583e74d370a0f88ad"
3638            b"a98f026f27762fb3d5da7836f986dfcdb3589e5b925bea114defc03ef81dae30"
3639            b"c24bbc6df3d588e93427bba64203d4a5b1687b2b5e3b643d4c614976f89f95a3"
3640            b"8d3e4c89065fba97514c22c50adbbf289163a74b54859b35b7021500835de56b"
3641            b"d07cf7f82e2032fe78949aed117aa2ef0281801f717b5a07782fc2e4e68e311f"
3642            b"ea91a54edd36b86ac634d14f05a68a97eae9d2ef31fb1ef3de42c3d100df9ca6"
3643            b"4f5bdc2aec7bfdfb474cf831fea05853b5e059f2d24980a0ac463f1e818af352"
3644            b"3e3cb79a39d45fa92731897752842469cf8540b01491024eaafbce6018e8a1f4"
3645            b"658c343f4ba7c0b21e5376a21f4beb8491961e038184000281800713f07641f6"
3646            b"369bb5a9545274a2d4c01998367fb371bb9e13436363672ed68f82174c2de05c"
3647            b"8e839bc6de568dd50ba28d8d9d8719423aaec5557df10d773ab22d6d65cbb878"
3648            b"04a697bc8fd965b952f9f7e850edf13c8acdb5d753b6d10e59e0b5732e3c82ba"
3649            b"fa140342bc4a3bba16bd0681c8a6a2dbbb7efe6ce2b8463b170ba000"
3650        )
3651        request.public_key().verify(
3652            request.signature,
3653            request.tbs_certrequest_bytes,
3654            request.signature_hash_algorithm
3655        )
3656
3657
3658@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
3659@pytest.mark.requires_backend_interface(interface=X509Backend)
3660class TestECDSACertificate(object):
3661    def test_load_ecdsa_cert(self, backend):
3662        _skip_curve_unsupported(backend, ec.SECP384R1())
3663        cert = _load_cert(
3664            os.path.join("x509", "ecdsa_root.pem"),
3665            x509.load_pem_x509_certificate,
3666            backend
3667        )
3668        assert isinstance(cert.signature_hash_algorithm, hashes.SHA384)
3669        public_key = cert.public_key()
3670        assert isinstance(public_key, ec.EllipticCurvePublicKey)
3671        num = public_key.public_numbers()
3672        assert num.x == int(
3673            "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f"
3674            "6f0ccd00bba615b51467e9e2d9fee8e630c17", 16
3675        )
3676        assert num.y == int(
3677            "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7"
3678            "2deae88a7a16bb543ce67dc23ff031ca3e23e", 16
3679        )
3680        assert isinstance(num.curve, ec.SECP384R1)
3681
3682    def test_signature(self, backend):
3683        cert = _load_cert(
3684            os.path.join("x509", "ecdsa_root.pem"),
3685            x509.load_pem_x509_certificate,
3686            backend
3687        )
3688        assert cert.signature == binascii.unhexlify(
3689            b"3065023100adbcf26c3f124ad12d39c30a099773f488368c8827bbe6888d5085"
3690            b"a763f99e32de66930ff1ccb1098fdd6cabfa6b7fa0023039665bc2648db89e50"
3691            b"dca8d549a2edc7dcd1497f1701b8c8868f4e8c882ba89aa98ac5d100bdf854e2"
3692            b"9ae55b7cb32717"
3693        )
3694        r, s = decode_dss_signature(cert.signature)
3695        assert r == int(
3696            "adbcf26c3f124ad12d39c30a099773f488368c8827bbe6888d5085a763f99e32"
3697            "de66930ff1ccb1098fdd6cabfa6b7fa0",
3698            16
3699        )
3700        assert s == int(
3701            "39665bc2648db89e50dca8d549a2edc7dcd1497f1701b8c8868f4e8c882ba89a"
3702            "a98ac5d100bdf854e29ae55b7cb32717",
3703            16
3704        )
3705
3706    def test_tbs_certificate_bytes(self, backend):
3707        _skip_curve_unsupported(backend, ec.SECP384R1())
3708        cert = _load_cert(
3709            os.path.join("x509", "ecdsa_root.pem"),
3710            x509.load_pem_x509_certificate,
3711            backend
3712        )
3713        assert cert.tbs_certificate_bytes == binascii.unhexlify(
3714            b"308201c5a0030201020210055556bcf25ea43535c3a40fd5ab4572300a06082"
3715            b"a8648ce3d0403033061310b300906035504061302555331153013060355040a"
3716            b"130c446967694365727420496e6331193017060355040b13107777772e64696"
3717            b"769636572742e636f6d3120301e06035504031317446967694365727420476c"
3718            b"6f62616c20526f6f74204733301e170d3133303830313132303030305a170d3"
3719            b"338303131353132303030305a3061310b300906035504061302555331153013"
3720            b"060355040a130c446967694365727420496e6331193017060355040b1310777"
3721            b"7772e64696769636572742e636f6d3120301e06035504031317446967694365"
3722            b"727420476c6f62616c20526f6f742047333076301006072a8648ce3d0201060"
3723            b"52b8104002203620004dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34"
3724            b"eadec69bbcd095f6f0ccd00bba615b51467e9e2d9fee8e630c17ec0770f5cf8"
3725            b"42e40839ce83f416d3badd3a4145936789d0343ee10136c72deae88a7a16bb5"
3726            b"43ce67dc23ff031ca3e23ea3423040300f0603551d130101ff040530030101f"
3727            b"f300e0603551d0f0101ff040403020186301d0603551d0e04160414b3db48a4"
3728            b"f9a1c5d8ae3641cc1163696229bc4bc6"
3729        )
3730        cert.public_key().verify(
3731            cert.signature, cert.tbs_certificate_bytes,
3732            ec.ECDSA(cert.signature_hash_algorithm)
3733        )
3734
3735    def test_load_ecdsa_no_named_curve(self, backend):
3736        _skip_curve_unsupported(backend, ec.SECP256R1())
3737        cert = _load_cert(
3738            os.path.join("x509", "custom", "ec_no_named_curve.pem"),
3739            x509.load_pem_x509_certificate,
3740            backend
3741        )
3742        with pytest.raises(NotImplementedError):
3743            cert.public_key()
3744
3745
3746@pytest.mark.requires_backend_interface(interface=X509Backend)
3747@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
3748class TestECDSACertificateRequest(object):
3749    @pytest.mark.parametrize(
3750        ("path", "loader_func"),
3751        [
3752            [
3753                os.path.join("x509", "requests", "ec_sha256.pem"),
3754                x509.load_pem_x509_csr
3755            ],
3756            [
3757                os.path.join("x509", "requests", "ec_sha256.der"),
3758                x509.load_der_x509_csr
3759            ],
3760        ]
3761    )
3762    def test_load_ecdsa_certificate_request(self, path, loader_func, backend):
3763        _skip_curve_unsupported(backend, ec.SECP384R1())
3764        request = _load_cert(path, loader_func, backend)
3765        assert isinstance(request.signature_hash_algorithm, hashes.SHA256)
3766        public_key = request.public_key()
3767        assert isinstance(public_key, ec.EllipticCurvePublicKey)
3768        subject = request.subject
3769        assert isinstance(subject, x509.Name)
3770        assert list(subject) == [
3771            x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
3772            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
3773            x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
3774            x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
3775            x509.NameAttribute(NameOID.LOCALITY_NAME, u'Austin'),
3776        ]
3777
3778    def test_signature(self, backend):
3779        _skip_curve_unsupported(backend, ec.SECP384R1())
3780        request = _load_cert(
3781            os.path.join("x509", "requests", "ec_sha256.pem"),
3782            x509.load_pem_x509_csr,
3783            backend
3784        )
3785        assert request.signature == binascii.unhexlify(
3786            b"306502302c1a9f7de8c1787332d2307a886b476a59f172b9b0e250262f3238b1"
3787            b"b45ee112bb6eb35b0fb56a123b9296eb212dffc302310094cf440c95c52827d5"
3788            b"56ae6d76500e3008255d47c29f7ee782ed7558e51bfd76aa45df6d999ed5c463"
3789            b"347fe2382d1751"
3790        )
3791
3792    def test_tbs_certrequest_bytes(self, backend):
3793        _skip_curve_unsupported(backend, ec.SECP384R1())
3794        request = _load_cert(
3795            os.path.join("x509", "requests", "ec_sha256.pem"),
3796            x509.load_pem_x509_csr,
3797            backend
3798        )
3799        assert request.tbs_certrequest_bytes == binascii.unhexlify(
3800            b"3081d602010030573118301606035504030c0f63727970746f6772617068792"
3801            b"e696f310d300b060355040a0c0450794341310b300906035504061302555331"
3802            b"0e300c06035504080c055465786173310f300d06035504070c0641757374696"
3803            b"e3076301006072a8648ce3d020106052b8104002203620004de19b514c0b3c3"
3804            b"ae9b398ea3e26b5e816bdcf9102cad8f12fe02f9e4c9248724b39297ed7582e"
3805            b"04d8b32a551038d09086803a6d3fb91a1a1167ec02158b00efad39c9396462f"
3806            b"accff0ffaf7155812909d3726bd59fde001cff4bb9b2f5af8cbaa000"
3807        )
3808        request.public_key().verify(
3809            request.signature, request.tbs_certrequest_bytes,
3810            ec.ECDSA(request.signature_hash_algorithm)
3811        )
3812
3813
3814@pytest.mark.requires_backend_interface(interface=X509Backend)
3815class TestOtherCertificate(object):
3816    def test_unsupported_subject_public_key_info(self, backend):
3817        cert = _load_cert(
3818            os.path.join(
3819                "x509", "custom", "unsupported_subject_public_key_info.pem"
3820            ),
3821            x509.load_pem_x509_certificate,
3822            backend,
3823        )
3824
3825        with pytest.raises(ValueError):
3826            cert.public_key()
3827
3828    def test_bad_time_in_validity(self, backend):
3829        cert = _load_cert(
3830            os.path.join(
3831                "x509", "badasn1time.pem"
3832            ),
3833            x509.load_pem_x509_certificate,
3834            backend,
3835        )
3836
3837        with pytest.raises(ValueError, match='19020701025736Z'):
3838            cert.not_valid_after
3839
3840
3841class TestNameAttribute(object):
3842    EXPECTED_TYPES = [
3843        (NameOID.COMMON_NAME, _ASN1Type.UTF8String),
3844        (NameOID.COUNTRY_NAME, _ASN1Type.PrintableString),
3845        (NameOID.LOCALITY_NAME, _ASN1Type.UTF8String),
3846        (NameOID.STATE_OR_PROVINCE_NAME, _ASN1Type.UTF8String),
3847        (NameOID.STREET_ADDRESS, _ASN1Type.UTF8String),
3848        (NameOID.ORGANIZATION_NAME, _ASN1Type.UTF8String),
3849        (NameOID.ORGANIZATIONAL_UNIT_NAME, _ASN1Type.UTF8String),
3850        (NameOID.SERIAL_NUMBER, _ASN1Type.PrintableString),
3851        (NameOID.SURNAME, _ASN1Type.UTF8String),
3852        (NameOID.GIVEN_NAME, _ASN1Type.UTF8String),
3853        (NameOID.TITLE, _ASN1Type.UTF8String),
3854        (NameOID.GENERATION_QUALIFIER, _ASN1Type.UTF8String),
3855        (NameOID.X500_UNIQUE_IDENTIFIER, _ASN1Type.UTF8String),
3856        (NameOID.DN_QUALIFIER, _ASN1Type.PrintableString),
3857        (NameOID.PSEUDONYM, _ASN1Type.UTF8String),
3858        (NameOID.USER_ID, _ASN1Type.UTF8String),
3859        (NameOID.DOMAIN_COMPONENT, _ASN1Type.IA5String),
3860        (NameOID.EMAIL_ADDRESS, _ASN1Type.IA5String),
3861        (NameOID.JURISDICTION_COUNTRY_NAME, _ASN1Type.PrintableString),
3862        (NameOID.JURISDICTION_LOCALITY_NAME, _ASN1Type.UTF8String),
3863        (
3864            NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME,
3865            _ASN1Type.UTF8String
3866        ),
3867        (NameOID.BUSINESS_CATEGORY, _ASN1Type.UTF8String),
3868        (NameOID.POSTAL_ADDRESS, _ASN1Type.UTF8String),
3869        (NameOID.POSTAL_CODE, _ASN1Type.UTF8String),
3870    ]
3871
3872    def test_default_types(self):
3873        for oid, asn1_type in TestNameAttribute.EXPECTED_TYPES:
3874            na = x509.NameAttribute(oid, u"US")
3875            assert na._type == asn1_type
3876
3877    def test_alternate_type(self):
3878        na2 = x509.NameAttribute(
3879            NameOID.COMMON_NAME, u"common", _ASN1Type.IA5String
3880        )
3881        assert na2._type == _ASN1Type.IA5String
3882
3883    def test_init_bad_oid(self):
3884        with pytest.raises(TypeError):
3885            x509.NameAttribute(None, u'value')
3886
3887    def test_init_bad_value(self):
3888        with pytest.raises(TypeError):
3889            x509.NameAttribute(
3890                x509.ObjectIdentifier('2.999.1'),
3891                b'bytes'
3892            )
3893
3894    def test_init_bad_country_code_value(self):
3895        with pytest.raises(ValueError):
3896            x509.NameAttribute(
3897                NameOID.COUNTRY_NAME,
3898                u'United States'
3899            )
3900
3901        # unicode string of length 2, but > 2 bytes
3902        with pytest.raises(ValueError):
3903            x509.NameAttribute(
3904                NameOID.COUNTRY_NAME,
3905                u'\U0001F37A\U0001F37A'
3906            )
3907
3908    def test_init_empty_value(self):
3909        with pytest.raises(ValueError):
3910            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'')
3911
3912    def test_invalid_type(self):
3913        with pytest.raises(TypeError):
3914            x509.NameAttribute(NameOID.COMMON_NAME, u"common", "notanenum")
3915
3916    def test_eq(self):
3917        assert x509.NameAttribute(
3918            x509.ObjectIdentifier('2.999.1'), u'value'
3919        ) == x509.NameAttribute(
3920            x509.ObjectIdentifier('2.999.1'), u'value'
3921        )
3922
3923    def test_ne(self):
3924        assert x509.NameAttribute(
3925            x509.ObjectIdentifier('2.5.4.3'), u'value'
3926        ) != x509.NameAttribute(
3927            x509.ObjectIdentifier('2.5.4.5'), u'value'
3928        )
3929        assert x509.NameAttribute(
3930            x509.ObjectIdentifier('2.999.1'), u'value'
3931        ) != x509.NameAttribute(
3932            x509.ObjectIdentifier('2.999.1'), u'value2'
3933        )
3934        assert x509.NameAttribute(
3935            x509.ObjectIdentifier('2.999.2'), u'value'
3936        ) != object()
3937
3938    def test_repr(self):
3939        na = x509.NameAttribute(x509.ObjectIdentifier('2.5.4.3'), u'value')
3940        if not six.PY2:
3941            assert repr(na) == (
3942                "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
3943                "nName)>, value='value')>"
3944            )
3945        else:
3946            assert repr(na) == (
3947                "<NameAttribute(oid=<ObjectIdentifier(oid=2.5.4.3, name=commo"
3948                "nName)>, value=u'value')>"
3949            )
3950
3951    def test_distinugished_name(self):
3952        # Escaping
3953        na = x509.NameAttribute(NameOID.COMMON_NAME, u'James "Jim" Smith, III')
3954        assert na.rfc4514_string() == r'CN=James \"Jim\" Smith\, III'
3955        na = x509.NameAttribute(NameOID.USER_ID, u'# escape+,;\0this ')
3956        assert na.rfc4514_string() == r'UID=\# escape\+\,\;\00this\ '
3957
3958        # Nonstandard attribute OID
3959        na = x509.NameAttribute(NameOID.EMAIL_ADDRESS, u'somebody@example.com')
3960        assert (na.rfc4514_string() ==
3961                '1.2.840.113549.1.9.1=somebody@example.com')
3962
3963
3964class TestRelativeDistinguishedName(object):
3965    def test_init_empty(self):
3966        with pytest.raises(ValueError):
3967            x509.RelativeDistinguishedName([])
3968
3969    def test_init_not_nameattribute(self):
3970        with pytest.raises(TypeError):
3971            x509.RelativeDistinguishedName(["not-a-NameAttribute"])
3972
3973    def test_init_duplicate_attribute(self):
3974        with pytest.raises(ValueError):
3975            x509.RelativeDistinguishedName([
3976                x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'val1'),
3977                x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'val1'),
3978            ])
3979
3980    def test_hash(self):
3981        rdn1 = x509.RelativeDistinguishedName([
3982            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1'),
3983            x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value2'),
3984        ])
3985        rdn2 = x509.RelativeDistinguishedName([
3986            x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value2'),
3987            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1'),
3988        ])
3989        rdn3 = x509.RelativeDistinguishedName([
3990            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1'),
3991            x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value3'),
3992        ])
3993        assert hash(rdn1) == hash(rdn2)
3994        assert hash(rdn1) != hash(rdn3)
3995
3996    def test_eq(self):
3997        rdn1 = x509.RelativeDistinguishedName([
3998            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1'),
3999            x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value2'),
4000        ])
4001        rdn2 = x509.RelativeDistinguishedName([
4002            x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value2'),
4003            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1'),
4004        ])
4005        assert rdn1 == rdn2
4006
4007    def test_ne(self):
4008        rdn1 = x509.RelativeDistinguishedName([
4009            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1'),
4010            x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value2'),
4011        ])
4012        rdn2 = x509.RelativeDistinguishedName([
4013            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1'),
4014            x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value3'),
4015        ])
4016        assert rdn1 != rdn2
4017        assert rdn1 != object()
4018
4019    def test_iter_input(self):
4020        # Order must be preserved too
4021        attrs = [
4022            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1'),
4023            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value2'),
4024            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value3')
4025        ]
4026        rdn = x509.RelativeDistinguishedName(iter(attrs))
4027        assert list(rdn) == attrs
4028        assert list(rdn) == attrs
4029
4030    def test_get_attributes_for_oid(self):
4031        oid = x509.ObjectIdentifier('2.999.1')
4032        attr = x509.NameAttribute(oid, u'value1')
4033        rdn = x509.RelativeDistinguishedName([attr])
4034        assert rdn.get_attributes_for_oid(oid) == [attr]
4035        assert rdn.get_attributes_for_oid(x509.ObjectIdentifier('1.2.3')) == []
4036
4037
4038class TestObjectIdentifier(object):
4039    def test_eq(self):
4040        oid1 = x509.ObjectIdentifier('2.999.1')
4041        oid2 = x509.ObjectIdentifier('2.999.1')
4042        assert oid1 == oid2
4043
4044    def test_ne(self):
4045        oid1 = x509.ObjectIdentifier('2.999.1')
4046        assert oid1 != x509.ObjectIdentifier('2.999.2')
4047        assert oid1 != object()
4048
4049    def test_repr(self):
4050        oid = x509.ObjectIdentifier("2.5.4.3")
4051        assert repr(oid) == "<ObjectIdentifier(oid=2.5.4.3, name=commonName)>"
4052        oid = x509.ObjectIdentifier("2.999.1")
4053        assert repr(oid) == "<ObjectIdentifier(oid=2.999.1, name=Unknown OID)>"
4054
4055    def test_name_property(self):
4056        oid = x509.ObjectIdentifier("2.5.4.3")
4057        assert oid._name == 'commonName'
4058        oid = x509.ObjectIdentifier("2.999.1")
4059        assert oid._name == 'Unknown OID'
4060
4061    def test_too_short(self):
4062        with pytest.raises(ValueError):
4063            x509.ObjectIdentifier("1")
4064
4065    def test_invalid_input(self):
4066        with pytest.raises(ValueError):
4067            x509.ObjectIdentifier("notavalidform")
4068
4069    def test_invalid_node1(self):
4070        with pytest.raises(ValueError):
4071            x509.ObjectIdentifier("7.1.37")
4072
4073    def test_invalid_node2(self):
4074        with pytest.raises(ValueError):
4075            x509.ObjectIdentifier("1.50.200")
4076
4077    def test_valid(self):
4078        x509.ObjectIdentifier("0.35.200")
4079        x509.ObjectIdentifier("1.39.999")
4080        x509.ObjectIdentifier("2.5.29.3")
4081        x509.ObjectIdentifier("2.999.37.5.22.8")
4082        x509.ObjectIdentifier("2.25.305821105408246119474742976030998643995")
4083
4084
4085class TestName(object):
4086    def test_eq(self):
4087        ava1 = x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1')
4088        ava2 = x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value2')
4089        name1 = x509.Name([ava1, ava2])
4090        name2 = x509.Name([
4091            x509.RelativeDistinguishedName([ava1]),
4092            x509.RelativeDistinguishedName([ava2]),
4093        ])
4094        name3 = x509.Name([x509.RelativeDistinguishedName([ava1, ava2])])
4095        name4 = x509.Name([x509.RelativeDistinguishedName([ava2, ava1])])
4096        assert name1 == name2
4097        assert name3 == name4
4098
4099    def test_ne(self):
4100        ava1 = x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1')
4101        ava2 = x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value2')
4102        name1 = x509.Name([ava1, ava2])
4103        name2 = x509.Name([ava2, ava1])
4104        name3 = x509.Name([x509.RelativeDistinguishedName([ava1, ava2])])
4105        assert name1 != name2
4106        assert name1 != name3
4107        assert name1 != object()
4108
4109    def test_hash(self):
4110        ava1 = x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1')
4111        ava2 = x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value2')
4112        name1 = x509.Name([ava1, ava2])
4113        name2 = x509.Name([
4114            x509.RelativeDistinguishedName([ava1]),
4115            x509.RelativeDistinguishedName([ava2]),
4116        ])
4117        name3 = x509.Name([ava2, ava1])
4118        name4 = x509.Name([x509.RelativeDistinguishedName([ava1, ava2])])
4119        name5 = x509.Name([x509.RelativeDistinguishedName([ava2, ava1])])
4120        assert hash(name1) == hash(name2)
4121        assert hash(name1) != hash(name3)
4122        assert hash(name1) != hash(name4)
4123        assert hash(name4) == hash(name5)
4124
4125    def test_iter_input(self):
4126        attrs = [
4127            x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1')
4128        ]
4129        name = x509.Name(iter(attrs))
4130        assert list(name) == attrs
4131        assert list(name) == attrs
4132
4133    def test_rdns(self):
4134        rdn1 = x509.NameAttribute(x509.ObjectIdentifier('2.999.1'), u'value1')
4135        rdn2 = x509.NameAttribute(x509.ObjectIdentifier('2.999.2'), u'value2')
4136        name1 = x509.Name([rdn1, rdn2])
4137        assert name1.rdns == [
4138            x509.RelativeDistinguishedName([rdn1]),
4139            x509.RelativeDistinguishedName([rdn2]),
4140        ]
4141        name2 = x509.Name([x509.RelativeDistinguishedName([rdn1, rdn2])])
4142        assert name2.rdns == [x509.RelativeDistinguishedName([rdn1, rdn2])]
4143
4144    def test_repr(self):
4145        name = x509.Name([
4146            x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
4147            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
4148        ])
4149
4150        assert repr(name) == "<Name(CN=cryptography.io,O=PyCA)>"
4151
4152    def test_rfc4514_string(self):
4153        n = x509.Name([
4154            x509.RelativeDistinguishedName([
4155                x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, u'Sales'),
4156                x509.NameAttribute(NameOID.COMMON_NAME, u'J.  Smith'),
4157            ]),
4158            x509.RelativeDistinguishedName([
4159                x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'example'),
4160            ]),
4161            x509.RelativeDistinguishedName([
4162                x509.NameAttribute(NameOID.DOMAIN_COMPONENT, u'net'),
4163            ]),
4164        ])
4165        assert (n.rfc4514_string() ==
4166                'OU=Sales+CN=J.  Smith,DC=example,DC=net')
4167
4168    def test_not_nameattribute(self):
4169        with pytest.raises(TypeError):
4170            x509.Name(["not-a-NameAttribute"])
4171
4172    @pytest.mark.requires_backend_interface(interface=X509Backend)
4173    def test_bytes(self, backend):
4174        name = x509.Name([
4175            x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'),
4176            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
4177        ])
4178        assert name.public_bytes(backend) == binascii.unhexlify(
4179            b"30293118301606035504030c0f63727970746f6772617068792e696f310d300"
4180            b"b060355040a0c0450794341"
4181        )
4182
4183    @pytest.mark.requires_backend_interface(interface=X509Backend)
4184    def test_bmpstring_bytes(self, backend):
4185        # For this test we need an odd length string. BMPString is UCS-2
4186        # encoded so it will always be even length and OpenSSL will error if
4187        # you pass an odd length string without encoding it properly first.
4188        name = x509.Name([
4189            x509.NameAttribute(
4190                NameOID.COMMON_NAME,
4191                u'cryptography.io',
4192                _ASN1Type.BMPString
4193            ),
4194            x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'),
4195        ])
4196        assert name.public_bytes(backend) == binascii.unhexlify(
4197            b"30383127302506035504031e1e00630072007900700074006f00670072006100"
4198            b"7000680079002e0069006f310d300b060355040a0c0450794341"
4199        )
4200
4201
4202def test_random_serial_number(monkeypatch):
4203    sample_data = os.urandom(20)
4204
4205    def notrandom(size):
4206        assert size == len(sample_data)
4207        return sample_data
4208
4209    monkeypatch.setattr(os, "urandom", notrandom)
4210
4211    serial_number = x509.random_serial_number()
4212
4213    assert (
4214        serial_number == utils.int_from_bytes(sample_data, "big") >> 1
4215    )
4216    assert serial_number.bit_length() < 160
4217