70-test_sslrecords.t (1.1.1.4) | 70-test_sslrecords.t (1.1.1.1) |
---|---|
1#! /usr/bin/env perl | 1#! /usr/bin/env perl |
2# Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. | 2# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. |
3# 4# Licensed under the OpenSSL license (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; | 3# 4# Licensed under the OpenSSL license (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" | 10use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/; 11use OpenSSL::Test::Utils; 12use TLSProxy::Proxy; 13 14my $test_name = "test_sslrecords"; 15setup($test_name); 16 17plan skip_all => "TLSProxy isn't usable on $^O" |
20 if $^O =~ /^(VMS)$/; | 18 if $^O =~ /^(VMS|MSWin32)$/; |
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 | 19 20plan skip_all => "$test_name needs the dynamic engine feature enabled" 21 if disabled("engine") || disabled("dynamic-engine"); 22 23plan skip_all => "$test_name needs the sock feature enabled" 24 if disabled("sock"); 25 26plan skip_all => "$test_name needs TLSv1.2 enabled" 27 if disabled("tls1_2"); 28 29$ENV{OPENSSL_ia32cap} = '~0x200000200000000'; 30my $proxy = TLSProxy::Proxy->new( 31 \&add_empty_recs_filter, 32 cmdstr(app(["openssl"]), display => 1), 33 srctop_file("apps", "server.pem"), 34 (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}) 35); 36 |
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; | 37#Test 1: Injecting out of context empty records should fail 38my $content_type = TLSProxy::Record::RT_APPLICATION_DATA; 39my $inject_recs_num = 1; |
45$proxy->serverflags("-tls1_2"); | |
46$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; | 40$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; |
47plan tests => 20; 48ok($fatal_alert, "Out of context empty records test"); | 41my $num_tests = 10; 42if (!disabled("tls1_1")) { 43 $num_tests++; 44} 45plan tests => $num_tests; 46ok(TLSProxy::Message->fail(), "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; | 47 48#Test 2: Injecting in context empty records should succeed 49$proxy->clear(); 50$content_type = TLSProxy::Record::RT_HANDSHAKE; |
53$proxy->serverflags("-tls1_2"); | |
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 | 51$proxy->start(); 52ok(TLSProxy::Message->success(), "In context empty records test"); 53 54#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; | 55$proxy->clear(); 56#We allow 32 consecutive in context empty records 57$inject_recs_num = 33; |
62$proxy->serverflags("-tls1_2"); | |
63$proxy->start(); | 58$proxy->start(); |
64ok($fatal_alert, "Too many in context empty records test"); | 59ok(TLSProxy::Message->fail(), "Too many in context empty records test"); |
65 | 60 |
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; | 61#Test 4: Injecting a fragmented fatal alert should fail. We actually expect no 62# alerts to be sent from either side because *we* injected the fatal 63# alert, i.e. this will look like a disorderly close |
70$proxy->clear(); 71$proxy->filter(\&add_frag_alert_filter); | 64$proxy->clear(); 65$proxy->filter(\&add_frag_alert_filter); |
72$proxy->serverflags("-tls1_2"); | |
73$proxy->start(); | 66$proxy->start(); |
74ok($fatal_alert, "Fragmented alert records test"); | 67ok(!TLSProxy::Message->end(), "Fragmented alert records test"); |
75 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 86my $sslv2testtype = TLSV1_2_IN_SSLV2; 87$proxy->clear(); 88$proxy->filter(\&add_sslv2_filter); | 68 69#Run some SSLv2 ClientHello tests 70 71use constant { 72 TLSV1_2_IN_SSLV2 => 0, 73 SSLV2_IN_SSLV2 => 1, 74 FRAGMENTED_IN_TLSV1_2 => 2, 75 FRAGMENTED_IN_SSLV2 => 3, 76 ALERT_BEFORE_SSLV2 => 4 77}; 78#Test 5: Inject an SSLv2 style record format for a TLSv1.2 ClientHello 79my $sslv2testtype = TLSV1_2_IN_SSLV2; 80$proxy->clear(); 81$proxy->filter(\&add_sslv2_filter); |
89$proxy->serverflags("-tls1_2"); | |
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(); | 82$proxy->start(); 83ok(TLSProxy::Message->success(), "TLSv1.2 in SSLv2 ClientHello test"); 84 85#Test 6: Inject an SSLv2 style record format for an SSLv2 ClientHello. We don't 86# support this so it should fail. We actually treat it as an unknown 87# protocol so we don't even send an alert in this case. 88$sslv2testtype = SSLV2_IN_SSLV2; 89$proxy->clear(); |
98$proxy->serverflags("-tls1_2"); | |
99$proxy->start(); | 90$proxy->start(); |
100ok(TLSProxy::Message->fail(), "SSLv2 in SSLv2 ClientHello test"); | 91ok(!TLSProxy::Message->end(), "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(); | 92 93#Test 7: Sanity check ClientHello fragmentation. This isn't really an SSLv2 test 94# at all, but it gives us confidence that Test 8 fails for the right 95# reasons 96$sslv2testtype = FRAGMENTED_IN_TLSV1_2; 97$proxy->clear(); |
107$proxy->serverflags("-tls1_2"); | |
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(); | 98$proxy->start(); 99ok(TLSProxy::Message->success(), "Fragmented ClientHello in TLSv1.2 test"); 100 101#Test 8: Fragment a TLSv1.2 ClientHello across a TLS1.2 record; an SSLv2 102# record; and another TLS1.2 record. This isn't allowed so should fail 103$sslv2testtype = FRAGMENTED_IN_SSLV2; 104$proxy->clear(); |
115$proxy->serverflags("-tls1_2"); | |
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(); | 105$proxy->start(); 106ok(TLSProxy::Message->fail(), "Fragmented ClientHello in TLSv1.2/SSLv2 test"); 107 108#Test 9: Send a TLS warning alert before an SSLv2 ClientHello. This should 109# fail because an SSLv2 ClientHello must be the first record. 110$sslv2testtype = ALERT_BEFORE_SSLV2; 111$proxy->clear(); |
123$proxy->serverflags("-tls1_2"); | |
124$proxy->start(); 125ok(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 | 112$proxy->start(); 113ok(TLSProxy::Message->fail(), "Alert before SSLv2 ClientHello test"); 114 115#Unrecognised record type tests 116 117#Test 10: Sending an unrecognised record type in TLS1.2 should fail |
130$fatal_alert = 0; | |
131$proxy->clear(); | 118$proxy->clear(); |
132$proxy->serverflags("-tls1_2"); | |
133$proxy->filter(\&add_unknown_record_type); 134$proxy->start(); | 119$proxy->filter(\&add_unknown_record_type); 120$proxy->start(); |
135ok($fatal_alert, "Unrecognised record type in TLS1.2"); | 121ok(TLSProxy::Message->fail(), "Unrecognised record type in TLS1.2"); |
136 | 122 |
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 141 $fatal_alert = 0; | 123#Test 11: Sending an unrecognised record type in TLS1.1 should fail 124if (!disabled("tls1_1")) { |
142 $proxy->clear(); 143 $proxy->clientflags("-tls1_1"); 144 $proxy->start(); | 125 $proxy->clear(); 126 $proxy->clientflags("-tls1_1"); 127 $proxy->start(); |
145 ok($fatal_alert, "Unrecognised record type in TLS1.1"); | 128 ok(TLSProxy::Message->fail(), "Unrecognised record type in TLS1.1"); |
146} 147 | 129} 130 |
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(); 154ok($fatal_alert, "Changed record version in TLS1.2"); 155 156#TLS1.3 specific tests 157SKIP: { 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(\¬_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 | |
232sub add_empty_recs_filter 233{ 234 my $proxy = shift; | 131sub add_empty_recs_filter 132{ 133 my $proxy = shift; |
235 my $records = $proxy->record_list; | |
236 237 # We're only interested in the initial ClientHello 238 if ($proxy->flight != 0) { | 134 135 # We're only interested in the initial ClientHello 136 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 ); | 137 return; 138 } 139 140 for (my $i = 0; $i < $inject_recs_num; $i++) { 141 my $record = TLSProxy::Record->new( 142 0, 143 $content_type, 144 TLSProxy::Record::VERS_TLS_1_2, 145 0, 146 0, 147 0, 148 0, 149 "", 150 "" 151 ); |
255 push @{$records}, $record; | 152 153 push @{$proxy->record_list}, $record; |
256 } 257} 258 259sub add_frag_alert_filter 260{ 261 my $proxy = shift; | 154 } 155} 156 157sub add_frag_alert_filter 158{ 159 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) { | 160 my $byte; 161 162 # We're only interested in the initial ClientHello 163 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, --- 13 unchanged lines hidden (view full) --- 289 TLSProxy::Record::VERS_TLS_1_2, 290 1, 291 0, 292 1, 293 1, 294 $byte, 295 $byte 296 ); | 164 return; 165 } 166 167 # Add a zero length fragment first 168 #my $record = TLSProxy::Record->new( 169 # 0, 170 # TLSProxy::Record::RT_ALERT, 171 # TLSProxy::Record::VERS_TLS_1_2, --- 13 unchanged lines hidden (view full) --- 185 TLSProxy::Record::VERS_TLS_1_2, 186 1, 187 0, 188 1, 189 1, 190 $byte, 191 $byte 192 ); |
297 push @{$records}, $record; | 193 push @{$proxy->record_list}, $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 ); | 194 195 # And finally the description (Unexpected message) in a third record 196 $byte = pack('C', TLSProxy::Message::AL_DESC_UNEXPECTED_MESSAGE); 197 $record = TLSProxy::Record->new( 198 0, 199 TLSProxy::Record::RT_ALERT, 200 TLSProxy::Record::VERS_TLS_1_2, 201 1, 202 0, 203 1, 204 1, 205 $byte, 206 $byte 207 ); |
312 push @{$records}, $record; | 208 push @{$proxy->record_list}, $record; |
313} 314 315sub add_sslv2_filter 316{ 317 my $proxy = shift; 318 my $clienthello; 319 my $record; 320 --- 136 unchanged lines hidden (view full) --- 457 push @{$proxy->record_list}, $record; 458 } 459 460} 461 462sub add_unknown_record_type 463{ 464 my $proxy = shift; | 209} 210 211sub add_sslv2_filter 212{ 213 my $proxy = shift; 214 my $clienthello; 215 my $record; 216 --- 136 unchanged lines hidden (view full) --- 353 push @{$proxy->record_list}, $record; 354 } 355 356} 357 358sub add_unknown_record_type 359{ 360 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 | 361 362 # We'll change a record after the initial version neg has taken place |
469 if ($proxy->flight == 0) { 470 $added_record = 0; | 363 if ($proxy->flight != 2) { |
471 return; | 364 return; |
472 } elsif ($proxy->flight != 1 || $added_record) { 473 $fatal_alert = 1 if @{$records}[-1]->is_fatal_alert(0) == 10; 474 return; | |
475 } 476 | 365 } 366 |
367 my $lastrec = ${$proxy->record_list}[-1]; |
|
477 my $record = TLSProxy::Record->new( | 368 my $record = TLSProxy::Record->new( |
478 1, | 369 2, |
479 TLSProxy::Record::RT_UNKNOWN, | 370 TLSProxy::Record::RT_UNKNOWN, |
480 @{$records}[-1]->version(), | 371 $lastrec->version(), |
481 1, 482 0, 483 1, 484 1, 485 "X", 486 "X" 487 ); 488 | 372 1, 373 0, 374 1, 375 1, 376 "X", 377 "X" 378 ); 379 |
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; | 380 unshift @{$proxy->record_list}, $record; |
498} | 381} |
499 500sub 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 517sub 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 539sub 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} | |