From 92d97feaf1e3f2a31e8a110f1e793af2aacfcc36 Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Mon, 29 Aug 2016 22:32:21 +0200 Subject: [PATCH] Add checks for certificate expiry --- check_dane/cert.py | 33 +++++++++++++++++++++++++++++++++ check_dane_smtp | 7 ++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/check_dane/cert.py b/check_dane/cert.py index 289f514..a66a134 100644 --- a/check_dane/cert.py +++ b/check_dane/cert.py @@ -1,10 +1,43 @@ #!/usr/bin/python3 +from datetime import datetime +import logging +from ssl import cert_time_to_seconds + from pyasn1_modules import rfc2459 from pyasn1.codec.der import decoder, encoder +def verify_certificate(cert, args): + expiretimestamp = cert_time_to_seconds(cert['notAfter']) + starttimestamp = cert_time_to_seconds(cert['notBefore']) + + if datetime.utcfromtimestamp(starttimestamp) > datetime.utcnow(): + logging.error("Certificate will only be valid starting %s", cert['notBefore']) + return 2 + + if datetime.utcfromtimestamp(expiretimestamp) < datetime.utcnow(): + logging.error("Certificate will only be valid until %s", cert['notAfter']) + return 2 + + delta = datetime.utcfromtimestamp(expiretimestamp) - datetime.utcnow() + deltastr = str(delta).split(",") + + if delta.days < args.critdays: + logging.error("expires in %8s,%16s", deltastr[0], deltastr[1]) + return 2 + elif delta.days < args.warndays: + logging.warn("expires in %8s,%16s", deltastr[0], deltastr[1]) + return 1 + + return 0 def get_spki(certificate): cert = decoder.decode(certificate, asn1Spec=rfc2459.Certificate())[0] spki = cert['tbsCertificate']["subjectPublicKeyInfo"] return encoder.encode(spki) + +def add_certificate_options(argparser): + argparser.add_argument("--warndays", type=int, default=-1, + help="Days before certificate expiration to warn") + argparser.add_argument("--critdays", type=int, default=-1, + help="Days before certificate expiration to raise error") diff --git a/check_dane_smtp b/check_dane_smtp index 8a40445..05ff348 100755 --- a/check_dane_smtp +++ b/check_dane_smtp @@ -13,6 +13,7 @@ from ssl import SSLContext, PROTOCOL_TLSv1_2, CERT_REQUIRED, cert_time_to_second from unbound import ub_ctx, idn2dname, ub_strerror from check_dane.tlsa import verify_tlsa_record +from check_dane.cert import verify_certificate, add_certificate_options def init_connection(sslcontext, args): host = args.Host @@ -96,6 +97,8 @@ def main(): group.add_argument("-4", "--4", action="store_true", help="check via IPv4 only") group.add_argument("--64", action="store_false", help="check via IPv4 and IPv6 (default)") + add_certificate_options(parser) + args = parser.parse_args() if args.verbose: @@ -117,7 +120,9 @@ def main(): logging.error("Connection refused") return 2 - retval = verify_tlsa_record(resolver, "_%d._tcp.%s" % (port, host), connection.getpeercert(binary_form=True)) + retval = verify_certificate(connection.getpeercert(), args) + nretval = verify_tlsa_record(resolver, "_%d._tcp.%s" % (port, host), connection.getpeercert(binary_form=True)) + retval = max(retval, nretval) close_connection(connection) return retval -- 2.39.2