Checking SSL Certificates
Verify whether a certificate matches a private key and has valid timestamp
The certificate is the signed public key (and some meta data); to verify whether a certificate matches the private key, one has to extract the public key of both and compare them.
Both the rsa and the x509 subcommand of openssl have a -modulus option to extract the modulus; they can also extract the complete public key, but the option has a different name for each of the subcommands:
1 2 |
openssl x509 -in "$CRT" -noout -pubkey
openssl rsa -in "$KEY" -pubout 2>/dev/null
|
The timestamps are in the text output of the certificate in the fields “Not Before:” and “Not After :”:
1 2 |
openssl x509 -in "$CRT" -text -noout | \
awk -- 'BEGIN {FS=": ";b="";e=""} /^ *Not Before *: / { b = $2 } /^ *Not After *: / { e = $2 } END { print b; print e }
|
You can convert those timestamps to “seconds since 1970-01-01 00:00:00 UTC” width date +%s, making it easy to compare them to the current date (in the same format).
All in one script (you have to set KEY and CRT before; you probably may want to check whether the files exist too):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
A=$(openssl x509 -in "$CRT" -noout -pubkey)
B=$(openssl rsa -in "$KEY" -pubout 2>/dev/null)
if [ "$A" != "$B" ]; then
echo "cert doesn't match private key" >&2
printf "$CRT pubkey:\n%s\n$KEY pubkey:\n%s\n" "$A" "$B" >&2
else
DATES=$(openssl x509 -in "$CRT" -text -noout |
awk -- 'BEGIN {FS=": ";b="";e=""} /^ *Not Before *: / { b = $2 } /^ *Not After *: / { e = $2 } END { print b; print e }')
begin=$(echo "$DATES" | head -n1)
end=$(echo "$DATES" | tail -n1)
ubegin=$(date -d "$begin" +%s)
uend=$(date -d "$end" +%s)
unow=$(date +%s)
if [ $unow -lt $ubegin -o $uend -lt $unow ]; then
echo "Invalid timestamps for $CRT, was valid for:" >&2
echo "$DATES" >&2
else
echo "Valid timestamps for $CRT (which matches privkey):"
echo "$DATES"
fi
fi
|