mirror of
https://github.com/drwetter/testssl.sh.git
synced 2025-01-30 12:21:17 +01:00
Fix #2614
Currently `compare_server_name_to_cert()` only indicates whether the server's host name matches a wildcard name in the certificate. So, it does not indicate if the certificate includes a wildcard name that does not match the server's host name. As a result, if a certificate includes the names "api.sub.example.tld" and "*.api.sub.example.tld," then a wildcard certificate warning will be issued for host names such as www.api.sub.example.tld, but not for api.sub.example.tld. This commit changes `compare_server_name_to_cert()` to indicate whether the certificate is a wildcard certificate in addition to providing information about how the certificate matches the server's host name. Functions that use this function's response are then changed to extract the information they need (matching or wildcard) from the return value.
This commit is contained in:
parent
daf0671878
commit
95b6258f82
47
testssl.sh
47
testssl.sh
@ -8386,12 +8386,14 @@ wildcard_match()
|
|||||||
# 8, if the server name provided is a wildcard match against the CN
|
# 8, if the server name provided is a wildcard match against the CN
|
||||||
# 9, if the server name provided matches a name in the SAN AND is a wildcard match against the CN
|
# 9, if the server name provided matches a name in the SAN AND is a wildcard match against the CN
|
||||||
# 10, if the server name provided is a wildcard match against the CN AND a name in the SAN
|
# 10, if the server name provided is a wildcard match against the CN AND a name in the SAN
|
||||||
|
#
|
||||||
|
# Add 128 to the return value if the CN or a DNS name in the SAN is a wildcard.
|
||||||
|
|
||||||
compare_server_name_to_cert() {
|
compare_server_name_to_cert() {
|
||||||
local cert="$1"
|
local cert="$1"
|
||||||
local servername cns cn dns_sans ip_sans san dercert tag
|
local servername cns cn dns_sans ip_sans san dercert tag
|
||||||
local srv_id="" xmppaddr=""
|
local srv_id="" xmppaddr=""
|
||||||
local -i i len len1 cn_match=0
|
local -i i len len1 cn_match=0 wildcard_cert=0
|
||||||
local -i subret=0 # no error condition, passing results
|
local -i subret=0 # no error condition, passing results
|
||||||
|
|
||||||
HAS_DNS_SANS=false
|
HAS_DNS_SANS=false
|
||||||
@ -8536,10 +8538,16 @@ compare_server_name_to_cert() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check whether any of the DNS names in the certificate are wildcard names
|
# Check whether any of the DNS names in the certificate are wildcard names
|
||||||
# that match the servername
|
# and if they match the servername
|
||||||
if [[ $subret -eq 0 ]]; then
|
if [[ $subret -eq 0 ]]; then
|
||||||
while read san; do
|
while read san; do
|
||||||
[[ -n "$san" ]] || continue
|
[[ -n "$san" ]] || continue
|
||||||
|
is_wildcard "$san"
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
wildcard_cert=128
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
fi
|
||||||
wildcard_match "$servername" "$san"
|
wildcard_match "$servername" "$san"
|
||||||
[[ $? -eq 0 ]] && subret=2 && break
|
[[ $? -eq 0 ]] && subret=2 && break
|
||||||
done <<< "$dns_sans"
|
done <<< "$dns_sans"
|
||||||
@ -8555,13 +8563,20 @@ compare_server_name_to_cert() {
|
|||||||
# Check whether the CN matches the servername
|
# Check whether the CN matches the servername
|
||||||
[[ $(toupper "$cn") == "$servername" ]] && cn_match=4 && break
|
[[ $(toupper "$cn") == "$servername" ]] && cn_match=4 && break
|
||||||
|
|
||||||
# Check whether the CN is a wildcard name that matches the servername
|
# Check whether the CN is a wildcard name and if it matches the servername
|
||||||
# NOTE: Don't stop loop on a wildcard match in case there is another CN
|
# NOTE: Don't stop loop on a wildcard match in case there is another CN
|
||||||
# that is an exact match.
|
# that is an exact match.
|
||||||
|
is_wildcard "$cn"
|
||||||
|
if [[ $? -eq 0 ]]; then
|
||||||
|
wildcard_cert=128
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
fi
|
||||||
wildcard_match "$servername" "$cn"
|
wildcard_match "$servername" "$cn"
|
||||||
[[ $? -eq 0 ]] && cn_match=8
|
[[ $? -eq 0 ]] && cn_match=8
|
||||||
done <<< "$cns"
|
done <<< "$cns"
|
||||||
subret+=$cn_match
|
subret+=$cn_match
|
||||||
|
subret+=$wildcard_cert
|
||||||
return $subret
|
return $subret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9456,7 +9471,7 @@ certificate_info() {
|
|||||||
# supported by the client.
|
# supported by the client.
|
||||||
has_dns_sans=$HAS_DNS_SANS
|
has_dns_sans=$HAS_DNS_SANS
|
||||||
|
|
||||||
case $trust_sni in
|
case $((trust_sni%128)) in
|
||||||
0) trustfinding="certificate does not match supplied URI"
|
0) trustfinding="certificate does not match supplied URI"
|
||||||
set_grade_cap "M" "Domain name mismatch"
|
set_grade_cap "M" "Domain name mismatch"
|
||||||
;;
|
;;
|
||||||
@ -9483,10 +9498,10 @@ certificate_info() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ $trust_sni -eq 0 ]]; then
|
if [[ $((trust_sni%128)) -eq 0 ]]; then
|
||||||
pr_svrty_high "$trustfinding"
|
pr_svrty_high "$trustfinding"
|
||||||
trust_sni_finding="HIGH"
|
trust_sni_finding="HIGH"
|
||||||
elif [[ $trust_sni -eq 4 ]] || [[ $trust_sni -eq 8 ]]; then
|
elif [[ $((trust_sni%128)) -eq 4 ]] || [[ $((trust_sni%128)) -eq 8 ]]; then
|
||||||
if [[ $SERVICE == HTTP ]] || "$ASSUME_HTTP"; then
|
if [[ $SERVICE == HTTP ]] || "$ASSUME_HTTP"; then
|
||||||
# https://bugs.chromium.org/p/chromium/issues/detail?id=308330
|
# https://bugs.chromium.org/p/chromium/issues/detail?id=308330
|
||||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1245280
|
# https://bugzilla.mozilla.org/show_bug.cgi?id=1245280
|
||||||
@ -9513,17 +9528,17 @@ certificate_info() {
|
|||||||
# See issue #733.
|
# See issue #733.
|
||||||
if [[ -z "$sni_used" ]]; then
|
if [[ -z "$sni_used" ]]; then
|
||||||
trustfinding_nosni=""
|
trustfinding_nosni=""
|
||||||
elif [[ $trust_sni -eq $trust_nosni && "$has_dns_sans" == "$has_dns_sans_nosni" ]] || \
|
elif [[ $((trust_sni%128)) -eq $((trust_nosni%128)) && "$has_dns_sans" == "$has_dns_sans_nosni" ]] || \
|
||||||
[[ $trust_sni -eq 0 && $trust_nosni -eq 0 ]]; then
|
[[ $((trust_sni%128)) -eq 0 && $((trust_nosni%128)) -eq 0 ]]; then
|
||||||
trustfinding_nosni=" (same w/o SNI)"
|
trustfinding_nosni=" (same w/o SNI)"
|
||||||
elif [[ $trust_nosni -eq 0 ]]; then
|
elif [[ $((trust_nosni%128)) -eq 0 ]]; then
|
||||||
if [[ $trust_sni -eq 4 ]] || [[ $trust_sni -eq 8 ]]; then
|
if [[ $((trust_sni%128)) -eq 4 ]] || [[ $((trust_sni%128)) -eq 8 ]]; then
|
||||||
trustfinding_nosni=" (w/o SNI: certificate does not match supplied URI)"
|
trustfinding_nosni=" (w/o SNI: certificate does not match supplied URI)"
|
||||||
else
|
else
|
||||||
trustfinding_nosni=" (SNI mandatory)"
|
trustfinding_nosni=" (SNI mandatory)"
|
||||||
fi
|
fi
|
||||||
elif [[ $trust_nosni -eq 4 ]] || [[ $trust_nosni -eq 8 ]] || [[ $trust_sni -eq 4 ]] || [[ $trust_sni -eq 8 ]]; then
|
elif [[ $((trust_nosni%128)) -eq 4 ]] || [[ $((trust_nosni%128)) -eq 8 ]] || [[ $((trust_sni%128)) -eq 4 ]] || [[ $((trust_sni%128)) -eq 8 ]]; then
|
||||||
case $trust_nosni in
|
case $((trust_nosni%128)) in
|
||||||
1) trustfinding_nosni=" (w/o SNI: Ok via SAN)" ;;
|
1) trustfinding_nosni=" (w/o SNI: Ok via SAN)" ;;
|
||||||
2) trustfinding_nosni=" (w/o SNI: Ok via SAN wildcard)" ;;
|
2) trustfinding_nosni=" (w/o SNI: Ok via SAN wildcard)" ;;
|
||||||
4) if "$has_dns_sans_nosni"; then
|
4) if "$has_dns_sans_nosni"; then
|
||||||
@ -9543,12 +9558,12 @@ certificate_info() {
|
|||||||
9) trustfinding_nosni=" (w/o SNI: Ok via CN wildcard and SAN)" ;;
|
9) trustfinding_nosni=" (w/o SNI: Ok via CN wildcard and SAN)" ;;
|
||||||
10) trustfinding_nosni=" (w/o SNI: Ok via SAN wildcard and CN wildcard)" ;;
|
10) trustfinding_nosni=" (w/o SNI: Ok via SAN wildcard and CN wildcard)" ;;
|
||||||
esac
|
esac
|
||||||
elif [[ $trust_sni -ne 0 ]]; then
|
elif [[ $((trust_sni%128)) -ne 0 ]]; then
|
||||||
trustfinding_nosni=" (works w/o SNI)"
|
trustfinding_nosni=" (works w/o SNI)"
|
||||||
else
|
else
|
||||||
trustfinding_nosni=" (however, works w/o SNI)"
|
trustfinding_nosni=" (however, works w/o SNI)"
|
||||||
fi
|
fi
|
||||||
if [[ -n "$sni_used" ]] || [[ $trust_nosni -eq 0 ]] || [[ $trust_nosni -ne 4 && $trust_nosni -ne 8 ]]; then
|
if [[ -n "$sni_used" ]] || [[ $((trust_nosni%128)) -eq 0 ]] || [[ $((trust_nosni%128)) -ne 4 && $((trust_nosni%128)) -ne 8 ]]; then
|
||||||
outln "$trustfinding_nosni"
|
outln "$trustfinding_nosni"
|
||||||
elif [[ $SERVICE == HTTP ]] || "$ASSUME_HTTP"; then
|
elif [[ $SERVICE == HTTP ]] || "$ASSUME_HTTP"; then
|
||||||
prln_svrty_high "$trustfinding_nosni"
|
prln_svrty_high "$trustfinding_nosni"
|
||||||
@ -9558,7 +9573,7 @@ certificate_info() {
|
|||||||
|
|
||||||
fileout "cert_trust${json_postfix}" "$trust_sni_finding" "${trustfinding}${trustfinding_nosni}"
|
fileout "cert_trust${json_postfix}" "$trust_sni_finding" "${trustfinding}${trustfinding_nosni}"
|
||||||
|
|
||||||
if [[ "$trust_sni" =~ ^(2|6|8|9|10)$ ]] || [[ "$trust_nosni" =~ ^(2|6|8|9|10)$ ]]; then
|
if [[ $((trust_sni&128)) -eq 128 ]] || [[ $((trust_nosni&128)) -eq 128 ]]; then
|
||||||
out "${spaces}"
|
out "${spaces}"
|
||||||
pr_svrty_low "wildcard certificate" ; outln " could be problematic, see other hosts at"
|
pr_svrty_low "wildcard certificate" ; outln " could be problematic, see other hosts at"
|
||||||
outln "${spaces}https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=$cert_fingerprint_sha2"
|
outln "${spaces}https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=$cert_fingerprint_sha2"
|
||||||
@ -10164,7 +10179,7 @@ run_server_defaults() {
|
|||||||
# $NODE being tested or if it has the same subject
|
# $NODE being tested or if it has the same subject
|
||||||
# (CN and SAN) as other certificates for this host.
|
# (CN and SAN) as other certificates for this host.
|
||||||
compare_server_name_to_cert "$HOSTCERT"
|
compare_server_name_to_cert "$HOSTCERT"
|
||||||
[[ $? -ne 0 ]] && success[n]=0 || success[n]=1
|
[[ $(($?%128)) -ne 0 ]] && success[n]=0 || success[n]=1
|
||||||
|
|
||||||
if [[ ${success[n]} -ne 0 ]]; then
|
if [[ ${success[n]} -ne 0 ]]; then
|
||||||
cn_nosni="$(toupper "$(get_cn_from_cert $HOSTCERT)")"
|
cn_nosni="$(toupper "$(get_cn_from_cert $HOSTCERT)")"
|
||||||
|
Loading…
Reference in New Issue
Block a user