From bba98f95b3aecdd62a9c88c0cc5b8bd49d2ca206 Mon Sep 17 00:00:00 2001 From: Martin Schobert Date: Sun, 6 Sep 2020 22:19:12 +0200 Subject: [PATCH] ssl-certificate-expiry: Feature added: checking intermediate certs as well (#1088) --- plugins/ssl/ssl-certificate-expiry | 34 ++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/plugins/ssl/ssl-certificate-expiry b/plugins/ssl/ssl-certificate-expiry index c757c8a9..41f6fce3 100755 --- a/plugins/ssl/ssl-certificate-expiry +++ b/plugins/ssl/ssl-certificate-expiry @@ -57,9 +57,11 @@ uncached updates after the cache file is older than an hour. * Pactrick Domack (ssl_) * Olivier Mehani (ssl-certificate-expiry) - + * Martin Schobert (check for intermediate certs) + * Copyright (C) 2013 Patrick Domack * Copyright (C) 2017, 2019 Olivier Mehani + * Copyright (C) 2020 Martin Schobert =head1 LICENSE @@ -90,6 +92,7 @@ parse_valid_days_from_certificate() { local now_epoch local input_data input_data=$(cat) + if echo "$input_data" | grep -q -- "-----BEGIN CERTIFICATE-----"; then valid_until_string=$(echo "$input_data" | openssl x509 -noout -enddate \ | grep "^notAfter=" | cut -f 2 -d "=") @@ -122,11 +125,34 @@ print_expire_days() { local s_client_args= [ -n "$starttls" ] && s_client_args="-starttls $starttls" + # We extract and check the server certificate, + # but the end date also depends on intermediate certs. Therefore + # we want to check intermediate certs as well. + # + # The following cryptic lines do: + # - invoke openssl and connect to a port + # - print certs, not only the server cert + # - extract each certificate as a single line + # - pipe each cert to the parse_valid_days_from_certificate + # function, which basically is 'openssl x509 -enddate' + # - get a list of the parse_valid_days_from_certificate + # results and sort them + # shellcheck disable=SC2086 echo "" | openssl s_client \ - -servername "$host" -connect "${host}:${port}" \ - $s_client_args 2>/dev/null \ - | parse_valid_days_from_certificate + -servername "$host" -connect "${host}:${port}" \ + -showcerts \ + $s_client_args 2>/dev/null | \ + awk '{ + if ($0 == "-----BEGIN CERTIFICATE-----") cert="" + else if ($0 == "-----END CERTIFICATE-----") print cert + else cert=cert$0 + }' | \ + while read -r CERT; do + (printf '\n-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n' "$CERT") | \ + parse_valid_days_from_certificate + done | sort -n | head -n 1 + } main() {