# Copyright 2026 jCloud Services GbR # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from cryptography.hazmat.primitives.asymmetric import padding from cryptography import x509 import datetime __all__ = [ 'load_cert_file', 'Identity', 'Verifier' ] def load_cert_file(path: str) -> x509.Certificate: ''' Loads a certificate from a file :param path: File path :type path: str :return: The certificate :rtype: cryptography.x509.Certificate ''' with open(path, 'rb') as f: cert_data = f.read() return x509.load_pem_x509_certificate(cert_data) class Identity: def __init__(self, cert: x509.Certificate = None): self.cert = cert @property def public_key(self): return self.cert.public_key() @property def issuer(self): return self.cert.issuer @property def subject(self): return self.cert.subject @property def not_valid_before(self): return self.cert.not_valid_before_utc @property def not_valid_after(self): return self.cert.not_valid_after_utc @property def signature_algorithm(self): return self.cert.signature_hash_algorithm class Verifier: def __init__(self, trusted_ca: Identity): self.trusted_ca = trusted_ca def verify(self, identity: Identity, now = datetime.datetime.now(datetime.timezone.utc), verify_issuer = True): if not (identity.not_valid_before <= now <= identity.not_valid_after): return False try: self.trusted_ca.public_key.verify( identity.cert.signature, identity.cert.tbs_certificate_bytes, padding.PKCS1v15(), identity.cert.signature_hash_algorithm ) except: return False if (identity.issuer != self.trusted_ca.subject) and verify_issuer: return False return True