Addressed comments by @drwetter
It is OK for a site to pin a CA that is not part of the chain (like github.com does) This is a provision against a CA compromise (like diginotar) which could lead to a briked site in case of CA compromise. GitHub has built in multiple levels of security they have both backup pins for host certs and back pins for CAs (and I wouldn;t be surprised if they have a backup intermediate pin too).
This commit is contained in:
parent
9133eddb9a
commit
dd10194977
20
testssl.sh
20
testssl.sh
|
@ -1056,8 +1056,8 @@ run_hpkp() {
|
||||||
nrsaved=$(count_words "$(echo $TEMPDIR/level?.crt 2>/dev/null)")
|
nrsaved=$(count_words "$(echo $TEMPDIR/level?.crt 2>/dev/null)")
|
||||||
rm $TEMPDIR/level0.crt 2>/dev/null
|
rm $TEMPDIR/level0.crt 2>/dev/null
|
||||||
|
|
||||||
|
echo -n > "$TEMPDIR/intermediate.hashes"
|
||||||
if [[ nrsaved -ge 2 ]]; then
|
if [[ nrsaved -ge 2 ]]; then
|
||||||
echo -n "" > "$TEMPDIR/intermediate.hashes"
|
|
||||||
for cert_fname in $TEMPDIR/level?.crt; do
|
for cert_fname in $TEMPDIR/level?.crt; do
|
||||||
hpkp_key_ca="$($OPENSSL x509 -in "$cert_fname" -pubkey -noout | grep -v PUBLIC | $OPENSSL base64 -d |
|
hpkp_key_ca="$($OPENSSL x509 -in "$cert_fname" -pubkey -noout | grep -v PUBLIC | $OPENSSL base64 -d |
|
||||||
$OPENSSL dgst -sha256 -binary | $OPENSSL enc -base64)"
|
$OPENSSL dgst -sha256 -binary | $OPENSSL enc -base64)"
|
||||||
|
@ -1067,14 +1067,11 @@ run_hpkp() {
|
||||||
echo "$hpkp_key_ca $hpkp_name" >> "$TEMPDIR/intermediate.hashes"
|
echo "$hpkp_key_ca $hpkp_name" >> "$TEMPDIR/intermediate.hashes"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
rm $TEMPDIR/level*.crt 2>/dev/null
|
|
||||||
# I'd like to keep all certs retrieved for debugging
|
|
||||||
|
|
||||||
# Get keys from Root CAs
|
|
||||||
|
|
||||||
|
# This is where the matching magic happens...
|
||||||
pins_match=false
|
pins_match=false
|
||||||
for hpkp_key in $(echo $pins); do
|
has_backup_pin=false
|
||||||
# exho needed here? ^^^^
|
for hpkp_key in $pins; do
|
||||||
key_found=false
|
key_found=false
|
||||||
# compare pin against the host certificate
|
# compare pin against the host certificate
|
||||||
if [[ "$hpkp_key_hostcert" == "$hpkp_key" ]] || [[ "$hpkp_key_hostcert" == "$hpkp_key=" ]]; then
|
if [[ "$hpkp_key_hostcert" == "$hpkp_key" ]] || [[ "$hpkp_key_hostcert" == "$hpkp_key=" ]]; then
|
||||||
|
@ -1089,7 +1086,6 @@ run_hpkp() {
|
||||||
|
|
||||||
# Check for intermediate match
|
# Check for intermediate match
|
||||||
if ! $key_found; then
|
if ! $key_found; then
|
||||||
# doesn't work, "grep: /tmp/ssltester.Dp2ovS/intermediate.hashes: No such file or directory" if teested against testss.sh
|
|
||||||
hpkp_matches=$(grep "$hpkp_key" $TEMPDIR/intermediate.hashes 2>/dev/null)
|
hpkp_matches=$(grep "$hpkp_key" $TEMPDIR/intermediate.hashes 2>/dev/null)
|
||||||
if [[ -n $hpkp_matches ]]; then
|
if [[ -n $hpkp_matches ]]; then
|
||||||
# We have a match
|
# We have a match
|
||||||
|
@ -1122,7 +1118,7 @@ run_hpkp() {
|
||||||
out " (part of the chain)"
|
out " (part of the chain)"
|
||||||
fileout "hpkp_$hpkp_key" "INFO" "Root CA key matches a key pinned in the HPKP header. Key/OS/CA: $hpkp_matches. The CA is part of the chain"
|
fileout "hpkp_$hpkp_key" "INFO" "Root CA key matches a key pinned in the HPKP header. Key/OS/CA: $hpkp_matches. The CA is part of the chain"
|
||||||
else
|
else
|
||||||
# there's a root CA match for github AND this message.
|
has_backup_pin=true
|
||||||
out "\n$spaces This CA is not part of the chain and likely a backup PIN"
|
out "\n$spaces This CA is not part of the chain and likely a backup PIN"
|
||||||
fileout "hpkp_$hpkp_key" "INFO" "Root CA key matches a key pinned in the HPKP header. Key/OS/CA: $hpkp_matches. The CA is not part of the chain, this is a backup PIN"
|
fileout "hpkp_$hpkp_key" "INFO" "Root CA key matches a key pinned in the HPKP header. Key/OS/CA: $hpkp_matches. The CA is not part of the chain, this is a backup PIN"
|
||||||
fi
|
fi
|
||||||
|
@ -1131,6 +1127,7 @@ run_hpkp() {
|
||||||
|
|
||||||
if ! $key_found; then
|
if ! $key_found; then
|
||||||
# Most likely a backup pin
|
# Most likely a backup pin
|
||||||
|
has_backup_pin=true
|
||||||
out "\n\n$spaces Unmatched key: "
|
out "\n\n$spaces Unmatched key: "
|
||||||
out "$hpkp_key"
|
out "$hpkp_key"
|
||||||
out "\n$spaces (This is OK for a backup pin of a host cert)"
|
out "\n$spaces (This is OK for a backup pin of a host cert)"
|
||||||
|
@ -1143,6 +1140,11 @@ run_hpkp() {
|
||||||
pr_svrty_high " No matching key for pins found "
|
pr_svrty_high " No matching key for pins found "
|
||||||
fileout "hpkp_keymatch" "NOT ok" "None of the HPKP PINS match your host certificate, intermediate CA or known root CAs. You may have bricked this site"
|
fileout "hpkp_keymatch" "NOT ok" "None of the HPKP PINS match your host certificate, intermediate CA or known root CAs. You may have bricked this site"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ! $has_backup_pin; then
|
||||||
|
pr_svrty_high " No backup pins found. Loss/compromise of the currently pinned key(s) will lead to bricked site. "
|
||||||
|
fileout "hpkp_backup" "NOT ok" "No backup pins found. Loss/compromise of the currently pinned key(s) will lead to bricked site."
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
out "--"
|
out "--"
|
||||||
fileout "hpkp" "INFO" "No support for HTTP Public Key Pinning"
|
fileout "hpkp" "INFO" "No support for HTTP Public Key Pinning"
|
||||||
|
|
Loading…
Reference in New Issue