Determine $SERVER_SIZE_LIMIT_BUG upfront

In order to handle better Cisco ACE loadbalancers (almost extinct species) which
have a problem with ClientHellos >127 ciphers we have had introduced a variable which
needs to be filled better with some sense.

This commit does that by introducing the function determine_sizelimitbug() which
is called in lets_roll().

It also removes then redundant code in cipher_pref_check().

Open:
* handle run_grease()
* do we want this information at least in a logfile
* or maybe eben on screen?

See also #1202 .
This commit is contained in:
Dirk Wetter 2019-03-05 16:47:19 +01:00
parent d965f14a15
commit 4442c6c236

View File

@ -6374,20 +6374,6 @@ cipher_pref_check() {
[[ $(has_server_protocol "$p") -eq 1 ]] && return 0
if ( [[ $p != tls1_3 ]] || "$HAS_TLS13" ) && ( [[ $p != ssl3 ]] || "$HAS_SSL3" ); then
# with the supplied binaries SNI works also for SSLv3
if [[ $p == tls1_2 ]] && ! "$SERVER_SIZE_LIMIT_BUG"; then
# for some servers the ClientHello is limited to 128 ciphers or the ClientHello itself has a length restriction.
# So far, this was only observed in TLS 1.2, affected are e.g. old Cisco LBs or ASAs, see issue #189
# To check whether a workaround is needed we send a large list of ciphers/big client hello. If connect fails,
# we hit the bug and automagically do the workaround. Cost: this is for all servers only 1x more connect
$OPENSSL s_client $(s_client_options "$STARTTLS -tls1_2 $BUGS -cipher "$overflow_probe_cipherlist" -connect $NODEIP:$PORT $PROXY $SNI") </dev/null 2>>$ERRFILE >$TMPFILE
if ! sclient_connect_successful $? $TMPFILE; then
SERVER_SIZE_LIMIT_BUG=true
# A simple check upfront for every server would be better. tls_sockets() would be better as we cannot be sure that the
# binary supports >=128 ciphers.
fi
fi
if [[ $p == tls1_2 ]] && "$SERVER_SIZE_LIMIT_BUG"; then
order="$(check_tls12_pref)"
else
@ -17677,6 +17663,69 @@ determine_service() {
}
# Sets SERVER_SIZE_LIMIT_BUG to true or false, depending on whether we hit the 128 cipher limit.
# Return value is 0 unless we have a problem executing
#
determine_sizelimitbug() {
local test_ciphers='CC,14, CC,13, CC,15, C0,30, C0,2C, C0,28, C0,24, 00,A5, 00,A3, 00,A1, 00,9F, CC,A9, CC,A8, CC,AA, C0,AF, C0,AD, C0,A3, C0,9F, 00,6B, 00,6A, 00,69, 00,68, C0,77, C0,73, 00,C4, 00,C3, 00,C2, 00,C1, C0,32, C0,2E, C0,2A, C0,26, C0,79, C0,75, 00,9D, C0,A1, C0,9D, 00,3D, 00,C0, C0,3D, C0,3F, C0,41, C0,43, C0,45, C0,49, C0,4B, C0,4D, C0,4F, C0,51, C0,53, C0,55, C0,57, C0,59, C0,5D, C0,5F, C0,61, C0,63, C0,7B, C0,7D, C0,7F, C0,81, C0,83, C0,87, C0,89, C0,8B, C0,8D, 16,B7, 16,B8, 16,B9, 16,BA, C0,2F, C0,2B, C0,27, C0,23, 00,A4, 00,A2, 00,A0, 00,9E, C0,AE, C0,AC, C0,A2, C0,9E, C0,A0, C0,9C, 00,67, 00,40, 00,3F, 00,3E, C0,76, C0,72, 00,BE, 00,BD, 00,BC, 00,BB, C0,31, C0,2D, C0,29, C0,25, C0,78, C0,74, 00,9C, 00,3C, 00,BA, C0,3C, C0,3E, C0,40, C0,42, C0,44, C0,48, C0,4A, C0,4C, C0,4E, C0,50, C0,52, C0,54, C0,56, C0,58, C0,5C, C0,5E, C0,60, C0,62, C0,7A, C0,7C, C0,7E, C0,80, C0,82'
local overflow_cipher1='C0,86'
local overflow_cipher2='C0,88'
# Only with TLS 1.2 offered at the server side it is possible to hit this bug, in practise. Thus
# we assume if TLS 1.2 is not supported, the server has no cipher size limit bug. It still may,
# theoretically, but in a regular check with testssl.sh we won't hit this limit with lower protocols.
# Upon calling this function we may know already whether TLS 1.2 is supported. If not we just
# check for it (and add it to the known protocols to be supported).
# Then we send 127 ciphers, check whether they work, and increase it by one and check again. The
# limit bug should occur @ 128 ciphers. To be sure we test until 129 ciphers.
if [[ 1 -eq $(has_server_protocol 03) ]]; then
SERVER_SIZE_LIMIT_BUG=false
elif [[ 0 -eq $(has_server_protocol 03) ]]; then
# Send 127 ciphers
tls_sockets 03 "${test_ciphers}, 00,FF"
if [[ $? -eq 0 ]]; then
# send 128 ciphers
tls_sockets 03 "${test_ciphers}, ${overflow_cipher1}, 00,FF"
if [[ $? -ne 0 ]]; then
SERVER_SIZE_LIMIT_BUG=true
else
tls_sockets 03 "${test_ciphers}, ${overflow_cipher1}, ${overflow_cipher2}, 00,FF"
if [[ $? -ne 0 ]]; then
SERVER_SIZE_LIMIT_BUG=true
else
SERVER_SIZE_LIMIT_BUG=false
fi
fi
debugme echo -e "\nSERVER_SIZE_LIMIT_BUG: $SERVER_SIZE_LIMIT_BUG"
else
pr_warning "FIXME line $LINENO, TLS 1.2 handshake in ${FUNCNAME[0]} failed"
return 1
fi
elif [[ 2 -eq $(has_server_protocol 03) ]]; then
tls_sockets 03 "${test_ciphers}, 00,FF"
if [[ $? -eq 0 ]]; then
add_tls_offered tls1_2 yes
tls_sockets 03 "${test_ciphers}, ${overflow_cipher1}, 00,FF"
if [[ $? -ne 0 ]]; then
SERVER_SIZE_LIMIT_BUG=true
else
tls_sockets 03 "${test_ciphers}, ${overflow_cipher1}, ${overflow_cipher2}, 00,FF"
if [[ $? -ne 0 ]]; then
SERVER_SIZE_LIMIT_BUG=true
else
SERVER_SIZE_LIMIT_BUG=false
fi
fi
debugme echo -e "\nSERVER_SIZE_LIMIT_BUG: $SERVER_SIZE_LIMIT_BUG"
else
debugme echo -e "\nNo TLS 1.2 in ${FUNCNAME[0]} found"
fi
fi
return 0
}
display_rdns_etc() {
local ip further_ip_addrs=""
local nodeip="$(tr -d '[]' <<< $NODEIP)" # for displaying IPv6 addresses we don't need []
@ -18007,7 +18056,7 @@ run_mass_testing() {
while read -r cmdline; do
cmdline="$(filter_input "$cmdline")"
[[ -z "$cmdline" ]] && continue
[[ "$cmdline" == "EOF" ]] && break
[[ "$cmdline" == EOF ]] && break
# Create the command line for the child in the form of an array (see #702)
create_mass_testing_cmdline "serial" $cmdline
draw_line "=" $((TERM_WIDTH / 2)); outln;
@ -18895,6 +18944,7 @@ lets_roll() {
datebanner " Start"
determine_service "$1" # STARTTLS service? Other will be determined here too. Returns 0 if test connect was ok or has already exited if fatal error occurred
# determine_service() can return 1, it indicates that this IP cannot be reached but there are more IPs to check
determine_sizelimitbug
if [[ $? -eq 0 ]] ; then
# "secret" devel options --devel:
if "$do_tls_sockets"; then