Not done yet, but the basic code is working
This commit is contained in:
parent
946506f3ac
commit
a648470988
87
testssl.sh
87
testssl.sh
|
@ -960,6 +960,7 @@ run_hpkp() {
|
||||||
local i
|
local i
|
||||||
local hpkp_headers
|
local hpkp_headers
|
||||||
local first_hpkp_header
|
local first_hpkp_header
|
||||||
|
local ca_bundles="$INSTALL_DIR/etc/*.pem"
|
||||||
|
|
||||||
if [[ ! -s $HEADERFILE ]]; then
|
if [[ ! -s $HEADERFILE ]]; then
|
||||||
run_http_header "$1" || return 3
|
run_http_header "$1" || return 3
|
||||||
|
@ -1029,21 +1030,99 @@ run_hpkp() {
|
||||||
if [[ ! -s "$HOSTCERT" ]]; then
|
if [[ ! -s "$HOSTCERT" ]]; then
|
||||||
get_host_cert || return 1
|
get_host_cert || return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Get the pins first
|
||||||
|
pins=$(tr ';' '\n' < $TMPFILE | tr -d ' ' | tr -d '\"' | awk -F'=' '/pin.*=/ { print $2 }')
|
||||||
|
|
||||||
# get the key fingerprint from the host certificate
|
# get the key fingerprint from the host certificate
|
||||||
hpkp_key_hostcert="$($OPENSSL x509 -in $HOSTCERT -pubkey -noout | grep -v PUBLIC | \
|
hpkp_key_hostcert="$($OPENSSL x509 -in $HOSTCERT -pubkey -noout | grep -v PUBLIC | \
|
||||||
$OPENSSL base64 -d | $OPENSSL dgst -sha256 -binary | $OPENSSL base64)"
|
$OPENSSL base64 -d | $OPENSSL dgst -sha256 -binary | $OPENSSL base64)"
|
||||||
# compare it with the ones provided in the header
|
# compare it with the ones provided in the header
|
||||||
while read hpkp_key; do
|
for hpkp_key in $(echo "$pins"); do
|
||||||
if [[ "$hpkp_key_hostcert" == "$hpkp_key" ]] || [[ "$hpkp_key_hostcert" == "$hpkp_key=" ]]; then
|
if [[ "$hpkp_key_hostcert" == "$hpkp_key" ]] || [[ "$hpkp_key_hostcert" == "$hpkp_key=" ]]; then
|
||||||
out "\n$spaces matching host key: "
|
out "\n$spaces matching host key: "
|
||||||
pr_done_good "$hpkp_key"
|
pr_done_good "$hpkp_key"
|
||||||
fileout "hpkp_keymatch" "OK" "Key matches a key pinned in the HPKP header"
|
fileout "hpkp_keymatch" "OK" "Host certificate key matches a key pinned in the HPKP header"
|
||||||
key_found=true
|
key_found=true
|
||||||
fi
|
fi
|
||||||
debugme out "\n $hpkp_key | $hpkp_key_hostcert"
|
debugme out "\n $hpkp_key | $hpkp_key_hostcert"
|
||||||
done < <(tr ';' '\n' < $TMPFILE | tr -d ' ' | tr -d '\"' | awk -F'=' '/pin.*=/ { print $2 }')
|
done
|
||||||
|
|
||||||
|
if ! $key_found ; then
|
||||||
|
# Get keys from intermediate certificates
|
||||||
|
$OPENSSL s_client -showcerts $STARTTLS $BUGS $PROXY -showcerts -connect $NODEIP:$PORT ${sni[i]} </dev/null >$TMPFILE 2>$ERRFILE
|
||||||
|
# Place the server's certificate in $HOSTCERT and any intermediate
|
||||||
|
# certificates that were provided in $TEMPDIR/intermediatecerts.pem
|
||||||
|
# http://backreference.org/2010/05/09/ocsp-verification-with-openssl/
|
||||||
|
awk -v n=-1 "/Certificate chain/ {start=1}
|
||||||
|
/-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} }
|
||||||
|
inc { print > (\"$TEMPDIR/level\" n \".crt\") }
|
||||||
|
/---END CERTIFICATE-----/{ inc=0 }" $TMPFILE
|
||||||
|
nrsaved=$(count_words "$(echo $TEMPDIR/level?.crt 2>/dev/null)")
|
||||||
|
rm $TEMPDIR/level0.crt
|
||||||
|
|
||||||
|
# Compare them against the hashes found
|
||||||
|
if [[ nrsaved -ge 2 ]]; then
|
||||||
|
echo -n "" > "/tmp/hashes.intermediate"
|
||||||
|
for cert_fname in $TEMPDIR/level?.crt; do
|
||||||
|
hpkp_key_ca="$($OPENSSL x509 -in "$cert_fname" -pubkey -noout | grep -v PUBLIC|$OPENSSL dgst -sha256 -binary | $OPENSSL enc -base64)"
|
||||||
|
issuer="$(get_cn_from_cert $cert_fname)"
|
||||||
|
[[ -n $hpkp_name ]] || hpkp_name=$($OPENSSL x509 -in "$cert_fname" -subject -noout| sed "s/^subject= //")
|
||||||
|
echo "$hpkp_key_ca $bundle_name $issuer" >> "/tmp/hashes.intermediate"
|
||||||
|
done
|
||||||
|
for hpkp_key in $(echo $pins); do
|
||||||
|
hpkp_matches=$(grep "$hpkp_key" /tmp/hashes.intermediate)
|
||||||
|
if [[ -n $hpkp_matches ]]; then
|
||||||
|
# We have a winner!
|
||||||
|
key_found=true
|
||||||
|
out "\n$spaces Intermediate CA match : "
|
||||||
|
pr_done_good "$hpkp_matches"
|
||||||
|
fileout "hpkp_keymatch" "OK" "Intermediate CA key matches a key pinned in the HPKP header\nKey/CA: $hpkp_matches"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! $key_found ; then
|
||||||
|
# Get keys from Root CAs
|
||||||
|
for bundle_fname in $ca_bundles; do
|
||||||
|
local bundle_name=$(basename ${bundle_fname//.pem})
|
||||||
|
if [[ ! -r $bundle_fname ]]; then
|
||||||
|
pr_warningln "\"$bundle_fname\" cannot be found / not readable"
|
||||||
|
return 7
|
||||||
|
fi
|
||||||
|
debugme printf -- " %-12s" "${certificate_file[i]}"
|
||||||
|
# Split up the certificate bundle
|
||||||
|
awk -v n=-1 "BEGIN {start=1}
|
||||||
|
/-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} }
|
||||||
|
inc { print >> (\"/tmp/$bundle_name.\" n \".crt\") ; close (\"/tmp/$bundle_name.\" n \".crt\") }
|
||||||
|
/---END CERTIFICATE-----/{ inc=0 }" $bundle_fname
|
||||||
|
# Clear temp file
|
||||||
|
echo -n "" > "/tmp/hashes.$bundle_name"
|
||||||
|
for cert_fname in /tmp/$bundle_name.*.crt; do
|
||||||
|
hpkp_key_ca="$($OPENSSL x509 -in "$cert_fname" -pubkey -noout | grep -v PUBLIC|$OPENSSL dgst -sha256 -binary | $OPENSSL enc -base64)"
|
||||||
|
issuer="$(get_cn_from_cert $cert_fname)"
|
||||||
|
[[ -n $hpkp_name ]] || hpkp_name=$($OPENSSL x509 -in "$cert_fname" -subject -noout| sed "s/^subject= //")
|
||||||
|
echo "$hpkp_key_ca $bundle_name : $issuer" >> "/tmp/hashes.$bundle_name"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
for hpkp_key in $(echo $pins); do
|
||||||
|
hpkp_matches=$(grep -h "$hpkp_key" /tmp/hashes.*)
|
||||||
|
if [[ -n $hpkp_matches ]]; then
|
||||||
|
# We have a winner!
|
||||||
|
key_found=true
|
||||||
|
out "\n$spaces Root CA match : "
|
||||||
|
pr_done_goodln "$hpkp_key"
|
||||||
|
out "$hpkp_matches"
|
||||||
|
|
||||||
|
fileout "hpkp_keymatch" "OK" "Root CA key matches a key pinned in the HPKP header\nKey/OS/CA: $hpkp_matches"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
exit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If all else fails...
|
||||||
if ! $key_found ; then
|
if ! $key_found ; then
|
||||||
out "\n$spaces"
|
|
||||||
pr_svrty_high " No matching key for pins found "
|
pr_svrty_high " No matching key for pins found "
|
||||||
out "(CAs pinned? -- not checked for yet)"
|
out "(CAs pinned? -- not checked for yet)"
|
||||||
fileout "hpkp_keymatch" "DEBUG" "The TLS key does not match any key pinned in the HPKP header. If you pinned a CA key you can ignore this"
|
fileout "hpkp_keymatch" "DEBUG" "The TLS key does not match any key pinned in the HPKP header. If you pinned a CA key you can ignore this"
|
||||||
|
|
Loading…
Reference in New Issue