diff --git a/cipherscan b/cipherscan index 61bd12e..e817285 100755 --- a/cipherscan +++ b/cipherscan @@ -297,13 +297,18 @@ display_results_in_terminal() { else echo "OCSP stapling: not supported" fi + if [[ $serverside == "True" ]]; then + echo "Server side cipher ordering" + else + echo "Client side cipher ordering" + fi } display_results_in_json() { # Display the results in json ctr=0 - echo -n "{\"target\":\"$TARGET\",\"date\":\"$(date -R)\",\"ciphersuite\": [" + echo -n "{\"target\":\"$TARGET\",\"date\":\"$(date -R)\",\"serverside\":\"${serverside}\",\"ciphersuite\": [" for cipher in "${cipherspref[@]}"; do [ $ctr -gt 0 ] && echo -n ',' echo -n "{\"cipher\":\"$(echo $cipher|awk '{print $1}')\"," @@ -321,6 +326,59 @@ display_results_in_json() { echo ']}' } +test_serverside_ordering() { + + local ciphersuite="" + local prefered="" + # server supports only one cipher or no ciphers, so it effectively uses server side ordering... + if [[ ${#cipherspref[@]} -lt 2 ]]; then + serverside="True" + return 0 + # server supports just two ciphers, so rotate them, that should be enough + elif [[ ${#cipherspref[@]} -eq 2 ]]; then + + local cipher=$(awk '{print $1}' <<< ${cipherspref[1]}) + prefered="$cipher" + ciphersuite=$cipher + + cipher=$(awk '{print $1}' <<< ${cipherspref[0]}) + ciphersuite+=":$cipher" + + # server supports 3 or more ciphers, rotate all three. This is necessary because google does + # select first client provided cipher, if it is either CDHE-RSA-AES128-GCM-SHA256 or + # ECDHE-RSA-CHACHA20-POLY1305 + else + local cipher=$(awk '{print $1}' <<< ${cipherspref[2]}) + prefered="$cipher" + ciphersuite="$cipher" + + cipher=$(awk '{print $1}' <<< ${cipherspref[1]}) + ciphersuite+=":$cipher" + + cipher=$(awk '{print $1}' <<< ${cipherspref[0]}) + ciphersuite+=":$cipher" + fi + + + if [ -e $CACERTS ]; then + local sslcommand="timeout $TIMEOUT $OPENSSLBIN s_client -CAfile $CACERTS -status $SCLIENTARGS -connect $TARGET -cipher $ciphersuite" + else + local sslcommand="timeout $TIMEOUT $OPENSSLBIN s_client -status $SCLIENTARGS -connect $TARGET -cipher $ciphersuite" + fi + + test_cipher_on_target "$sslcommand" + if [ $? -ne 0 ]; then + serverside="True" + else + local selected=$(awk '{print $1}' <<< $result) + if [[ $selected == $prefered ]]; then + serverside="False" + else + serverside="True" + fi + fi +} + # UNKNOWNOPTIONS="" while : do @@ -407,6 +465,8 @@ results=() # Call to the recursive loop that retrieves the cipher preferences get_cipher_pref $CIPHERSUITE +test_serverside_ordering + if [ "$OUTPUTFORMAT" == "json" ]; then display_results_in_json else