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",
90 VERS_TLS_1_3, "TLS1.3",
91 VERS_TLS_1_2, "TLS1.2",
92 VERS_TLS_1_1, "TLS1.1",
93 VERS_TLS_1_0, "TLS1.0",
97 #Class method to extract records from a packet of data
104 my @record_list = ();
105 my @message_list = ();
114 while (length ($packet) > 0) {
115 print " Record $recnum";
117 print " (server -> client)\n";
119 print " (client -> server)\n";
121 #Get the record header
122 if (length($packet) < TLS_RECORD_HEADER_LENGTH) {
123 print "Partial data : ".length($packet)." bytes\n";
126 ($content_type, $version, $len) = unpack('CnnC*', $packet);
127 $data = substr($packet, 5, $len);
129 print " Content type: ".$record_type{$content_type}."\n";
130 print " Version: $tls_version{$version}\n";
131 print " Length: $len";
132 if ($len == length($data)) {
134 $decrypt_len = $len_real = $len;
136 print " (expected), ".length($data)." (actual)\n";
137 $decrypt_len = $len_real = length($data);
140 my $record = TLSProxy::Record->new(
147 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real),
148 substr($packet, TLS_RECORD_HEADER_LENGTH, $len_real)
151 if (($server && $server_ccs_seen)
152 || (!$server && $client_ccs_seen)) {
154 $record->decryptETM();
160 push @record_list, $record;
162 #Now figure out what messages are contained within this record
163 my @messages = TLSProxy::Message->get_messages($server, $record);
164 push @message_list, @messages;
166 $packet = substr($packet, TLS_RECORD_HEADER_LENGTH + $len_real);
171 return (\@record_list, \@message_list);
176 $server_ccs_seen = 0;
177 $client_ccs_seen = 0;
180 #Class level accessors
185 $server_ccs_seen = shift;
187 return $server_ccs_seen;
193 $client_ccs_seen = shift;
195 return $client_ccs_seen;
197 #Enable/Disable Encrypt-then-MAC
221 content_type => $content_type,
224 len_real => $len_real,
225 decrypt_len => $decrypt_len,
227 decrypt_data => $decrypt_data,
228 orig_decrypt_data => $decrypt_data
231 return bless $self, $class;
234 #Decrypt using encrypt-then-MAC
239 my $data = $self->data;
241 if($self->version >= VERS_TLS_1_1()) {
242 #TLS1.1+ has an explicit IV. Throw it away
243 $data = substr($data, 16);
246 #Throw away the MAC (assumes MAC is 20 bytes for now. FIXME)
247 $data = substr($data, 0, length($data) - 20);
249 #Find out what the padding byte is
250 my $padval = unpack("C", substr($data, length($data) - 1));
252 #Throw away the padding
253 $data = substr($data, 0, length($data) - ($padval + 1));
255 $self->decrypt_data($data);
256 $self->decrypt_len(length($data));
266 my $data = $self->data;
268 if($self->version >= VERS_TLS_1_1()) {
269 #TLS1.1+ has an explicit IV. Throw it away
270 $data = substr($data, 16);
273 #Find out what the padding byte is
274 my $padval = unpack("C", substr($data, length($data) - 1));
276 #Throw away the padding
277 $data = substr($data, 0, length($data) - ($padval + 1));
279 #Throw away the MAC (assumes MAC is 20 bytes for now. FIXME)
280 $data = substr($data, 0, length($data) - 20);
282 $self->decrypt_data($data);
283 $self->decrypt_len(length($data));
288 #Reconstruct the on-the-wire record representation
289 sub reconstruct_record
294 $data = pack('Cnn', $self->content_type, $self->version, $self->len);
295 $data .= $self->data;
304 return $self->{flight};
309 return $self->{content_type};
314 return $self->{version};
319 return $self->{len_real};
321 sub orig_decrypt_data
324 return $self->{orig_decrypt_data};
327 #Read/write accessors
332 $self->{decrypt_len} = shift;
334 return $self->{decrypt_len};
340 $self->{data} = shift;
342 return $self->{data};
348 $self->{decrypt_data} = shift;
350 return $self->{decrypt_data};
356 $self->{len} = shift;