Deleted Added
full compact
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(\&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
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}