Created
May 5, 2023 16:08
-
-
Save JonTheNiceGuy/7929f15b86d6171b00984f8eb6bf35c0 to your computer and use it in GitHub Desktop.
A bash script which gets the certificate SHA256 hashes of certificates in a chain, or for an individual certificate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -Eeuo pipefail | |
trap cleanup SIGINT SIGTERM ERR EXIT | |
cleanup() { | |
trap - SIGINT SIGTERM ERR EXIT | |
if [ -z "${KEEP:-}" ] && [ -n "${tempdir:-}" ] | |
then | |
rm -Rf "$tempdir" | |
fi | |
} | |
fail() { | |
stderr "FAIL: $1" | |
exit $2 | |
} | |
stderr() { | |
echo "$1" >&2 | |
} | |
debug() { | |
if [ -n "${DEBUG:-}" ] | |
then | |
stderr "DBUG: $1" | |
fi | |
} | |
info() { | |
if [ -n "${DEBUG:-}" ] || [ -n "${INFO:-}" ] | |
then | |
stderr "INFO: $1" | |
fi | |
} | |
warning() { | |
stderr "WARN: $1" | |
} | |
log() { | |
stderr "LOG : $1" | |
} | |
usage() { | |
stderr "Need to provide the domain name you want the certificate pinning statements for, or a single PEM file." | |
exit 1 | |
} | |
get_sha256_base64() { | |
openssl x509 -in "$1" -outform der | openssl dgst -sha256 -binary | base64 | |
} | |
get_CN() { | |
echo "$1" | sed -e 's/^.*CN = //' | |
} | |
get_subject() { | |
get_CN "$(openssl x509 -in "$1" -text | grep "Subject:")" | |
} | |
get_issuer() { | |
get_CN "$(openssl x509 -in "$1" -text | grep "Issuer:")" | |
} | |
get_validity_dates_from() { | |
openssl x509 -in "$1" -text | grep -iA2 "Validity" | grep "Not Before" | sed -e 's/^.*: //' | |
} | |
get_validity_dates_to() { | |
openssl x509 -in "$1" -text | grep -iA2 "Validity" | grep "Not After" | sed -e 's/^.*: //' | |
} | |
get_data() { | |
echo "/**" | |
echo " * $(get_subject "$1")" | |
echo " * Verified by: $(get_issuer "$1")" | |
echo " * Valid from: $(get_validity_dates_from "$1")" | |
echo " * Expires: $(get_validity_dates_to "$1")" | |
echo " */" | |
echo "const val PIN = \"sha256/$(get_sha256_base64 "$1")\"" | |
} | |
if [ -z "${1:-}" ] | |
then | |
usage | |
elif [[ "$1" =~ .*\.pem$ ]] | |
then | |
get_data "$1" | |
else | |
tempdir="$(mktemp -d)" | |
debug "Temporary directory is $tempdir" | |
log "Connecting for certificate chain" | |
openssl s_client -showcerts -servername "$1" -connect "$1:443" <<< "Q" > "${tempdir}/chain.txt" 2>/dev/null || fail "Connection failed" 1 | |
log "Chain received" | |
log "Getting individual certificates from the chain" | |
unset CERT_ON | |
while read -r line | |
do | |
if [[ $line =~ .*\ s:.* ]] | |
then | |
debug "Found CN Line: $line" | |
pos="$(echo "$line" | cut -ds -f1 | sed -e 's/ //g')" | |
cn="$(echo "$line" | sed -e 's/.*CN = //')" | |
debug "Found CN: $cn" | |
fi | |
if [ -n "${CERT_ON:-}" ] | |
then | |
if [[ $line =~ -----END\ CERTIFICATE----- ]] | |
then | |
unset CERT_ON | |
debug "Found the end of the cert for $cn" | |
fi | |
echo "$line" >> "${tempdir}/${pos}.${cn}.pem" | |
else | |
if [[ $line =~ -----BEGIN\ CERTIFICATE----- ]] | |
then | |
CERT_ON=1 | |
debug "Found the start of the cert for $cn" | |
echo "$line" > "${tempdir}/${pos}.${cn}.pem" | |
fi | |
fi | |
done < "${tempdir}/chain.txt" | |
find "${tempdir}" -name \*.pem | sort | while read -r file | |
do | |
get_data "$file" | |
done | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment