56 lines
1.9 KiB
Python
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")
|