mirror of
https://github.com/drwetter/testssl.sh.git
synced 2024-12-31 22:09:44 +01:00
manually merged #728 (see #423), credits also to @seccubus. Unfortunately the unit tests don't make so much sense atm
This commit is contained in:
parent
699b48c8b8
commit
ebd9e6ae65
236
testssl.sh
236
testssl.sh
@ -3521,6 +3521,7 @@ run_client_simulation() {
|
||||
local i=0
|
||||
local name tls proto cipher temp what_dh bits curve
|
||||
local has_dh_bits using_sockets=true
|
||||
local client_service
|
||||
|
||||
# source the external file
|
||||
. "$TESTSSL_INSTALL_DIR/etc/client_simulation.txt" 2>/dev/null
|
||||
@ -3529,14 +3530,18 @@ run_client_simulation() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
#FIXME, see client_simulation branch which has to be merged
|
||||
if "$SSL_NATIVE" || [[ -n "$STARTTLS" ]]; then
|
||||
using_sockets=false
|
||||
fi
|
||||
"$SSL_NATIVE" && using_sockets=false
|
||||
|
||||
# doesn't make sense for other services
|
||||
if [[ $SERVICE != "HTTP" ]]; then
|
||||
return 0
|
||||
if [[ $SERVICE != "" ]]; then
|
||||
client_service="$SERVICE"
|
||||
else
|
||||
# Can we take the service from STARTTLS?
|
||||
if [[ -n "$STARTTLS_PROTOCOL" ]]; then
|
||||
client_service=$(toupper "${STARTTLS_PROTOCOL%s}") # strip trailing 's' in ftp(s), smtp(s), pop3(s), etc
|
||||
else
|
||||
outln "Could not determine which protocol was started, only simulating generic clients."
|
||||
client_service="undetermined"
|
||||
fi
|
||||
fi
|
||||
|
||||
outln
|
||||
@ -3550,7 +3555,7 @@ run_client_simulation() {
|
||||
outln
|
||||
|
||||
debugme tmln_out
|
||||
|
||||
|
||||
if "$WIDE"; then
|
||||
if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]]; then
|
||||
out " Browser Protocol Cipher Suite Name (OpenSSL) "
|
||||
@ -3567,116 +3572,121 @@ run_client_simulation() {
|
||||
outln
|
||||
fi
|
||||
for name in "${short[@]}"; do
|
||||
out " $(printf -- "%-33s" "${names[i]}")"
|
||||
if "$using_sockets" && [[ -n "${handshakebytes[i]}" ]]; then
|
||||
client_simulation_sockets "${handshakebytes[i]}"
|
||||
sclient_success=$?
|
||||
if [[ $sclient_success -eq 0 ]]; then
|
||||
if [[ "0x${DETECTED_TLS_VERSION}" -lt ${lowest_protocol[i]} ]] || \
|
||||
[[ "0x${DETECTED_TLS_VERSION}" -gt ${highest_protocol[i]} ]]; then
|
||||
sclient_success=1
|
||||
fi
|
||||
[[ $sclient_success -eq 0 ]] && cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE >$ERRFILE
|
||||
fi
|
||||
else
|
||||
! "$HAS_NO_SSL2" && protos[i]="$(sed 's/-no_ssl2//' <<< "${protos[i]}")"
|
||||
debugme echo "$OPENSSL s_client -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} </dev/null"
|
||||
$OPENSSL s_client -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} </dev/null >$TMPFILE 2>$ERRFILE
|
||||
sclient_connect_successful $? $TMPFILE
|
||||
sclient_success=$?
|
||||
fi
|
||||
if [[ $sclient_success -eq 0 ]]; then
|
||||
# If an ephemeral DH key was used, check that the number of bits is within range.
|
||||
temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TMPFILE") # extract line
|
||||
what_dh=$(awk -F',' '{ print $1 }' <<< $temp)
|
||||
bits=$(awk -F',' '{ print $3 }' <<< $temp)
|
||||
if grep -q bits <<< $bits; then
|
||||
curve="$(strip_spaces "$(awk -F',' '{ print $2 }' <<< $temp)")"
|
||||
else
|
||||
curve=""
|
||||
bits=$(awk -F',' '{ print $2 }' <<< $temp)
|
||||
fi
|
||||
bits="${bits/bits/}"
|
||||
bits="${bits// /}"
|
||||
if [[ "$what_dh" == "X25519" ]] || [[ "$what_dh" == "X448" ]]; then
|
||||
curve="$what_dh"
|
||||
what_dh="ECDH"
|
||||
fi
|
||||
if [[ "$what_dh" == "DH" ]]; then
|
||||
[[ ${minDhBits[i]} -ne -1 ]] && [[ $bits -lt ${minDhBits[i]} ]] && sclient_success=1
|
||||
[[ ${maxDhBits[i]} -ne -1 ]] && [[ $bits -gt ${maxDhBits[i]} ]] && sclient_success=1
|
||||
fi
|
||||
fi
|
||||
if [[ $sclient_success -ne 0 ]]; then
|
||||
outln "No connection"
|
||||
fileout "client_${short[i]}" "INFO" "$(strip_spaces "${names[i]}") client simulation: No connection"
|
||||
else
|
||||
proto=$(get_protocol $TMPFILE)
|
||||
# hack:
|
||||
[[ "$proto" == TLSv1 ]] && proto="TLSv1.0"
|
||||
[[ "$proto" == SSLv3 ]] && proto="SSLv3 "
|
||||
if [[ "$proto" == TLSv1.2 ]] && ( ! "$using_sockets" || [[ -z "${handshakebytes[i]}" ]] ); then
|
||||
# OpenSSL reports TLS1.2 even if the connection is TLS1.1 or TLS1.0. Need to figure out which one it is...
|
||||
for tls in ${tlsvers[i]}; do
|
||||
debugme echo "$OPENSSL s_client $tls -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} </dev/null"
|
||||
$OPENSSL s_client $tls -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} </dev/null >$TMPFILE 2>$ERRFILE
|
||||
sclient_connect_successful $? $TMPFILE
|
||||
if ${current[i]} ; then
|
||||
# for ANY we test this service or if the service we determined from STARTTLS matches
|
||||
if [[ "${service[i]}" == "ANY" ]] || grep -q "$client_service" <<< "${service[i]}"; then
|
||||
out " $(printf -- "%-33s" "${names[i]}")"
|
||||
if "$using_sockets" && [[ -n "${handshakebytes[i]}" ]]; then
|
||||
client_simulation_sockets "${handshakebytes[i]}"
|
||||
sclient_success=$?
|
||||
if [[ $sclient_success -eq 0 ]]; then
|
||||
case "$tls" in
|
||||
"-tls1_2")
|
||||
break
|
||||
;;
|
||||
"-tls1_1")
|
||||
proto="TLSv1.1"
|
||||
break
|
||||
;;
|
||||
"-tls1")
|
||||
proto="TLSv1.0"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
if [[ "0x${DETECTED_TLS_VERSION}" -lt ${lowest_protocol[i]} ]] || \
|
||||
[[ "0x${DETECTED_TLS_VERSION}" -gt ${highest_protocol[i]} ]]; then
|
||||
sclient_success=1
|
||||
fi
|
||||
[[ $sclient_success -eq 0 ]] && cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE >$ERRFILE
|
||||
fi
|
||||
done
|
||||
fi
|
||||
cipher=$(get_cipher $TMPFILE)
|
||||
if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]] && ( [[ "$cipher" == TLS_* ]] || [[ "$cipher" == SSL_* ]] ); then
|
||||
cipher="$(rfc2openssl "$cipher")"
|
||||
[[ -z "$cipher" ]] && cipher=$(get_cipher $TMPFILE)
|
||||
elif [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]] && [[ "$cipher" != TLS_* ]] && [[ "$cipher" != SSL_* ]]; then
|
||||
cipher="$(openssl2rfc "$cipher")"
|
||||
[[ -z "$cipher" ]] && cipher=$(get_cipher $TMPFILE)
|
||||
fi
|
||||
if ! "$WIDE"; then
|
||||
out "$proto $cipher"
|
||||
elif [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]]; then
|
||||
out "$(printf -- "%-7s %-33s" "$proto" "$cipher")"
|
||||
else
|
||||
out "$(printf -- "%-7s %-49s" "$proto" "$cipher")"
|
||||
fi
|
||||
if ! "$WIDE"; then
|
||||
"$using_sockets" && [[ -n "${handshakebytes[i]}" ]] && has_dh_bits=$HAS_DH_BITS && HAS_DH_BITS=true
|
||||
"$HAS_DH_BITS" && read_dhbits_from_file $TMPFILE
|
||||
"$using_sockets" && [[ -n "${handshakebytes[i]}" ]] && HAS_DH_BITS=$has_dh_bits
|
||||
elif [[ -n "$what_dh" ]]; then
|
||||
[[ -n "$curve" ]] && curve="($curve)"
|
||||
if [[ "$what_dh" == "ECDH" ]]; then
|
||||
pr_ecdh_quality "$bits" "$(printf -- "%-12s" "$bits bit $what_dh") $curve"
|
||||
else
|
||||
pr_dh_quality "$bits" "$(printf -- "%-12s" "$bits bit $what_dh") $curve"
|
||||
! "$HAS_NO_SSL2" && protos[i]="$(sed 's/-no_ssl2//' <<< "${protos[i]}")"
|
||||
debugme echo "$OPENSSL s_client -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} </dev/null"
|
||||
$OPENSSL s_client -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} </dev/null >$TMPFILE 2>$ERRFILE
|
||||
sclient_connect_successful $? $TMPFILE
|
||||
sclient_success=$?
|
||||
fi
|
||||
elif "$HAS_DH_BITS" || ( "$using_sockets" && [[ -n "${handshakebytes[i]}" ]] ); then
|
||||
out "No FS"
|
||||
fi
|
||||
outln
|
||||
if [[ -n "${warning[i]}" ]]; then
|
||||
out " "
|
||||
outln "${warning[i]}"
|
||||
fi
|
||||
fileout "client_${short[i]}" "INFO" \
|
||||
"$(strip_spaces "${names[i]}") client simulation: $proto $cipher ${warning[i]}"
|
||||
debugme cat $TMPFILE
|
||||
fi
|
||||
if [[ $sclient_success -eq 0 ]]; then
|
||||
# If an ephemeral DH key was used, check that the number of bits is within range.
|
||||
temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TMPFILE") # extract line
|
||||
what_dh=$(awk -F',' '{ print $1 }' <<< $temp)
|
||||
bits=$(awk -F',' '{ print $3 }' <<< $temp)
|
||||
if grep -q bits <<< $bits; then
|
||||
curve="$(strip_spaces "$(awk -F',' '{ print $2 }' <<< $temp)")"
|
||||
else
|
||||
curve=""
|
||||
bits=$(awk -F',' '{ print $2 }' <<< $temp)
|
||||
fi
|
||||
bits="${bits/bits/}"
|
||||
bits="${bits// /}"
|
||||
if [[ "$what_dh" == "X25519" ]] || [[ "$what_dh" == "X448" ]]; then
|
||||
curve="$what_dh"
|
||||
what_dh="ECDH"
|
||||
fi
|
||||
if [[ "$what_dh" == "DH" ]]; then
|
||||
[[ ${minDhBits[i]} -ne -1 ]] && [[ $bits -lt ${minDhBits[i]} ]] && sclient_success=1
|
||||
[[ ${maxDhBits[i]} -ne -1 ]] && [[ $bits -gt ${maxDhBits[i]} ]] && sclient_success=1
|
||||
fi
|
||||
fi
|
||||
if [[ $sclient_success -ne 0 ]]; then
|
||||
outln "No connection"
|
||||
fileout "client_${short[i]}" "INFO" "$(strip_spaces "${names[i]}") client simulation: No connection"
|
||||
else
|
||||
proto=$(get_protocol $TMPFILE)
|
||||
# hack:
|
||||
[[ "$proto" == TLSv1 ]] && proto="TLSv1.0"
|
||||
[[ "$proto" == SSLv3 ]] && proto="SSLv3 "
|
||||
if [[ "$proto" == TLSv1.2 ]] && ( ! "$using_sockets" || [[ -z "${handshakebytes[i]}" ]] ); then
|
||||
# OpenSSL reports TLS1.2 even if the connection is TLS1.1 or TLS1.0. Need to figure out which one it is...
|
||||
for tls in ${tlsvers[i]}; do
|
||||
debugme echo "$OPENSSL s_client $tls -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} </dev/null"
|
||||
$OPENSSL s_client $tls -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} </dev/null >$TMPFILE 2>$ERRFILE
|
||||
sclient_connect_successful $? $TMPFILE
|
||||
sclient_success=$?
|
||||
if [[ $sclient_success -eq 0 ]]; then
|
||||
case "$tls" in
|
||||
"-tls1_2")
|
||||
break
|
||||
;;
|
||||
"-tls1_1")
|
||||
proto="TLSv1.1"
|
||||
break
|
||||
;;
|
||||
"-tls1")
|
||||
proto="TLSv1.0"
|
||||
break
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
fi
|
||||
cipher=$(get_cipher $TMPFILE)
|
||||
if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]] && ( [[ "$cipher" == TLS_* ]] || [[ "$cipher" == SSL_* ]] ); then
|
||||
cipher="$(rfc2openssl "$cipher")"
|
||||
[[ -z "$cipher" ]] && cipher=$(get_cipher $TMPFILE)
|
||||
elif [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]] && [[ "$cipher" != TLS_* ]] && [[ "$cipher" != SSL_* ]]; then
|
||||
cipher="$(openssl2rfc "$cipher")"
|
||||
[[ -z "$cipher" ]] && cipher=$(get_cipher $TMPFILE)
|
||||
fi
|
||||
if ! "$WIDE"; then
|
||||
out "$proto $cipher"
|
||||
elif [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]]; then
|
||||
out "$(printf -- "%-7s %-33s" "$proto" "$cipher")"
|
||||
else
|
||||
out "$(printf -- "%-7s %-49s" "$proto" "$cipher")"
|
||||
fi
|
||||
if ! "$WIDE"; then
|
||||
"$using_sockets" && [[ -n "${handshakebytes[i]}" ]] && has_dh_bits=$HAS_DH_BITS && HAS_DH_BITS=true
|
||||
"$HAS_DH_BITS" && read_dhbits_from_file $TMPFILE
|
||||
"$using_sockets" && [[ -n "${handshakebytes[i]}" ]] && HAS_DH_BITS=$has_dh_bits
|
||||
elif [[ -n "$what_dh" ]]; then
|
||||
[[ -n "$curve" ]] && curve="($curve)"
|
||||
if [[ "$what_dh" == "ECDH" ]]; then
|
||||
pr_ecdh_quality "$bits" "$(printf -- "%-12s" "$bits bit $what_dh") $curve"
|
||||
else
|
||||
pr_dh_quality "$bits" "$(printf -- "%-12s" "$bits bit $what_dh") $curve"
|
||||
fi
|
||||
elif "$HAS_DH_BITS" || ( "$using_sockets" && [[ -n "${handshakebytes[i]}" ]] ); then
|
||||
out "No FS"
|
||||
fi
|
||||
outln
|
||||
if [[ -n "${warning[i]}" ]]; then
|
||||
out " "
|
||||
outln "${warning[i]}"
|
||||
fi
|
||||
fileout "client_${short[i]}" "INFO" \
|
||||
"$(strip_spaces "${names[i]}") client simulation: $proto $cipher ${warning[i]}"
|
||||
debugme cat $TMPFILE
|
||||
fi
|
||||
fi # correct service?
|
||||
fi #current?
|
||||
i=$((i+1))
|
||||
done
|
||||
tmpfile_handle $FUNCNAME.txt
|
||||
|
341
utils/update_client_sim_data.pl
Executable file
341
utils/update_client_sim_data.pl
Executable file
@ -0,0 +1,341 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use Data::Dumper;
|
||||
use JSON;
|
||||
|
||||
my $namelength = 30;
|
||||
|
||||
my @spec;
|
||||
my %ciphers;
|
||||
foreach my $line ( split /\n/, `../bin/openssl.Linux.x86_64 ciphers -V 'ALL:COMPLEMENTOFALL:\@STRENGTH'`) {
|
||||
my @fields = split /\s+/, $line;
|
||||
my $hex = "";
|
||||
foreach my $byte ( split /,/, $fields[1] ) {
|
||||
$byte = lc $byte;
|
||||
$byte =~ s/^0x//;
|
||||
$hex .= $byte;
|
||||
}
|
||||
$hex =~ s/^0+//;
|
||||
$ciphers{hex "0x$hex"} = $fields[3];
|
||||
}
|
||||
|
||||
# Get the data
|
||||
my $json = `curl 'https://api.dev.ssllabs.com/api/v3/getClients'`;
|
||||
my $ssllabs = decode_json($json);
|
||||
|
||||
my %sims;
|
||||
foreach my $client ( @$ssllabs ) {
|
||||
# Shorts
|
||||
my $has_matched = 1;
|
||||
my $shortname = "$client->{name}_$client->{version}";
|
||||
$shortname =~ s/ /_/g;
|
||||
$shortname =~ s/\.//g;
|
||||
$shortname .= "_$client->{platform}" if exists $client->{platform};
|
||||
$shortname =~ s/[ \.]//g;
|
||||
$shortname = lc($shortname);
|
||||
|
||||
# Deduplicate
|
||||
if ( ! exists $sims{$shortname} || $sims{$shortname}->{id} < $client->{id} ) {
|
||||
my $sim = {};
|
||||
$sims{$shortname} = $sim;
|
||||
$sim->{shortname} = "short+=(\"$shortname\")";
|
||||
|
||||
# Names
|
||||
my $name = "$client->{name} $client->{version}";
|
||||
$name .= " $client->{platform}" if exists $client->{platform};
|
||||
# Get first namelength characters only
|
||||
$name = substr($name . "" x $namelength,0,$namelength);
|
||||
$sim->{name} = "names+=(\"$name\")";
|
||||
|
||||
# Ciphers
|
||||
my @ciphers = ();
|
||||
foreach my $suite ( @{$client->{suiteIds}} ) {
|
||||
if ( exists $ciphers{$suite} ) {
|
||||
push @ciphers, $ciphers{$suite}; }
|
||||
elsif ( $suite == "255" ) {
|
||||
# no openssl name for this:
|
||||
if ( $has_matched ) {
|
||||
print "Ignored: \"$shortname\" has" ;
|
||||
$has_matched = 0;
|
||||
}
|
||||
print " \"0xFF\""; }
|
||||
elsif ( $suite == "65279" ) {
|
||||
# SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA
|
||||
if ( $has_matched ) {
|
||||
print "Ignored: \"$shortname\" has" ;
|
||||
$has_matched = 0;
|
||||
}
|
||||
print " \"0xFEFF\""; }
|
||||
elsif ( $suite == "52392" ) {
|
||||
push @ciphers, "ECDHE-RSA-CHACHA20-POLY1305"; }
|
||||
elsif ( $suite == "52393" ) {
|
||||
push @ciphers, "ECDHE-ECDSA-CHACHA20-POLY1305"; }
|
||||
elsif ( $suite == "52394" ) {
|
||||
push @ciphers, "DHE-RSA-CHACHA20-POLY1305"; }
|
||||
else {
|
||||
print "ALERT: ";
|
||||
if ( $has_matched ) {
|
||||
print " \"$shortname\" has ";
|
||||
$has_matched = 0;
|
||||
}
|
||||
print "$suite. Please FIXME ";
|
||||
}
|
||||
}
|
||||
print "\n" if ! $has_matched ;
|
||||
$sim->{ciphers} = "ciphers+=(\"" . (join ":", @ciphers) . "\")";
|
||||
|
||||
# SNI
|
||||
if ( exists $client->{supportsSni} && $client->{supportsSni} ) {
|
||||
$sim->{sni} = "sni+=(\"\$SNI\")";
|
||||
} else {
|
||||
$sim->{sni} = "sni+=(\"\")";
|
||||
}
|
||||
|
||||
# warning (if needed)
|
||||
$sim->{warning} = "warning+=(\"\")";
|
||||
|
||||
# Handshake
|
||||
if ( exists $client->{hexHandshakeBytes} ) {
|
||||
$sim->{handshakebytes} = "handshakebytes+=(\"$client->{hexHandshakeBytes}\")";
|
||||
} else {
|
||||
$sim->{handshakebytes} = "handshakebytes+=(\"\")";
|
||||
}
|
||||
|
||||
# protos
|
||||
my @proto_flags = ();
|
||||
my @tls_flags = ();
|
||||
# Figure out if we need to support sslv2
|
||||
if ( $client->{lowestProtocol} < 768 && $client->{highestProtocol} >= 512 ) {
|
||||
# 512 = 0x200 = sslv2
|
||||
# 768 = 0x300 = sslv3
|
||||
push @proto_flags, "-ssl2";
|
||||
}
|
||||
# Do we need to support SSL3?
|
||||
if ( $client->{lowestProtocol} <= 768 && $client->{highestProtocol} >= 768 ) {
|
||||
# 768 = 0x300 = sslv3
|
||||
push @proto_flags, "-ssl3";
|
||||
}
|
||||
# Do we need to support TLS 1.0?
|
||||
if ( $client->{lowestProtocol} <= 769 && $client->{highestProtocol} >= 769 ) {
|
||||
# 769 = 0x301 = tls1.0
|
||||
push @proto_flags, "-tls1";
|
||||
}
|
||||
# Do we need to support TLS 1.1?
|
||||
if ( $client->{lowestProtocol} <= 770 && $client->{highestProtocol} >= 770 ) {
|
||||
# 770 = 0x302 = tls1.1
|
||||
push @proto_flags, "-tls1_1";
|
||||
}
|
||||
# Do we need to support TLS 1.2?
|
||||
if ( $client->{lowestProtocol} <= 771 && $client->{highestProtocol} >= 771 ) {
|
||||
# 771 = 0x303 = tls1.2
|
||||
push @proto_flags, "-tls1_2";
|
||||
}
|
||||
$sim->{protos} = "protos+=(\"" . (join " ", reverse @proto_flags) . "\")";
|
||||
$sim->{lowestProtocol} = sprintf("lowest_protocol+=(\"0x%04x\")", $client->{lowestProtocol});
|
||||
$sim->{highestProtocol} = sprintf("highest_protocol+=(\"0x%04x\")", $client->{highestProtocol});
|
||||
|
||||
if ( lc($client->{name}) eq "java" || lc($client->{name}) eq "openssl" ) {
|
||||
# Java and OpenSSL are generic clients
|
||||
$sim->{service} = "service+=(\"ANY\")";
|
||||
} elsif ( $shortname =~ /^apple_ats/ ) {
|
||||
# Apple ATS is HTTP(s) only
|
||||
$sim->{service} = "service+=(\"HTTP\")";
|
||||
} else {
|
||||
# All others are HTTP(s)/FTP only
|
||||
$sim->{service} = "service+=(\"HTTP,FTP\")";
|
||||
}
|
||||
|
||||
# Bit size limitations
|
||||
$sim->{minDhBits} = "minDhBits+=($client->{minDhBits})";
|
||||
$sim->{maxDhBits} = "maxDhBits+=($client->{maxDhBits})";
|
||||
$sim->{minRsaBits} = "minRsaBits+=($client->{minRsaBits})";
|
||||
$sim->{maxRsaBits} = "maxRsaBits+=($client->{maxRsaBits})";
|
||||
$sim->{minEcdsaBits} = "minEcdsaBits+=($client->{minEcdsaBits})";
|
||||
if ( defined $client->{requiresSha2} && $client->{requiresSha2} ) {
|
||||
$sim->{requiresSha2} = "requiresSha2+=(true)";
|
||||
} else {
|
||||
$sim->{requiresSha2} = "requiresSha2+=(false)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# This is where we maintain our own clients
|
||||
my $sim = {};
|
||||
#$sim->{name} = "names+=(\"Mail iOS 9.3.2 \")";
|
||||
#$sim->{shortname} = "short+=(\"mail_ios_932\")";
|
||||
#$sim->{ciphers} = "ciphers+=(\"ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:RC4-SHA:RC4-MD5\")";
|
||||
#$sim->{sni} = "sni+=(\"\$SNI\")";
|
||||
#$sim->{warning} = "warning+=(\"\")";
|
||||
#$sim->{handshakebytes} = "handshakebytes+=(\"16030100bb010000b703015767e6ae46f9abf3138e26a9f9880f9697bf3387f7eff709db1fa220e692d80420fb04b0979bae1664e11ef172d4dfba15af59dd200b7831992a35c73cde9efed9003200ffc024c023c00ac009c008c028c027c014c013c012006b0067003900330016003d003c0035002f000ac007c011000500040100003c000000190017000014696d61702e73656374696f6e7a65726f2e6f7267000a00080006001700180019000b0002010000050005010000000000120000\")";
|
||||
#$sim->{protos} = "protos+=(\"#-tls1_1 -tls1\")";
|
||||
#$sim->{lowestProtocol} = "lowest_protocol+=(\"0x0300\")";
|
||||
#$sim->{highestProtocol} = "highest_protocol+=(\"0x0301\")";
|
||||
#$sim->{service} = "service+=(\"SMTP,POP,IMAP\")";
|
||||
#$sim->{minDhBits} = "minDhBits+=(-1)";
|
||||
#$sim->{maxDhBits} = "maxDhBits+=(-1)";
|
||||
#$sim->{minRsaBits} = "minRsaBits+=(-1)";
|
||||
#$sim->{maxRsaBits} = "maxRsaBits+=(-1)";
|
||||
#$sim->{minEcdsaBits} = "minEcdsaBits+=(-1)";
|
||||
#$sim->{requiresSha2} = "requiresSha2+=(false)";
|
||||
#
|
||||
#$sim->{name} = "names+=(\"Mail OSX 10.11.15 \")";
|
||||
#$sim->{shortname} = "short+=(\"mail_osx_101115\")";
|
||||
#$sim->{ciphers} = "ciphers+=(\"ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:RC4-SHA:RC4-MD5\")";
|
||||
#$sim->{sni} = "sni+=(\"\$SNI\")";
|
||||
#$sim->{warning} = "warning+=(\"\")";
|
||||
#$sim->{handshakebytes} = "handshakebytes+=(\"16030100940100009003015770e928499e82df2eb7477200e2a828d9fa4109514385bd1602df44aaf2b0f400003200ffc024c023c00ac009c008c028c027c014c013c012006b0067003900330016003d003c0035002f000ac007c011000500040100003500000012001000000d3137382e3233372e33342e3932000a00080006001700180019000b0002010000050005010000000000120000\")";
|
||||
#$sim->{protos} = "protos+=(\"-tls1\")";
|
||||
#$sim->{lowestProtocol} = "lowest_protocol+=(\"0x0301\")";
|
||||
#$sim->{highestProtocol} = "highest_protocol+=(\"0x0301\")";
|
||||
#$sim->{service} = "service+=(\"SMTP,POP,IMAP\")";
|
||||
#$sim->{minDhBits} = "minDhBits+=(-1)";
|
||||
#$sim->{maxDhBits} = "maxDhBits+=(-1)";
|
||||
#$sim->{minRsaBits} = "minRsaBits+=(-1)";
|
||||
#$sim->{maxRsaBits} = "maxRsaBits+=(-1)";
|
||||
#$sim->{minEcdsaBits} = "minEcdsaBits+=(-1)";
|
||||
#$sim->{requiresSha2} = "requiresSha2+=(false)";
|
||||
|
||||
$sim->{name} = "names+=(\"Thunderbird 45.1.1 OSX 10.11 \")";
|
||||
$sim->{shortname} = "short+=(\"thunderbird_45.1.1_osx_101115\")";
|
||||
$sim->{ciphers} = "ciphers+=(\"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA\")";
|
||||
$sim->{sni} = "sni+=(\"\$SNI\")";
|
||||
$sim->{warning} = "warning+=(\"\")";
|
||||
$sim->{handshakebytes} = "handshakebytes+=(\"160301009d010000990303c7c5b3ff80b3aa597c770c538b98ae34a94c9590ad8f947ba7bc28692061cb57000016c02bc02fc00ac009c013c01400330039002f0035000a0100005a0000001800160000136d78332e73656374696f6e7a65726f2e6f7267ff01000100000a00080006001700180019000b0002010000230000000500050100000000000d001600140401050106010201040305030603020304020202\")";
|
||||
$sim->{protos} = "protos+=(\"-tls1_2 -tls1_1 -tls1\")";
|
||||
$sim->{lowestProtocol} = "lowest_protocol+=(\"0x0301\")";
|
||||
$sim->{highestProtocol} = "highest_protocol+=(\"0x0303\")";
|
||||
$sim->{service} = "service+=(\"SMTP,POP,IMAP\")";
|
||||
$sim->{minDhBits} = "minDhBits+=(-1)";
|
||||
$sim->{maxDhBits} = "maxDhBits+=(-1)";
|
||||
$sim->{minRsaBits} = "minRsaBits+=(-1)";
|
||||
$sim->{maxRsaBits} = "maxRsaBits+=(-1)";
|
||||
$sim->{minEcdsaBits} = "minEcdsaBits+=(-1)";
|
||||
$sim->{requiresSha2} = "requiresSha2+=(false)";
|
||||
|
||||
my %count;
|
||||
foreach my $shortname ( reverse sort keys %sims ) {
|
||||
if ( $shortname =~ /^baidu/ ) {
|
||||
$count{baidu}++;
|
||||
if ( $count{baidu} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^bing/) {
|
||||
$count{bing}++;
|
||||
if ( $count{bing} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^chrome/) {
|
||||
$count{chrome}++;
|
||||
if ( $count{chrome} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^firefox/) {
|
||||
# Latest version + ESR releases
|
||||
if ( $shortname =~ /ESR/ ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$count{firefox}++;
|
||||
if ( $count{firefox} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
}
|
||||
} elsif ($shortname =~ /^googlebot/) {
|
||||
$count{googlebot}++;
|
||||
if ( $count{googlebot} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^tor/) {
|
||||
$count{tor}++;
|
||||
if ( $count{tor} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^yahoo/) {
|
||||
$count{yahoo}++;
|
||||
if ( $count{yahoo} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^yandex/) {
|
||||
$count{yandex}++;
|
||||
if ( $count{yandex} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^opera/) {
|
||||
$count{opera}++;
|
||||
if ( $count{opera} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^java 7/) {
|
||||
$count{java7}++;
|
||||
if ( $count{java7} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^java 8/) {
|
||||
$count{java8}++;
|
||||
if ( $count{java8} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^java/) {
|
||||
# Other/older versions of java aren't current
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
} elsif ($shortname =~ /^openssl/) {
|
||||
$count{openssl}++;
|
||||
if ( $count{openssl} <= 1 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} elsif ($shortname =~ /^safari/) {
|
||||
$count{safari}++;
|
||||
if ( $count{safari} <= 2 ) {
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
} else {
|
||||
$sims{$shortname}->{current} = "current+=(false)";
|
||||
}
|
||||
} else {
|
||||
# All versions are current
|
||||
$sims{$shortname}->{current} = "current+=(true)";
|
||||
}
|
||||
}
|
||||
|
||||
open OUT, ">client-simulation-data.sh" or die "Unable to open client-simulation-data.sh";
|
||||
print OUT "#!/usr/bin/env bash
|
||||
|
||||
# This file contains client handshake data used in the run_client_simulation function
|
||||
# Don't update this file by hand, but run util/update_client_sim_data.pl instead
|
||||
|
||||
# Most clients are taken from Qualys SSL Labs --- From: https://api.dev.ssllabs.com/api/v3/getClients
|
||||
";
|
||||
foreach my $shortname ( sort keys %sims ) {
|
||||
foreach my $k ( qw(name shortname ciphers sni warning handshakebytes protos lowestProtocol highestProtocol service
|
||||
minDhBits maxDhBits minRsaBits maxRsaBits minEcdsaBits requiresSha2 current) ) {
|
||||
print OUT " $sims{$shortname}->{$k}\n";
|
||||
}
|
||||
print OUT "\n";
|
||||
}
|
||||
close OUT;
|
||||
|
||||
exit;
|
43
utils/wireshark2ciphers.pl
Executable file
43
utils/wireshark2ciphers.pl
Executable file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use Data::Dumper;
|
||||
use JSON;
|
||||
|
||||
my $namelength = 30;
|
||||
|
||||
# Get all ciphers first (sorry only works on 64 bit mac atm)
|
||||
my @spec;
|
||||
my %ciphers;
|
||||
foreach my $line ( split /\n/, `bin/openssl.Darwin.x86_64 ciphers -V 'ALL:COMPLEMENTOFALL:\@STRENGTH'`) {
|
||||
my @fields = split /\s+/, $line;
|
||||
my $hex = "";
|
||||
foreach my $byte ( split /,/, $fields[1] ) {
|
||||
$byte = lc $byte;
|
||||
$byte =~ s/^0x//;
|
||||
$hex .= $byte;
|
||||
}
|
||||
$hex =~ s/^0+//;
|
||||
$ciphers{"0x$hex"} = $fields[3];
|
||||
}
|
||||
#die Dumper \%ciphers;
|
||||
#exit;
|
||||
|
||||
my @ciphers = ();
|
||||
while (<>) {
|
||||
if ( /^\s*Cipher Suite\:/ ) {
|
||||
/\((0x[0-9a-f]+)\)\s*$/;
|
||||
my $n = $1;
|
||||
$n =~ s/0x0*/0x/;
|
||||
if ( $n && exists $ciphers{$n} ) {
|
||||
push @ciphers, $ciphers{$n};
|
||||
} else {
|
||||
print STDERR "No matching cipher for: $n on line\n$_"
|
||||
}
|
||||
} else {
|
||||
print STDERR "Ignoring line $_"
|
||||
}
|
||||
}
|
||||
|
||||
print "\n\n" . join ":", @ciphers;
|
||||
print "\n";
|
Loading…
Reference in New Issue
Block a user