mirror of
https://github.com/drwetter/testssl.sh.git
synced 2025-01-06 00:39:44 +01:00
output + code polishing, phrasing. lf still has space for improvements
This commit is contained in:
parent
364bea1da0
commit
d786a94a8c
86
testssl.sh
86
testssl.sh
@ -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 $?
|
||||||
|
Loading…
Reference in New Issue
Block a user