Add test for CVE-2020-1967
Add to test_sslsigalgs a TLSProxy test that injects a
"signature_algorithms_cert" extension that contains an unallocated
codepoint.
The test currently fails, since s_server segfaults instead of
ignoring the unrecognized value.
Since "signature_algorithms" and "signature_algorithms_cert" are very
similar, also add the analogous test for "signature_algorithms".
Reviewed-by: Matt Caswell <matt@openssl.org>
Benjamin Kaduk authored 4 years ago
Matt Caswell committed 4 years ago
43 | 43 | COMPAT_SIGALGS => 6, |
44 | 44 | SIGALGS_CERT_ALL => 7, |
45 | 45 | SIGALGS_CERT_PKCS => 8, |
46 | SIGALGS_CERT_INVALID => 9 | |
46 | SIGALGS_CERT_INVALID => 9, | |
47 | UNRECOGNIZED_SIGALGS_CERT => 10, | |
48 | UNRECOGNIZED_SIGALG => 11 | |
47 | 49 | }; |
48 | 50 | |
49 | 51 | #Note: Throughout this test we override the default ciphersuites where TLSv1.2 |
52 | 54 | |
53 | 55 | #Test 1: Default sig algs should succeed |
54 | 56 | $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; |
55 | plan tests => 24; | |
57 | plan tests => 26; | |
56 | 58 | ok(TLSProxy::Message->success, "Default sigalgs"); |
57 | 59 | my $testtype; |
58 | 60 | |
279 | 281 | $proxy->filter(\&modify_sigalgs_cert_filter); |
280 | 282 | $proxy->start(); |
281 | 283 | ok(TLSProxy::Message->fail, "No matching certificate for sigalgs_cert"); |
284 | } | |
285 | ||
286 | SKIP: { | |
287 | skip "TLS 1.3 disabled", 2 if disabled("tls1_3"); | |
288 | #Test 25: Send an unrecognized signature_algorithms_cert | |
289 | # We should be able to skip over the unrecognized value and use a | |
290 | # valid one that appears later in the list. | |
291 | $proxy->clear(); | |
292 | $proxy->filter(\&inject_unrecognized_sigalg); | |
293 | $proxy->clientflags("-tls1_3"); | |
294 | # Use -xcert to get SSL_check_chain() to run in the cert_cb. This is | |
295 | # needed to trigger (e.g.) CVE-2020-1967 | |
296 | $proxy->serverflags("" . | |
297 | " -xcert " . srctop_file("test", "certs", "servercert.pem") . | |
298 | " -xkey " . srctop_file("test", "certs", "serverkey.pem") . | |
299 | " -xchain " . srctop_file("test", "certs", "rootcert.pem")); | |
300 | $testtype = UNRECOGNIZED_SIGALGS_CERT; | |
301 | $proxy->start(); | |
302 | ok(TLSProxy::Message->success(), "Unrecognized sigalg_cert in ClientHello"); | |
303 | ||
304 | #Test 26: Send an unrecognized signature_algorithms | |
305 | # We should be able to skip over the unrecognized value and use a | |
306 | # valid one that appears later in the list. | |
307 | $proxy->clear(); | |
308 | $proxy->filter(\&inject_unrecognized_sigalg); | |
309 | $proxy->clientflags("-tls1_3"); | |
310 | $proxy->serverflags("" . | |
311 | " -xcert " . srctop_file("test", "certs", "servercert.pem") . | |
312 | " -xkey " . srctop_file("test", "certs", "serverkey.pem") . | |
313 | " -xchain " . srctop_file("test", "certs", "rootcert.pem")); | |
314 | $testtype = UNRECOGNIZED_SIGALG; | |
315 | $proxy->start(); | |
316 | ok(TLSProxy::Message->success(), "Unrecognized sigalg in ClientHello"); | |
282 | 317 | } |
283 | 318 | |
284 | 319 | |
426 | 461 | } |
427 | 462 | } |
428 | 463 | } |
464 | ||
465 | sub inject_unrecognized_sigalg | |
466 | { | |
467 | my $proxy = shift; | |
468 | my $type; | |
469 | ||
470 | # We're only interested in the initial ClientHello | |
471 | if ($proxy->flight != 0) { | |
472 | return; | |
473 | } | |
474 | if ($testtype == UNRECOGNIZED_SIGALGS_CERT) { | |
475 | $type = TLSProxy::Message::EXT_SIG_ALGS_CERT; | |
476 | } elsif ($testtype == UNRECOGNIZED_SIGALG) { | |
477 | $type = TLSProxy::Message::EXT_SIG_ALGS; | |
478 | } else { | |
479 | return; | |
480 | } | |
481 | ||
482 | my $ext = pack "C8", | |
483 | 0x00, 0x06, #Extension length | |
484 | 0xfe, 0x18, #private use | |
485 | 0x04, 0x01, #rsa_pkcs1_sha256 | |
486 | 0x08, 0x04; #rsa_pss_rsae_sha256; | |
487 | my $message = ${$proxy->message_list}[0]; | |
488 | $message->set_extension($type, $ext); | |
489 | $message->repack; | |
490 | } |