mirror of
https://github.com/drwetter/testssl.sh.git
synced 2025-01-05 16:29:45 +01:00
Fixes related to session tickets and resumption
This commit fixes a the regression "Session Ticket RFC 5077 hint missing/incomplete" #1218. Reason was that in some case where the ticket lifetime hint was not restrieved before, later $OPENSSL s_client -connect with -cipher ALL:COMPLEMENTOFALL didn't get the ticket either. Just using "$OPTIMAL_PROTO" instead of -cipher ALL:COMPLEMENTOFALL fixed it in the cases tested so far. Then a global variable is instroduced -- TLS_TICKETS. Which keeps in any case the state whether session tickets are supported. This is being used to fix #1089. It remains a bit unclear what is meant in https://tools.ietf.org/html/rfc5077#section-5.6 by "TLS clients MAY be given a hint of the lifetime of the ticket". We use this information to chck for resumption by ticket which seems realistically the best solution. Sessin resumption was also made a bit more reliably: The ServerHello is now being tested for "New" also. If this and "Reused" wasn't detected, an error is raised. In general we could do better in keeping and reusing information of a ServerHello in TMPDIR.
This commit is contained in:
parent
bc6b2c6f94
commit
ae7b8988b9
51
testssl.sh
51
testssl.sh
@ -296,6 +296,7 @@ TEMPDIR=""
|
||||
TMPFILE=""
|
||||
ERRFILE=""
|
||||
CLIENT_AUTH=false
|
||||
TLS_TICKETS=false
|
||||
NO_SSL_SESSIONID=false
|
||||
HOSTCERT="" # File with host certificate, without intermediate certificate
|
||||
HEADERFILE=""
|
||||
@ -5845,13 +5846,21 @@ read_dhbits_from_file() {
|
||||
}
|
||||
|
||||
|
||||
# arg1: ID or empty. if empty resumption by ticket will be tested
|
||||
# arg1: ID or empty. If empty resumption by ticket will be tested, otherwise by ID
|
||||
# return: 0: it has resumption, 1:nope, 2: nope (OpenSSL 1.1.1), 6: CLIENT_AUTH --> problem for resumption, 7: can't tell
|
||||
#
|
||||
# This is basically a short(?) version from Bulletproof SSL and TLS (p386). The version according to that would be e.g.
|
||||
# echo | $OPENSSL s_client -connect testssl.sh:443 -servername testssl.sh -no_ssl2 -reconnect 2>&1 | grep -E 'New|Reused'
|
||||
# echo | $OPENSSL s_client -connect testssl.sh:443 -servername testssl.sh -no_ssl2 -no_ticket -reconnect 2>&1 | grep -E 'New|Reused|Session-ID'
|
||||
#
|
||||
# FIXME: actually Ivan's version seems faster. Worth to check and since when -reconnect is a/v
|
||||
#
|
||||
sub_session_resumption() {
|
||||
local ret ret1 ret2
|
||||
local tmpfile=$(mktemp $TEMPDIR/session_resumption.$NODEIP.XXXXXX)
|
||||
local sess_data=$(mktemp $TEMPDIR/sub_session_data_resumption.$NODEIP.XXXXXX)
|
||||
local -a rw_line
|
||||
local not_new_reused=false
|
||||
|
||||
if [[ "$1" == ID ]]; then
|
||||
local byID=true
|
||||
@ -5859,6 +5868,9 @@ sub_session_resumption() {
|
||||
else
|
||||
local byID=false
|
||||
local addcmd=""
|
||||
if ! "$TLS_TICKETS"; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
"$CLIENT_AUTH" && return 3
|
||||
"$HAS_NO_SSL2" && addcmd+=" -no_ssl2" || addcmd+=" $OPTIMAL_PROTO"
|
||||
@ -5884,7 +5896,17 @@ sub_session_resumption() {
|
||||
debugme echo -n "Couldn't connect #2 "
|
||||
return 7
|
||||
fi
|
||||
# now get the line and compare the numbers read" and "written" as a second criteria.
|
||||
# "Reused" indicates session material was reused, "New": not
|
||||
if grep -aq "^Reused" "$tmpfile"; then
|
||||
new_sid=false
|
||||
elif grep -aq "^New" "$tmpfile"; then
|
||||
new_sid=true
|
||||
else
|
||||
debugme echo -n "Problem with 2nd ServerHello "
|
||||
not_new_reused=true
|
||||
fi
|
||||
# Now get the line and compare the numbers "read" and "written" as a second criteria.
|
||||
# If the "read" number is bigger: a new session ID was probably used
|
||||
rw_line="$(awk '/^SSL handshake has read/ { print $5" "$(NF-1) }' "$tmpfile" )"
|
||||
rw_line=($rw_line)
|
||||
if [[ "${rw_line[0]}" -gt "${rw_line[1]}" ]]; then
|
||||
@ -5893,8 +5915,7 @@ sub_session_resumption() {
|
||||
new_sid2=false
|
||||
fi
|
||||
debugme echo "${rw_line[0]}, ${rw_line[1]}"
|
||||
# grep -aq "^New" "$tmpfile" && new_sid=true || new_sid=false
|
||||
grep -aq "^Reused" "$tmpfile" && new_sid=false || new_sid=true
|
||||
|
||||
if "$new_sid2" && "$new_sid"; then
|
||||
debugme echo -n "No session resumption "
|
||||
ret=1
|
||||
@ -7689,11 +7710,11 @@ certificate_transparency() {
|
||||
# server's certificate. If they aren't, check whether the server provided
|
||||
# a stapled OCSP response with SCTs. If no SCTs were found in the certificate
|
||||
# or OCSP response, check for an SCT TLS extension.
|
||||
if [[ "$cert_txt" =~ "CT Precertificate SCTs" ]] || [[ "$cert_txt" =~ '1.3.6.1.4.1.11129.2.4.2' ]]; then
|
||||
if [[ "$cert_txt" =~ CT\ Precertificate\ SCTs ]] || [[ "$cert_txt" =~ '1.3.6.1.4.1.11129.2.4.2' ]]; then
|
||||
tm_out "certificate extension"
|
||||
return 0
|
||||
fi
|
||||
if [[ "$ocsp_response" =~ "CT Certificate SCTs" ]] || [[ "$ocsp_response" =~ '1.3.6.1.4.1.11129.2.4.5' ]]; then
|
||||
if [[ "$ocsp_response" =~ CT\ Certificate\ SCTs ]] || [[ "$ocsp_response" =~ '1.3.6.1.4.1.11129.2.4.5' ]]; then
|
||||
tm_out "OCSP extension"
|
||||
return 0
|
||||
fi
|
||||
@ -7708,11 +7729,11 @@ certificate_transparency() {
|
||||
fi
|
||||
|
||||
if [[ $number_of_certificates -gt 1 ]] && ! "$SSL_NATIVE"; then
|
||||
if [[ "$tls_version" == "0304" ]]; then
|
||||
if [[ "$tls_version" == 0304 ]]; then
|
||||
ciphers=", 13,01, 13,02, 13,03, 13,04, 13,05"
|
||||
if [[ "$cipher" == "tls1_3_RSA" ]]; then
|
||||
if [[ "$cipher" == tls1_3_RSA ]]; then
|
||||
extra_extns=", 00,0d,00,10,00,0e,08,04,08,05,08,06,04,01,05,01,06,01,02,01"
|
||||
elif [[ "$cipher" == "tls1_3_ECDSA" ]]; then
|
||||
elif [[ "$cipher" == tls1_3_ECDSA ]]; then
|
||||
extra_extns=", 00,0d,00,0a,00,08,04,03,05,03,06,03,02,03"
|
||||
else
|
||||
return 1
|
||||
@ -8772,15 +8793,17 @@ run_server_defaults() {
|
||||
done
|
||||
|
||||
determine_tls_extensions
|
||||
|
||||
if [[ $? -eq 0 ]] && [[ "$OPTIMAL_PROTO" != -ssl2 ]]; then
|
||||
cp "$TEMPDIR/$NODEIP.determine_tls_extensions.txt" $TMPFILE
|
||||
>$ERRFILE
|
||||
[[ -z "$sessticket_lifetime_hint" ]] && sessticket_lifetime_hint=$(awk '/session ticket lifetime/' $TMPFILE)
|
||||
fi
|
||||
if "$using_sockets" && [[ -z "$sessticket_lifetime_hint" ]] && [[ "$OPTIMAL_PROTO" != -ssl2 ]]; then
|
||||
$OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -cipher ALL:COMPLEMENTOFALL -connect $NODEIP:$PORT $PROXY $SNI") </dev/null 2>$ERRFILE >$TMPFILE
|
||||
$OPENSSL s_client $(s_client_options "$STARTTLS $BUGS "$OPTIMAL_PROTO" -connect $NODEIP:$PORT $PROXY $SNI") </dev/null 2>$ERRFILE >$TMPFILE
|
||||
sclient_connect_successful $? $TMPFILE && sessticket_lifetime_hint=$(awk '/session ticket lifetime/' $TMPFILE)
|
||||
fi
|
||||
[[ -z "$sessticket_lifetime_hint" ]] && TLS_TICKETS=false || TLS_TICKETS=true
|
||||
|
||||
debugme echo "# certificates found $certs_found"
|
||||
# Now that all of the server's certificates have been found, determine for
|
||||
@ -8819,8 +8842,8 @@ run_server_defaults() {
|
||||
pr_bold " Session Ticket RFC 5077 hint "
|
||||
jsonID="TLS_session_ticket"
|
||||
if [[ -z "$sessticket_lifetime_hint" ]]; then
|
||||
outln "(no lifetime advertised)"
|
||||
fileout "${jsonID}" "INFO" "No lifetime advertised"
|
||||
outln "no -- no lifetime advertised"
|
||||
fileout "${jsonID}" "INFO" "no -- no lifetime advertised"
|
||||
# it MAY be given a hint of the lifetime of the ticket, see https://tools.ietf.org/html/rfc5077#section-5.6 .
|
||||
# Sometimes it just does not -- but it then may also support TLS session tickets reuse
|
||||
else
|
||||
@ -13513,15 +13536,15 @@ run_ccs_injection(){
|
||||
|
||||
sub_session_ticket_tls() {
|
||||
local sessticket_tls=""
|
||||
|
||||
#FIXME: we likely have done this already before (either @ run_server_defaults() or at least the output
|
||||
# from a previous handshake) --> would save 1x connect
|
||||
# from a previous handshake) --> would save 1x connect. We have TLS_TICKET but not yet the ticket itself #FIXME
|
||||
#ATTENTION: we DO NOT use SNI here as we assume ticketbleed is a vulnerability of the TLS stack. If we'd do SNI here, we'd also need
|
||||
# it in the ClientHello of run_ticketbleed() otherwise the ticket will be different and the whole thing won't work!
|
||||
#
|
||||
sessticket_tls="$($OPENSSL s_client $(s_client_options "$BUGS $OPTIMAL_PROTO $PROXY -connect $NODEIP:$PORT") </dev/null 2>$ERRFILE | awk '/TLS session ticket:/,/^$/' | awk '!/TLS session ticket/')"
|
||||
sessticket_tls="$(sed -e 's/^.* - /x/g' -e 's/ .*$//g' <<< "$sessticket_tls" | tr '\n' ',')"
|
||||
sed -e 's/ /,x/g' -e 's/-/,x/g' <<< "$sessticket_tls"
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user