run_cipher_per_proto speedup
This PR makes basically the same changes to run_cipher_per_proto() as I previously made to run_allciphers(). The main difference is that in this function, round 0 consists of a single call to "$OPENSSL s_client" with "-cipher" including all of the locally supported ciphers. The reason for the difference is that in run_allciphers() its saves time to assume the server supports at least one cipher suite. In the case of run_cipher_per_proto(), however, it is likely that the server will not support some protocols at all, so its usually faster to start with a single call to "$OPENSSL s_client" that tests whether the server supports the protocol at all.
This commit is contained in:
parent
16927f523f
commit
bbcc869dec
122
testssl.sh
122
testssl.sh
|
@ -1670,11 +1670,14 @@ run_allciphers() {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# test for all ciphers per protocol locally configured (w/o distinguishing whether they are good or bad
|
# test for all ciphers per protocol locally configured (w/o distinguishing whether they are good or bad)
|
||||||
run_cipher_per_proto(){
|
run_cipher_per_proto() {
|
||||||
local proto proto_text
|
local proto proto_text
|
||||||
local hexcode n ciph sslvers kx auth enc mac export
|
local -i nr_ciphers
|
||||||
local -i sclient_success=0
|
local n sslvers auth mac export
|
||||||
|
local -a hexcode ciph kx enc export2
|
||||||
|
local -i i j parent child end_of_bundle round_num bundle_size num_bundles mod_check
|
||||||
|
local -a ciphers_found
|
||||||
local dhlen
|
local dhlen
|
||||||
local available
|
local available
|
||||||
local id
|
local id
|
||||||
|
@ -1686,39 +1689,88 @@ run_cipher_per_proto(){
|
||||||
outln " -ssl2 SSLv2\n -ssl3 SSLv3\n -tls1 TLS 1\n -tls1_1 TLS 1.1\n -tls1_2 TLS 1.2"| while read proto proto_text; do
|
outln " -ssl2 SSLv2\n -ssl3 SSLv3\n -tls1 TLS 1\n -tls1_1 TLS 1.1\n -tls1_2 TLS 1.2"| while read proto proto_text; do
|
||||||
locally_supported "$proto" "$proto_text" || continue
|
locally_supported "$proto" "$proto_text" || continue
|
||||||
outln
|
outln
|
||||||
$OPENSSL ciphers $proto -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE | while read hexcode n ciph sslvers kx auth enc mac export; do # -V doesn't work with openssl < 1.0
|
|
||||||
$OPENSSL s_client -cipher $ciph $proto $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE </dev/null
|
# get a list of all the cipher suites to test (only need the hexcode, ciph, kx, enc, and export values)
|
||||||
sclient_connect_successful "$?" "$TMPFILE"
|
nr_ciphers=0
|
||||||
sclient_success=$?
|
while read hexcode[nr_ciphers] n ciph[nr_ciphers] sslvers kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do
|
||||||
if [[ $sclient_success -ne 0 ]] && ! "$SHOW_EACH_C"; then
|
nr_ciphers=$nr_ciphers+1
|
||||||
continue # no successful connect AND not verbose displaying each cipher
|
done < <($OPENSSL ciphers $proto -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE)
|
||||||
fi
|
|
||||||
normalize_ciphercode "$hexcode"
|
# Split ciphers into bundles of size 4**n, starting with the smallest
|
||||||
if [[ $kx == "Kx=ECDH" ]] || [[ $kx == "Kx=DH" ]] || [[ $kx == "Kx=EDH" ]]; then
|
# "n" that leaves the ciphers in one bundle, and then reducing "n" by
|
||||||
dhlen=$(read_dhbits_from_file "$TMPFILE" quiet)
|
# one in each round. Only test a bundle of 4**n ciphers against the
|
||||||
kx="$kx $dhlen"
|
# server if it was part of a bundle of 4**(n+1) ciphers that included
|
||||||
fi
|
# a cipher supported by the server. Continue until n=0.
|
||||||
neat_list "$HEXC" "$ciph" "$kx" "$enc"
|
|
||||||
available="available"
|
# Determine the smallest bundle size that will result in their being one bundle.
|
||||||
if "$SHOW_EACH_C"; then
|
for(( bundle_size=1; bundle_size < nr_ciphers; bundle_size*=4 )); do
|
||||||
if [[ $sclient_success -eq 0 ]]; then
|
:
|
||||||
pr_cyan " available"
|
done
|
||||||
else
|
|
||||||
out " not a/v"
|
# set ciphers_found[1] so that the complete bundle will be tested in round 0.
|
||||||
available="not a/v"
|
ciphers_found[1]=true
|
||||||
fi
|
for (( round_num=0; bundle_size>=1; bundle_size/=4 )); do
|
||||||
fi
|
# Note that since the number of ciphers isn't a power of 4, the number
|
||||||
if "$SHOW_SIGALGO"; then
|
# of bundles may be may be less than 4**(round_num+1), and the final
|
||||||
$OPENSSL x509 -noout -text -in $TMPFILE | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1
|
# bundle may have fewer than bundle_size ciphers.
|
||||||
else
|
num_bundles=$nr_ciphers/$bundle_size
|
||||||
outln
|
mod_check=$nr_ciphers%$bundle_size
|
||||||
fi
|
[[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1
|
||||||
id="cipher$proto"
|
for (( i=0; i<num_bundles; i++ )); do
|
||||||
id+="_$HEXC"
|
# parent=index of bundle from previous round that includes this bundle of ciphers
|
||||||
fileout "$id" "INFO" "$proto_text $(neat_list "$HEXC" "$ciph" "$kx" "$enc") $available"
|
parent=4**$round_num+$i/4
|
||||||
tmpfile_handle $FUNCNAME.txt
|
# child=index for this bundle of ciphers
|
||||||
|
child=4*4**$round_num+$i
|
||||||
|
if ${ciphers_found[parent]}; then
|
||||||
|
ciphers_to_test=""
|
||||||
|
end_of_bundle=$i*$bundle_size+$bundle_size
|
||||||
|
[[ $end_of_bundle -gt $nr_ciphers ]] && end_of_bundle=$nr_ciphers
|
||||||
|
for (( j=i*bundle_size; j<end_of_bundle; j++ )); do
|
||||||
|
ciphers_to_test="${ciphers_to_test}:${ciph[j]}"
|
||||||
|
done
|
||||||
|
ciphers_found[child]=false
|
||||||
|
$OPENSSL s_client -cipher "${ciphers_to_test:1}" $proto $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE </dev/null
|
||||||
|
sclient_connect_successful "$?" "$TMPFILE"
|
||||||
|
[[ "$?" -eq 0 ]] && ciphers_found[child]=true
|
||||||
|
else
|
||||||
|
# No need to test, since test of parent demonstrated none of these ciphers work.
|
||||||
|
ciphers_found[child]=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If this is a "leaf" of the test tree, then print out the results.
|
||||||
|
if [[ $bundle_size -eq 1 ]] && ( ${ciphers_found[child]} || "$SHOW_EACH_C"); then
|
||||||
|
export=${export2[i]}
|
||||||
|
normalize_ciphercode "${hexcode[i]}"
|
||||||
|
if [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]]; then
|
||||||
|
if ${ciphers_found[child]}; then
|
||||||
|
dhlen=$(read_dhbits_from_file "$TMPFILE" quiet)
|
||||||
|
kx[i]="${kx[i]} $dhlen"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
neat_list "$HEXC" "${ciph[i]}" "${kx[i]}" "${enc[i]}"
|
||||||
|
available="available"
|
||||||
|
if "$SHOW_EACH_C"; then
|
||||||
|
if ${ciphers_found[child]}; then
|
||||||
|
pr_cyan " available"
|
||||||
|
else
|
||||||
|
out " not a/v"
|
||||||
|
available="not a/v"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if "$SHOW_SIGALGO" && ${ciphers_found[child]}; then
|
||||||
|
$OPENSSL x509 -noout -text -in $TMPFILE | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1
|
||||||
|
else
|
||||||
|
outln
|
||||||
|
fi
|
||||||
|
id="cipher$proto"
|
||||||
|
id+="_$HEXC"
|
||||||
|
fileout "$id" "INFO" "$proto_text $(neat_list "$HEXC" "${ciph[i]}" "${kx[i]}" "${enc[i]}") $available"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
round_num=round_num+1
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
tmpfile_handle $FUNCNAME.txt
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue