Commit 1c361b4a authored by Matt Caswell's avatar Matt Caswell
Browse files

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: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2259)
parent 93fa7e8d
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -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;
+31 −0
Original line number Diff line number Diff line
@@ -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;