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