# -*- coding: utf8 -*- """ Manage X.509 certificate life cycle =================================== This state is useful for managing X.509 certificates' life cycles. Copyright (c) 2014-2020 Jan Dittberner """ from cryptography import x509 from cryptography.hazmat.backends import default_backend from datetime import datetime import os def _error(ret, err_msg): ret["result"] = False ret["comment"] = err_msg return ret def valid_certificate( name, mindays=14, keyfile=None, checkchain=False, trustedcerts=None ): """ Checks whether the given certificate file is valid. name The name of the certificate file to check mindays Mark the certificate as invalid if it is valid for less then this many days """ ret = {"name": name, "changes": {}, "result": None, "comment": ""} if not os.path.isfile(name): return _error(ret, "certificate file {0} does not exist".format(name)) with open(name, "rb") as pemfile: try: cert = x509.load_pem_x509_certificate(pemfile.read(), default_backend()) except Exception as e: return _error(ret, "error loading certificate {0}: {1}".format(name, e)) notafter = cert.not_valid_after delta = notafter - datetime.utcnow() if delta.days < mindays: return _error( ret, "certificate {0} is only valid for {1} more day(s)".format( name, delta.days ), ) # TODO: check keyfile match # TODO: check trust chain ret["comment"] = "certificate {0} is ok and still valid for {1} days".format( name, delta.days ) ret["result"] = True return ret