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",
44 VERS_SSL_LT_3_0 => 767
48 VERS_TLS_1_3, "TLS1.3",
49 VERS_TLS_1_2, "TLS1.2",
50 VERS_TLS_1_1, "TLS1.1",
51 VERS_TLS_1_0, "TLS1.0",
53 VERS_SSL_LT_3_0, "SSL<3"
56 #Class method to extract records from a packet of data
64 my @message_list = ();
73 while (length ($packet) > 0) {
74 print " Record $recnum";
76 print " (server -> client)\n";
78 print " (client -> server)\n";
80 #Get the record header
81 if (length($packet) < TLS_RECORD_HEADER_LENGTH) {
82 print "Partial data : ".length($packet)." bytes\n";
85 ($content_type, $version, $len) = unpack('CnnC*', $packet);
86 $data = substr($packet, 5, $len);
88 print " Content type: ".$record_type{$content_type}."\n";
89 print " Version: $tls_version{$version}\n";
90 print " Length: $len";
91 if ($len == length($data)) {
93 $decrypt_len = $len_real = $len;
95 print " (expected), ".length($data)." (actual)\n";
96 $decrypt_len = $len_real = length($data);
99 my $record = TLSProxy::Record->new(
107 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real),
108 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real)
111 if (($server && $server_ccs_seen)
112 || (!$server && $client_ccs_seen)) {
113 if ($version != VERS_TLS_1_3() && $etm) {
114 $record->decryptETM();
120 push @record_list, $record;
122 #Now figure out what messages are contained within this record
123 my @messages = TLSProxy::Message->get_messages($server, $record);
124 push @message_list, @messages;
126 $packet = substr($packet, TLS_RECORD_HEADER_LENGTH + $len_real);
131 return (\@record_list, \@message_list);
136 $server_ccs_seen = 0;
137 $client_ccs_seen = 0;
140 #Class level accessors
145 $server_ccs_seen = shift;
147 return $server_ccs_seen;
153 $client_ccs_seen = shift;
155 return $client_ccs_seen;
157 #Enable/Disable Encrypt-then-MAC
182 content_type => $content_type,
186 len_real => $len_real,
187 decrypt_len => $decrypt_len,
189 decrypt_data => $decrypt_data,
190 orig_decrypt_data => $decrypt_data
193 return bless $self, $class;
196 #Decrypt using encrypt-then-MAC
201 my $data = $self->data;
203 if($self->version >= VERS_TLS_1_1()) {
204 #TLS1.1+ has an explicit IV. Throw it away
205 $data = substr($data, 16);
208 #Throw away the MAC (assumes MAC is 20 bytes for now. FIXME)
209 $data = substr($data, 0, length($data) - 20);
211 #Find out what the padding byte is
212 my $padval = unpack("C", substr($data, length($data) - 1));
214 #Throw away the padding
215 $data = substr($data, 0, length($data) - ($padval + 1));
217 $self->decrypt_data($data);
218 $self->decrypt_len(length($data));
228 my $data = $self->data;
231 if ($self->version >= VERS_TLS_1_3()) {
232 #8 bytes for a GCM IV
233 $data = substr($data, 8);
235 } elsif ($self->version >= VERS_TLS_1_1()) {
236 #16 bytes for a standard IV
237 $data = substr($data, 16);
239 #Find out what the padding byte is
240 my $padval = unpack("C", substr($data, length($data) - 1));
242 #Throw away the padding
243 $data = substr($data, 0, length($data) - ($padval + 1));
246 #Throw away the MAC or TAG
247 $data = substr($data, 0, length($data) - $mactaglen);
249 $self->decrypt_data($data);
250 $self->decrypt_len(length($data));
255 #Reconstruct the on-the-wire record representation
256 sub reconstruct_record
262 $data = pack('n', $self->len | 0x8000);
264 $data = pack('Cnn', $self->content_type, $self->version, $self->len);
266 $data .= $self->data;
275 return $self->{flight};
280 return $self->{content_type};
285 return $self->{sslv2};
290 return $self->{len_real};
292 sub orig_decrypt_data
295 return $self->{orig_decrypt_data};
298 #Read/write accessors
303 $self->{decrypt_len} = shift;
305 return $self->{decrypt_len};
311 $self->{data} = shift;
313 return $self->{data};
319 $self->{decrypt_data} = shift;
321 return $self->{decrypt_data};
327 $self->{len} = shift;
335 $self->{version} = shift;
337 return $self->{version};