|
1 | 1 | #!/bin/sh |
2 | | -# Walk the committed certificates and flag ones that are about to expire, so a |
3 | | -# cert dying becomes a scheduled regeneration instead of a red morning. Already |
4 | | -# expired certs are reported but not failed: several are legacy or deliberately |
5 | | -# stale fixtures (ntru-cert.pem, expired-* used for negative tests). |
| 2 | +# Walk the committed certificates and CRLs and flag ones that are about to |
| 3 | +# expire, so a cert dying becomes a scheduled regeneration instead of a red |
| 4 | +# morning. Already expired ones are reported but not failed: several are legacy |
| 5 | +# or deliberately stale fixtures (ntru-cert.pem, expired-* used for negative |
| 6 | +# tests). Covers PEM and DER X.509 certs, and PEM/DER CRLs (nextUpdate). |
6 | 7 | set -eu |
7 | 8 |
|
8 | 9 | DIR="${1:-certs}" |
9 | 10 | WARN_DAYS="${WARN_DAYS:-30}" |
10 | 11 | FAIL_DAYS="${FAIL_DAYS:-7}" |
11 | 12 | warn_secs=$((WARN_DAYS * 86400)) |
12 | 13 | fail_secs=$((FAIL_DAYS * 86400)) |
| 14 | +now=$(date +%s) |
13 | 15 |
|
14 | 16 | rc=0 |
15 | 17 | checked=0 |
16 | | -for f in $(find "$DIR" -name '*.pem' | sort); do |
17 | | - # skip PEMs that are not X.509 certs (keys, CSRs, params) |
18 | | - openssl x509 -noout -in "$f" >/dev/null 2>&1 || continue |
19 | | - checked=$((checked + 1)) |
20 | 18 |
|
21 | | - if ! openssl x509 -checkend 0 -noout -in "$f" >/dev/null 2>&1; then |
| 19 | +# openssl prints dates like "Jun 10 12:00:00 2027 GMT"; parse with GNU then BSD. |
| 20 | +to_epoch() { |
| 21 | + date -d "$1" +%s 2>/dev/null || date -jf "%b %e %T %Y %Z" "$1" +%s 2>/dev/null || echo 0 |
| 22 | +} |
| 23 | + |
| 24 | +check_cert() { |
| 25 | + f="$1"; form="$2" |
| 26 | + openssl x509 -inform "$form" -noout -in "$f" >/dev/null 2>&1 || return 0 |
| 27 | + checked=$((checked + 1)) |
| 28 | + if ! openssl x509 -inform "$form" -checkend 0 -noout -in "$f" >/dev/null 2>&1; then |
22 | 29 | echo "::notice::already expired (legacy/fixture, not failing): $f" |
23 | | - elif ! openssl x509 -checkend "$fail_secs" -noout -in "$f" >/dev/null 2>&1; then |
24 | | - end=$(openssl x509 -enddate -noout -in "$f" | cut -d= -f2) |
| 30 | + elif ! openssl x509 -inform "$form" -checkend "$fail_secs" -noout -in "$f" >/dev/null 2>&1; then |
| 31 | + end=$(openssl x509 -inform "$form" -enddate -noout -in "$f" | cut -d= -f2) |
25 | 32 | echo "::error::$f expires within $FAIL_DAYS days ($end) -- regenerate now" |
26 | 33 | rc=1 |
27 | | - elif ! openssl x509 -checkend "$warn_secs" -noout -in "$f" >/dev/null 2>&1; then |
28 | | - end=$(openssl x509 -enddate -noout -in "$f" | cut -d= -f2) |
| 34 | + elif ! openssl x509 -inform "$form" -checkend "$warn_secs" -noout -in "$f" >/dev/null 2>&1; then |
| 35 | + end=$(openssl x509 -inform "$form" -enddate -noout -in "$f" | cut -d= -f2) |
29 | 36 | echo "::warning::$f expires within $WARN_DAYS days ($end) -- schedule regeneration" |
30 | 37 | fi |
31 | | -done |
| 38 | +} |
| 39 | + |
| 40 | +check_crl() { |
| 41 | + f="$1"; form="$2" |
| 42 | + nu=$(openssl crl -inform "$form" -nextupdate -noout -in "$f" 2>/dev/null | cut -d= -f2) |
| 43 | + [ -n "$nu" ] || return 0 |
| 44 | + checked=$((checked + 1)) |
| 45 | + secs=$(to_epoch "$nu") |
| 46 | + [ "$secs" -ne 0 ] || return 0 |
| 47 | + if [ "$secs" -le "$now" ]; then |
| 48 | + echo "::notice::CRL past nextUpdate (fixture, not failing): $f" |
| 49 | + elif [ "$secs" -le $((now + fail_secs)) ]; then |
| 50 | + echo "::error::$f CRL nextUpdate within $FAIL_DAYS days ($nu) -- regenerate now" |
| 51 | + rc=1 |
| 52 | + elif [ "$secs" -le $((now + warn_secs)) ]; then |
| 53 | + echo "::warning::$f CRL nextUpdate within $WARN_DAYS days ($nu) -- schedule regeneration" |
| 54 | + fi |
| 55 | +} |
| 56 | + |
| 57 | +for f in $(find "$DIR" -name '*.pem' | sort); do check_cert "$f" PEM; done |
| 58 | +for f in $(find "$DIR" -name '*.der' | sort); do check_cert "$f" DER; done |
| 59 | +for f in $(find "$DIR" \( -name '*crl*.pem' -o -name '*.crl' \) | sort); do check_crl "$f" PEM; done |
| 60 | +for f in $(find "$DIR" -name '*crl*.der' | sort); do check_crl "$f" DER; done |
32 | 61 |
|
33 | | -echo "checked $checked certificate(s); fail threshold ${FAIL_DAYS}d, warn ${WARN_DAYS}d" |
| 62 | +echo "checked $checked cert/CRL file(s); fail threshold ${FAIL_DAYS}d, warn ${WARN_DAYS}d" |
34 | 63 | exit $rc |
0 commit comments