]> git.ipfire.org Git - thirdparty/openssl.git/blame_incremental - test/recipes/70-test_sslrecords.t
Update copyright year
[thirdparty/openssl.git] / test / recipes / 70-test_sslrecords.t
... / ...
CommitLineData
1#! /usr/bin/env perl
2# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
3#
4# Licensed under the Apache License 2.0 (the "License"). You may not use
5# this file except in compliance with the License. You can obtain a copy
6# in the file LICENSE in the source distribution or at
7# https://www.openssl.org/source/license.html
8
9use strict;
10use feature 'state';
11
12use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/;
13use OpenSSL::Test::Utils;
14use TLSProxy::Proxy;
15
16my $test_name = "test_sslrecords";
17setup($test_name);
18
19plan skip_all => "TLSProxy isn't usable on $^O"
20 if $^O =~ /^(VMS)$/;
21
22plan skip_all => "$test_name needs the dynamic engine feature enabled"
23 if disabled("engine") || disabled("dynamic-engine");
24
25plan skip_all => "$test_name needs the sock feature enabled"
26 if disabled("sock");
27
28plan skip_all => "$test_name needs TLSv1.2 enabled"
29 if disabled("tls1_2");
30
31$ENV{OPENSSL_ia32cap} = '~0x200000200000000';
32my $proxy = TLSProxy::Proxy->new(
33 \&add_empty_recs_filter,
34 cmdstr(app(["openssl"]), display => 1),
35 srctop_file("apps", "server.pem"),
36 (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
37);
38
39my $boundary_test_type;
40my $fatal_alert = 0; # set by filters at expected fatal alerts
41
42#Test 1: Injecting out of context empty records should fail
43my $content_type = TLSProxy::Record::RT_APPLICATION_DATA;
44my $inject_recs_num = 1;
45$proxy->serverflags("-tls1_2");
46$proxy->clientflags("-no_tls1_3");
47$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
48plan tests => 20;
49ok($fatal_alert, "Out of context empty records test");
50
51#Test 2: Injecting in context empty records should succeed
52$proxy->clear();
53$content_type = TLSProxy::Record::RT_HANDSHAKE;
54$proxy->serverflags("-tls1_2");
55$proxy->clientflags("-no_tls1_3");
56$proxy->start();
57ok(TLSProxy::Message->success(), "In context empty records test");
58
59#Test 3: Injecting too many in context empty records should fail
60$fatal_alert = 0;
61$proxy->clear();
62#We allow 32 consecutive in context empty records
63$inject_recs_num = 33;
64$proxy->serverflags("-tls1_2");
65$proxy->clientflags("-no_tls1_3");
66$proxy->start();
67ok($fatal_alert, "Too many in context empty records test");
68
69#Test 4: Injecting a fragmented fatal alert should fail. We expect the server to
70# send back an alert of its own because it cannot handle fragmented
71# alerts
72$fatal_alert = 0;
73$proxy->clear();
74$proxy->filter(\&add_frag_alert_filter);
75$proxy->serverflags("-tls1_2");
76$proxy->clientflags("-no_tls1_3");
77$proxy->start();
78ok($fatal_alert, "Fragmented alert records test");
79
80#Run some SSLv2 ClientHello tests
81
82use constant {
83 TLSV1_2_IN_SSLV2 => 0,
84 SSLV2_IN_SSLV2 => 1,
85 FRAGMENTED_IN_TLSV1_2 => 2,
86 FRAGMENTED_IN_SSLV2 => 3,
87 ALERT_BEFORE_SSLV2 => 4
88};
89
90# The TLSv1.2 in SSLv2 ClientHello need to run at security level 0
91# because in a SSLv2 ClientHello we can't send extentions to indicate
92# which signature algorithm we want to use, and the default is SHA1.
93
94#Test 5: Inject an SSLv2 style record format for a TLSv1.2 ClientHello
95my $sslv2testtype = TLSV1_2_IN_SSLV2;
96$proxy->clear();
97$proxy->filter(\&add_sslv2_filter);
98$proxy->serverflags("-tls1_2");
99$proxy->clientflags("-no_tls1_3");
100$proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
101$proxy->start();
102ok(TLSProxy::Message->success(), "TLSv1.2 in SSLv2 ClientHello test");
103
104#Test 6: Inject an SSLv2 style record format for an SSLv2 ClientHello. We don't
105# support this so it should fail. We actually treat it as an unknown
106# protocol so we don't even send an alert in this case.
107$sslv2testtype = SSLV2_IN_SSLV2;
108$proxy->clear();
109$proxy->serverflags("-tls1_2");
110$proxy->clientflags("-no_tls1_3");
111$proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
112$proxy->start();
113ok(TLSProxy::Message->fail(), "SSLv2 in SSLv2 ClientHello test");
114
115#Test 7: Sanity check ClientHello fragmentation. This isn't really an SSLv2 test
116# at all, but it gives us confidence that Test 8 fails for the right
117# reasons
118$sslv2testtype = FRAGMENTED_IN_TLSV1_2;
119$proxy->clear();
120$proxy->serverflags("-tls1_2");
121$proxy->clientflags("-no_tls1_3");
122$proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
123$proxy->start();
124ok(TLSProxy::Message->success(), "Fragmented ClientHello in TLSv1.2 test");
125
126#Test 8: Fragment a TLSv1.2 ClientHello across a TLS1.2 record; an SSLv2
127# record; and another TLS1.2 record. This isn't allowed so should fail
128$sslv2testtype = FRAGMENTED_IN_SSLV2;
129$proxy->clear();
130$proxy->serverflags("-tls1_2");
131$proxy->clientflags("-no_tls1_3");
132$proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
133$proxy->start();
134ok(TLSProxy::Message->fail(), "Fragmented ClientHello in TLSv1.2/SSLv2 test");
135
136#Test 9: Send a TLS warning alert before an SSLv2 ClientHello. This should
137# fail because an SSLv2 ClientHello must be the first record.
138$sslv2testtype = ALERT_BEFORE_SSLV2;
139$proxy->clear();
140$proxy->serverflags("-tls1_2");
141$proxy->clientflags("-no_tls1_3");
142$proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
143$proxy->start();
144ok(TLSProxy::Message->fail(), "Alert before SSLv2 ClientHello test");
145
146#Unrecognised record type tests
147
148#Test 10: Sending an unrecognised record type in TLS1.2 should fail
149$fatal_alert = 0;
150$proxy->clear();
151$proxy->serverflags("-tls1_2");
152$proxy->clientflags("-no_tls1_3");
153$proxy->filter(\&add_unknown_record_type);
154$proxy->start();
155ok($fatal_alert, "Unrecognised record type in TLS1.2");
156
157SKIP: {
158 skip "TLSv1.1 disabled", 1 if disabled("tls1_1");
159
160 #Test 11: Sending an unrecognised record type in TLS1.1 should fail
161 $fatal_alert = 0;
162 $proxy->clear();
163 $proxy->clientflags("-tls1_1 -cipher DEFAULT:\@SECLEVEL=0");
164 $proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
165 $proxy->start();
166 ok($fatal_alert, "Unrecognised record type in TLS1.1");
167}
168
169#Test 12: Sending a different record version in TLS1.2 should fail
170$fatal_alert = 0;
171$proxy->clear();
172$proxy->clientflags("-tls1_2");
173$proxy->filter(\&change_version);
174$proxy->start();
175ok($fatal_alert, "Changed record version in TLS1.2");
176
177#TLS1.3 specific tests
178SKIP: {
179 skip "TLSv1.3 disabled", 8
180 if disabled("tls1_3") || (disabled("ec") && disabled("dh"));
181
182 #Test 13: Sending a different record version in TLS1.3 should fail
183 $proxy->clear();
184 $proxy->filter(\&change_version);
185 $proxy->start();
186 ok(TLSProxy::Message->fail(), "Changed record version in TLS1.3");
187
188 #Test 14: Sending an unrecognised record type in TLS1.3 should fail
189 $fatal_alert = 0;
190 $proxy->clear();
191 $proxy->filter(\&add_unknown_record_type);
192 $proxy->start();
193 ok($fatal_alert, "Unrecognised record type in TLS1.3");
194
195 #Test 15: Sending an outer record type other than app data once encrypted
196 #should fail
197 $fatal_alert = 0;
198 $proxy->clear();
199 $proxy->filter(\&change_outer_record_type);
200 $proxy->start();
201 ok($fatal_alert, "Wrong outer record type in TLS1.3");
202
203 use constant {
204 DATA_AFTER_SERVER_HELLO => 0,
205 DATA_AFTER_FINISHED => 1,
206 DATA_AFTER_KEY_UPDATE => 2,
207 DATA_BETWEEN_KEY_UPDATE => 3,
208 NO_DATA_BETWEEN_KEY_UPDATE => 4,
209 };
210
211 #Test 16: Sending a ServerHello which doesn't end on a record boundary
212 # should fail
213 $fatal_alert = 0;
214 $proxy->clear();
215 $boundary_test_type = DATA_AFTER_SERVER_HELLO;
216 $proxy->filter(\&not_on_record_boundary);
217 $proxy->start();
218 ok($fatal_alert, "Record not on boundary in TLS1.3 (ServerHello)");
219
220 #Test 17: Sending a Finished which doesn't end on a record boundary
221 # should fail
222 $fatal_alert = 0;
223 $proxy->clear();
224 $boundary_test_type = DATA_AFTER_FINISHED;
225 $proxy->start();
226 ok($fatal_alert, "Record not on boundary in TLS1.3 (Finished)");
227
228 #Test 18: Sending a KeyUpdate which doesn't end on a record boundary
229 # should fail
230 $fatal_alert = 0;
231 $proxy->clear();
232 $boundary_test_type = DATA_AFTER_KEY_UPDATE;
233 $proxy->start();
234 ok($fatal_alert, "Record not on boundary in TLS1.3 (KeyUpdate)");
235
236 #Test 19: Sending application data in the middle of a fragmented KeyUpdate
237 # should fail. Strictly speaking this is not a record boundary test
238 # but we use the same filter.
239 $fatal_alert = 0;
240 $proxy->clear();
241 $boundary_test_type = DATA_BETWEEN_KEY_UPDATE;
242 $proxy->start();
243 ok($fatal_alert, "Data between KeyUpdate");
244
245 #Test 20: Fragmented KeyUpdate. This should succeed. Strictly speaking this
246 # is not a record boundary test but we use the same filter.
247 $proxy->clear();
248 $boundary_test_type = NO_DATA_BETWEEN_KEY_UPDATE;
249 $proxy->start();
250 ok(TLSProxy::Message->success(), "No data between KeyUpdate");
251 }
252
253
254sub add_empty_recs_filter
255{
256 my $proxy = shift;
257 my $records = $proxy->record_list;
258
259 # We're only interested in the initial ClientHello
260 if ($proxy->flight != 0) {
261 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(1) == 10;
262 return;
263 }
264
265 for (my $i = 0; $i < $inject_recs_num; $i++) {
266 my $record = TLSProxy::Record->new(
267 0,
268 $content_type,
269 TLSProxy::Record::VERS_TLS_1_2,
270 0,
271 0,
272 0,
273 0,
274 "",
275 ""
276 );
277 push @{$records}, $record;
278 }
279}
280
281sub add_frag_alert_filter
282{
283 my $proxy = shift;
284 my $records = $proxy->record_list;
285 my $byte;
286
287 # We're only interested in the initial ClientHello
288 if ($proxy->flight != 0) {
289 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(1) == 10;
290 return;
291 }
292
293 # Add a zero length fragment first
294 #my $record = TLSProxy::Record->new(
295 # 0,
296 # TLSProxy::Record::RT_ALERT,
297 # TLSProxy::Record::VERS_TLS_1_2,
298 # 0,
299 # 0,
300 # 0,
301 # "",
302 # ""
303 #);
304 #push @{$proxy->record_list}, $record;
305
306 # Now add the alert level (Fatal) as a separate record
307 $byte = pack('C', TLSProxy::Message::AL_LEVEL_FATAL);
308 my $record = TLSProxy::Record->new(
309 0,
310 TLSProxy::Record::RT_ALERT,
311 TLSProxy::Record::VERS_TLS_1_2,
312 1,
313 0,
314 1,
315 1,
316 $byte,
317 $byte
318 );
319 push @{$records}, $record;
320
321 # And finally the description (Unexpected message) in a third record
322 $byte = pack('C', TLSProxy::Message::AL_DESC_UNEXPECTED_MESSAGE);
323 $record = TLSProxy::Record->new(
324 0,
325 TLSProxy::Record::RT_ALERT,
326 TLSProxy::Record::VERS_TLS_1_2,
327 1,
328 0,
329 1,
330 1,
331 $byte,
332 $byte
333 );
334 push @{$records}, $record;
335}
336
337sub add_sslv2_filter
338{
339 my $proxy = shift;
340 my $clienthello;
341 my $record;
342
343 # We're only interested in the initial ClientHello
344 if ($proxy->flight != 0) {
345 return;
346 }
347
348 # Ditch the real ClientHello - we're going to replace it with our own
349 shift @{$proxy->record_list};
350
351 if ($sslv2testtype == ALERT_BEFORE_SSLV2) {
352 my $alert = pack('CC', TLSProxy::Message::AL_LEVEL_FATAL,
353 TLSProxy::Message::AL_DESC_NO_RENEGOTIATION);
354 my $alertlen = length $alert;
355 $record = TLSProxy::Record->new(
356 0,
357 TLSProxy::Record::RT_ALERT,
358 TLSProxy::Record::VERS_TLS_1_2,
359 $alertlen,
360 0,
361 $alertlen,
362 $alertlen,
363 $alert,
364 $alert
365 );
366
367 push @{$proxy->record_list}, $record;
368 }
369
370 if ($sslv2testtype == ALERT_BEFORE_SSLV2
371 || $sslv2testtype == TLSV1_2_IN_SSLV2
372 || $sslv2testtype == SSLV2_IN_SSLV2) {
373 # This is an SSLv2 format ClientHello
374 $clienthello =
375 pack "C44",
376 0x01, # ClientHello
377 0x03, 0x03, #TLSv1.2
378 0x00, 0x03, # Ciphersuites len
379 0x00, 0x00, # Session id len
380 0x00, 0x20, # Challenge len
381 0x00, 0x00, 0x2f, #AES128-SHA
382 0x01, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
383 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
384 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6; # Challenge
385
386 if ($sslv2testtype == SSLV2_IN_SSLV2) {
387 # Set the version to "real" SSLv2
388 vec($clienthello, 1, 8) = 0x00;
389 vec($clienthello, 2, 8) = 0x02;
390 }
391
392 my $chlen = length $clienthello;
393
394 $record = TLSProxy::Record->new(
395 0,
396 TLSProxy::Record::RT_HANDSHAKE,
397 TLSProxy::Record::VERS_TLS_1_2,
398 $chlen,
399 1, #SSLv2
400 $chlen,
401 $chlen,
402 $clienthello,
403 $clienthello
404 );
405
406 push @{$proxy->record_list}, $record;
407 } else {
408 # For this test we're using a real TLS ClientHello
409 $clienthello =
410 pack "C49",
411 0x01, # ClientHello
412 0x00, 0x00, 0x2D, # Message length
413 0x03, 0x03, # TLSv1.2
414 0x01, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
415 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
416 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, # Random
417 0x00, # Session id len
418 0x00, 0x04, # Ciphersuites len
419 0x00, 0x2f, # AES128-SHA
420 0x00, 0xff, # Empty reneg info SCSV
421 0x01, # Compression methods len
422 0x00, # Null compression
423 0x00, 0x00; # Extensions len
424
425 # Split this into 3: A TLS record; a SSLv2 record and a TLS record.
426 # We deliberately split the second record prior to the Challenge/Random
427 # and set the first byte of the random to 1. This makes the second SSLv2
428 # record look like an SSLv2 ClientHello
429 my $frag1 = substr $clienthello, 0, 6;
430 my $frag2 = substr $clienthello, 6, 32;
431 my $frag3 = substr $clienthello, 38;
432
433 my $fraglen = length $frag1;
434 $record = TLSProxy::Record->new(
435 0,
436 TLSProxy::Record::RT_HANDSHAKE,
437 TLSProxy::Record::VERS_TLS_1_2,
438 $fraglen,
439 0,
440 $fraglen,
441 $fraglen,
442 $frag1,
443 $frag1
444 );
445 push @{$proxy->record_list}, $record;
446
447 $fraglen = length $frag2;
448 my $recvers;
449 if ($sslv2testtype == FRAGMENTED_IN_SSLV2) {
450 $recvers = 1;
451 } else {
452 $recvers = 0;
453 }
454 $record = TLSProxy::Record->new(
455 0,
456 TLSProxy::Record::RT_HANDSHAKE,
457 TLSProxy::Record::VERS_TLS_1_2,
458 $fraglen,
459 $recvers,
460 $fraglen,
461 $fraglen,
462 $frag2,
463 $frag2
464 );
465 push @{$proxy->record_list}, $record;
466
467 $fraglen = length $frag3;
468 $record = TLSProxy::Record->new(
469 0,
470 TLSProxy::Record::RT_HANDSHAKE,
471 TLSProxy::Record::VERS_TLS_1_2,
472 $fraglen,
473 0,
474 $fraglen,
475 $fraglen,
476 $frag3,
477 $frag3
478 );
479 push @{$proxy->record_list}, $record;
480 }
481
482}
483
484sub add_unknown_record_type
485{
486 my $proxy = shift;
487 my $records = $proxy->record_list;
488 state $added_record;
489
490 # We'll change a record after the initial version neg has taken place
491 if ($proxy->flight == 0) {
492 $added_record = 0;
493 return;
494 } elsif ($proxy->flight != 1 || $added_record) {
495 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(0) == 10;
496 return;
497 }
498
499 my $record = TLSProxy::Record->new(
500 1,
501 TLSProxy::Record::RT_UNKNOWN,
502 @{$records}[-1]->version(),
503 1,
504 0,
505 1,
506 1,
507 "X",
508 "X"
509 );
510
511 #Find ServerHello record and insert after that
512 my $i;
513 for ($i = 0; ${$proxy->record_list}[$i]->flight() < 1; $i++) {
514 next;
515 }
516 $i++;
517
518 splice @{$proxy->record_list}, $i, 0, $record;
519 $added_record = 1;
520}
521
522sub change_version
523{
524 my $proxy = shift;
525 my $records = $proxy->record_list;
526
527 # We'll change a version after the initial version neg has taken place
528 if ($proxy->flight != 1) {
529 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(0) == 70;
530 return;
531 }
532
533 if ($#{$records} > 1) {
534 # ... typically in ServerHelloDone
535 @{$records}[-1]->version(TLSProxy::Record::VERS_TLS_1_1);
536 }
537}
538
539sub change_outer_record_type
540{
541 my $proxy = shift;
542 my $records = $proxy->record_list;
543
544 # We'll change a record after the initial version neg has taken place
545 if ($proxy->flight != 1) {
546 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(0) == 10;
547 return;
548 }
549
550 # Find CCS record and change record after that
551 my $i = 0;
552 foreach my $record (@{$records}) {
553 last if $record->content_type == TLSProxy::Record::RT_CCS;
554 $i++;
555 }
556 if (defined(${$records}[++$i])) {
557 ${$records}[$i]->outer_content_type(TLSProxy::Record::RT_HANDSHAKE);
558 }
559}
560
561sub not_on_record_boundary
562{
563 my $proxy = shift;
564 my $records = $proxy->record_list;
565 my $data;
566
567 #Find server's first flight
568 if ($proxy->flight != 1) {
569 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(0) == 10;
570 return;
571 }
572
573 if ($boundary_test_type == DATA_AFTER_SERVER_HELLO) {
574 #Merge the ServerHello and EncryptedExtensions records into one
575 my $i = 0;
576 foreach my $record (@{$records}) {
577 if ($record->content_type == TLSProxy::Record::RT_HANDSHAKE) {
578 $record->{sent} = 1; # pretend it's sent already
579 last;
580 }
581 $i++;
582 }
583
584 if (defined(${$records}[$i+1])) {
585 $data = ${$records}[$i]->data();
586 $data .= ${$records}[$i+1]->decrypt_data();
587 ${$records}[$i+1]->data($data);
588 ${$records}[$i+1]->len(length $data);
589
590 #Delete the old ServerHello record
591 splice @{$records}, $i, 1;
592 }
593 } elsif ($boundary_test_type == DATA_AFTER_FINISHED) {
594 return if @{$proxy->{message_list}}[-1]->{mt}
595 != TLSProxy::Message::MT_FINISHED;
596
597 my $last_record = @{$records}[-1];
598 $data = $last_record->decrypt_data;
599
600 #Add a KeyUpdate message onto the end of the Finished record
601 my $keyupdate = pack "C5",
602 0x18, # KeyUpdate
603 0x00, 0x00, 0x01, # Message length
604 0x00; # Update not requested
605
606 $data .= $keyupdate;
607
608 #Add content type and tag
609 $data .= pack("C", TLSProxy::Record::RT_HANDSHAKE).("\0"x16);
610
611 #Update the record
612 $last_record->data($data);
613 $last_record->len(length $data);
614 } elsif ($boundary_test_type == DATA_AFTER_KEY_UPDATE) {
615 return if @{$proxy->{message_list}}[-1]->{mt}
616 != TLSProxy::Message::MT_FINISHED;
617
618 #KeyUpdates must end on a record boundary
619
620 my $record = TLSProxy::Record->new(
621 1,
622 TLSProxy::Record::RT_APPLICATION_DATA,
623 TLSProxy::Record::VERS_TLS_1_2,
624 0,
625 0,
626 0,
627 0,
628 "",
629 ""
630 );
631
632 #Add two KeyUpdate messages into a single record
633 my $keyupdate = pack "C5",
634 0x18, # KeyUpdate
635 0x00, 0x00, 0x01, # Message length
636 0x00; # Update not requested
637
638 $data = $keyupdate.$keyupdate;
639
640 #Add content type and tag
641 $data .= pack("C", TLSProxy::Record::RT_HANDSHAKE).("\0"x16);
642
643 $record->data($data);
644 $record->len(length $data);
645 push @{$records}, $record;
646 } else {
647 return if @{$proxy->{message_list}}[-1]->{mt}
648 != TLSProxy::Message::MT_FINISHED;
649
650 my $record = TLSProxy::Record->new(
651 1,
652 TLSProxy::Record::RT_APPLICATION_DATA,
653 TLSProxy::Record::VERS_TLS_1_2,
654 0,
655 0,
656 0,
657 0,
658 "",
659 ""
660 );
661
662 #Add a partial KeyUpdate message into the record
663 $data = pack "C1",
664 0x18; # KeyUpdate message type. Omit the rest of the message header
665
666 #Add content type and tag
667 $data .= pack("C", TLSProxy::Record::RT_HANDSHAKE).("\0"x16);
668
669 $record->data($data);
670 $record->len(length $data);
671 push @{$records}, $record;
672
673 if ($boundary_test_type == DATA_BETWEEN_KEY_UPDATE) {
674 #Now add an app data record
675 $record = TLSProxy::Record->new(
676 1,
677 TLSProxy::Record::RT_APPLICATION_DATA,
678 TLSProxy::Record::VERS_TLS_1_2,
679 0,
680 0,
681 0,
682 0,
683 "",
684 ""
685 );
686
687 #Add an empty app data record (just content type and tag)
688 $data = pack("C", TLSProxy::Record::RT_APPLICATION_DATA).("\0"x16);
689
690 $record->data($data);
691 $record->len(length $data);
692 push @{$records}, $record;
693 }
694
695 #Now add the rest of the KeyUpdate message
696 $record = TLSProxy::Record->new(
697 1,
698 TLSProxy::Record::RT_APPLICATION_DATA,
699 TLSProxy::Record::VERS_TLS_1_2,
700 0,
701 0,
702 0,
703 0,
704 "",
705 ""
706 );
707
708 #Add the last 4 bytes of the KeyUpdate record
709 $data = pack "C4",
710 0x00, 0x00, 0x01, # Message length
711 0x00; # Update not requested
712
713 #Add content type and tag
714 $data .= pack("C", TLSProxy::Record::RT_HANDSHAKE).("\0"x16);
715
716 $record->data($data);
717 $record->len(length $data);
718 push @{$records}, $record;
719
720 }
721}