]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/recipes/70-test_sslrecords.t
Add DRBG self tests
[thirdparty/openssl.git] / test / recipes / 70-test_sslrecords.t
CommitLineData
4f0c4757 1#! /usr/bin/env perl
6738bf14 2# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
4f0c4757 3#
909f1a2e 4# Licensed under the Apache License 2.0 (the "License"). You may not use
4f0c4757
MC
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;
c4220c0f
AP
10use feature 'state';
11
4f0c4757
MC
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"
c5856878 20 if $^O =~ /^(VMS)$/;
4f0c4757
MC
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
80f397e2
MC
28plan skip_all => "$test_name needs TLSv1.2 enabled"
29 if disabled("tls1_2");
4f0c4757
MC
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
774c909b 39my $boundary_test_type;
c4220c0f 40my $fatal_alert = 0; # set by filters at expected fatal alerts
774c909b 41
4f0c4757
MC
42#Test 1: Injecting out of context empty records should fail
43my $content_type = TLSProxy::Record::RT_APPLICATION_DATA;
44my $inject_recs_num = 1;
837e591d 45$proxy->serverflags("-tls1_2");
b02b5743 46$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
73e62d40 47plan tests => 20;
c4220c0f 48ok($fatal_alert, "Out of context empty records test");
4f0c4757
MC
49
50#Test 2: Injecting in context empty records should succeed
51$proxy->clear();
52$content_type = TLSProxy::Record::RT_HANDSHAKE;
837e591d 53$proxy->serverflags("-tls1_2");
4f0c4757
MC
54$proxy->start();
55ok(TLSProxy::Message->success(), "In context empty records test");
56
57#Test 3: Injecting too many in context empty records should fail
c4220c0f 58$fatal_alert = 0;
4f0c4757
MC
59$proxy->clear();
60#We allow 32 consecutive in context empty records
61$inject_recs_num = 33;
837e591d 62$proxy->serverflags("-tls1_2");
4f0c4757 63$proxy->start();
c4220c0f 64ok($fatal_alert, "Too many in context empty records test");
4f0c4757 65
bd990e25
MC
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
c4220c0f 69$fatal_alert = 0;
c3fd55d4
MC
70$proxy->clear();
71$proxy->filter(\&add_frag_alert_filter);
837e591d 72$proxy->serverflags("-tls1_2");
c3fd55d4 73$proxy->start();
c4220c0f 74ok($fatal_alert, "Fragmented alert records test");
c3fd55d4 75
a2a0c86b
MC
76#Run some SSLv2 ClientHello tests
77
78use 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
a2a0c86b
MC
86my $sslv2testtype = TLSV1_2_IN_SSLV2;
87$proxy->clear();
88$proxy->filter(\&add_sslv2_filter);
837e591d 89$proxy->serverflags("-tls1_2");
a2a0c86b
MC
90$proxy->start();
91ok(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();
837e591d 98$proxy->serverflags("-tls1_2");
a2a0c86b 99$proxy->start();
0f82d2f5 100ok(TLSProxy::Message->fail(), "SSLv2 in SSLv2 ClientHello test");
a2a0c86b
MC
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();
837e591d 107$proxy->serverflags("-tls1_2");
a2a0c86b
MC
108$proxy->start();
109ok(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();
837e591d 115$proxy->serverflags("-tls1_2");
a2a0c86b
MC
116$proxy->start();
117ok(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();
837e591d 123$proxy->serverflags("-tls1_2");
a2a0c86b
MC
124$proxy->start();
125ok(TLSProxy::Message->fail(), "Alert before SSLv2 ClientHello test");
1f3e70a4 126
69687aa8 127#Unrecognised record type tests
1f3e70a4
MC
128
129#Test 10: Sending an unrecognised record type in TLS1.2 should fail
c4220c0f 130$fatal_alert = 0;
1f3e70a4 131$proxy->clear();
9970290e 132$proxy->serverflags("-tls1_2");
1f3e70a4
MC
133$proxy->filter(\&add_unknown_record_type);
134$proxy->start();
c4220c0f 135ok($fatal_alert, "Unrecognised record type in TLS1.2");
1f3e70a4 136
774c909b
MC
137SKIP: {
138 skip "TLSv1.1 disabled", 1 if disabled("tls1_1");
139
140 #Test 11: Sending an unrecognised record type in TLS1.1 should fail
c4220c0f 141 $fatal_alert = 0;
1f3e70a4
MC
142 $proxy->clear();
143 $proxy->clientflags("-tls1_1");
144 $proxy->start();
c4220c0f 145 ok($fatal_alert, "Unrecognised record type in TLS1.1");
1f3e70a4
MC
146}
147
8e47ee18 148#Test 12: Sending a different record version in TLS1.2 should fail
c4220c0f 149$fatal_alert = 0;
8e47ee18
MC
150$proxy->clear();
151$proxy->clientflags("-tls1_2");
152$proxy->filter(\&change_version);
153$proxy->start();
c4220c0f 154ok($fatal_alert, "Changed record version in TLS1.2");
8e47ee18 155
b4c6e37e 156#TLS1.3 specific tests
774c909b 157SKIP: {
73e62d40 158 skip "TLSv1.3 disabled", 8 if disabled("tls1_3");
774c909b 159
3295d242 160 #Test 13: Sending a different record version in TLS1.3 should fail
8e47ee18
MC
161 $proxy->clear();
162 $proxy->filter(\&change_version);
163 $proxy->start();
3295d242 164 ok(TLSProxy::Message->fail(), "Changed record version in TLS1.3");
b4c6e37e
MC
165
166 #Test 14: Sending an unrecognised record type in TLS1.3 should fail
c4220c0f 167 $fatal_alert = 0;
b4c6e37e
MC
168 $proxy->clear();
169 $proxy->filter(\&add_unknown_record_type);
170 $proxy->start();
c4220c0f 171 ok($fatal_alert, "Unrecognised record type in TLS1.3");
b4c6e37e
MC
172
173 #Test 15: Sending an outer record type other than app data once encrypted
174 #should fail
c4220c0f 175 $fatal_alert = 0;
b4c6e37e
MC
176 $proxy->clear();
177 $proxy->filter(\&change_outer_record_type);
178 $proxy->start();
c4220c0f 179 ok($fatal_alert, "Wrong outer record type in TLS1.3");
774c909b
MC
180
181 use constant {
182 DATA_AFTER_SERVER_HELLO => 0,
183 DATA_AFTER_FINISHED => 1,
73e62d40
MC
184 DATA_AFTER_KEY_UPDATE => 2,
185 DATA_BETWEEN_KEY_UPDATE => 3,
186 NO_DATA_BETWEEN_KEY_UPDATE => 4,
774c909b
MC
187 };
188
189 #Test 16: Sending a ServerHello which doesn't end on a record boundary
190 # should fail
c4220c0f 191 $fatal_alert = 0;
774c909b
MC
192 $proxy->clear();
193 $boundary_test_type = DATA_AFTER_SERVER_HELLO;
194 $proxy->filter(\&not_on_record_boundary);
195 $proxy->start();
c4220c0f 196 ok($fatal_alert, "Record not on boundary in TLS1.3 (ServerHello)");
774c909b
MC
197
198 #Test 17: Sending a Finished which doesn't end on a record boundary
199 # should fail
c4220c0f 200 $fatal_alert = 0;
774c909b
MC
201 $proxy->clear();
202 $boundary_test_type = DATA_AFTER_FINISHED;
774c909b 203 $proxy->start();
c4220c0f 204 ok($fatal_alert, "Record not on boundary in TLS1.3 (Finished)");
774c909b
MC
205
206 #Test 18: Sending a KeyUpdate which doesn't end on a record boundary
207 # should fail
c4220c0f 208 $fatal_alert = 0;
774c909b
MC
209 $proxy->clear();
210 $boundary_test_type = DATA_AFTER_KEY_UPDATE;
774c909b 211 $proxy->start();
c4220c0f 212 ok($fatal_alert, "Record not on boundary in TLS1.3 (KeyUpdate)");
73e62d40
MC
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");
b4c6e37e
MC
229 }
230
8e47ee18 231
4f0c4757
MC
232sub add_empty_recs_filter
233{
234 my $proxy = shift;
c4220c0f 235 my $records = $proxy->record_list;
4f0c4757
MC
236
237 # We're only interested in the initial ClientHello
238 if ($proxy->flight != 0) {
c4220c0f 239 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(1) == 10;
4f0c4757
MC
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,
a2a0c86b 251 0,
4f0c4757
MC
252 "",
253 ""
254 );
c4220c0f 255 push @{$records}, $record;
4f0c4757
MC
256 }
257}
c3fd55d4
MC
258
259sub add_frag_alert_filter
260{
261 my $proxy = shift;
c4220c0f 262 my $records = $proxy->record_list;
c3fd55d4
MC
263 my $byte;
264
265 # We're only interested in the initial ClientHello
266 if ($proxy->flight != 0) {
c4220c0f 267 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(1) == 10;
c3fd55d4
MC
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
60250017 284 # Now add the alert level (Fatal) as a separate record
c3fd55d4
MC
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,
a2a0c86b 291 0,
c3fd55d4
MC
292 1,
293 1,
294 $byte,
295 $byte
296 );
c4220c0f 297 push @{$records}, $record;
c3fd55d4
MC
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,
a2a0c86b 306 0,
c3fd55d4
MC
307 1,
308 1,
309 $byte,
310 $byte
311 );
c4220c0f 312 push @{$records}, $record;
c3fd55d4 313}
a2a0c86b
MC
314
315sub 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}
1f3e70a4
MC
461
462sub add_unknown_record_type
463{
464 my $proxy = shift;
c4220c0f
AP
465 my $records = $proxy->record_list;
466 state $added_record;
1f3e70a4
MC
467
468 # We'll change a record after the initial version neg has taken place
c4220c0f
AP
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;
1f3e70a4
MC
474 return;
475 }
476
1f3e70a4 477 my $record = TLSProxy::Record->new(
b4c6e37e 478 1,
1f3e70a4 479 TLSProxy::Record::RT_UNKNOWN,
c4220c0f 480 @{$records}[-1]->version(),
1f3e70a4
MC
481 1,
482 0,
483 1,
484 1,
485 "X",
486 "X"
487 );
488
b4c6e37e
MC
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;
c4220c0f 497 $added_record = 1;
1f3e70a4 498}
8e47ee18
MC
499
500sub change_version
501{
502 my $proxy = shift;
c4220c0f 503 my $records = $proxy->record_list;
8e47ee18
MC
504
505 # We'll change a version after the initial version neg has taken place
3295d242 506 if ($proxy->flight != 1) {
c4220c0f 507 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(0) == 70;
8e47ee18
MC
508 return;
509 }
510
c4220c0f
AP
511 if ($#{$records} > 1) {
512 # ... typically in ServerHelloDone
513 @{$records}[-1]->version(TLSProxy::Record::VERS_TLS_1_1);
514 }
8e47ee18 515}
b4c6e37e
MC
516
517sub change_outer_record_type
518{
519 my $proxy = shift;
c4220c0f 520 my $records = $proxy->record_list;
b4c6e37e
MC
521
522 # We'll change a record after the initial version neg has taken place
523 if ($proxy->flight != 1) {
c4220c0f 524 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(0) == 10;
b4c6e37e
MC
525 return;
526 }
527
c4220c0f
AP
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);
b4c6e37e 536 }
b4c6e37e 537}
774c909b
MC
538
539sub not_on_record_boundary
540{
541 my $proxy = shift;
c4220c0f 542 my $records = $proxy->record_list;
774c909b
MC
543 my $data;
544
545 #Find server's first flight
546 if ($proxy->flight != 1) {
c4220c0f 547 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(0) == 10;
774c909b
MC
548 return;
549 }
550
551 if ($boundary_test_type == DATA_AFTER_SERVER_HELLO) {
552 #Merge the ServerHello and EncryptedExtensions records into one
c4220c0f
AP
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++;
774c909b 560 }
774c909b 561
c4220c0f
AP
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 }
774c909b 571 } elsif ($boundary_test_type == DATA_AFTER_FINISHED) {
c4220c0f
AP
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;
774c909b
MC
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
c4220c0f
AP
590 $last_record->data($data);
591 $last_record->len(length $data);
73e62d40 592 } elsif ($boundary_test_type == DATA_AFTER_KEY_UPDATE) {
c4220c0f
AP
593 return if @{$proxy->{message_list}}[-1]->{mt}
594 != TLSProxy::Message::MT_FINISHED;
595
774c909b
MC
596 #KeyUpdates must end on a record boundary
597
598 my $record = TLSProxy::Record->new(
599 1,
600 TLSProxy::Record::RT_APPLICATION_DATA,
c4220c0f 601 TLSProxy::Record::VERS_TLS_1_2,
774c909b
MC
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);
c4220c0f 623 push @{$records}, $record;
73e62d40
MC
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
774c909b
MC
698 }
699}