mirror of
https://github.com/mozilla/cipherscan.git
synced 2024-11-22 14:23:41 +01:00
Re-add curve fallback detection
This commit is contained in:
parent
04314bffdc
commit
4d7e1cb05a
114
cipherscan
114
cipherscan
@ -63,6 +63,8 @@ CAPATH=""
|
|||||||
SAVECRT=""
|
SAVECRT=""
|
||||||
TEST_CURVES="False"
|
TEST_CURVES="False"
|
||||||
has_curves="False"
|
has_curves="False"
|
||||||
|
# openssl formated list of curves that will cause server to select ECC suite
|
||||||
|
ecc_ciphers=""
|
||||||
unset known_certs
|
unset known_certs
|
||||||
declare -A known_certs
|
declare -A known_certs
|
||||||
unset cert_checksums
|
unset cert_checksums
|
||||||
@ -458,7 +460,11 @@ test_cipher_on_target() {
|
|||||||
if [[ $pfs =~ ECDH ]]; then
|
if [[ $pfs =~ ECDH ]]; then
|
||||||
has_curves="True"
|
has_curves="True"
|
||||||
if [ $TEST_CURVES == "True" ]; then
|
if [ $TEST_CURVES == "True" ]; then
|
||||||
test_ecc_curves
|
test_curves
|
||||||
|
if [ "$ecc_ciphers" != "" ]; then
|
||||||
|
ecc_ciphers+=":"
|
||||||
|
fi
|
||||||
|
ecc_ciphers+="$cipher"
|
||||||
else
|
else
|
||||||
# resolve the openssl curve to the proper IANA name
|
# resolve the openssl curve to the proper IANA name
|
||||||
current_curves="$(get_curve_name $(echo $pfs|cut -d ',' -f2))"
|
current_curves="$(get_curve_name $(echo $pfs|cut -d ',' -f2))"
|
||||||
@ -622,6 +628,7 @@ display_results_in_terminal() {
|
|||||||
fi
|
fi
|
||||||
if [ $TEST_CURVES == "True" ]; then
|
if [ $TEST_CURVES == "True" ]; then
|
||||||
echo "Curves ordering: $curvesordering"
|
echo "Curves ordering: $curvesordering"
|
||||||
|
echo "Curves fallback: $fallback_supported"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,7 +663,11 @@ display_results_in_json() {
|
|||||||
echo -n "}"
|
echo -n "}"
|
||||||
ctr=$((ctr+1))
|
ctr=$((ctr+1))
|
||||||
done
|
done
|
||||||
echo ']}'
|
echo -n ']'
|
||||||
|
if [ $TEST_CURVES == "True" ]; then
|
||||||
|
echo -n ",\"curves_fallback\":\"$fallback_supported\""
|
||||||
|
fi
|
||||||
|
echo '}'
|
||||||
}
|
}
|
||||||
|
|
||||||
test_serverside_ordering() {
|
test_serverside_ordering() {
|
||||||
@ -712,9 +723,7 @@ test_serverside_ordering() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
test_ecc_curves() {
|
test_curves() {
|
||||||
# openssl formated list of curves that will cause server to select ECC suite
|
|
||||||
local ecc_ciphers=""
|
|
||||||
# "True" if server supports ciphers that don't use ECC at a lower priority
|
# "True" if server supports ciphers that don't use ECC at a lower priority
|
||||||
local fallback_available="False"
|
local fallback_available="False"
|
||||||
|
|
||||||
@ -817,8 +826,7 @@ test_ecc_curves() {
|
|||||||
local tmp=$(echo Q | $sslcommand -curves $test_curves 2>/dev/null)
|
local tmp=$(echo Q | $sslcommand -curves $test_curves 2>/dev/null)
|
||||||
parse_openssl_output <<<"$tmp"
|
parse_openssl_output <<<"$tmp"
|
||||||
|
|
||||||
if [[ -z $current_protocol || $current_cipher == "(NONE)" \
|
if [[ -z $current_protocol || $current_cipher == "(NONE)" || $current_cipher == '0000' ]]; then
|
||||||
|| $current_cipher == '0000' ]]; then
|
|
||||||
fallback_supported="order-specific"
|
fallback_supported="order-specific"
|
||||||
verbose "Server aborted connection"
|
verbose "Server aborted connection"
|
||||||
else
|
else
|
||||||
@ -829,18 +837,14 @@ test_ecc_curves() {
|
|||||||
if [[ ${ephem_data[0]} =~ ECDH ]]; then
|
if [[ ${ephem_data[0]} =~ ECDH ]]; then
|
||||||
verbose "Server did select ${ephem_data[1]} curve"
|
verbose "Server did select ${ephem_data[1]} curve"
|
||||||
curves_ordering="inconclusive-${ephem_data[1]}"
|
curves_ordering="inconclusive-${ephem_data[1]}"
|
||||||
for id in "${!curve_names[@]}"; do
|
local cname="$(get_curve_name ${ephem_data[1]})"
|
||||||
if [[ ${curve_names[$id]} =~ ${ephem_data[1]} ]]; then
|
if [ "$cname" == "$most_wanted" ]; then
|
||||||
local canonic_name=(${curve_names[$id]})
|
curves_ordering="client"
|
||||||
if [[ ${canonic_name[0]} == $most_wanted ]]; then
|
break
|
||||||
curves_ordering="client"
|
else
|
||||||
break
|
curves_ordering="server"
|
||||||
else
|
break
|
||||||
curves_ordering="server"
|
fi
|
||||||
break
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
else
|
else
|
||||||
# some servers downgrade to non ECDH when curve order is changed
|
# some servers downgrade to non ECDH when curve order is changed
|
||||||
curves_ordering="inconclusive-noecc"
|
curves_ordering="inconclusive-noecc"
|
||||||
@ -849,6 +853,76 @@ test_ecc_curves() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test_curves_fallback() {
|
||||||
|
# "True" if server supports ciphers that don't use ECC at a lower priority
|
||||||
|
local fallback_available="False"
|
||||||
|
# return variable: whatever a server will fall back to non ECC suite when
|
||||||
|
# client doesn't advertise support for curves the server needs
|
||||||
|
fallback_supported="False"
|
||||||
|
|
||||||
|
# prepare the ssl command we'll be using
|
||||||
|
local sslcommand=""
|
||||||
|
sslcommand="$TIMEOUTBIN $TIMEOUT $OPENSSLBIN s_client"
|
||||||
|
if [ -n "$CAPATH" ]; then
|
||||||
|
sslcommand+=" -CApath $CAPATH -showcerts"
|
||||||
|
elif [ -e "$CACERTS" ]; then
|
||||||
|
sslcommand+=" -CAfile $CACERTS"
|
||||||
|
fi
|
||||||
|
sslcommand+=" -status $SCLIENTARGS -connect $TARGET -cipher $ecc_ciphers"
|
||||||
|
# force the TLS to send a TLS1.0 client hello at least, as with SSLv2
|
||||||
|
# ciphers present it will try to send a SSLv2 compatible client hello
|
||||||
|
sslcommand+=" -no_ssl2 -no_ssl3"
|
||||||
|
|
||||||
|
#
|
||||||
|
# here we use the same logic as with detecting cipher suites: first
|
||||||
|
# advertise all curves as supported, then remove curves one by one until we
|
||||||
|
# either get a fallback to a non ECC cipher, we run of curves or server
|
||||||
|
# tries to negotiate a curve we didn't advertise
|
||||||
|
#
|
||||||
|
local curves=(${CURVES[*]})
|
||||||
|
while [[ ${#curves[@]} -gt 0 ]]; do
|
||||||
|
OLDIFS="$IFS"
|
||||||
|
IFS=':'
|
||||||
|
local test_curves="${curves[*]}"
|
||||||
|
IFS="$OLDIFS"
|
||||||
|
verbose "Testing $test_curves"
|
||||||
|
|
||||||
|
ratelimit
|
||||||
|
local tmp=$(echo Q | $sslcommand -curves $test_curves 2>/dev/null)
|
||||||
|
parse_openssl_output <<<"$tmp"
|
||||||
|
|
||||||
|
if [[ -z $current_protocol || $current_cipher == "(NONE)" || $current_cipher == '0000' ]]; then
|
||||||
|
# server aborted connection
|
||||||
|
if [[ $fallback_available == "True" ]]; then
|
||||||
|
fallback_supported="False"
|
||||||
|
else
|
||||||
|
fallback_supported="unknown"
|
||||||
|
fi
|
||||||
|
break
|
||||||
|
else
|
||||||
|
# server accepted connection
|
||||||
|
local ephem_data=(${current_pfs//,/ })
|
||||||
|
|
||||||
|
if [[ ${ephem_data[0]} =~ ECDH ]]; then
|
||||||
|
# we got an ecc connection, remove the curve from the list of testable curves
|
||||||
|
local cname="$(get_curve_name ${ephem_data[1]})"
|
||||||
|
verbose "Server selected curve $cname"
|
||||||
|
for id in "${!curves[@]}"; do
|
||||||
|
if [ "${curves[id]}" == "$cname" ]; then
|
||||||
|
unset curves[$id]
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
verbose "Server fell back to $current_cipher"
|
||||||
|
# ok, we got a fallback
|
||||||
|
fallback_supported="True"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
# If no options are given, give usage information and exit (with error code)
|
# If no options are given, give usage information and exit (with error code)
|
||||||
if [ $# -eq 0 ]; then
|
if [ $# -eq 0 ]; then
|
||||||
usage;
|
usage;
|
||||||
@ -979,7 +1053,7 @@ get_cipher_pref $CIPHERSUITE
|
|||||||
test_serverside_ordering
|
test_serverside_ordering
|
||||||
|
|
||||||
if [[ $TEST_CURVES == "True" ]]; then
|
if [[ $TEST_CURVES == "True" ]]; then
|
||||||
test_ecc_curves
|
test_curves_fallback
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$OUTPUTFORMAT" == "json" ]; then
|
if [ "$OUTPUTFORMAT" == "json" ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user