from datetime import datetime from cryptography import x509 from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import rsa class Certificate: """ A certificate. Wrapper around cryptography.x509.Certificate. """ def __init__( self, issuer: str, issuer_private_key: bytes = None, subject: str, valid_start: datetime, valid_end: datetime ): # generate a private key for the certificate self._private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) # get the public key from it self.public_key = self._private_key.public_key() # if the issuer private key is not specified, consider it a self-signed certificate if issuer_private_key is None: issuer_private_key = self._private_key # create a builder for the certificate builder = x509.CertificateBuilder( issuer_name=x509.Name([x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, issuer)]), subject_name=x509.Name([x509.NameAttribute(x509.oid.NameOID.COMMON_NAME, subject)]), serial_number=x509.random_serial_number(), public_key=self.public_key, not_valid_before=valid_start, not_valid_after=valid_end, ) # create the certificate by signing it self._certificate = builder.sign(issuer_private_key, algorithm=hashes.SHA256()) def is_valid(self, date: datetime, issuer_public_key: bytes) -> bool: return ( # check if the date is valid self._certificate.not_valid_before <= date <= self._certificate.not_valid_after and # check the signature of the certificate self._certificate.verify_directly_issued_by() ) # Exemple d'utilisation if __name__ == "__main__": certificate = Certificate("Example Subject")