1 # Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3 # Licensed under the OpenSSL license (the "License"). You may not use
4 # this file except in compliance with the License. You can obtain a copy
5 # in the file LICENSE in the source distribution or at
6 # https://www.openssl.org/source/license.html
12 package TLSProxy::Record;
14 my $server_ccs_seen = 0;
15 my $client_ccs_seen = 0;
18 use constant TLS_RECORD_HEADER_LENGTH => 5;
22 RT_APPLICATION_DATA => 23,
29 RT_APPLICATION_DATA, "APPLICATION DATA",
30 RT_HANDSHAKE, "HANDSHAKE",
41 VERS_SSL_LT_3_0 => 767
45 VERS_TLS_1_3, "TLS1.3",
46 VERS_TLS_1_2, "TLS1.2",
47 VERS_TLS_1_1, "TLS1.1",
48 VERS_TLS_1_0, "TLS1.0",
50 VERS_SSL_LT_3_0, "SSL<3"
53 #Class method to extract records from a packet of data
61 my @message_list = ();
70 while (length ($packet) > 0) {
71 print " Record $recnum";
73 print " (server -> client)\n";
75 print " (client -> server)\n";
77 #Get the record header
78 if (length($packet) < TLS_RECORD_HEADER_LENGTH) {
79 print "Partial data : ".length($packet)." bytes\n";
82 ($content_type, $version, $len) = unpack('CnnC*', $packet);
83 $data = substr($packet, 5, $len);
85 print " Content type: ".$record_type{$content_type}."\n";
86 print " Version: $tls_version{$version}\n";
87 print " Length: $len";
88 if ($len == length($data)) {
90 $decrypt_len = $len_real = $len;
92 print " (expected), ".length($data)." (actual)\n";
93 $decrypt_len = $len_real = length($data);
96 my $record = TLSProxy::Record->new(
103 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real),
104 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real)
107 if (($server && $server_ccs_seen)
108 || (!$server && $client_ccs_seen)) {
110 $record->decryptETM();
116 push @record_list, $record;
118 #Now figure out what messages are contained within this record
119 my @messages = TLSProxy::Message->get_messages($server, $record);
120 push @message_list, @messages;
122 $packet = substr($packet, TLS_RECORD_HEADER_LENGTH + $len_real);
127 return (\@record_list, \@message_list);
132 $server_ccs_seen = 0;
133 $client_ccs_seen = 0;
136 #Class level accessors
141 $server_ccs_seen = shift;
143 return $server_ccs_seen;
149 $client_ccs_seen = shift;
151 return $client_ccs_seen;
153 #Enable/Disable Encrypt-then-MAC
177 content_type => $content_type,
180 len_real => $len_real,
181 decrypt_len => $decrypt_len,
183 decrypt_data => $decrypt_data,
184 orig_decrypt_data => $decrypt_data
187 return bless $self, $class;
190 #Decrypt using encrypt-then-MAC
195 my $data = $self->data;
197 if($self->version >= VERS_TLS_1_1()) {
198 #TLS1.1+ has an explicit IV. Throw it away
199 $data = substr($data, 16);
202 #Throw away the MAC (assumes MAC is 20 bytes for now. FIXME)
203 $data = substr($data, 0, length($data) - 20);
205 #Find out what the padding byte is
206 my $padval = unpack("C", substr($data, length($data) - 1));
208 #Throw away the padding
209 $data = substr($data, 0, length($data) - ($padval + 1));
211 $self->decrypt_data($data);
212 $self->decrypt_len(length($data));
222 my $data = $self->data;
224 if($self->version >= VERS_TLS_1_1()) {
225 #TLS1.1+ has an explicit IV. Throw it away
226 $data = substr($data, 16);
229 #Find out what the padding byte is
230 my $padval = unpack("C", substr($data, length($data) - 1));
232 #Throw away the padding
233 $data = substr($data, 0, length($data) - ($padval + 1));
235 #Throw away the MAC (assumes MAC is 20 bytes for now. FIXME)
236 $data = substr($data, 0, length($data) - 20);
238 $self->decrypt_data($data);
239 $self->decrypt_len(length($data));
244 #Reconstruct the on-the-wire record representation
245 sub reconstruct_record
250 $data = pack('Cnn', $self->content_type, $self->version, $self->len);
251 $data .= $self->data;
260 return $self->{flight};
265 return $self->{content_type};
270 return $self->{version};
275 return $self->{len_real};
277 sub orig_decrypt_data
280 return $self->{orig_decrypt_data};
283 #Read/write accessors
288 $self->{decrypt_len} = shift;
290 return $self->{decrypt_len};
296 $self->{data} = shift;
298 return $self->{data};
304 $self->{decrypt_data} = shift;
306 return $self->{decrypt_data};
312 $self->{len} = shift;