def generate_crl(self, ca, certs, next_update=1): # There is a tricky case here - what happens if the root CA is compromised ? # In normal world scenarios, that CA is removed from app's trust store and any # subsequent certs it had issues wouldn't be validated by the app then. Making a CRL # for a revoked root CA in normal cases doesn't make sense as the thief can sign a # counter CRL saying that everything is fine. As our environment is controlled, # i think we are safe to create a crl for root CA as well which we can publish for # services which make use of it i.e openvpn and they'll know that the certs/ca's have been # compromised. # # `ca` is root ca from where the chain `certs` starts. # `certs` is a list of all certs ca inclusive which are to be # included in the CRL ( if root ca is compromised, it will be in `certs` as well ). private_key = load_private_key(ca['privatekey']) ca_cert = x509.load_pem_x509_certificate(ca['certificate'].encode(), default_backend()) if not private_key: return None ca_data = self.middleware.call_sync('cryptokey.load_certificate', ca['certificate']) issuer = {k: ca_data.get(v) for k, v in CERT_BACKEND_MAPPINGS.items()} crl_builder = x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(getattr(NameOID, k.upper()), v) for k, v in issuer.items() if v ])).last_update(datetime.datetime.utcnow()).next_update( datetime.datetime.utcnow() + datetime.timedelta(next_update, 300, 0)) for cert in certs: crl_builder = crl_builder.add_revoked_certificate( x509.RevokedCertificateBuilder().serial_number( self.middleware.call_sync( 'cryptokey.load_certificate', cert['certificate'])['serial']).revocation_date( cert['revoked_date']).build(default_backend())) # https://www.ietf.org/rfc/rfc5280.txt # We should add AuthorityKeyIdentifier and CRLNumber at the very least crl = crl_builder.add_extension( x509.AuthorityKeyIdentifier( x509.SubjectKeyIdentifier.from_public_key( ca_cert.public_key()).digest, [ x509.DirectoryName( x509.Name([ x509.NameAttribute(getattr(NameOID, k.upper()), v) for k, v in issuer.items() if v ])) ], ca_cert.serial_number), False).add_extension(x509.CRLNumber(1), False).sign( private_key=private_key, algorithm=retrieve_signing_algorithm({}, private_key), backend=default_backend()) return crl.public_bytes(serialization.Encoding.PEM).decode()
def test_sign_extensions(self, backend, extension): private_key = RSA_KEY_2048.private_key(backend) last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = ( x509.CertificateRevocationListBuilder() .issuer_name( x509.Name( [ x509.NameAttribute( NameOID.COMMON_NAME, "cryptography.io CA" ) ] ) ) .last_update(last_update) .next_update(next_update) .add_extension(extension, False) ) crl = builder.sign(private_key, hashes.SHA256(), backend) assert len(crl) == 0 assert len(crl.extensions) == 1 ext = crl.extensions.get_extension_for_class(type(extension)) assert ext.critical is False assert ext.value == extension
def create_crl(crl_path, ca_key, ca_cert): now = datetime.utcnow() builder = ( x509.CertificateRevocationListBuilder() .last_update(now) .next_update(now + timedelta(days=1)) .issuer_name(ca_cert.subject) ) for i in [3,4,5]: cert = ( x509.RevokedCertificateBuilder() .revocation_date(now) .serial_number(i) .add_extension( x509.CRLReason(x509.ReasonFlags.key_compromise), critical=False) .build(default_backend()) ) builder = builder.add_revoked_certificate(cert) cert = builder.sign( private_key=ca_key, algorithm=hashes.SHA256(), backend=default_backend()) write_public(cert, crl_path)
def _make_crl( private_key, last_update_days=-1, next_update_days=30, cn="ATAT", expired_serials=None, ): one_day = timedelta(1, 0, 0) builder = x509.CertificateRevocationListBuilder() builder = builder.issuer_name( x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, cn)])) last_update = datetime.today() + (one_day * last_update_days) next_update = datetime.today() + (one_day * next_update_days) builder = builder.last_update(last_update) builder = builder.next_update(next_update) if expired_serials: for serial in expired_serials: builder = add_revoked_cert(builder, serial, last_update) crl = builder.sign( private_key=private_key, algorithm=hashes.SHA256(), backend=default_backend(), ) return crl
def create_crl(*serials): """ Returns a new certificate revocation list that contains all of the revoked certificates with the given list of serial numbers. :return: str """ signer = certificate_authority() builder = x509.CertificateRevocationListBuilder( last_update=datetime.now() - timedelta(days=1), next_update=datetime.now() + timedelta(days=3650), issuer_name=signer.crt.subject, ) # iterate over each serial number and create a new revoked certificate # that is added to the CRL builder for serial in serials: revoked = x509.RevokedCertificateBuilder( serial_number=int(serial), revocation_date=datetime.now() - timedelta(days=1), ) revoked = revoked.build(default_backend()) builder = builder.add_revoked_certificate(revoked) # sign the CRL with the certificate authority private key crl = builder.sign( private_key=signer.key, algorithm=hashes.SHA512(), backend=default_backend(), ) return encode_certificate(crl)
def get_crl(self): """ Creates a new CRL in the pem format Parameters ---------- Returns ------- CRL in the pem format """ # Load our root cert root_key = load_key(self.root_private_key_file) root_certificate = read_certificate(self.root_certificate_file) builder = x509.CertificateRevocationListBuilder() builder = builder.last_update(datetime.datetime.today()) builder = builder.next_update(datetime.datetime.today() + datetime.timedelta(1, 0, 0)) builder = builder.issuer_name(root_certificate.issuer) if self.revoked_certificates: for revoked_cert in self.revoked_certificates: builder = builder.add_revoked_certificate(revoked_cert) cert_revocation_list = builder.sign(private_key=root_key, algorithm=hashes.SHA256(), backend=default_backend()) return cert_revocation_list, cert_revocation_list.public_bytes( encoding=serialization.Encoding.PEM)
def test_sign_dsa_key(self, backend): if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000: pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1") private_key = DSA_KEY_2048.private_key(backend) invalidity_date = x509.InvalidityDate( datetime.datetime(2002, 1, 1, 0, 0)) ian = x509.IssuerAlternativeName([ x509.UniformResourceIdentifier(u"https://cryptography.io"), ]) revoked_cert0 = x509.RevokedCertificateBuilder().serial_number( 2).revocation_date(datetime.datetime(2012, 1, 1, 1, 1)).add_extension( invalidity_date, False).build(backend) last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io CA") ])).last_update(last_update).next_update( next_update).add_revoked_certificate( revoked_cert0).add_extension(ian, False) crl = builder.sign(private_key, hashes.SHA256(), backend) assert crl.extensions.get_extension_for_class( x509.IssuerAlternativeName).value == ian assert crl[0].serial_number == revoked_cert0.serial_number assert crl[0].revocation_date == revoked_cert0.revocation_date assert len(crl[0].extensions) == 1 ext = crl[0].extensions.get_extension_for_class(x509.InvalidityDate) assert ext.critical is False assert ext.value == invalidity_date
def create_crl(result_dir): # Note: you can read the CRL from the CLI using `openssl crl -inform PEM -text -noout -in crl.pem` if os.path.isfile("{}/crl.pem".format(result_dir)): logging.info("CRL already exists, not creating a new one..") return with open("{}/ca.crt".format(result_dir), "rb") as f: data = f.read() ca_cert = x509.load_pem_x509_certificate(data, default_backend()) with open("{}/ca.key".format(result_dir), "rb") as f: data = f.read() ca_key = load_pem_private_key(data, None, default_backend()) builder = x509.CertificateRevocationListBuilder() builder = builder.last_update(datetime.datetime.now()) builder = builder.next_update(datetime.datetime.now() + datetime.timedelta(days=36500)) builder = builder.issuer_name(ca_cert.issuer) cert_revocation_list = builder.sign(private_key=ca_key, algorithm=hashes.SHA256(), backend=default_backend()) with open("{}/crl.pem".format(result_dir), "wb") as f: f.write(cert_revocation_list.public_bytes(serialization.Encoding.PEM))
def build(ca, path): builder = x509.CertificateRevocationListBuilder() builder = builder.issuer_name(ca.cert.subject) builder = builder.last_update(datetime.datetime.now(tz=tz)) builder = builder.next_update( datetime.datetime.now(tz=tz) + datetime.timedelta(days=1)) return builder
def test_add_extension_checks_for_duplicates(self): builder = x509.CertificateRevocationListBuilder().add_extension( x509.CRLNumber(1), False ) with pytest.raises(ValueError): builder.add_extension(x509.CRLNumber(2), False)
def regenerate_certificate_revocation_list(self, certification_authority): logger.info("Updating CRL for CA %s" % certification_authority.common_name) one_day = datetime.timedelta(1, 0, 0) ca_cert = x509.load_pem_x509_certificate( str(certification_authority.certificate), default_backend()) ca_key = serialization.load_pem_private_key( str(certification_authority.private_key), None, default_backend()) builder = x509.CertificateRevocationListBuilder() builder = builder.issuer_name(ca_cert.subject) builder = builder.last_update(datetime.datetime.today()) builder = builder.next_update(datetime.datetime.today() + one_day) for certificate in SSLRevokedCertificate.objects.filter( certification_authority=certification_authority): logger.info("Adding certificate 0x%X" % certificate.serial_number) revoked_cert = x509.RevokedCertificateBuilder().serial_number( certificate.serial_number).revocation_date( certificate.revocation_date.replace(tzinfo=None)).build( default_backend()) builder = builder.add_revoked_certificate(revoked_cert) crl = builder.sign(private_key=ca_key, algorithm=hashes.SHA256(), backend=default_backend()) logger.info('Saving models') certification_authority.revocation_list = crl.public_bytes( serialization.Encoding.PEM) print certification_authority.revocation_list certification_authority.save()
def test_sign_with_revoked_certificates(self, backend): private_key = RSA_KEY_2048.private_key(backend) last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) invalidity_date = x509.InvalidityDate( datetime.datetime(2002, 1, 1, 0, 0)) revoked_cert0 = ( x509.RevokedCertificateBuilder().serial_number(38).revocation_date( datetime.datetime(2011, 1, 1, 1, 1)).build(backend)) revoked_cert1 = ( x509.RevokedCertificateBuilder().serial_number(2).revocation_date( datetime.datetime(2012, 1, 1, 1, 1)).add_extension(invalidity_date, False).build(backend)) builder = (x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io CA") ])).last_update(last_update).next_update( next_update).add_revoked_certificate( revoked_cert0).add_revoked_certificate(revoked_cert1)) crl = builder.sign(private_key, hashes.SHA256(), backend) assert len(crl) == 2 assert crl.last_update == last_update assert crl.next_update == next_update assert crl[0].serial_number == revoked_cert0.serial_number assert crl[0].revocation_date == revoked_cert0.revocation_date assert len(crl[0].extensions) == 0 assert crl[1].serial_number == revoked_cert1.serial_number assert crl[1].revocation_date == revoked_cert1.revocation_date assert len(crl[1].extensions) == 1 ext = crl[1].extensions.get_extension_for_class(x509.InvalidityDate) assert ext.critical is False assert ext.value == invalidity_date
def build_crl(): #from cryptography import x509 # from cryptography.hazmat.backends import default_backend #from cryptography.hazmat.primitives import hashes # from cryptography.hazmat.primitives.asymmetric import rsa #from cryptography.x509.oid import NameOID #import datetime ca = get_newest_ca() one_day = datetime.timedelta(1, 0, 0) builder = x509.CertificateRevocationListBuilder() builder = builder.issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, ca.common_name), ])) builder = builder.last_update(datetime.datetime.today()) builder = builder.next_update(datetime.datetime.today() + one_day) revoked_list = Certificate.objects.filter( issuer_serial_number=ca.serial_number, revoked=True) for revoked_cert in revoked_list: logger.debug("revoked serial_number: %s", revoked_cert.serial_number) revoked_cert = x509.RevokedCertificateBuilder().serial_number( int(revoked_cert.serial_number)).revocation_date( datetime.datetime.today()).build(default_backend()) builder = builder.add_revoked_certificate(revoked_cert) crl = builder.sign(private_key=loadPEMKey(keyStorePath(ca.serial_number)), algorithm=hashes.SHA256(), backend=default_backend()) dataStream = crl.public_bytes(serialization.Encoding.PEM) return dataStream
def test_sign_ec_key(self, backend): _skip_curve_unsupported(backend, ec.SECP256R1()) private_key = ec.generate_private_key(ec.SECP256R1(), backend) invalidity_date = x509.InvalidityDate( datetime.datetime(2002, 1, 1, 0, 0)) ian = x509.IssuerAlternativeName( [x509.UniformResourceIdentifier("https://cryptography.io")]) revoked_cert0 = ( x509.RevokedCertificateBuilder().serial_number(2).revocation_date( datetime.datetime(2012, 1, 1, 1, 1)).add_extension(invalidity_date, False).build(backend)) last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = (x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, "cryptography.io CA") ])).last_update(last_update).next_update(next_update). add_revoked_certificate(revoked_cert0).add_extension( ian, False)) crl = builder.sign(private_key, hashes.SHA256(), backend) assert (crl.extensions.get_extension_for_class( x509.IssuerAlternativeName).value == ian) assert crl[0].serial_number == revoked_cert0.serial_number assert crl[0].revocation_date == revoked_cert0.revocation_date assert len(crl[0].extensions) == 1 ext = crl[0].extensions.get_extension_for_class(x509.InvalidityDate) assert ext.critical is False assert ext.value == invalidity_date
def get_crl(self): """Generates a Certificate Revocation List. Returns: A Certificate Revocation List. """ ca_pkey = self.get_ca_key() ca_cert = self.get_ca_cert(ca_pkey) crl = (x509.CertificateRevocationListBuilder().issuer_name( ca_cert.subject).last_update( datetime.datetime.utcnow()).next_update( datetime.datetime.utcnow() + datetime.timedelta(minutes=15))) for cert in self.storage.get_revoked_certs(): # Convert the string cert into a cryptography cert object cert = x509.load_pem_x509_certificate(bytes(str(cert), "UTF-8"), backend=default_backend()) # Add the certificate to the CRL crl = crl.add_revoked_certificate( x509.RevokedCertificateBuilder().serial_number( cert.serial_number).revocation_date( datetime.datetime.utcnow()).build( backend=default_backend())) # Sign the CRL crl = crl.sign(private_key=ca_pkey, algorithm=hashes.SHA256(), backend=default_backend()) return crl
def test_sign_multiple_extensions_critical(self, backend): private_key = RSA_KEY_2048.private_key(backend) last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) ian = x509.IssuerAlternativeName([ x509.UniformResourceIdentifier(u"https://cryptography.io"), ]) crl_number = x509.CRLNumber(13) builder = x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io CA") ]) ).last_update( last_update ).next_update( next_update ).add_extension( crl_number, False ).add_extension( ian, True ) crl = builder.sign(private_key, hashes.SHA256(), backend) assert len(crl) == 0 assert len(crl.extensions) == 2 ext1 = crl.extensions.get_extension_for_class(x509.CRLNumber) assert ext1.critical is False assert ext1.value == crl_number ext2 = crl.extensions.get_extension_for_class( x509.IssuerAlternativeName ) assert ext2.critical is True assert ext2.value == ian
def ca_crl(ca_cert, ca_key=None, common_name=None, certificates_revoke=None): """ Generates the CA Certificate Revocation List (CRL) :param ca_cert: CA certificate object ``cryptography.x509.Certificate`` :type ca_cert: object, required. :param ca_key: CA key object ``cryptography.hazmat.backends.openssl.rsa`` :type ca_key: object, required. :param common_name: Common Name when issuing Certificate Authority cert. :type common_name: string, required. :param certificates_revoke: List of certificates to be revoked, if none \ an empty list is returned :type certificates_revoke: list of \ ``cryptography.hazmat.backends.openssl.x509._RevokedCertificate``, optional. :return: Certificate Revocation List object :rtype: ``cryptography.hazmat.backends.openssl.x509._CertificateRevocationList`` """ builder = x509.CertificateRevocationListBuilder() builder = builder.issuer_name(ca_cert.subject) builder = builder.last_update(datetime.datetime.today()) builder = builder.next_update(datetime.datetime.today() + one_day) if certificates_revoke: for certificate in certificates_revoke: builder = builder.add_revoked_certificate(certificate) crl = builder.sign(private_key=ca_key, algorithm=hashes.SHA256(), backend=default_backend()) return crl
def test_freshestcrl_extension(self, backend): private_key = RSA_KEY_2048.private_key(backend) last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) freshest = x509.FreshestCRL([ x509.DistributionPoint( [x509.UniformResourceIdentifier("http://d.om/delta")], None, None, None, ) ]) builder = (x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, "cryptography.io CA") ])).last_update(last_update).next_update( next_update).add_extension(freshest, False)) crl = builder.sign(private_key, hashes.SHA256(), backend) assert len(crl) == 0 assert len(crl.extensions) == 1 ext1 = crl.extensions.get_extension_for_class(x509.FreshestCRL) assert ext1.critical is False assert isinstance(ext1.value, x509.FreshestCRL) assert isinstance(ext1.value[0], x509.DistributionPoint) assert ext1.value[0].full_name is not None uri = ext1.value[0].full_name[0] assert isinstance(uri, x509.UniformResourceIdentifier) assert uri.value == "http://d.om/delta"
def test_add_invalid_extension(self): builder = x509.CertificateRevocationListBuilder() with pytest.raises(TypeError): builder.add_extension( object(), False )
def test_sign_ed448_key(self, backend): private_key = ed448.Ed448PrivateKey.generate() invalidity_date = x509.InvalidityDate( datetime.datetime(2002, 1, 1, 0, 0)) ian = x509.IssuerAlternativeName( [x509.UniformResourceIdentifier("https://cryptography.io")]) revoked_cert0 = ( x509.RevokedCertificateBuilder().serial_number(2).revocation_date( datetime.datetime(2012, 1, 1, 1, 1)).add_extension(invalidity_date, False).build(backend)) last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = (x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, "cryptography.io CA") ])).last_update(last_update).next_update(next_update). add_revoked_certificate(revoked_cert0).add_extension( ian, False)) crl = builder.sign(private_key, None, backend) assert crl.signature_hash_algorithm is None assert crl.signature_algorithm_oid == SignatureAlgorithmOID.ED448 assert (crl.extensions.get_extension_for_class( x509.IssuerAlternativeName).value == ian) assert crl[0].serial_number == revoked_cert0.serial_number assert crl[0].revocation_date == revoked_cert0.revocation_date assert len(crl[0].extensions) == 1 ext = crl[0].extensions.get_extension_for_class(x509.InvalidityDate) assert ext.critical is False assert ext.value == invalidity_date
def test_next_update_after_last_update(self): builder = x509.CertificateRevocationListBuilder() builder = builder.last_update( datetime.datetime(2002, 1, 1, 12, 1) ) with pytest.raises(ValueError): builder.next_update(datetime.datetime(2001, 1, 1, 12, 1))
def test_no_next_update(self, backend): private_key = RSA_KEY_2048.private_key(backend) builder = (x509.CertificateRevocationListBuilder().issuer_name( x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, "US") ])).last_update(datetime.datetime(2030, 1, 1, 12, 1))) with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA256(), backend)
def test_no_issuer_name(self, backend): private_key = RSA_KEY_2048.private_key(backend) builder = (x509.CertificateRevocationListBuilder().last_update( datetime.datetime(2002, 1, 1, 12, 1)).next_update( datetime.datetime(2030, 1, 1, 12, 1))) with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA256(), backend)
def test_set_issuer_name_twice(self): builder = x509.CertificateRevocationListBuilder().issuer_name( x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')]) ) with pytest.raises(ValueError): builder.issuer_name( x509.Name([x509.NameAttribute(NameOID.COUNTRY_NAME, u'US')]) )
def test_dsa_key_sign_md5(self, backend): private_key = DSA_KEY_2048.private_key(backend) last_time = datetime.datetime(2012, 1, 16, 22, 43) next_time = datetime.datetime(2022, 1, 17, 6, 43) builder = (x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, "cryptography.io CA") ])).last_update(last_time).next_update(next_time)) with pytest.raises(ValueError): builder.sign(private_key, hashes.MD5(), backend)
def test_sign_with_dsa_private_key_is_unsupported(self): private_key = DSA_KEY_2048.private_key(backend) builder = x509.CertificateRevocationListBuilder() builder = builder.issuer_name( x509.Name([ x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u'US') ])).last_update(datetime.datetime(2002, 1, 1, 12, 1)).next_update( datetime.datetime(2032, 1, 1, 12, 1)) with pytest.raises(NotImplementedError): builder.sign(private_key, hashes.SHA1(), backend)
def test_add_unsupported_extension(self, backend): private_key = RSA_KEY_2048.private_key(backend) last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = (x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, "cryptography.io CA") ])).last_update(last_update).next_update( next_update).add_extension(DummyExtension(), False)) with pytest.raises(NotImplementedError): builder.sign(private_key, hashes.SHA256(), backend)
def test_sign_with_invalid_hash(self, backend): private_key = RSA_KEY_2048.private_key(backend) last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = (x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, u"cryptography.io CA") ])).last_update(last_update).next_update(next_update)) with pytest.raises(TypeError): builder.sign(private_key, object(), backend)
def test_sign_rsa_key_too_small(self, backend): private_key = RSA_KEY_512.private_key(backend) last_update = datetime.datetime(2002, 1, 1, 12, 1) next_update = datetime.datetime(2030, 1, 1, 12, 1) builder = (x509.CertificateRevocationListBuilder().issuer_name( x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, "cryptography.io CA") ])).last_update(last_update).next_update(next_update)) with pytest.raises(ValueError): builder.sign(private_key, hashes.SHA512(), backend)
def test_sign_with_ec_private_key_is_unsupported(self): _skip_curve_unsupported(backend, ec.SECP256R1()) private_key = ec.generate_private_key(ec.SECP256R1(), backend) builder = x509.CertificateRevocationListBuilder() builder = builder.issuer_name( x509.Name([ x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u'US') ])).last_update(datetime.datetime(2002, 1, 1, 12, 1)).next_update( datetime.datetime(2032, 1, 1, 12, 1)) with pytest.raises(NotImplementedError): builder.sign(private_key, hashes.SHA512(), backend)