output + code polishing, phrasing. lf still has space for improvements

This commit is contained in:
Dirk 2016-09-28 20:32:01 +02:00
parent 364bea1da0
commit d786a94a8c

View File

@ -513,6 +513,7 @@ hex2dec() {
count_lines() { count_lines() {
wc -l <<<"$1" | sed 's/ //g' wc -l <<<"$1" | sed 's/ //g'
} }
count_words() { count_words() {
wc -w <<<"$1" | sed 's/ //g' wc -w <<<"$1" | sed 's/ //g'
} }
@ -541,6 +542,10 @@ strip_spaces() {
echo "${1// /}" echo "${1// /}"
} }
trim_trailing_space() {
echo "${1%%*( )}"
}
toupper() { toupper() {
echo -n "$1" | tr 'a-z' 'A-Z' echo -n "$1" | tr 'a-z' 'A-Z'
} }
@ -958,6 +963,7 @@ run_hpkp() {
local -i hpkp_age_days local -i hpkp_age_days
local -i hpkp_nr_keys local -i hpkp_nr_keys
local hpkp_key hpkp_key_hostcert local hpkp_key hpkp_key_hostcert
local -a backup_keys
local spaces=" " local spaces=" "
local key_found=false local key_found=false
local i local i
@ -968,7 +974,6 @@ run_hpkp() {
if [[ ! -s $HEADERFILE ]]; then if [[ ! -s $HEADERFILE ]]; then
run_http_header "$1" || return 3 run_http_header "$1" || return 3
fi fi
#pr_bold " HPKP "
pr_bold " Public Key Pinning " pr_bold " Public Key Pinning "
egrep -aiw '^Public-Key-Pins|Public-Key-Pins-Report-Only' $HEADERFILE >$TMPFILE egrep -aiw '^Public-Key-Pins|Public-Key-Pins-Report-Only' $HEADERFILE >$TMPFILE
if [[ $? -eq 0 ]]; then if [[ $? -eq 0 ]]; then
@ -1001,7 +1006,7 @@ run_hpkp() {
out "# of keys: " out "# of keys: "
if [[ $hpkp_nr_keys -eq 1 ]]; then if [[ $hpkp_nr_keys -eq 1 ]]; then
pr_svrty_high "1 (NOT ok), " pr_svrty_high "1 (NOT ok), "
fileout "hpkp_keys" "NOT ok" "Only one key pinned in HPKP header, this means the site may become unavailable if the key is revoked" fileout "hpkp_keys" "HIGH" "Only one key pinned in HPKP header, this means the site may become unavailable if the key is revoked"
else else
out "$hpkp_nr_keys, " out "$hpkp_nr_keys, "
fileout "hpkp_keys" "OK" "$hpkp_nr_keys keys pinned in HPKP header, additional keys are available if the current key is revoked" fileout "hpkp_keys" "OK" "$hpkp_nr_keys keys pinned in HPKP header, additional keys are available if the current key is revoked"
@ -1030,8 +1035,8 @@ run_hpkp() {
fileout "hpkp_preload" "INFO" "HPKP header is NOT marked for browser preloading" fileout "hpkp_preload" "INFO" "HPKP header is NOT marked for browser preloading"
fi fi
# Get the pins first # Get the spki first
pins=$(tr ';' '\n' < $TMPFILE | tr -d ' ' | tr -d '\"' | awk -F'=' '/pin.*=/ { print $2 }') spki=$(tr ';' '\n' < $TMPFILE | tr -d ' ' | tr -d '\"' | awk -F'=' '/pin.*=/ { print $2 }')
# Look at the host certificate first # Look at the host certificate first
@ -1069,18 +1074,19 @@ run_hpkp() {
fi fi
# This is where the matching magic happens... # This is where the matching magic happens...
pins_match=false spki_match=false
has_backup_pin=false has_backup_spki=false
for hpkp_key in $pins; do i=0
for hpkp_key in $spki; do
key_found=false key_found=false
# compare pin against the host certificate # compare spki 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
# We have a match # We have a match
key_found=true key_found=true
pins_match=true spki_match=true
out "\n$spaces Host cert match: " out "\n$spaces Host cert match: "
pr_done_good "$hpkp_key" pr_done_good "$hpkp_key"
fileout "hpkp_$hpkp_key" "OK" "PIN $hpkp_key matches the host certificate" fileout "hpkp_$hpkp_key" "OK" "SPKI $hpkp_key matches the host certificate"
fi fi
debugme out "\n $hpkp_key | $hpkp_key_hostcert" debugme out "\n $hpkp_key | $hpkp_key_hostcert"
@ -1090,66 +1096,78 @@ run_hpkp() {
if [[ -n $hpkp_matches ]]; then if [[ -n $hpkp_matches ]]; then
# We have a match # We have a match
key_found=true key_found=true
pins_match=true spki_match=true
out "\n$spaces Sub CA match: " out "\n$spaces Sub CA match: "
pr_done_good "$hpkp_key" pr_done_good "$hpkp_key"
out "\n$spaces $(echo $hpkp_matches|sed "s/^[a-zA-Z0-9\+\/]*=* *//")" out "\n$spaces \"$(sed "s/^[a-zA-Z0-9\+\/]*=* *//" <<< $"$hpkp_matches" )\""
fileout "hpkp_$hpkp_key" "OK" "Intermediate CA key matches a key pinned in the HPKP header. Key/CA: $hpkp_matches" fileout "hpkp_$hpkp_key" "OK" "Intermediate CA key matches a key pinned in the HPKP header. Key/CA: $hpkp_matches"
fi fi
fi fi
if ! $key_found; then if ! $key_found; then
# we compare now against a precompiled list of SPKIs against the ROOT CAs we have!
hpkp_matches=$(grep -h "$hpkp_key" $ca_hashes | sort -u) hpkp_matches=$(grep -h "$hpkp_key" $ca_hashes | sort -u)
if [[ -n $hpkp_matches ]]; then if [[ -n $hpkp_matches ]]; then
# We have a match
key_found=true key_found=true
pins_match=true spki_match=true
if [[ $(count_lines "$hpkp_matches") -eq 1 ]]; then if [[ $(count_lines "$hpkp_matches") -eq 1 ]]; then
match_ca=$(echo "$hpkp_matches" | sed "s/[a-zA-Z0-9\+\/]*=* *//") match_ca=$(sed "s/[a-zA-Z0-9\+\/]*=* *//" <<< "$hpkp_matches")
else else
match_ca="" match_ca=""
fi fi
out "\n\n$spaces Root CA match: " out "\n\n$spaces Root CA match: "
pr_done_good "$hpkp_key" pr_done_good "$hpkp_key"
echo "$hpkp_matches"|sort -u|while read line; do echo "$hpkp_matches"|sort -u|while read line; do
out "\n$spaces $(echo $line |sed "s/^[a-zA-Z0-9\+\/]*=* *//")" out "\n$spaces \"$(sed "s/^[a-zA-Z0-9\+\/]*=* *//" <<< "$line")\""
done done
if [[ $match_ca == $hpkp_ca ]]; then if [[ $match_ca == $hpkp_ca ]]; then
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 matches a key pinned in the HPKP header. Key/OS/CA: $hpkp_matches. The CA is part of the chain"
else else
has_backup_pin=true has_backup_spki=true
out "\n$spaces This CA is not part of the chain and likely a backup PIN" out " -- not part of chain, probable backup key"
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 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 SPKI"
fi fi
fi fi
fi fi
if ! $key_found; then if ! $key_found; then
# Most likely a backup pin # Most likely a backup SPKI, unfortunately we can't tell for what it is: host, intermediates
has_backup_pin=true has_backup_spki=true
out "\n\n$spaces Unmatched key: " backup_keys[i]="$hpkp_key"
out "$hpkp_key" i=$((i + 1))
out "\n$spaces (This is OK for a backup pin of a host cert)" fileout "hpkp_$hpkp_key" "INFO" "SPKI $hpkp_key doesn't match anything. This is ok for a backup for any certificate"
fileout "hpkp_$hpkp_key" "INFO" "PIN $hpkp_key doesn't match anything. This could be ok if it is a backup pin for a host certificate" # CVS/JSON output here for the sake of simplicity, rest we do en bloc below
fi fi
done done
if [[ $i -eq 1 ]]; then
out "\n$spaces Unmatched SPKI: "
outln "${backup_keys[0]}"
else
out "\n\n$spaces Unmatched SPKIs: "
outln "${backup_keys[0]}"
for ((i=1; i <= ${#backup_keys[@]} ;i++ )); do
outln "$spaces ${backup_keys[i]}"
done
fi
# OK for SPKI backup of host or different intermediate certificate is ok!
# If all else fails... # If all else fails...
if ! $pins_match; then if ! $spki_match; then
pr_svrty_high " No matching key for pins found " "$has_backup_spki" && out "$spaces" # we had a few lines with backup SPKIs already
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" pr_svrty_highln " No matching key for SPKI found "
fileout "hpkp_keymatch" "HIGH" "None of the HPKP SPKI match your host certificate, intermediate CA or known root CAs. You may have bricked this site"
fi fi
if ! $has_backup_pin; then if ! $has_backup_spki; then
pr_svrty_high " No backup pins found. Loss/compromise of the currently pinned key(s) will lead to bricked site. " pr_svrty_highln " No backup keys 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." fileout "hpkp_backup" "HIGH" "No backup keys found. Loss/compromise of the currently pinned key(s) will lead to bricked site."
fi fi
else else
out "--" outln "--"
fileout "hpkp" "INFO" "No support for HTTP Public Key Pinning" fileout "hpkp" "INFO" "No support for HTTP Public Key Pinning"
fi fi
outln
tmpfile_handle $FUNCNAME.txt tmpfile_handle $FUNCNAME.txt
return $? return $?