From 1c361b4a39d0db647e8e91a6215976544f4dfc53 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 20 Jan 2017 12:08:51 +0000 Subject: [PATCH] Add a capability for TLSProxy to wait for a session before killing s_client TLSProxy normally fires off s_client, which creates a connection to the server. TLSProxy also pipes some data to send to the process and s_client automatically exits when the pipe hits eof. Unfortunately this means that it sends the data and closes before it has processed the NewSessionTicket returned from the server in TLSv1.3. This commits adds an option for s_client to stay loaded until the sesion has been processed. A side effect of this is that s_client never sends a close_notify in this mode, so we count success as seeing that data has been transferred. Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/2259) --- util/TLSProxy/Message.pm | 17 ++++++++++++++++- util/TLSProxy/Proxy.pm | 31 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/util/TLSProxy/Message.pm b/util/TLSProxy/Message.pm index 99c3689ca2..ab90586952 100644 --- a/util/TLSProxy/Message.pm +++ b/util/TLSProxy/Message.pm @@ -74,6 +74,7 @@ use constant { EXT_EXTENDED_MASTER_SECRET => 23, EXT_SESSION_TICKET => 35, EXT_KEY_SHARE => 40, + EXT_PSK => 41, EXT_SUPPORTED_VERSIONS => 43, EXT_PSK_KEX_MODES => 45, EXT_RENEGOTIATE => 65281, @@ -99,6 +100,7 @@ my $end = 0; my @message_rec_list = (); my @message_frag_lens = (); my $ciphersuite = 0; +my $successondata = 0; sub clear { @@ -108,6 +110,7 @@ sub clear $server = 0; $success = 0; $end = 0; + $successondata = 0; @message_rec_list = (); @message_frag_lens = (); } @@ -219,6 +222,11 @@ sub get_messages } elsif ($record->content_type == TLSProxy::Record::RT_APPLICATION_DATA) { print " [ENCRYPTED APPLICATION DATA]\n"; print " [".$record->decrypt_data."]\n"; + + if ($successondata) { + $success = 1; + $end = 1; + } } elsif ($record->content_type == TLSProxy::Record::RT_ALERT) { my ($alertlev, $alertdesc) = unpack('CC', $record->decrypt_data); #A CloseNotify from the client indicates we have finished successfully @@ -507,5 +515,12 @@ sub encoded_length my $self = shift; return TLS_MESSAGE_HEADER_LENGTH + length($self->data); } - +sub successondata +{ + my $class = shift; + if (@_) { + $successondata = shift; + } + return $successondata; +} 1; diff --git a/util/TLSProxy/Proxy.pm b/util/TLSProxy/Proxy.pm index 2e90ab0a18..cee3bc5199 100644 --- a/util/TLSProxy/Proxy.pm +++ b/util/TLSProxy/Proxy.pm @@ -49,6 +49,7 @@ sub new serverconnects => 1, serverpid => 0, reneg => 0, + sessionfile => undef, #Public read execute => $execute, @@ -110,6 +111,7 @@ sub clearClient $self->{record_list} = []; $self->{message_list} = []; $self->{clientflags} = ""; + $self->{sessionfile} = undef; $is_tls13 = 0; $ciphersuite = undef; @@ -226,6 +228,9 @@ sub clientstart if ($self->clientflags ne "") { $execcmd .= " ".$self->clientflags; } + if (defined $self->sessionfile) { + $execcmd .= " -ign_eof"; + } exec($execcmd); } } @@ -295,6 +300,16 @@ sub clientstart } } + for (my $ctr = 0; + defined $self->sessionfile() + && (!(-f $self->sessionfile()) || $ctr == 3); + $ctr++) { + sleep 1; + } + + die "Session file not created" + if (defined $self->sessionfile() && !(-f $self->sessionfile())); + END: print "Connection closed\n"; if($server_sock) { @@ -540,6 +555,22 @@ sub reneg return $self->{reneg}; } +#Setting a sessionfile means that the client will not close until the given +#file exists. This is useful in TLSv1.3 where otherwise s_client will close +#immediately at the end of the handshake, but before the session has been +#received from the server. A side effect of this is that s_client never sends +#a close_notify, so instead we consider success to be when it sends application +#data over the connection. +sub sessionfile +{ + my $self = shift; + if (@_) { + $self->{sessionfile} = shift; + TLSProxy::Message->successondata(1); + } + return $self->{sessionfile}; +} + sub ciphersuite { my $class = shift; -- 2.25.1