1 # Written by Matt Caswell for the OpenSSL project.
2 # ====================================================================
3 # Copyright (c) 1998-2015 The OpenSSL Project. All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in
14 # the documentation and/or other materials provided with the
17 # 3. All advertising materials mentioning features or use of this
18 # software must display the following acknowledgment:
19 # "This product includes software developed by the OpenSSL Project
20 # for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
22 # 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 # endorse or promote products derived from this software without
24 # prior written permission. For written permission, please contact
25 # openssl-core@openssl.org.
27 # 5. Products derived from this software may not be called "OpenSSL"
28 # nor may "OpenSSL" appear in their names without prior written
29 # permission of the OpenSSL Project.
31 # 6. Redistributions of any form whatsoever must retain the following
33 # "This product includes software developed by the OpenSSL Project
34 # for use in the OpenSSL Toolkit (http://www.openssl.org/)"
36 # THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 # ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 # OF THE POSSIBILITY OF SUCH DAMAGE.
48 # ====================================================================
50 # This product includes cryptographic software written by Eric Young
51 # (eay@cryptsoft.com). This product includes software written by Tim
52 # Hudson (tjh@cryptsoft.com).
58 package TLSProxy::Record;
60 my $server_ccs_seen = 0;
61 my $client_ccs_seen = 0;
64 use constant TLS_RECORD_HEADER_LENGTH => 5;
68 RT_APPLICATION_DATA => 23,
75 RT_APPLICATION_DATA, "APPLICATION DATA",
76 RT_HANDSHAKE, "HANDSHAKE",
87 VERS_SSL_LT_3_0 => 767
91 VERS_TLS_1_3, "TLS1.3",
92 VERS_TLS_1_2, "TLS1.2",
93 VERS_TLS_1_1, "TLS1.1",
94 VERS_TLS_1_0, "TLS1.0",
96 VERS_SSL_LT_3_0, "SSL<3"
99 #Class method to extract records from a packet of data
106 my @record_list = ();
107 my @message_list = ();
116 while (length ($packet) > 0) {
117 print " Record $recnum";
119 print " (server -> client)\n";
121 print " (client -> server)\n";
123 #Get the record header
124 if (length($packet) < TLS_RECORD_HEADER_LENGTH) {
125 print "Partial data : ".length($packet)." bytes\n";
128 ($content_type, $version, $len) = unpack('CnnC*', $packet);
129 $data = substr($packet, 5, $len);
131 print " Content type: ".$record_type{$content_type}."\n";
132 print " Version: $tls_version{$version}\n";
133 print " Length: $len";
134 if ($len == length($data)) {
136 $decrypt_len = $len_real = $len;
138 print " (expected), ".length($data)." (actual)\n";
139 $decrypt_len = $len_real = length($data);
142 my $record = TLSProxy::Record->new(
149 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real),
150 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real)
153 if (($server && $server_ccs_seen)
154 || (!$server && $client_ccs_seen)) {
156 $record->decryptETM();
162 push @record_list, $record;
164 #Now figure out what messages are contained within this record
165 my @messages = TLSProxy::Message->get_messages($server, $record);
166 push @message_list, @messages;
168 $packet = substr($packet, TLS_RECORD_HEADER_LENGTH + $len_real);
173 return (\@record_list, \@message_list);
178 $server_ccs_seen = 0;
179 $client_ccs_seen = 0;
182 #Class level accessors
187 $server_ccs_seen = shift;
189 return $server_ccs_seen;
195 $client_ccs_seen = shift;
197 return $client_ccs_seen;
199 #Enable/Disable Encrypt-then-MAC
223 content_type => $content_type,
226 len_real => $len_real,
227 decrypt_len => $decrypt_len,
229 decrypt_data => $decrypt_data,
230 orig_decrypt_data => $decrypt_data
233 return bless $self, $class;
236 #Decrypt using encrypt-then-MAC
241 my $data = $self->data;
243 if($self->version >= VERS_TLS_1_1()) {
244 #TLS1.1+ has an explicit IV. Throw it away
245 $data = substr($data, 16);
248 #Throw away the MAC (assumes MAC is 20 bytes for now. FIXME)
249 $data = substr($data, 0, length($data) - 20);
251 #Find out what the padding byte is
252 my $padval = unpack("C", substr($data, length($data) - 1));
254 #Throw away the padding
255 $data = substr($data, 0, length($data) - ($padval + 1));
257 $self->decrypt_data($data);
258 $self->decrypt_len(length($data));
268 my $data = $self->data;
270 if($self->version >= VERS_TLS_1_1()) {
271 #TLS1.1+ has an explicit IV. Throw it away
272 $data = substr($data, 16);
275 #Find out what the padding byte is
276 my $padval = unpack("C", substr($data, length($data) - 1));
278 #Throw away the padding
279 $data = substr($data, 0, length($data) - ($padval + 1));
281 #Throw away the MAC (assumes MAC is 20 bytes for now. FIXME)
282 $data = substr($data, 0, length($data) - 20);
284 $self->decrypt_data($data);
285 $self->decrypt_len(length($data));
290 #Reconstruct the on-the-wire record representation
291 sub reconstruct_record
296 $data = pack('Cnn', $self->content_type, $self->version, $self->len);
297 $data .= $self->data;
306 return $self->{flight};
311 return $self->{content_type};
316 return $self->{version};
321 return $self->{len_real};
323 sub orig_decrypt_data
326 return $self->{orig_decrypt_data};
329 #Read/write accessors
334 $self->{decrypt_len} = shift;
336 return $self->{decrypt_len};
342 $self->{data} = shift;
344 return $self->{data};
350 $self->{decrypt_data} = shift;
352 return $self->{decrypt_data};
358 $self->{len} = shift;