def test_ca_crl(self): # create a child CA child = self.create_ca(name='Child', parent=self.ca) self.assertNotRevoked(child) stdout, stderr = self.cmd('dump_crl', ca=self.ca, ca_crl=True, stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), []) # revoke the CA and see if it's there child.revoke() self.assertRevoked(child) stdout, stderr = self.cmd('dump_crl', ca=self.ca, ca_crl=True, stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(len(list(crl)), 1) self.assertEqual(crl[0].serial_number, child.x509.serial) self.assertEqual(len(crl[0].extensions), 0)
def test_revoked(self): cert = self.certs['root-cert'] cert.revoke() stdout, stderr = self.cmd('dump_crl', ca=self.ca, scope='user', stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(len(list(crl)), 1) self.assertEqual(crl[0].serial_number, cert.x509.serial_number) self.assertEqual(len(crl[0].extensions), 0) # try all possible reasons for reason in [r[0] for r in Certificate.REVOCATION_REASONS if r[0]]: cert.revoked_reason = reason cert.save() stdout, stderr = self.cmd('dump_crl', ca=self.ca, scope='user', stdout=BytesIO(), stderr=BytesIO()) crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(len(list(crl)), 1) self.assertEqual(crl[0].serial_number, cert.x509.serial_number) # unspecified is not included (see RFC 5280, 5.3.1) if reason != 'unspecified': self.assertEqual(crl[0].extensions[0].value.reason.name, reason)
def test_ca_crl(self): child = self.create_ca(name='child', parent=self.ca) self.assertIsNotNone(child.key(password=None)) response = self.client.get( reverse('ca_crl', kwargs={'serial': self.ca.serial})) self.assertEqual(response.status_code, 200) self.assertEqual(response['Content-Type'], 'text/plain') crl = x509.load_pem_x509_crl(response.content, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), []) child.revoke() child.save() # fetch again - we should see a cached response response = self.client.get( reverse('ca_crl', kwargs={'serial': self.ca.serial})) self.assertEqual(response.status_code, 200) self.assertEqual(response['Content-Type'], 'text/plain') crl = x509.load_pem_x509_crl(response.content, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(len(list(crl)), 0) # clear the cache and fetch again cache.clear() response = self.client.get( reverse('ca_crl', kwargs={'serial': self.ca.serial})) self.assertEqual(response.status_code, 200) self.assertEqual(response['Content-Type'], 'text/plain') crl = x509.load_pem_x509_crl(response.content, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(len(list(crl)), 1) self.assertEqual(crl[0].serial_number, child.x509.serial)
def test_ca_crl(self): ca = self.cas['root'] child = self.cas['child'] self.assertIsNotNone(child.key(password=None)) self.assertNotRevoked(child) stdout, stderr = self.cmd('dump_crl', ca=ca, scope='ca', stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), []) # revoke the CA and see if it's there child.revoke() self.assertRevoked(child) stdout, stderr = self.cmd('dump_crl', ca=ca, scope='ca', stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(len(list(crl)), 1) self.assertEqual(crl[0].serial_number, child.x509.serial_number) self.assertEqual(len(crl[0].extensions), 0)
def test_revoked(self): cert = Certificate.objects.get(serial=self.cert.serial) cert.revoke() stdout, stderr = self.cmd('dump_crl', stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(len(list(crl)), 1) self.assertEqual(crl[0].serial_number, cert.x509.serial) self.assertEqual(len(crl[0].extensions), 0) # try all possible reasons for reason in [r[0] for r in Certificate.REVOCATION_REASONS if r[0]]: cert.revoked_reason = reason cert.save() stdout, stderr = self.cmd('dump_crl', stdout=BytesIO(), stderr=BytesIO()) crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(len(list(crl)), 1) self.assertEqual(crl[0].serial_number, cert.x509.serial) self.assertEqual(crl[0].extensions[0].value.reason.name, reason)
def test_password(self) -> None: """Test creating a CRL with a CA with a password.""" ca = self.new_cas["pwd"] # Giving no password raises a CommandError with self.assertCommandError( "^Password was not given but private key is encrypted$"): self.cmd("dump_crl", ca=ca, scope="user") # False password ca = CertificateAuthority.objects.get(pk=ca.pk) with self.assertCommandError(self.re_false_password): self.cmd("dump_crl", ca=ca, scope="user", password=b"wrong") stdout, stderr = self.cmd( "dump_crl", ca=ca, scope="user", password=certs["pwd"]["password"], stdout=BytesIO(), stderr=BytesIO(), ) self.assertEqual(stderr, b"") crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), [])
def _load_ca_crl(self, ca_name): ca_crl_filename = self._get_path_crl(ca_name) if ca_crl_filename.exists(): with ca_crl_filename.open("rb") as ca_crl_file: crl = x509.load_pem_x509_crl(ca_crl_file.read(), backend=default_backend()) return crl
def test_revocation_list_builder_serialization(self): crl = revocation_list_builder([], self.root_certificate) pem = serialize(crl) self.assertIn("-----BEGIN X509 CRL-----", pem) crl_deserialized = x509.load_pem_x509_crl(pem.encode("utf8"), backend=default_backend()) self.assert_subject(crl_deserialized.issuer, self.root_certificate)
def __init__(self, module): super(CRLInfo, self).__init__(module.params['path'] or '', 'present', False, module.check_mode) self.content = module.params['content'] self.module = module self.crl = None if self.content is None: try: with open(self.path, 'rb') as f: data = f.read() except Exception as e: self.module.fail_json( msg='Error while reading CRL file from disk: {0}'.format( e)) else: data = self.content.encode('utf-8') if not identify_pem_format(data): data = base64.b64decode(self.content) self.crl_pem = identify_pem_format(data) try: if self.crl_pem: self.crl = x509.load_pem_x509_crl(data, default_backend()) else: self.crl = x509.load_der_x509_crl(data, default_backend()) except Exception as e: self.module.fail_json( msg='Error while decoding CRL: {0}'.format(e))
def assertCRL(self, crl, certs=None, signer=None, expires=86400, algorithm=None, encoding=Encoding.PEM, idp=None, extensions=None, crl_number=0, skip_authority_key_identifier=False): certs = certs or [] signer = signer or self.cas['child'] algorithm = algorithm or ca_settings.CA_DIGEST_ALGORITHM extensions = extensions or [] expires = datetime.utcnow() + timedelta(seconds=expires) if idp is not None: # pragma: no branch, pragma: only cryptography>=2.5 extensions.append(idp) extensions.append(x509.Extension( value=x509.CRLNumber(crl_number=crl_number), critical=False, oid=ExtensionOID.CRL_NUMBER )) if not skip_authority_key_identifier: extensions.append(signer.authority_key_identifier.as_extension()) if encoding == Encoding.PEM: crl = x509.load_pem_x509_crl(crl, default_backend()) else: crl = x509.load_der_x509_crl(crl, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, type(algorithm)) self.assertTrue(crl.is_signature_valid(signer.x509.public_key())) self.assertEqual(crl.issuer, signer.x509.subject) self.assertEqual(crl.last_update, datetime.utcnow()) self.assertEqual(crl.next_update, expires) self.assertCountEqual(list(crl.extensions), extensions) entries = {e.serial_number: e for e in crl} expected = {c.x509.serial_number: c for c in certs} self.assertCountEqual(entries, expected) for serial, entry in entries.items(): self.assertEqual(entry.revocation_date, datetime.utcnow()) self.assertEqual(list(entry.extensions), [])
def checkCRL(publicKey, serialNumber): path = os.path.join('Certification_Authority', 'crl.pem') with open(path, 'rb') as f: pem_crl_data_text = f.read() pem_crl_data = x509.load_pem_x509_crl(pem_crl_data_text, backend=default_backend()) valid = pem_crl_data.is_signature_valid(publicKey) if valid is False: return False now = datetime.datetime.now() if now < pem_crl_data.last_update or now > pem_crl_data.next_update: print '[Error] Invalid CRL certificate.' sys.exit(1) isinstance(pem_crl_data.signature_hash_algorithm, hashes.SHA256) revoked_certificates = [] for i in range(0, len(pem_crl_data)): revoked_certificates.append(pem_crl_data[i].serial_number) if serialNumber in revoked_certificates: return False return True
def test_password(self): """Test creating a CRL with a CA with a password.""" ca = self.cas['pwd'] # Giving no password raises a CommandError with self.assertCommandError( '^Password was not given but private key is encrypted$'): self.cmd('dump_crl', ca=ca, scope='user') # False password ca = CertificateAuthority.objects.get(pk=ca.pk) with self.assertCommandError(self.re_false_password): self.cmd('dump_crl', ca=ca, scope='user', password=b'wrong') stdout, stderr = self.cmd('dump_crl', ca=ca, scope='user', password=certs['pwd']['password'], stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), [])
def test_file(self) -> None: """Test dumping to a file.""" path = os.path.join(ca_settings.CA_DIR, "crl-test.crl") stdout, stderr = self.cmd("dump_crl", path, ca=self.ca, scope="user", stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stdout, b"") self.assertEqual(stderr, b"") with open(path, "rb") as stream: crl = x509.load_pem_x509_crl(stream.read(), default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), []) # test an output path that doesn't exist path = os.path.join(ca_settings.CA_DIR, "test", "crl-test.crl") msg = r"^\[Errno 2\] No such file or directory: '%s'$" % re.escape( path) with self.assertCommandError(msg): self.cmd("dump_crl", path, ca=self.ca, scope="user", stdout=BytesIO(), stderr=BytesIO())
def test_file(self): path = os.path.join(ca_settings.CA_DIR, 'crl-test.crl') stdout, stderr = self.cmd('dump_crl', path, ca=self.ca, scope='user', stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stdout, b'') self.assertEqual(stderr, b'') with open(path, 'rb') as stream: crl = x509.load_pem_x509_crl(stream.read(), default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), []) # test an output path that doesn't exist path = os.path.join(ca_settings.CA_DIR, 'test', 'crl-test.crl') msg = r"^\[Errno 2\] No such file or directory: '%s'$" % re.escape( path) with self.assertCommandError(msg): self.cmd('dump_crl', path, ca=self.ca, scope='user', stdout=BytesIO(), stderr=BytesIO())
def schedule_crl_renew(self): crl = x509.load_pem_x509_crl(self._ssl_crl.encode(), default_backend()) # rotate before clients will load new crl offset = 0.85 if self.auto_rotate_crl else 0.9 self._timer_crl = self._get_cert_renewal_time(crl, stagger=0.05, offset=offset)
def test_basic(self): stdout, stderr = self.cmd('dump_crl', ca=self.ca, scope='user', stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), [])
def test_password(self): password = b'testpassword' ca = self.create_ca('with password', password=password) ca = CertificateAuthority.objects.get(pk=ca.pk) # Giving no password raises a CommandError stdin = six.StringIO(self.csr_pem) with self.assertRaisesRegex( CommandError, '^Password was not given but private key is encrypted$'): self.cmd('dump_crl', ca=ca, stdin=stdin) # False password stdin = six.StringIO(self.csr_pem) ca = CertificateAuthority.objects.get(pk=ca.pk) stdin = six.StringIO(self.csr_pem) with self.assertRaisesRegex(CommandError, '^Bad decrypt\. Incorrect password\?$'): self.cmd('dump_crl', ca=ca, stdin=stdin, password=b'wrong') stdout, stderr = self.cmd('dump_crl', ca=ca, stdout=BytesIO(), stderr=BytesIO(), password=password) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), [])
def load_crl_pem(fn: str) -> CertificateRevocationList: crl_return = None if (fn and Path(fn).exists()): with open(fn, "rb") as file: data = file.read() if data and len(data) > 0: crl_return = load_pem_x509_crl(data, default_backend()) return crl_return
def is_certificate_revoked(serial_number, crl_url): r = requests.get(crl_url) try: crl = x509.load_der_x509_crl(r.content, default_backend()) except ValueError as e: crl = x509.load_pem_x509_crl(r.content, default_backend()) return crl.get_revoked_certificate_by_serial_number( serial_number) is not None
def load_cert_revocation_list(filename,file_type): with open(filename, "rb") as pem_file: pem_data = pem_file.read() if file_type=="der": cert = x509.load_der_x509_crl(pem_data, default_backend()) elif file_type=="pem": cert = x509.load_pem_x509_crl(pem_data, default_backend()) return cert
def _load_crl(self, crl_data, data_type): if data_type == "PEM": return x509.load_pem_x509_crl(crl_data, default_backend()) elif data_type == "DER": return x509.load_der_x509_crl(crl_data, default_backend()) else: raise InvalidCRLDataTypeException( 'crl data type %s not recognized' % data_type) return None
def assertCRL( self, crl, expected=None, signer=None, expires=86400, # pylint: disable=invalid-name algorithm=None, encoding=Encoding.PEM, idp=None, extensions=None, crl_number=0): """Test the given CRL. Parameters ---------- crl : bytes The raw CRL expected : list List of CAs/certs to be expected in this CRL """ expected = expected or [] signer = signer or self.cas['child'] algorithm = algorithm or ca_settings.CA_DIGEST_ALGORITHM extensions = extensions or [] expires = datetime.utcnow() + timedelta(seconds=expires) if idp is not None: # pragma: no branch extensions.append(idp) extensions.append( x509.Extension(value=x509.CRLNumber(crl_number=crl_number), critical=False, oid=ExtensionOID.CRL_NUMBER)) extensions.append( x509.Extension(value=signer.get_authority_key_identifier(), oid=ExtensionOID.AUTHORITY_KEY_IDENTIFIER, critical=False)) if encoding == Encoding.PEM: crl = x509.load_pem_x509_crl(crl, default_backend()) else: crl = x509.load_der_x509_crl(crl, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, type(algorithm)) self.assertTrue(crl.is_signature_valid(signer.x509.public_key())) self.assertEqual(crl.issuer, signer.x509.subject) self.assertEqual(crl.last_update, datetime.utcnow()) self.assertEqual(crl.next_update, expires) self.assertCountEqual(list(crl.extensions), extensions) entries = {e.serial_number: e for e in crl} expected = {c.x509.serial_number: c for c in expected} self.assertCountEqual(entries, expected) for entry in entries.values(): self.assertEqual(entry.revocation_date, datetime.utcnow()) self.assertEqual(list(entry.extensions), [])
def load_crl(self, crl_bytes): try: crl = x509.load_pem_x509_crl(crl_bytes, backend=default_backend()) return crl except: try: crl = x509.load_der_x509_crl(crl_bytes, backend=default_backend()) return crl except: return None
def test_disabled(self): ca = self.create_ca('disabled') ca.enabled = False ca.save() stdout, stderr = self.cmd('dump_crl', ca=ca, stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), [])
def test_overwrite(self): response = self.client.get( reverse('advanced', kwargs={'serial': self.ca.serial})) self.assertEqual(response.status_code, 200) self.assertEqual(response['Content-Type'], 'text/plain') crl = x509.load_pem_x509_crl(response.content, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.MD5) # parse Last/Next Update to see if they match 321 seconds self.assertEqual((crl.next_update - crl.last_update).seconds, 321)
def test_revoked(self) -> None: """Test revoked certificates NOTE: freeze time because expired certs are not in a CRL. """ self.cert.revoke() stdout, stderr = self.cmd("dump_crl", ca=self.ca, scope="user", stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b"") crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(len(list(crl)), 1) self.assertEqual(crl[0].serial_number, self.cert.pub.loaded.serial_number) self.assertEqual(len(crl[0].extensions), 0) # try all possible reasons for reason in [r[0] for r in Certificate.REVOCATION_REASONS if r[0]]: self.cert.revoked_reason = reason self.cert.save() stdout, stderr = self.cmd("dump_crl", ca=self.ca, scope="user", stdout=BytesIO(), stderr=BytesIO()) crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(len(list(crl)), 1) self.assertEqual(crl[0].serial_number, self.cert.pub.loaded.serial_number) # unspecified is not included (see RFC 5280, 5.3.1) if reason != "unspecified": self.assertEqual(crl[0].extensions[0].value.reason.name, reason)
def _validate_client_ca_and_crl_refs(self, client_ca_ref, crl_ref): context = pecan.request.context.get('octavia_context') bad_refs = [] try: self.cert_manager.set_acls(context, client_ca_ref) ca_pem = self.cert_manager.get_secret(context, client_ca_ref) except Exception: bad_refs.append(client_ca_ref) pem_crl = None if crl_ref: try: self.cert_manager.set_acls(context, crl_ref) pem_crl = self.cert_manager.get_secret(context, crl_ref) except Exception: bad_refs.append(crl_ref) if bad_refs: raise exceptions.CertificateRetrievalException(ref=bad_refs) ca_cert = None try: # Test if it needs to be UTF-8 encoded try: ca_pem = ca_pem.encode('utf-8') except AttributeError: pass ca_cert = x509.load_pem_x509_certificate(ca_pem, default_backend()) except Exception as e: raise exceptions.ValidationException(detail=_( "The client authentication CA certificate is invalid. " "It must be a valid x509 PEM format certificate. " "Error: %s") % str(e)) # Validate the CRL is for the client CA if pem_crl: ca_pub_key = ca_cert.public_key() crl = None # Test if it needs to be UTF-8 encoded try: pem_crl = pem_crl.encode('utf-8') except AttributeError: pass try: crl = x509.load_pem_x509_crl(pem_crl, default_backend()) except Exception as e: raise exceptions.ValidationException(detail=_( "The client authentication certificate revocation list " "is invalid. It must be a valid x509 PEM format " "certificate revocation list. Error: %s") % str(e)) if not crl.is_signature_valid(ca_pub_key): raise exceptions.ValidationException(detail=_( "The CRL specified is not valid for client certificate " "authority reference supplied."))
def _validate_client_ca_and_crl_refs(self, client_ca_ref, crl_ref): context = pecan.request.context.get('octavia_context') bad_refs = [] try: self.cert_manager.set_acls(context, client_ca_ref) ca_pem = self.cert_manager.get_secret(context, client_ca_ref) except Exception: bad_refs.append(client_ca_ref) pem_crl = None if crl_ref: try: self.cert_manager.set_acls(context, crl_ref) pem_crl = self.cert_manager.get_secret(context, crl_ref) except Exception: bad_refs.append(crl_ref) if bad_refs: raise exceptions.CertificateRetrievalException(ref=bad_refs) ca_cert = None try: # Test if it needs to be UTF-8 encoded try: ca_pem = ca_pem.encode('utf-8') except AttributeError: pass ca_cert = x509.load_pem_x509_certificate(ca_pem, default_backend()) except Exception as e: raise exceptions.ValidationException(detail=_( "The client authentication CA certificate is invalid. " "It must be a valid x509 PEM format certificate. " "Error: %s") % str(e)) # Validate the CRL is for the client CA if pem_crl: ca_pub_key = ca_cert.public_key() crl = None # Test if it needs to be UTF-8 encoded try: pem_crl = pem_crl.encode('utf-8') except AttributeError: pass try: crl = x509.load_pem_x509_crl(pem_crl, default_backend()) except Exception as e: raise exceptions.ValidationException(detail=_( "The client authentication certificate revocation list " "is invalid. It must be a valid x509 PEM format " "certificate revocation list. Error: %s") % str(e)) if not crl.is_signature_valid(ca_pub_key): raise exceptions.ValidationException(detail=_( "The CRL specified is not valid for client certificate " "authority reference supplied."))
def test_disabled(self): ca = self.cas['root'] self.assertIsNotNone(ca.key(password=None)) ca.enabled = False ca.save() stdout, stderr = self.cmd('dump_crl', ca=ca, scope='user', stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b'') crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), [])
def check_revoked(self, cert): with open(self.crl_file_path, "rb") as f: crl = x509.load_pem_x509_crl(data=f.read(), backend=default_backend()) if cert.issuer != crl.issuer: click.secho("Cert does not match CRL", fg="red") sys.exit(1) for revoked in crl: if cert.serial == revoked.serial_number: return True return False
def test_basic(self) -> None: """Test basic creation of a CRL.""" stdout, stderr = self.cmd("dump_crl", ca=self.ca, scope="user", stdout=BytesIO(), stderr=BytesIO()) self.assertEqual(stderr, b"") crl = x509.load_pem_x509_crl(stdout, default_backend()) self.assertIsInstance(crl.signature_hash_algorithm, hashes.SHA512) self.assertEqual(list(crl), [])
def revoke_cert(ca, serial): now = datetime.datetime.utcnow() crl_builder = x509.CertificateRevocationListBuilder() crl_builder = crl_builder.issuer_name(ca.cert.subject) crl_builder = crl_builder.last_update(now) crl_builder = crl_builder.next_update(now + DAY) crl_filename = os.path.join(cert_dir, ca.nick + '.crl') try: f = open(crl_filename, 'rb') except IOError: pass else: with f: crl_pem = f.read() crl = x509.load_pem_x509_crl(crl_pem, default_backend()) for revoked_cert in crl: crl_builder = crl_builder.add_revoked_certificate(revoked_cert) builder = x509.RevokedCertificateBuilder() builder = builder.serial_number(serial) builder = builder.revocation_date(now) revoked_cert = builder.build(default_backend()) crl_builder = crl_builder.add_revoked_certificate(revoked_cert) crl = crl_builder.sign( private_key=ca.key, algorithm=hashes.SHA256(), backend=default_backend(), ) crl_pem = crl.public_bytes(serialization.Encoding.PEM) with open(crl_filename, 'wb') as f: f.write(crl_pem)