From a71bfe5ebdb637bc8bfea73ce5a16dacd5e6f3c9 Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Thu, 6 Nov 2014 23:50:35 +0100 Subject: [PATCH 1/4] detect some TLS intolerancies buggy servers may choke on large ClientHello's, TLSv1.2 ClientHello's, etc. try to detect such failures and report them among tried connections are TLS1.2, TLS1.1, TLS1.0 and SSLv3 with ability to downgrade to lower protocol versions as well as a size limited client hello, both TLS1.2 and TLS1.0 version --- cipherscan | 264 ++++++++++++++++++++++++++++++++++++++++- top1m/parse_results.py | 95 +++++++++++++++ 2 files changed, 358 insertions(+), 1 deletion(-) diff --git a/cipherscan b/cipherscan index d995355..9c3c3dc 100755 --- a/cipherscan +++ b/cipherscan @@ -63,6 +63,32 @@ fi # RSA ciphers are put at the end to force Google servers to accept ECDSA ciphers # (probably a result of a workaround for the bug in Apple implementation of ECDSA) CIPHERSUITE="ALL:COMPLEMENTOFALL:+aRSA" +# some servers are intolerant to large client hello, try a shorter list of +# ciphers with them +SHORTCIPHERSUITE=('ECDHE-ECDSA-AES128-GCM-SHA256' + 'ECDHE-RSA-AES128-GCM-SHA256' + 'ECDHE-RSA-AES256-GCM-SHA384' + 'ECDHE-ECDSA-AES256-SHA' + 'ECDHE-ECDSA-AES128-SHA' + 'ECDHE-RSA-AES128-SHA' + 'ECDHE-RSA-AES256-SHA' + 'ECDHE-RSA-DES-CBC3-SHA' + 'ECDHE-ECDSA-RC4-SHA' + 'ECDHE-RSA-RC4-SHA' + 'DHE-RSA-AES128-SHA' + 'DHE-DSS-AES128-SHA' + 'DHE-RSA-CAMELLIA128-SHA' + 'DHE-RSA-AES256-SHA' + 'DHE-DSS-AES256-SHA' + 'DHE-RSA-CAMELLIA256-SHA' + 'EDH-RSA-DES-CBC3-SHA' + 'AES128-SHA' + 'CAMELLIA128-SHA' + 'AES256-SHA' + 'CAMELLIA256-SHA' + 'DES-CBC3-SHA' + 'RC4-SHA' + 'RC4-MD5') # as some servers are intolerant to large client hello's (or ones that have # RC4 ciphers below position 64), use the following for cipher testing in case # of problems @@ -119,6 +145,8 @@ unset known_certs declare -A known_certs unset cert_checksums declare -A cert_checksums +# array with results of tolerance scans (TLS version, extensions, etc.) +declare -A tls_tolerance # because running external commands like sleep incurs a fork penalty, we # first check if it is necessary @@ -685,6 +713,17 @@ display_results_in_terminal() { echo "Curves ordering: $curvesordering" echo "Curves fallback: $fallback_supported" fi + + echo + echo "Fallbacks required:" + for test_name in "${!tls_tolerance[@]}"; do + if [[ ${tls_tolerance[$test_name]} == "False" ]]; then + echo "$test_name config not supported, connection failed" + else + local res=(${tls_tolerance[$test_name]}) + echo "$test_name no fallback req, connected: ${res[1]} ${res[2]}" + fi + done | sort } display_results_in_json() { @@ -722,7 +761,22 @@ display_results_in_json() { if [ $TEST_CURVES == "True" ]; then echo -n ",\"curves_fallback\":\"$fallback_supported\"" fi - echo '}' + echo -n ',"configs":{' + ctr=0 + for test_name in "${!tls_tolerance[@]}"; do + local result=(${tls_tolerance[$test_name]}) + [ $ctr -gt 0 ] && echo -n "," + echo -n "\"$test_name\":{" + if [[ ${result[0]} == "False" ]]; then + echo -n "\"tolerant\":\"False\"" + else + echo -n "\"tolerant\":\"True\",\"proto\":\"${result[1]}\"," + echo -n "\"cipher\":\"${result[2]}\",\"trusted\":\"${result[3]}\"" + fi + echo -n "}" + ctr=$((ctr+1)) + done + echo '}}' } test_serverside_ordering() { @@ -977,6 +1031,212 @@ test_curves_fallback() { done } +test_tls_tolerance() { + + # + # first test general version tolerance with all we've got (full list of + # curves, full list of ciphers, NPN, ALPN + # + declare -A tls_vers_tests + tls_vers_tests['big-TLSv1.2']="" + tls_vers_tests['big-TLSv1.1']="-no_tls1_2" + tls_vers_tests['big-TLSv1.0']="-no_tls1_2 -no_tls1_1" + tls_vers_tests['big-SSLv3']="-no_tls1_2 -no_tls1_1 -no_tls1" + + local sslcommand="$TIMEOUTBIN $TIMEOUT $OPENSSLBIN s_client" + sslcommand+=" -status -nextprotoneg 'http/1.1'" + sslcommand+=" $SCLIENTARGS -connect $TARGET -cipher $CIPHERSUITE" + + for version in "${!tls_vers_tests[@]}"; do + ratelimit + verbose "Testing fallback with $sslcommand ${tls_vers_tests[$version]}" + local tmp=$(echo Q | $sslcommand ${tls_vers_tests[$version]} 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance[$version]="False" + else + tls_tolerance[$version]="True $current_protocol $current_cipher $current_trusted" + fi + done + + # if TLS1.2 didn't succeeded, try different fallbacks + if [[ ${tls_tolerance['big-TLSv1.2']} == "False" ]]; then + # + # Try big client hello, but with a version 2 compatible format + # (openssl automatically does that when there are SSLv2 ciphers in + # cipher string and no options are specified) + # + local sslcommand="$TIMEOUTBIN $TIMEOUT $OPENSSLBIN s_client" + if [ -n "$CAPATH" ]; then + sslcommand+=" -CApath $CAPATH -showcerts" + elif [ -e "$CACERTS" ]; then + sslcommand+=" -CAfile $CACERTS" + fi + sslcommand+=" -connect $TARGET -cipher $CIPHERSUITE" + + ratelimit + verbose "Testing fallback with $sslcommand" + local tmp=$(echo Q | $sslcommand 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance['v2-big-TLSv1.2']="False" + else + tls_tolerance['v2-big-TLSv1.2']="True $current_protocol $current_cipher $current_trusted" + fi + + # + # try a smaller, but still v2 compatible Client Hello + # + OLDIFS="$IFS" + IFS=":" + local ciphers="${SHORTCIPHERSUITE[*]}" + IFS="$OLDIFS" + + local sslcommand="$TIMEOUTBIN $TIMEOUT $OPENSSLBIN s_client" + if [ -n "$CAPATH" ]; then + sslcommand+=" -CApath $CAPATH -showcerts" + elif [ -e "$CACERTS" ]; then + sslcommand+=" -CAfile $CACERTS" + fi + sslcommand+=" -connect $TARGET -cipher $ciphers" + + ratelimit + verbose "Testing fallback with $sslcommand" + local tmp=$(echo Q | $sslcommand 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance['v2-small-TLSv1.2']="False" + else + tls_tolerance['v2-small-TLSv1.2']="True $current_protocol $current_cipher $current_trusted" + fi + + # + # v2, small but with TLS1.1 as max version + # + ratelimit + verbose "Testing fallback with $sslcommand -no_tls1_2" + local tmp=$(echo Q | $sslcommand -no_tls1_2 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance['v2-small-TLSv1.1']="False" + else + tls_tolerance['v2-small-TLSv1.1']="True $current_protocol $current_cipher $current_trusted" + fi + + # + # v2, small but with TLS1.0 as max version + # + ratelimit + verbose "Testing fallback with $sslcommand -no_tls1_2 -no_tls1_1" + local tmp=$(echo Q | $sslcommand -no_tls1_2 -no_tls1_1 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance['v2-small-TLSv1.0']="False" + else + tls_tolerance['v2-small-TLSv1.0']="True $current_protocol $current_cipher $current_trusted" + fi + + # + # v2, small but with SSLv3 as max version + # + ratelimit + verbose "Testing fallback with $sslcommand -no_tls1_2 -no_tls1_1 -no_tls1" + local tmp=$(echo Q | $sslcommand -no_tls1_2 -no_tls1_1 -no_tls1 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance['v2-small-SSLv3']="False" + else + tls_tolerance['v2-small-SSLv3']="True $current_protocol $current_cipher $current_trusted" + fi + + + # + # use v3 format TLSv1.2 hello, small cipher list + # + OLDIFS="$IFS" + IFS=":" + local ciphers="${SHORTCIPHERSUITE[*]}" + IFS="$OLDIFS" + + local sslcommand="$TIMEOUTBIN $TIMEOUT $OPENSSLBIN s_client" + if [ -n "$CAPATH" ]; then + sslcommand+=" -CApath $CAPATH -showcerts" + elif [ -e "$CACERTS" ]; then + sslcommand+=" -CAfile $CACERTS" + fi + sslcommand+=" $SCLIENTARGS -connect $TARGET -cipher $ciphers:!SSLv2" + + ratelimit + verbose "Testing fallback with $sslcommand" + local tmp=$(echo Q | $sslcommand 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance['small-TLSv1.2']="False" + else + tls_tolerance['small-TLSv1.2']="True $current_protocol $current_cipher $current_trusted" + fi + + # + # v3 format TLSv1.1 hello, small cipher list + # + ratelimit + verbose "Testing fallback with $sslcommand -no_tls1_2" + local tmp=$(echo Q | $sslcommand -no_tls1_2 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance['small-TLSv1.1']="False" + else + tls_tolerance['small-TLSv1.1']="True $current_protocol $current_cipher $current_trusted" + fi + + # + # v3 format TLSv1.0 hello, small cipher list + # + ratelimit + verbose "Testing fallback with $sslcommand -no_tls1_2 -no_tls1_1" + local tmp=$(echo Q | $sslcommand -no_tls1_2 -no_tls1_1 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance['small-TLSv1.0']="False" + else + tls_tolerance['small-TLSv1.0']="True $current_protocol $current_cipher $current_trusted" + fi + + # + # v3 format SSLv3 hello, small cipher list + # + ratelimit + verbose "Testing fallback with $sslcommand -no_tls1_2 -no_tls1_1 -no_tls1" + local tmp=$(echo Q | $sslcommand -no_tls1_2 -no_tls1_1 -no_tls1 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance['small-SSLv3']="False" + else + tls_tolerance['small-SSLv3']="True $current_protocol $current_cipher $current_trusted" + fi + fi +} + # If no options are given, give usage information and exit (with error code) if [ $# -eq 0 ]; then usage; @@ -1120,6 +1380,8 @@ if [[ ${#cipherspref[@]} -eq 0 ]] || [[ ${pref[1]} == "SSLv2" ]]; then get_cipher_pref "$CIPHERS" fi +test_tls_tolerance + test_serverside_ordering if [[ $TEST_CURVES == "True" ]]; then diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 00f7342..62179fa 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -13,6 +13,7 @@ path = "./results/" import json import sys from collections import defaultdict +import operator import os import re @@ -94,6 +95,44 @@ eccfallback = defaultdict(int) eccordering = defaultdict(int) ecccurve = defaultdict(int) ocspstaple = defaultdict(int) +fallbacks = defaultdict(int) +# array with indexes of fallback names for the matrix report +fallback_ids = defaultdict(int) +i=0 +fallback_ids['big-SSLv3'] = i +i+=1 +fallback_ids['big-TLSv1.0'] = i +i+=1 +fallback_ids['big-TLSv1.1'] = i +i+=1 +fallback_ids['big-TLSv1.2'] = i +i+=1 +# padding space +fallback_ids[' '] = i +i+=1 +fallback_ids['small-SSLv3'] = i +i+=1 +fallback_ids['small-TLSv1.0'] = i +i+=1 +fallback_ids['small-TLSv1.1'] = i +i+=1 +fallback_ids['small-TLSv1.2'] = i +i+=1 +# 2nd padding space +fallback_ids[' '] = i +i+=1 +fallback_ids['v2-small-SSLv3'] = i +i+=1 +fallback_ids['v2-small-TLSv1.0'] = i +i+=1 +fallback_ids['v2-small-TLSv1.1'] = i +i+=1 +fallback_ids['v2-small-TLSv1.2'] = i +i+=1 +fallback_ids['v2-big-TLSv1.2'] = i +i+=1 +# 3rd padding space +fallback_ids[' '] = i dsarsastack = 0 total = 0 for r,d,flist in os.walk(path): @@ -111,6 +150,7 @@ for r,d,flist in os.walk(path): tempeccfallback = "unknown" tempeccordering = "unknown" tempecccurve = {} + tempfallbacks = {} """ supported ciphers by the server under scan """ tempcipherstats = {} ciphertypes = 0 @@ -165,8 +205,31 @@ for r,d,flist in os.walk(path): except ValueError: continue + """ discard files with empty results """ if len(results['ciphersuite']) < 1: + # if there are no results from regular scan but there are + # from fallback attempts that means that the scan of a host + # is inconclusive + if 'configs' in results: + tolerance = [' '] * len(fallback_ids) + for entry in results['configs']: + config = results['configs'][entry] + if config['tolerant'] == "True" and \ + config['trusted'] == "True": + + # save which protocols passed + if entry in fallback_ids: + tolerance[fallback_ids[entry]] = 'v' + else: + fallback_ids[entry] = len(fallback_ids) + tolerance.insert(fallback_ids[entry], 'v') + + # analysis of host won't be continued, so we have to add + # results to the permanent, not temporary table, but + # do that only when there actually were detected values + if "".join(tolerance).strip(): + fallbacks["".join(tolerance).rstrip()] += 1 continue """ save ECC fallback (new format) """ @@ -184,6 +247,21 @@ for r,d,flist in os.walk(path): if len(results['curve']) == 1: tempecccurve[curve + ' Only'] = 1 + if 'configs' in results: + tolerance = [' '] * len(fallback_ids) + for entry in results['configs']: + config = results['configs'][entry] + + if not entry in fallback_ids: + fallback_ids[entry] = len(fallback_ids) + tolerance.insert(fallback_ids[entry], ' ') + + if config['tolerant'] == "True": + tolerance[fallback_ids[entry]] = 'v' + else: + tolerance[fallback_ids[entry]] = 'X' + tempfallbacks["".join(tolerance).rstrip()] = 1 + """ loop over list of ciphers """ for entry in results['ciphersuite']: @@ -392,6 +470,9 @@ for r,d,flist in os.walk(path): client_RC4_Pref[client_name] = True break + for s in tempfallbacks: + fallbacks[s] += 1 + for s in tempsigstats: sigalg[s] += 1 @@ -650,3 +731,17 @@ print("-------------------------+---------+-------") for stat in sorted(protocolstats): percent = round(protocolstats[stat] / total * 100, 4) sys.stdout.write(stat.ljust(25) + " " + str(protocolstats[stat]).ljust(10) + str(percent).ljust(4) + "\n") + +print("\nRequired fallbacks Count Percent") +print("----------------------------------------+---------+-------") +print("big smal v2 ") +print("----+----+-----+------------------------+---------+-------") +for stat in sorted(fallbacks): + percent = round(fallbacks[stat] / total * 100, 4) + sys.stdout.write(stat.ljust(40) + " " + str(fallbacks[stat]).ljust(10) + str(percent).ljust(4) + "\n") + +print("\nFallback column names") +print("------------------------") +fallback_ids_sorted=sorted(fallback_ids.items(), key=operator.itemgetter(1)) +for touple in fallback_ids_sorted: + print(str(touple[1]+1).rjust(3) + " " + str(touple[0])) From 5c98fe2107627ae6db6796614fadc60f3515871a Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Fri, 29 May 2015 20:25:47 +0200 Subject: [PATCH 2/4] do a scan with -no_tlsext openssl if possible --- cipherscan | 31 +++++++++++++++++++++++++++++++ top1m/parse_results.py | 6 ++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/cipherscan b/cipherscan index 9c3c3dc..8b539ae 100755 --- a/cipherscan +++ b/cipherscan @@ -283,6 +283,20 @@ c_hash() { done } +crude_grep() { + while read line; do + if [[ $line =~ $1 ]]; then + return 0 + fi + done + return 1 +} + +check_option_support() { + $OPENSSLBIN s_client -help 2>&1 | crude_grep "$1" + return $? +} + parse_openssl_output() { # clear variables in case matching doesn't hit them current_ocspstaple="False" @@ -1220,6 +1234,23 @@ test_tls_tolerance() { tls_tolerance['small-TLSv1.0']="True $current_protocol $current_cipher $current_trusted" fi + # + # v3 format TLSv1.0 hello, small cipher list, no extensions + # + if check_option_support "-no_tlsext"; then + ratelimit + verbose "Testing fallback with $sslcommand -no_tls1_2 -no_tls1_1 -no_tlsext" + local tmp=$(echo Q | $sslcommand -no_tls1_2 -no_tls1_1 -no_tlsext 2>/dev/null) + parse_openssl_output <<<"$tmp" + verbose "Negotiated proto: $current_protocol, cipher: $current_cipher" + if [[ -z $current_protocol || $current_cipher == "(NONE)" \ + || $current_cipher == '0000' ]]; then + tls_tolerance['small-TLSv1.0-notlsext']="False" + else + tls_tolerance['small-TLSv1.0-notlsext']="True $current_protocol $current_cipher $current_trusted" + fi + fi + # # v3 format SSLv3 hello, small cipher list # diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 62179fa..56631b6 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -112,6 +112,8 @@ fallback_ids[' '] = i i+=1 fallback_ids['small-SSLv3'] = i i+=1 +fallback_ids['small-TLSv1.0-notlsext'] = i +i+=1 fallback_ids['small-TLSv1.0'] = i i+=1 fallback_ids['small-TLSv1.1'] = i @@ -734,8 +736,8 @@ for stat in sorted(protocolstats): print("\nRequired fallbacks Count Percent") print("----------------------------------------+---------+-------") -print("big smal v2 ") -print("----+----+-----+------------------------+---------+-------") +print("big small v2 ") +print("----+-----+-----+------------------------+---------+-------") for stat in sorted(fallbacks): percent = round(fallbacks[stat] / total * 100, 4) sys.stdout.write(stat.ljust(40) + " " + str(fallbacks[stat]).ljust(10) + str(percent).ljust(4) + "\n") From 5f5487307dce4be5fc65c6d5a03efdb61015f982 Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Wed, 1 Apr 2015 01:14:23 +0200 Subject: [PATCH 3/4] Interpret some intolerance test results --- top1m/parse_results.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 56631b6..74192be 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -263,6 +263,35 @@ for r,d,flist in os.walk(path): else: tolerance[fallback_ids[entry]] = 'X' tempfallbacks["".join(tolerance).rstrip()] = 1 + configs = results['configs'] + try: + if configs['big-TLSv1.1']['tolerant'] != "True" and \ + configs['big-TLSv1.2']['tolerant'] != "True" and \ + configs['small-TLSv1.1']['tolerant'] != "True" and \ + configs['small-TLSv1.2']['tolerant'] != "True": + if configs['v2-small-TLSv1.1']['tolerant'] != "True" and \ + configs['v2-small-TLSv1.2']['tolerant'] != "True": + tempfallbacks['TLSv1.1+ strict Intolerance'] = 1 + else: + tempfallbacks['TLSv1.1+ Intolerant'] = 1 + if configs['big-TLSv1.1']['tolerant'] == "True" and \ + configs['big-TLSv1.2']['tolerant'] != "True" and \ + configs['small-TLSv1.1']['tolerant'] == "True" and \ + configs['small-TLSv1.2']['tolerant'] != "True": + if configs['v2-small-TLSv1.2']['tolerant'] != "True": + tempfallbacks['TLSv1.2 strict Intolerance'] = 1 + else: + tempfallbacks['TLSv1.2 Intolerant'] = 1 + if configs['big-TLSv1.2']['tolerant'] != "True" and \ + configs['big-TLSv1.1']['tolerant'] == "True" and \ + configs['small-TLSv1.2']['tolerant'] == "True": + tempfallbacks['TLSv1.2 big Intolerance'] = 1 + if configs['big-TLSv1.2']['tolerant'] != "True" and \ + configs['small-TLSv1.0']['tolerant'] != "True" and \ + configs['small-TLSv1.0-notlsext']['tolerant'] == "True": + tempfallbacks['TLS extension Intolerance'] = 1 + except KeyError: + pass """ loop over list of ciphers """ for entry in results['ciphersuite']: From abe8d329a99b3d27a9b7807fcd1a3089a7e9c8f5 Mon Sep 17 00:00:00 2001 From: Hubert Kario Date: Sun, 5 Apr 2015 16:24:46 +0200 Subject: [PATCH 4/4] Big handshake intolerance report --- top1m/parse_results.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/top1m/parse_results.py b/top1m/parse_results.py index 74192be..e4ba944 100644 --- a/top1m/parse_results.py +++ b/top1m/parse_results.py @@ -290,6 +290,12 @@ for r,d,flist in os.walk(path): configs['small-TLSv1.0']['tolerant'] != "True" and \ configs['small-TLSv1.0-notlsext']['tolerant'] == "True": tempfallbacks['TLS extension Intolerance'] = 1 + if configs['big-TLSv1.2']['tolerant'] != "True" and \ + configs['big-TLSv1.1']['tolerant'] != "True" and \ + configs['big-TLSv1.0']['tolerant'] != "True" and \ + (configs['small-TLSv1.2']['tolerant'] == "True" or + configs['v2-small-TLSv1.2']['tolerant'] == "True"): + tempfallbacks['Big handshake intolerance'] = 1 except KeyError: pass