M1-PCA-Project/source/Certificate.py

56 lines
1.9 KiB
Python

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")