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