From 8ec40871211e6882bc7aee0f59b7a06e4396bc0d Mon Sep 17 00:00:00 2001 From: David Cooper Date: Mon, 30 Sep 2019 16:33:17 -0400 Subject: [PATCH] Fix session ticket issues This PR fixes two issues with finding session tickets when using OpenSSL 1.1.1. First, if OpenSSL connects to the server using TLSv1.3 and it receives more than one Post-Handshake New Session Ticket, then the "TLS session ticket lifetime hint" will appear more than once in $TMPFILE. This will cause the line to appear more than once in $sessticket_lifetime_hint, which causes problems when trying to extract the $lifetime and $unit from $sessticket_lifetime_hint. This PR fixes the first problem by changing the awk expression in the lines that set sessticket_lifetime_hint so that only the first line with "session ticket lifetime" is extracted. The second issue is that some servers (e.g., google.com) return a session ticket for TLSv1.2, but not for TLSv1.3. For such servers, testssl.sh will miss the session ticket if $OPTIMAL_PROTO is empty or "-tls1_3" and the --ssl-native flag is not set. This PR addresses the second issue with the changes in lines 9047 - 9053 -- the code that is intended to provide a last chance to find a session ticket. If $OPENSSL supports TLSv.1.3 and the server returns session tickets for TLSv1.3 connections, then the session ticket would have already been found by get_server_certificate(), since get_server_certificate() uses $OPENSSL for TLSv1.3 if $OPENSSL supports TLSv1.3. So, in such circumstances, the code in liens 9047 - 9053 should not try again with TLSv1.3. So, if $OPENSSL supports TLSv1.3 and $OPTIMAL_PROTO is empty or is set to "-tls1_3" (either of which would result in a TLSv1.3 ClientHello), the "$OPENSSL s_client" call is changed to specify -no_tls1_3 rather than $OPTIMAL_PROTO. The code on line 9047 is also changed to only make this final try is $TLS13_ONLY is false. If $TLS13_ONLY is true, then either: * $OPENSSL does not support TLSv1.3 and the connection attempt would fail anyway; or * $OPENSSL supports TLSv1.3, in which case any session ticket would have been found by get_server_certificate(), since get_server_certificate() uses $OPENSSL for TLSv1.3 if $OPENSSL supports TLSv1.3. In either case, there is no reason to try again to find a session ticket. --- testssl.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index ff75faa..c809381 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8889,7 +8889,7 @@ run_server_defaults() { cp "$TEMPDIR/$NODEIP.get_server_certificate.txt" $TMPFILE >$ERRFILE if [[ -z "$sessticket_lifetime_hint" ]]; then - sessticket_lifetime_hint=$(awk '/session ticket life/' $TMPFILE) + sessticket_lifetime_hint=$(awk '/session ticket life/ { if (!found) print; found=1 }' $TMPFILE) fi if [[ $n -le 7 ]]; then @@ -9042,11 +9042,17 @@ run_server_defaults() { 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) + [[ -z "$sessticket_lifetime_hint" ]] && sessticket_lifetime_hint=$(awk '/session ticket lifetime/ { if (!found) print; found=1 }' $TMPFILE) fi - if "$using_sockets" && [[ -z "$sessticket_lifetime_hint" ]] && [[ "$OPTIMAL_PROTO" != -ssl2 ]]; then - $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS "$OPTIMAL_PROTO" -connect $NODEIP:$PORT $PROXY $SNI") $ERRFILE >$TMPFILE - sclient_connect_successful $? $TMPFILE && sessticket_lifetime_hint=$(awk '/session ticket lifetime/' $TMPFILE) + if "$using_sockets" && ! "$TLS13_ONLY" && [[ -z "$sessticket_lifetime_hint" ]] && [[ "$OPTIMAL_PROTO" != -ssl2 ]]; then + if "$HAS_TLS13" && ( [[ -z "$OPTIMAL_PROTO" ]] || [[ "$OPTIMAL_PROTO" == -tls1_3 ]] ) ; then + # If a session ticket were sent in response to a TLSv1.3 ClientHello, then a session ticket + # would have been found by get_server_certificate(). So, try again with a TLSv1.2 ClientHello. + $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -no_tls1_3 -connect $NODEIP:$PORT $PROXY $SNI") $ERRFILE >$TMPFILE + else + $OPENSSL s_client $(s_client_options "$STARTTLS $BUGS "$OPTIMAL_PROTO" -connect $NODEIP:$PORT $PROXY $SNI") $ERRFILE >$TMPFILE + fi + sclient_connect_successful $? $TMPFILE && sessticket_lifetime_hint=$(awk '/session ticket lifetime/ { if (!found) print; found=1 }' $TMPFILE) fi [[ -z "$sessticket_lifetime_hint" ]] && TLS_TICKETS=false || TLS_TICKETS=true