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_encrypting = 0;
15 my $client_encrypting = 0;
18 use constant TLS_RECORD_HEADER_LENGTH => 5;
22 RT_APPLICATION_DATA => 23,
30 RT_APPLICATION_DATA, "APPLICATION DATA",
31 RT_HANDSHAKE, "HANDSHAKE",
39 VERS_TLS_1_3_DRAFT => 32530,
45 VERS_SSL_LT_3_0 => 767
49 VERS_TLS_1_3, "TLS1.3",
50 VERS_TLS_1_2, "TLS1.2",
51 VERS_TLS_1_1, "TLS1.1",
52 VERS_TLS_1_0, "TLS1.0",
54 VERS_SSL_LT_3_0, "SSL<3"
57 #Class method to extract records from a packet of data
65 my @message_list = ();
74 while (length ($packet) > 0) {
75 print " Record $recnum";
77 print " (server -> client)\n";
79 print " (client -> server)\n";
81 #Get the record header
82 if (length($packet) < TLS_RECORD_HEADER_LENGTH) {
83 print "Partial data : ".length($packet)." bytes\n";
86 ($content_type, $version, $len) = unpack('CnnC*', $packet);
87 $data = substr($packet, 5, $len);
89 print " Content type: ".$record_type{$content_type}."\n";
90 print " Version: $tls_version{$version}\n";
91 print " Length: $len";
92 if ($len == length($data)) {
94 $decrypt_len = $len_real = $len;
96 print " (expected), ".length($data)." (actual)\n";
97 $decrypt_len = $len_real = length($data);
100 my $record = TLSProxy::Record->new(
108 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real),
109 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real)
112 if (($server && $server_encrypting)
113 || (!$server && $client_encrypting)) {
114 if ($version != VERS_TLS_1_3() && $etm) {
115 $record->decryptETM();
121 push @record_list, $record;
123 #Now figure out what messages are contained within this record
124 my @messages = TLSProxy::Message->get_messages($server, $record);
125 push @message_list, @messages;
127 $packet = substr($packet, TLS_RECORD_HEADER_LENGTH + $len_real);
132 return (\@record_list, \@message_list);
137 $server_encrypting = 0;
138 $client_encrypting = 0;
141 #Class level accessors
142 sub server_encrypting
146 $server_encrypting = shift;
148 return $server_encrypting;
150 sub client_encrypting
154 $client_encrypting= shift;
156 return $client_encrypting;
158 #Enable/Disable Encrypt-then-MAC
183 content_type => $content_type,
187 len_real => $len_real,
188 decrypt_len => $decrypt_len,
190 decrypt_data => $decrypt_data,
191 orig_decrypt_data => $decrypt_data
194 return bless $self, $class;
197 #Decrypt using encrypt-then-MAC
202 my $data = $self->data;
204 if($self->version >= VERS_TLS_1_1()) {
205 #TLS1.1+ has an explicit IV. Throw it away
206 $data = substr($data, 16);
209 #Throw away the MAC (assumes MAC is 20 bytes for now. FIXME)
210 $data = substr($data, 0, length($data) - 20);
212 #Find out what the padding byte is
213 my $padval = unpack("C", substr($data, length($data) - 1));
215 #Throw away the padding
216 $data = substr($data, 0, length($data) - ($padval + 1));
218 $self->decrypt_data($data);
219 $self->decrypt_len(length($data));
229 my $data = $self->data;
232 if ($self->version >= VERS_TLS_1_3()) {
233 #8 bytes for a GCM IV
234 $data = substr($data, 8);
236 } elsif ($self->version >= VERS_TLS_1_1()) {
237 #16 bytes for a standard IV
238 $data = substr($data, 16);
240 #Find out what the padding byte is
241 my $padval = unpack("C", substr($data, length($data) - 1));
243 #Throw away the padding
244 $data = substr($data, 0, length($data) - ($padval + 1));
247 #Throw away the MAC or TAG
248 $data = substr($data, 0, length($data) - $mactaglen);
250 $self->decrypt_data($data);
251 $self->decrypt_len(length($data));
256 #Reconstruct the on-the-wire record representation
257 sub reconstruct_record
263 $data = pack('n', $self->len | 0x8000);
265 $data = pack('Cnn', $self->content_type, $self->version, $self->len);
267 $data .= $self->data;
276 return $self->{flight};
281 return $self->{content_type};
286 return $self->{sslv2};
291 return $self->{len_real};
293 sub orig_decrypt_data
296 return $self->{orig_decrypt_data};
299 #Read/write accessors
304 $self->{decrypt_len} = shift;
306 return $self->{decrypt_len};
312 $self->{data} = shift;
314 return $self->{data};
320 $self->{decrypt_data} = shift;
322 return $self->{decrypt_data};
328 $self->{len} = shift;
336 $self->{version} = shift;
338 return $self->{version};