X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=util%2Fperl%2FTLSProxy%2FRecord.pm;h=add7720ef290dccdc4f47ce7c2a6def3e6e8af18;hp=c5583082daadda89029378aab03959d1d7236d26;hb=3b09585bd67c41445be4be8a84233e5d9a699264;hpb=86b165e39fa94d4eceb9bb1611350b949fea7cc9 diff --git a/util/perl/TLSProxy/Record.pm b/util/perl/TLSProxy/Record.pm index c5583082da..add7720ef2 100644 --- a/util/perl/TLSProxy/Record.pm +++ b/util/perl/TLSProxy/Record.pm @@ -1,4 +1,4 @@ -# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the OpenSSL license (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -36,7 +36,6 @@ my %record_type = ( use constant { VERS_TLS_1_4 => 0x0305, - VERS_TLS_1_3_DRAFT => 0x7f16, VERS_TLS_1_3 => 0x0304, VERS_TLS_1_2 => 0x0303, VERS_TLS_1_1 => 0x0302, @@ -61,54 +60,45 @@ sub get_records my $server = shift; my $flight = shift; my $packet = shift; + my $partial = ""; my @record_list = (); my @message_list = (); - my $data; - my $content_type; - my $version; - my $len; - my $len_real; - my $decrypt_len; my $recnum = 1; while (length ($packet) > 0) { - print " Record $recnum"; - if ($server) { - print " (server -> client)\n"; - } else { - print " (client -> server)\n"; - } - #Get the record header - if (length($packet) < TLS_RECORD_HEADER_LENGTH) { - print "Partial data : ".length($packet)." bytes\n"; - $packet = ""; - } else { - ($content_type, $version, $len) = unpack('CnnC*', $packet); - $data = substr($packet, 5, $len); - - print " Content type: ".$record_type{$content_type}."\n"; - print " Version: $tls_version{$version}\n"; - print " Length: $len"; - if ($len == length($data)) { - print "\n"; - $decrypt_len = $len_real = $len; - } else { - print " (expected), ".length($data)." (actual)\n"; - $decrypt_len = $len_real = length($data); - } + print " Record $recnum ", $server ? "(server -> client)\n" + : "(client -> server)\n"; - my $record = TLSProxy::Record->new( - $flight, - $content_type, - $version, - $len, - 0, - $len_real, - $decrypt_len, - substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real), - substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real) - ); + #Get the record header (unpack can't fail if $packet is too short) + my ($content_type, $version, $len) = unpack('Cnn', $packet); + if (length($packet) < TLS_RECORD_HEADER_LENGTH + ($len // 0)) { + print "Partial data : ".length($packet)." bytes\n"; + $partial = $packet; + last; + } + + my $data = substr($packet, TLS_RECORD_HEADER_LENGTH, $len); + + print " Content type: ".$record_type{$content_type}."\n"; + print " Version: $tls_version{$version}\n"; + print " Length: $len\n"; + + my $record = TLSProxy::Record->new( + $flight, + $content_type, + $version, + $len, + 0, + $len, # len_real + $len, # decrypt_len + $data, # data + $data # decrypt_data + ); + + if ($content_type != RT_CCS + && (!TLSProxy::Proxy->is_tls13() + || $content_type != RT_ALERT)) { if (($server && $server_encrypting) || (!$server && $client_encrypting)) { if (!TLSProxy::Proxy->is_tls13() && $etm) { @@ -117,25 +107,25 @@ sub get_records $record->decrypt(); } $record->encrypted(1); - } - if (TLSProxy::Proxy->is_tls13()) { - print " Inner content type: " - .$record_type{$record->content_type()}."\n"; + if (TLSProxy::Proxy->is_tls13()) { + print " Inner content type: " + .$record_type{$record->content_type()}."\n"; + } } + } - push @record_list, $record; + push @record_list, $record; - #Now figure out what messages are contained within this record - my @messages = TLSProxy::Message->get_messages($server, $record); - push @message_list, @messages; + #Now figure out what messages are contained within this record + my @messages = TLSProxy::Message->get_messages($server, $record); + push @message_list, @messages; - $packet = substr($packet, TLS_RECORD_HEADER_LENGTH + $len_real); - $recnum++; - } + $packet = substr($packet, TLS_RECORD_HEADER_LENGTH + $len); + $recnum++; } - return (\@record_list, \@message_list); + return (\@record_list, \@message_list, $partial); } sub clear @@ -183,7 +173,7 @@ sub new $decrypt_len, $data, $decrypt_data) = @_; - + my $self = { flight => $flight, content_type => $content_type, @@ -195,6 +185,7 @@ sub new data => $data, decrypt_data => $decrypt_data, orig_decrypt_data => $decrypt_data, + sent => 0, encrypted => 0, outer_content_type => RT_APPLICATION_DATA }; @@ -284,15 +275,19 @@ sub reconstruct_record my $self = shift; my $server = shift; my $data; - my $tls13_enc = 0; + + #We only replay the records in the same direction + if ($self->{sent} || ($self->flight & 1) != $server) { + return ""; + } + $self->{sent} = 1; if ($self->sslv2) { $data = pack('n', $self->len | 0x8000); } else { if (TLSProxy::Proxy->is_tls13() && $self->encrypted) { $data = pack('Cnn', $self->outer_content_type, $self->version, - $self->len + 1); - $tls13_enc = 1; + $self->len); } else { $data = pack('Cnn', $self->content_type, $self->version, $self->len); @@ -301,10 +296,6 @@ sub reconstruct_record } $data .= $self->data; - if ($tls13_enc) { - $data .= pack('C', $self->content_type); - } - return $data; } @@ -395,4 +386,16 @@ sub outer_content_type } return $self->{outer_content_type}; } +sub is_fatal_alert +{ + my $self = shift; + my $server = shift; + + if (($self->{flight} & 1) == $server + && $self->{content_type} == TLSProxy::Record::RT_ALERT) { + my ($level, $alert) = unpack('CC', $self->decrypt_data); + return $alert if ($level == 2); + } + return 0; +} 1;