2 # Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
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
12 use OpenSSL
::Test qw
/:DEFAULT cmdstr srctop_file bldtop_dir/;
13 use OpenSSL
::Test
::Utils
;
15 use TLSProxy
::Message
;
17 my $test_name = "test_sslrecords";
20 plan skip_all
=> "TLSProxy isn't usable on $^O"
23 plan skip_all
=> "$test_name needs the dynamic engine feature enabled"
24 if disabled
("engine") || disabled
("dynamic-engine");
26 plan skip_all
=> "$test_name needs the sock feature enabled"
29 plan skip_all
=> "$test_name needs TLS1.2 or TLS1.3 for running dummyproxy check"
30 if disabled
("tls1_3") && disabled
("tls1_2");
32 my $testplanisset = 0;
33 my $inject_recs_num = undef;
34 my $content_type = undef;
35 my $boundary_test_type = undef;
36 my $fatal_alert = undef; # set by filters at expected fatal alerts
37 my $sslv2testtype = undef;
38 my $proxy_start_success = 0;
43 skip
"TLS 1.2 is disabled", 21 if disabled
("tls1_2");
49 skip
"DTLS 1.2 is disabled", 21 if disabled
("dtls1_2");
50 skip
"DTLSProxy does not work on Windows", 21 if $^O
=~ /^(MSWin32)$/;
56 my $run_test_as_dtls = shift;
59 if ($run_test_as_dtls == 1) {
60 $proxy = TLSProxy
::Proxy
->new_dtls(
61 \
&add_empty_recs_filter
,
62 cmdstr
(app
([ "openssl" ]), display
=> 1),
63 srctop_file
("apps", "server.pem"),
64 (!$ENV{HARNESS_ACTIVE
} || $ENV{HARNESS_VERBOSE
})
67 $proxy = TLSProxy
::Proxy
->new(
68 \
&add_empty_recs_filter
,
69 cmdstr
(app
([ "openssl" ]), display
=> 1),
70 srctop_file
("apps", "server.pem"),
71 (!$ENV{HARNESS_ACTIVE
} || $ENV{HARNESS_VERBOSE
})
75 $fatal_alert = 0; # set by filters at expected fatal alerts
77 skip
"Record tests not intended for dtls", 1 if $run_test_as_dtls == 1;
78 #Test 1: Injecting out of context empty records should fail
80 $content_type = TLSProxy
::Record
::RT_APPLICATION_DATA
;
83 $proxy->serverflags("-tls1_2");
84 $proxy->clientflags("-no_tls1_3");
85 $proxy_start_success = $proxy->start();
86 ok
($fatal_alert, "Out of context empty records test");
89 skip
"TLSProxy did not start correctly", 21 if $proxy_start_success == 0
90 && $run_test_as_dtls == 0;
92 #Test 2: Injecting in context empty records should succeed
94 $content_type = TLSProxy
::Record
::RT_HANDSHAKE
;
95 if ($run_test_as_dtls == 1) {
96 $proxy->serverflags("-min_protocol DTLSv1.2 -max_protocol DTLSv1.2");
97 $proxy->clientflags("-max_protocol DTLSv1.2");
99 $proxy->serverflags("-tls1_2");
100 $proxy->clientflags("-no_tls1_3");
102 $proxy_start_success = $proxy->start();
104 skip
"TLSProxy did not start correctly", 20 if $proxy_start_success == 0
105 && $run_test_as_dtls == 1;
107 ok
($proxy_start_success && TLSProxy
::Message
->success(),
108 "In context empty records test".($run_test_as_dtls == 1) ?
" for DTLS" : " for TLS");
111 skip
"Record tests not intended for dtls", 7 if $run_test_as_dtls == 1;
112 #Test 3: Injecting too many in context empty records should fail
115 #We allow 32 consecutive in context empty records
116 $inject_recs_num = 33;
117 $proxy->serverflags("-tls1_2");
118 $proxy->clientflags("-no_tls1_3");
120 ok
($fatal_alert, "Too many in context empty records test");
122 #Test 4: Injecting a fragmented fatal alert should fail. We expect the server to
123 # send back an alert of its own because it cannot handle fragmented
127 $proxy->filter(\
&add_frag_alert_filter
);
128 $proxy->serverflags("-tls1_2");
129 $proxy->clientflags("-no_tls1_3");
131 ok
($fatal_alert, "Fragmented alert records test");
133 #Run some SSLv2 ClientHello tests
136 TLSV1_2_IN_SSLV2
=> 0,
138 FRAGMENTED_IN_TLSV1_2
=> 2,
139 FRAGMENTED_IN_SSLV2
=> 3,
140 ALERT_BEFORE_SSLV2
=> 4
143 # The TLSv1.2 in SSLv2 ClientHello need to run at security level 0
144 # because in a SSLv2 ClientHello we can't send extensions to indicate
145 # which signature algorithm we want to use, and the default is SHA1.
147 #Test 5: Inject an SSLv2 style record format for a TLSv1.2 ClientHello
148 $sslv2testtype = TLSV1_2_IN_SSLV2
;
150 $proxy->filter(\
&add_sslv2_filter
);
151 $proxy->serverflags("-tls1_2");
152 $proxy->clientflags("-no_tls1_3 -legacy_renegotiation");
153 $proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
155 ok
(TLSProxy
::Message
->success(), "TLSv1.2 in SSLv2 ClientHello test");
157 #Test 6: Inject an SSLv2 style record format for an SSLv2 ClientHello. We don't
158 # support this so it should fail. We actually treat it as an unknown
159 # protocol so we don't even send an alert in this case.
160 $sslv2testtype = SSLV2_IN_SSLV2
;
162 $proxy->serverflags("-tls1_2");
163 $proxy->clientflags("-no_tls1_3");
164 $proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
166 ok
(TLSProxy
::Message
->fail(), "SSLv2 in SSLv2 ClientHello test");
168 #Test 7: Sanity check ClientHello fragmentation. This isn't really an SSLv2 test
169 # at all, but it gives us confidence that Test 8 fails for the right
171 $sslv2testtype = FRAGMENTED_IN_TLSV1_2
;
173 $proxy->serverflags("-tls1_2");
174 $proxy->clientflags("-no_tls1_3");
175 $proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
177 ok
(TLSProxy
::Message
->success(), "Fragmented ClientHello in TLSv1.2 test");
179 #Test 8: Fragment a TLSv1.2 ClientHello across a TLS1.2 record; an SSLv2
180 # record; and another TLS1.2 record. This isn't allowed so should fail
181 $sslv2testtype = FRAGMENTED_IN_SSLV2
;
183 $proxy->serverflags("-tls1_2");
184 $proxy->clientflags("-no_tls1_3");
185 $proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
187 ok
(TLSProxy
::Message
->fail(), "Fragmented ClientHello in TLSv1.2/SSLv2 test");
189 #Test 9: Send a TLS warning alert before an SSLv2 ClientHello. This should
190 # fail because an SSLv2 ClientHello must be the first record.
191 $sslv2testtype = ALERT_BEFORE_SSLV2
;
193 $proxy->serverflags("-tls1_2");
194 $proxy->clientflags("-no_tls1_3");
195 $proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
197 ok
(TLSProxy
::Message
->fail(), "Alert before SSLv2 ClientHello test");
199 #Unrecognised record type tests
201 #Test 10: Sending an unrecognised record type in TLS1.2 should fail
204 if ($run_test_as_dtls == 1) {
205 $proxy->serverflags("-min_protocol DTLSv1.2 -max_protocol DTLSv1.2");
206 $proxy->clientflags("-max_protocol DTLSv1.2");
208 $proxy->serverflags("-tls1_2");
209 $proxy->clientflags("-no_tls1_3");
211 $proxy->filter(\
&add_unknown_record_type
);
212 $proxy_start_success = $proxy->start();
214 if ($run_test_as_dtls == 1) {
215 ok
($proxy_start_success == 0, "Unrecognised record type in DTLS1.2");
217 ok
($fatal_alert, "Unrecognised record type in TLS1.2");
221 skip
"TLSv1.1 or DTLSv1 disabled", 1 if ($run_test_as_dtls == 0 && disabled
("tls1_1"))
222 || ($run_test_as_dtls == 1 && disabled
("dtls1"));
224 #Test 11: Sending an unrecognised record type in TLS1.1 should fail
227 if ($run_test_as_dtls == 1) {
228 $proxy->clientflags("-min_protocol DTLSv1 -max_protocol DTLSv1 -cipher DEFAULT:\@SECLEVEL=0");
230 $proxy->clientflags("-tls1_1 -cipher DEFAULT:\@SECLEVEL=0");
232 $proxy->ciphers("AES128-SHA:\@SECLEVEL=0");
233 $proxy_start_success = $proxy->start();
234 if ($run_test_as_dtls == 1) {
235 ok
($proxy_start_success == 0, "Unrecognised record type in DTLSv1");
237 ok
($fatal_alert, "Unrecognised record type in TLSv1.1");
242 skip
"Record tests not intended for dtls", 10 if $run_test_as_dtls == 1;
243 #Test 12: Sending a different record version in TLS1.2 should fail
246 $proxy->clientflags("-tls1_2");
247 $proxy->filter(\
&change_version
);
249 ok
($fatal_alert, "Changed record version in TLS1.2");
251 #TLS1.3 specific tests
253 skip
"TLSv1.3 disabled", 9
254 if disabled
("tls1_3") || (disabled
("ec") && disabled
("dh"));
256 #Test 13: Sending a different record version in TLS1.3 should fail
258 $proxy->filter(\
&change_version
);
260 ok
(TLSProxy
::Message
->fail(), "Changed record version in TLS1.3");
262 #Test 14: Sending an unrecognised record type in TLS1.3 should fail
265 $proxy->filter(\
&add_unknown_record_type
);
267 ok
($fatal_alert, "Unrecognised record type in TLS1.3");
269 #Test 15: Sending an outer record type other than app data once encrypted
273 $proxy->filter(\
&change_outer_record_type
);
275 ok
($fatal_alert, "Wrong outer record type in TLS1.3");
278 DATA_AFTER_SERVER_HELLO
=> 0,
279 DATA_AFTER_FINISHED
=> 1,
280 DATA_AFTER_KEY_UPDATE
=> 2,
281 DATA_BETWEEN_KEY_UPDATE
=> 3,
282 NO_DATA_BETWEEN_KEY_UPDATE
=> 4,
285 #Test 16: Sending a ServerHello which doesn't end on a record boundary
289 $boundary_test_type = DATA_AFTER_SERVER_HELLO
;
290 $proxy->filter(\
¬_on_record_boundary
);
292 ok
($fatal_alert, "Record not on boundary in TLS1.3 (ServerHello)");
294 #Test 17: Sending a Finished which doesn't end on a record boundary
298 $boundary_test_type = DATA_AFTER_FINISHED
;
300 ok
($fatal_alert, "Record not on boundary in TLS1.3 (Finished)");
302 #Test 18: Sending a KeyUpdate which doesn't end on a record boundary
306 $boundary_test_type = DATA_AFTER_KEY_UPDATE
;
308 ok
($fatal_alert, "Record not on boundary in TLS1.3 (KeyUpdate)");
310 #Test 19: Sending application data in the middle of a fragmented KeyUpdate
311 # should fail. Strictly speaking this is not a record boundary test
312 # but we use the same filter.
315 $boundary_test_type = DATA_BETWEEN_KEY_UPDATE
;
317 ok
($fatal_alert, "Data between KeyUpdate");
319 #Test 20: Fragmented KeyUpdate. This should succeed. Strictly speaking this
320 # is not a record boundary test but we use the same filter.
322 $boundary_test_type = NO_DATA_BETWEEN_KEY_UPDATE
;
324 ok
(TLSProxy
::Message
->success(), "No data between KeyUpdate");
327 skip
"EC disabled", 1 if disabled
("ec");
329 #Test 21: Force an HRR and change the "real" ServerHello to have a protocol
330 # record version of 0x0301 (TLSv1.0). At this point we have already
331 # decided that we are doing TLSv1.3 but are still using plaintext
332 # records. The server should be sending a record version of 0x303
333 # (TLSv1.2), but the RFC requires us to ignore this field so we
334 # should tolerate the incorrect version.
336 $proxy->filter(\
&change_server_hello_version
);
337 $proxy->serverflags("-groups P-256"); # Force an HRR
339 ok
(TLSProxy
::Message
->success(), "Bad ServerHello record version after HRR");
346 sub add_empty_recs_filter
349 my $records = $proxy->record_list;
350 my $isdtls = $proxy->isdtls();
352 # We're only interested in the initial ClientHello
353 if ($proxy->flight != 0) {
354 $fatal_alert = 1 if @
{$records}[-1]->is_fatal_alert(1) == TLSProxy
::Message
::AL_DESC_UNEXPECTED_MESSAGE
;
358 for (my $i = 0; $i < $inject_recs_num; $i++) {
361 $record = TLSProxy
::Record
->new_dtls(
364 TLSProxy
::Record
::VERS_DTLS_1_2
,
375 $record = TLSProxy
::Record
->new(
378 TLSProxy
::Record
::VERS_TLS_1_2
,
387 push @
{$records}, $record;
391 sub add_frag_alert_filter
394 my $records = $proxy->record_list;
397 # We're only interested in the initial ClientHello
398 if ($proxy->flight != 0) {
399 $fatal_alert = 1 if @
{$records}[-1]->is_fatal_alert(1) == TLSProxy
::Message
::AL_DESC_UNEXPECTED_MESSAGE
;
403 # Add a zero length fragment first
404 #my $record = TLSProxy::Record->new(
406 # TLSProxy::Record::RT_ALERT,
407 # TLSProxy::Record::VERS_TLS_1_2,
414 #push @{$proxy->record_list}, $record;
416 # Now add the alert level (Fatal) as a separate record
417 $byte = pack('C', TLSProxy
::Message
::AL_LEVEL_FATAL
);
418 my $record = TLSProxy
::Record
->new(
420 TLSProxy
::Record
::RT_ALERT
,
421 TLSProxy
::Record
::VERS_TLS_1_2
,
429 push @
{$records}, $record;
431 # And finally the description (Unexpected message) in a third record
432 $byte = pack('C', TLSProxy
::Message
::AL_DESC_UNEXPECTED_MESSAGE
);
433 $record = TLSProxy
::Record
->new(
435 TLSProxy
::Record
::RT_ALERT
,
436 TLSProxy
::Record
::VERS_TLS_1_2
,
444 push @
{$records}, $record;
453 # We're only interested in the initial ClientHello
454 if ($proxy->flight != 0) {
458 # Ditch the real ClientHello - we're going to replace it with our own
459 shift @
{$proxy->record_list};
461 if ($sslv2testtype == ALERT_BEFORE_SSLV2
) {
462 my $alert = pack('CC', TLSProxy
::Message
::AL_LEVEL_FATAL
,
463 TLSProxy
::Message
::AL_DESC_NO_RENEGOTIATION
);
464 my $alertlen = length $alert;
465 $record = TLSProxy
::Record
->new(
467 TLSProxy
::Record
::RT_ALERT
,
468 TLSProxy
::Record
::VERS_TLS_1_2
,
477 push @
{$proxy->record_list}, $record;
480 if ($sslv2testtype == ALERT_BEFORE_SSLV2
481 || $sslv2testtype == TLSV1_2_IN_SSLV2
482 || $sslv2testtype == SSLV2_IN_SSLV2
) {
483 # This is an SSLv2 format ClientHello
488 0x00, 0x03, # Ciphersuites len
489 0x00, 0x00, # Session id len
490 0x00, 0x20, # Challenge len
491 0x00, 0x00, 0x2f, #AES128-SHA
492 0x01, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
493 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
494 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6; # Challenge
496 if ($sslv2testtype == SSLV2_IN_SSLV2
) {
497 # Set the version to "real" SSLv2
498 vec($clienthello, 1, 8) = 0x00;
499 vec($clienthello, 2, 8) = 0x02;
502 my $chlen = length $clienthello;
504 $record = TLSProxy
::Record
->new(
506 TLSProxy
::Record
::RT_HANDSHAKE
,
507 TLSProxy
::Record
::VERS_TLS_1_2
,
516 push @
{$proxy->record_list}, $record;
518 # For this test we're using a real TLS ClientHello
522 0x00, 0x00, 0x2D, # Message length
523 0x03, 0x03, # TLSv1.2
524 0x01, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
525 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
526 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, # Random
527 0x00, # Session id len
528 0x00, 0x04, # Ciphersuites len
529 0x00, 0x2f, # AES128-SHA
530 0x00, 0xff, # Empty reneg info SCSV
531 0x01, # Compression methods len
532 0x00, # Null compression
533 0x00, 0x00; # Extensions len
535 # Split this into 3: A TLS record; a SSLv2 record and a TLS record.
536 # We deliberately split the second record prior to the Challenge/Random
537 # and set the first byte of the random to 1. This makes the second SSLv2
538 # record look like an SSLv2 ClientHello
539 my $frag1 = substr $clienthello, 0, 6;
540 my $frag2 = substr $clienthello, 6, 32;
541 my $frag3 = substr $clienthello, 38;
543 my $fraglen = length $frag1;
544 $record = TLSProxy
::Record
->new(
546 TLSProxy
::Record
::RT_HANDSHAKE
,
547 TLSProxy
::Record
::VERS_TLS_1_2
,
555 push @
{$proxy->record_list}, $record;
557 $fraglen = length $frag2;
559 if ($sslv2testtype == FRAGMENTED_IN_SSLV2
) {
564 $record = TLSProxy
::Record
->new(
566 TLSProxy
::Record
::RT_HANDSHAKE
,
567 TLSProxy
::Record
::VERS_TLS_1_2
,
575 push @
{$proxy->record_list}, $record;
577 $fraglen = length $frag3;
578 $record = TLSProxy
::Record
->new(
580 TLSProxy
::Record
::RT_HANDSHAKE
,
581 TLSProxy
::Record
::VERS_TLS_1_2
,
589 push @
{$proxy->record_list}, $record;
594 sub add_unknown_record_type
597 my $records = $proxy->record_list;
598 my $isdtls = $proxy->isdtls;
601 # We'll change a record after the initial version neg has taken place
602 if ($proxy->flight == 0) {
605 } elsif ($proxy->flight != 1 || $added_record) {
606 $fatal_alert = 1 if @
{$records}[-1]->is_fatal_alert(0) == TLSProxy
::Message
::AL_DESC_UNEXPECTED_MESSAGE
;
613 $record = TLSProxy
::Record
->new_dtls(
615 TLSProxy
::Record
::RT_UNKNOWN
,
616 @
{$records}[-1]->version(),
617 @
{$records}[-1]->epoch(),
618 @
{$records}[-1]->seq() +1,
627 $record = TLSProxy
::Record
->new(
629 TLSProxy
::Record
::RT_UNKNOWN
,
630 @
{$records}[-1]->version(),
640 #Find ServerHello record and insert after that
642 for ($i = 0; ${$proxy->record_list}[$i]->flight() < 1; $i++) {
647 splice @
{$proxy->record_list}, $i, 0, $record;
654 my $records = $proxy->record_list;
656 # We'll change a version after the initial version neg has taken place
657 if ($proxy->flight != 1) {
658 $fatal_alert = 1 if @
{$records}[-1]->is_fatal_alert(0) == TLSProxy
::Message
::AL_DESC_PROTOCOL_VERSION
;
662 if ($#{$records} > 1) {
663 # ... typically in ServerHelloDone
664 @
{$records}[-1]->version(TLSProxy
::Record
::VERS_TLS_1_1
);
668 sub change_server_hello_version
671 my $records = $proxy->record_list;
673 # We're only interested in changing the ServerHello after an HRR
674 if ($proxy->flight != 3) {
678 # The ServerHello has index 5
685 @
{$records}[5]->version(TLSProxy
::Record
::VERS_TLS_1_0
);
688 sub change_outer_record_type
691 my $records = $proxy->record_list;
693 # We'll change a record after the initial version neg has taken place
694 if ($proxy->flight != 1) {
695 $fatal_alert = 1 if @
{$records}[-1]->is_fatal_alert(0) == TLSProxy
::Message
::AL_DESC_UNEXPECTED_MESSAGE
;
699 # Find CCS record and change record after that
701 foreach my $record (@
{$records}) {
702 last if $record->content_type == TLSProxy
::Record
::RT_CCS
;
705 if (defined(${$records}[++$i])) {
706 ${$records}[$i]->outer_content_type(TLSProxy
::Record
::RT_HANDSHAKE
);
710 sub not_on_record_boundary
713 my $records = $proxy->record_list;
716 #Find server's first flight
717 if ($proxy->flight != 1) {
718 $fatal_alert = 1 if @
{$records}[-1]->is_fatal_alert(0) == TLSProxy
::Message
::AL_DESC_UNEXPECTED_MESSAGE
;
722 if ($boundary_test_type == DATA_AFTER_SERVER_HELLO
) {
723 #Merge the ServerHello and EncryptedExtensions records into one
725 foreach my $record (@
{$records}) {
726 if ($record->content_type == TLSProxy
::Record
::RT_HANDSHAKE
) {
727 $record->{sent
} = 1; # pretend it's sent already
733 if (defined(${$records}[$i+1])) {
734 $data = ${$records}[$i]->data();
735 $data .= ${$records}[$i+1]->decrypt_data();
736 ${$records}[$i+1]->data($data);
737 ${$records}[$i+1]->len(length $data);
739 #Delete the old ServerHello record
740 splice @
{$records}, $i, 1;
742 } elsif ($boundary_test_type == DATA_AFTER_FINISHED
) {
743 return if @
{$proxy->{message_list
}}[-1]->{mt
}
744 != TLSProxy
::Message
::MT_FINISHED
;
746 my $last_record = @
{$records}[-1];
747 $data = $last_record->decrypt_data;
749 #Add a KeyUpdate message onto the end of the Finished record
750 my $keyupdate = pack "C5",
752 0x00, 0x00, 0x01, # Message length
753 0x00; # Update not requested
757 #Add content type and tag
758 $data .= pack("C", TLSProxy
::Record
::RT_HANDSHAKE
).("\0"x16
);
761 $last_record->data($data);
762 $last_record->len(length $data);
763 } elsif ($boundary_test_type == DATA_AFTER_KEY_UPDATE
) {
764 return if @
{$proxy->{message_list
}}[-1]->{mt
}
765 != TLSProxy
::Message
::MT_FINISHED
;
767 #KeyUpdates must end on a record boundary
769 my $record = TLSProxy
::Record
->new(
771 TLSProxy
::Record
::RT_APPLICATION_DATA
,
772 TLSProxy
::Record
::VERS_TLS_1_2
,
781 #Add two KeyUpdate messages into a single record
782 my $keyupdate = pack "C5",
784 0x00, 0x00, 0x01, # Message length
785 0x00; # Update not requested
787 $data = $keyupdate.$keyupdate;
789 #Add content type and tag
790 $data .= pack("C", TLSProxy
::Record
::RT_HANDSHAKE
).("\0"x16
);
792 $record->data($data);
793 $record->len(length $data);
794 push @
{$records}, $record;
796 return if @
{$proxy->{message_list
}}[-1]->{mt
}
797 != TLSProxy
::Message
::MT_FINISHED
;
799 my $record = TLSProxy
::Record
->new(
801 TLSProxy
::Record
::RT_APPLICATION_DATA
,
802 TLSProxy
::Record
::VERS_TLS_1_2
,
811 #Add a partial KeyUpdate message into the record
813 0x18; # KeyUpdate message type. Omit the rest of the message header
815 #Add content type and tag
816 $data .= pack("C", TLSProxy
::Record
::RT_HANDSHAKE
).("\0"x16
);
818 $record->data($data);
819 $record->len(length $data);
820 push @
{$records}, $record;
822 if ($boundary_test_type == DATA_BETWEEN_KEY_UPDATE
) {
823 #Now add an app data record
824 $record = TLSProxy
::Record
->new(
826 TLSProxy
::Record
::RT_APPLICATION_DATA
,
827 TLSProxy
::Record
::VERS_TLS_1_2
,
836 #Add an empty app data record (just content type and tag)
837 $data = pack("C", TLSProxy
::Record
::RT_APPLICATION_DATA
).("\0"x16
);
839 $record->data($data);
840 $record->len(length $data);
841 push @
{$records}, $record;
844 #Now add the rest of the KeyUpdate message
845 $record = TLSProxy
::Record
->new(
847 TLSProxy
::Record
::RT_APPLICATION_DATA
,
848 TLSProxy
::Record
::VERS_TLS_1_2
,
857 #Add the last 4 bytes of the KeyUpdate record
859 0x00, 0x00, 0x01, # Message length
860 0x00; # Update not requested
862 #Add content type and tag
863 $data .= pack("C", TLSProxy
::Record
::RT_HANDSHAKE
).("\0"x16
);
865 $record->data($data);
866 $record->len(length $data);
867 push @
{$records}, $record;