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,
30 RT_APPLICATION_DATA, "APPLICATION DATA",
31 RT_HANDSHAKE, "HANDSHAKE",
43 VERS_SSL_LT_3_0 => 767
47 VERS_TLS_1_3, "TLS1.3",
48 VERS_TLS_1_2, "TLS1.2",
49 VERS_TLS_1_1, "TLS1.1",
50 VERS_TLS_1_0, "TLS1.0",
52 VERS_SSL_LT_3_0, "SSL<3"
55 #Class method to extract records from a packet of data
63 my @message_list = ();
72 while (length ($packet) > 0) {
73 print " Record $recnum";
75 print " (server -> client)\n";
77 print " (client -> server)\n";
79 #Get the record header
80 if (length($packet) < TLS_RECORD_HEADER_LENGTH) {
81 print "Partial data : ".length($packet)." bytes\n";
84 ($content_type, $version, $len) = unpack('CnnC*', $packet);
85 $data = substr($packet, 5, $len);
87 print " Content type: ".$record_type{$content_type}."\n";
88 print " Version: $tls_version{$version}\n";
89 print " Length: $len";
90 if ($len == length($data)) {
92 $decrypt_len = $len_real = $len;
94 print " (expected), ".length($data)." (actual)\n";
95 $decrypt_len = $len_real = length($data);
98 my $record = TLSProxy::Record->new(
106 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real),
107 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real)
110 if (($server && $server_ccs_seen)
111 || (!$server && $client_ccs_seen)) {
113 $record->decryptETM();
119 push @record_list, $record;
121 #Now figure out what messages are contained within this record
122 my @messages = TLSProxy::Message->get_messages($server, $record);
123 push @message_list, @messages;
125 $packet = substr($packet, TLS_RECORD_HEADER_LENGTH + $len_real);
130 return (\@record_list, \@message_list);
135 $server_ccs_seen = 0;
136 $client_ccs_seen = 0;
139 #Class level accessors
144 $server_ccs_seen = shift;
146 return $server_ccs_seen;
152 $client_ccs_seen = shift;
154 return $client_ccs_seen;
156 #Enable/Disable Encrypt-then-MAC
181 content_type => $content_type,
185 len_real => $len_real,
186 decrypt_len => $decrypt_len,
188 decrypt_data => $decrypt_data,
189 orig_decrypt_data => $decrypt_data
192 return bless $self, $class;
195 #Decrypt using encrypt-then-MAC
200 my $data = $self->data;
202 if($self->version >= VERS_TLS_1_1()) {
203 #TLS1.1+ has an explicit IV. Throw it away
204 $data = substr($data, 16);
207 #Throw away the MAC (assumes MAC is 20 bytes for now. FIXME)
208 $data = substr($data, 0, length($data) - 20);
210 #Find out what the padding byte is
211 my $padval = unpack("C", substr($data, length($data) - 1));
213 #Throw away the padding
214 $data = substr($data, 0, length($data) - ($padval + 1));
216 $self->decrypt_data($data);
217 $self->decrypt_len(length($data));
227 my $data = $self->data;
229 if($self->version >= VERS_TLS_1_1()) {
230 #TLS1.1+ has an explicit IV. Throw it away
231 $data = substr($data, 16);
234 #Find out what the padding byte is
235 my $padval = unpack("C", substr($data, length($data) - 1));
237 #Throw away the padding
238 $data = substr($data, 0, length($data) - ($padval + 1));
240 #Throw away the MAC (assumes MAC is 20 bytes for now. FIXME)
241 $data = substr($data, 0, length($data) - 20);
243 $self->decrypt_data($data);
244 $self->decrypt_len(length($data));
249 #Reconstruct the on-the-wire record representation
250 sub reconstruct_record
256 $data = pack('n', $self->len | 0x8000);
258 $data = pack('Cnn', $self->content_type, $self->version, $self->len);
260 $data .= $self->data;
269 return $self->{flight};
274 return $self->{content_type};
279 return $self->{version};
284 return $self->{sslv2};
289 return $self->{len_real};
291 sub orig_decrypt_data
294 return $self->{orig_decrypt_data};
297 #Read/write accessors
302 $self->{decrypt_len} = shift;
304 return $self->{decrypt_len};
310 $self->{data} = shift;
312 return $self->{data};
318 $self->{decrypt_data} = shift;
320 return $self->{decrypt_data};
326 $self->{len} = shift;