1 1.1 christos #! /usr/bin/env perl 2 1.1.1.4 christos # Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos # 4 1.1.1.4 christos # Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos # this file except in compliance with the License. You can obtain a copy 6 1.1 christos # in the file LICENSE in the source distribution or at 7 1.1 christos # https://www.openssl.org/source/license.html 8 1.1 christos 9 1.1 christos use strict; 10 1.1 christos use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/; 11 1.1 christos use OpenSSL::Test::Utils; 12 1.1 christos use TLSProxy::Proxy; 13 1.1 christos 14 1.1 christos my $test_name = "test_sslsigalgs"; 15 1.1 christos setup($test_name); 16 1.1 christos 17 1.1 christos plan skip_all => "TLSProxy isn't usable on $^O" 18 1.1 christos if $^O =~ /^(VMS)$/; 19 1.1 christos 20 1.1 christos plan skip_all => "$test_name needs the dynamic engine feature enabled" 21 1.1 christos if disabled("engine") || disabled("dynamic-engine"); 22 1.1 christos 23 1.1 christos plan skip_all => "$test_name needs the sock feature enabled" 24 1.1 christos if disabled("sock"); 25 1.1 christos 26 1.1 christos plan skip_all => "$test_name needs TLS1.2 or TLS1.3 enabled" 27 1.1 christos if disabled("tls1_2") && disabled("tls1_3"); 28 1.1 christos 29 1.1 christos $ENV{OPENSSL_ia32cap} = '~0x200000200000000'; 30 1.1 christos my $proxy = TLSProxy::Proxy->new( 31 1.1 christos undef, 32 1.1 christos cmdstr(app(["openssl"]), display => 1), 33 1.1 christos srctop_file("apps", "server.pem"), 34 1.1 christos (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}) 35 1.1 christos ); 36 1.1 christos 37 1.1 christos use constant { 38 1.1 christos NO_SIG_ALGS_EXT => 0, 39 1.1 christos EMPTY_SIG_ALGS_EXT => 1, 40 1.1 christos NO_KNOWN_SIG_ALGS => 2, 41 1.1 christos NO_PSS_SIG_ALGS => 3, 42 1.1 christos PSS_ONLY_SIG_ALGS => 4, 43 1.1 christos PURE_SIGALGS => 5, 44 1.1 christos COMPAT_SIGALGS => 6, 45 1.1 christos SIGALGS_CERT_ALL => 7, 46 1.1 christos SIGALGS_CERT_PKCS => 8, 47 1.1.1.3 christos SIGALGS_CERT_INVALID => 9, 48 1.1.1.3 christos UNRECOGNIZED_SIGALGS_CERT => 10, 49 1.1.1.3 christos UNRECOGNIZED_SIGALG => 11 50 1.1 christos }; 51 1.1 christos 52 1.1 christos #Note: Throughout this test we override the default ciphersuites where TLSv1.2 53 1.1 christos # is expected to ensure that a ServerKeyExchange message is sent that uses 54 1.1 christos # the sigalgs 55 1.1 christos 56 1.1 christos #Test 1: Default sig algs should succeed 57 1.1.1.4 christos $proxy->clientflags("-no_tls1_3") if disabled("ec") && disabled("dh"); 58 1.1 christos $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; 59 1.1.1.3 christos plan tests => 26; 60 1.1 christos ok(TLSProxy::Message->success, "Default sigalgs"); 61 1.1 christos my $testtype; 62 1.1 christos 63 1.1 christos SKIP: { 64 1.1.1.4 christos skip "TLSv1.3 disabled", 6 65 1.1.1.4 christos if disabled("tls1_3") || (disabled("ec") && disabled("dh")); 66 1.1 christos 67 1.1 christos $proxy->filter(\&sigalgs_filter); 68 1.1 christos 69 1.1 christos #Test 2: Sending no sig algs extension in TLSv1.3 should fail 70 1.1 christos $proxy->clear(); 71 1.1 christos $testtype = NO_SIG_ALGS_EXT; 72 1.1 christos $proxy->start(); 73 1.1 christos ok(TLSProxy::Message->fail, "No TLSv1.3 sigalgs"); 74 1.1 christos 75 1.1 christos #Test 3: Sending an empty sig algs extension in TLSv1.3 should fail 76 1.1 christos $proxy->clear(); 77 1.1 christos $testtype = EMPTY_SIG_ALGS_EXT; 78 1.1 christos $proxy->start(); 79 1.1 christos ok(TLSProxy::Message->fail, "Empty TLSv1.3 sigalgs"); 80 1.1 christos 81 1.1 christos #Test 4: Sending a list with no recognised sig algs in TLSv1.3 should fail 82 1.1 christos $proxy->clear(); 83 1.1 christos $testtype = NO_KNOWN_SIG_ALGS; 84 1.1 christos $proxy->start(); 85 1.1 christos ok(TLSProxy::Message->fail, "No known TLSv1.3 sigalgs"); 86 1.1 christos 87 1.1 christos #Test 5: Sending a sig algs list without pss for an RSA cert in TLSv1.3 88 1.1 christos # should fail 89 1.1 christos $proxy->clear(); 90 1.1 christos $testtype = NO_PSS_SIG_ALGS; 91 1.1 christos $proxy->start(); 92 1.1 christos ok(TLSProxy::Message->fail, "No PSS TLSv1.3 sigalgs"); 93 1.1 christos 94 1.1 christos #Test 6: Sending only TLSv1.3 PSS sig algs in TLSv1.3 should succeed 95 1.1 christos #TODO(TLS1.3): Do we need to verify the cert to make sure its a PSS only 96 1.1 christos #cert in this case? 97 1.1 christos $proxy->clear(); 98 1.1 christos $testtype = PSS_ONLY_SIG_ALGS; 99 1.1 christos $proxy->start(); 100 1.1 christos ok(TLSProxy::Message->success, "PSS only sigalgs in TLSv1.3"); 101 1.1 christos 102 1.1 christos #Test 7: Modify the CertificateVerify sigalg from rsa_pss_rsae_sha256 to 103 1.1 christos # rsa_pss_pss_sha256. This should fail because the public key OID 104 1.1 christos # in the certificate is rsaEncryption and not rsassaPss 105 1.1 christos $proxy->filter(\&modify_cert_verify_sigalg); 106 1.1 christos $proxy->clear(); 107 1.1 christos $proxy->start(); 108 1.1 christos ok(TLSProxy::Message->fail, 109 1.1 christos "Mismatch between CertVerify sigalg and public key OID"); 110 1.1 christos } 111 1.1 christos 112 1.1 christos SKIP: { 113 1.1 christos skip "EC or TLSv1.3 disabled", 1 114 1.1 christos if disabled("tls1_3") || disabled("ec"); 115 1.1 christos #Test 8: Sending a valid sig algs list but not including a sig type that 116 1.1 christos # matches the certificate should fail in TLSv1.3. 117 1.1 christos $proxy->clear(); 118 1.1 christos $proxy->clientflags("-sigalgs ECDSA+SHA256"); 119 1.1 christos $proxy->filter(undef); 120 1.1 christos $proxy->start(); 121 1.1 christos ok(TLSProxy::Message->fail, "No matching TLSv1.3 sigalgs"); 122 1.1 christos } 123 1.1 christos 124 1.1 christos SKIP: { 125 1.1 christos skip "EC, TLSv1.3 or TLSv1.2 disabled", 1 126 1.1 christos if disabled("tls1_2") || disabled("tls1_3") || disabled("ec"); 127 1.1 christos 128 1.1 christos #Test 9: Sending a full list of TLSv1.3 sig algs but negotiating TLSv1.2 129 1.1 christos # should succeed 130 1.1 christos $proxy->clear(); 131 1.1 christos $proxy->serverflags("-no_tls1_3"); 132 1.1 christos $proxy->ciphers("ECDHE-RSA-AES128-SHA"); 133 1.1 christos $proxy->filter(undef); 134 1.1 christos $proxy->start(); 135 1.1 christos ok(TLSProxy::Message->success, "TLSv1.3 client TLSv1.2 server"); 136 1.1 christos } 137 1.1 christos 138 1.1 christos SKIP: { 139 1.1.1.2 christos skip "EC or TLSv1.2 disabled", 10 if disabled("tls1_2") || disabled("ec"); 140 1.1 christos 141 1.1 christos $proxy->filter(\&sigalgs_filter); 142 1.1 christos 143 1.1.1.4 christos #Test 10: Sending no sig algs extension in TLSv1.2 will make it use 144 1.1.1.4 christos # SHA1, which is only supported at security level 0. 145 1.1 christos $proxy->clear(); 146 1.1 christos $testtype = NO_SIG_ALGS_EXT; 147 1.1.1.4 christos $proxy->clientflags("-no_tls1_3 -cipher DEFAULT:\@SECLEVEL=0"); 148 1.1.1.4 christos $proxy->ciphers("ECDHE-RSA-AES128-SHA:\@SECLEVEL=0"); 149 1.1.1.2 christos $proxy->start(); 150 1.1.1.4 christos ok(TLSProxy::Message->success, "No TLSv1.2 sigalgs seclevel 0"); 151 1.1.1.2 christos 152 1.1.1.2 christos #Test 11: Sending no sig algs extension in TLSv1.2 should fail at security 153 1.1.1.4 christos # level 1 since it will try to use SHA1. Testing client at level 0, 154 1.1.1.4 christos # server level 1. 155 1.1.1.2 christos $proxy->clear(); 156 1.1.1.2 christos $testtype = NO_SIG_ALGS_EXT; 157 1.1.1.4 christos $proxy->clientflags("-tls1_2 -cipher DEFAULT:\@SECLEVEL=0"); 158 1.1.1.4 christos $proxy->ciphers("DEFAULT:\@SECLEVEL=1"); 159 1.1.1.2 christos $proxy->start(); 160 1.1.1.4 christos ok(TLSProxy::Message->fail, "No TLSv1.2 sigalgs server seclevel 1"); 161 1.1.1.2 christos 162 1.1.1.2 christos #Test 12: Sending no sig algs extension in TLSv1.2 should fail at security 163 1.1.1.4 christos # level 1 since it will try to use SHA1. Testing client at level 1, 164 1.1.1.4 christos # server level 0. 165 1.1.1.2 christos $proxy->clear(); 166 1.1.1.2 christos $testtype = NO_SIG_ALGS_EXT; 167 1.1.1.4 christos $proxy->clientflags("-tls1_2 -cipher DEFAULT:\@SECLEVEL=1"); 168 1.1.1.4 christos $proxy->ciphers("DEFAULT:\@SECLEVEL=0"); 169 1.1 christos $proxy->start(); 170 1.1.1.2 christos ok(TLSProxy::Message->fail, "No TLSv1.2 sigalgs client seclevel 2"); 171 1.1 christos 172 1.1.1.2 christos #Test 13: Sending an empty sig algs extension in TLSv1.2 should fail 173 1.1 christos $proxy->clear(); 174 1.1 christos $testtype = EMPTY_SIG_ALGS_EXT; 175 1.1 christos $proxy->clientflags("-no_tls1_3"); 176 1.1 christos $proxy->ciphers("ECDHE-RSA-AES128-SHA"); 177 1.1 christos $proxy->start(); 178 1.1 christos ok(TLSProxy::Message->fail, "Empty TLSv1.2 sigalgs"); 179 1.1 christos 180 1.1.1.2 christos #Test 14: Sending a list with no recognised sig algs in TLSv1.2 should fail 181 1.1 christos $proxy->clear(); 182 1.1 christos $testtype = NO_KNOWN_SIG_ALGS; 183 1.1 christos $proxy->clientflags("-no_tls1_3"); 184 1.1 christos $proxy->ciphers("ECDHE-RSA-AES128-SHA"); 185 1.1 christos $proxy->start(); 186 1.1 christos ok(TLSProxy::Message->fail, "No known TLSv1.3 sigalgs"); 187 1.1 christos 188 1.1.1.2 christos #Test 15: Sending a sig algs list without pss for an RSA cert in TLSv1.2 189 1.1 christos # should succeed 190 1.1 christos $proxy->clear(); 191 1.1 christos $testtype = NO_PSS_SIG_ALGS; 192 1.1 christos $proxy->clientflags("-no_tls1_3"); 193 1.1 christos $proxy->ciphers("ECDHE-RSA-AES128-SHA"); 194 1.1 christos $proxy->start(); 195 1.1 christos ok(TLSProxy::Message->success, "No PSS TLSv1.2 sigalgs"); 196 1.1 christos 197 1.1.1.2 christos #Test 16: Sending only TLSv1.3 PSS sig algs in TLSv1.2 should succeed 198 1.1 christos $proxy->clear(); 199 1.1 christos $testtype = PSS_ONLY_SIG_ALGS; 200 1.1 christos $proxy->serverflags("-no_tls1_3"); 201 1.1 christos $proxy->ciphers("ECDHE-RSA-AES128-SHA"); 202 1.1 christos $proxy->start(); 203 1.1 christos ok(TLSProxy::Message->success, "PSS only sigalgs in TLSv1.2"); 204 1.1 christos 205 1.1.1.2 christos #Test 17: Responding with a sig alg we did not send in TLSv1.2 should fail 206 1.1 christos # We send rsa_pkcs1_sha256 and respond with rsa_pss_rsae_sha256 207 1.1 christos # TODO(TLS1.3): Add a similar test to the TLSv1.3 section above 208 1.1 christos # when we have an API capable of configuring the TLSv1.3 sig algs 209 1.1 christos $proxy->clear(); 210 1.1 christos $testtype = PSS_ONLY_SIG_ALGS; 211 1.1 christos $proxy->clientflags("-no_tls1_3 -sigalgs RSA+SHA256"); 212 1.1 christos $proxy->ciphers("ECDHE-RSA-AES128-SHA"); 213 1.1 christos $proxy->start(); 214 1.1 christos ok(TLSProxy::Message->fail, "Sigalg we did not send in TLSv1.2"); 215 1.1 christos 216 1.1.1.2 christos #Test 18: Sending a valid sig algs list but not including a sig type that 217 1.1 christos # matches the certificate should fail in TLSv1.2 218 1.1 christos $proxy->clear(); 219 1.1 christos $proxy->clientflags("-no_tls1_3 -sigalgs ECDSA+SHA256"); 220 1.1 christos $proxy->ciphers("ECDHE-RSA-AES128-SHA"); 221 1.1 christos $proxy->filter(undef); 222 1.1 christos $proxy->start(); 223 1.1 christos ok(TLSProxy::Message->fail, "No matching TLSv1.2 sigalgs"); 224 1.1 christos $proxy->filter(\&sigalgs_filter); 225 1.1 christos 226 1.1.1.4 christos #Test 19: No sig algs extension, ECDSA cert, will use SHA1, 227 1.1.1.4 christos # TLSv1.2 should succeed at security level 0 228 1.1 christos $proxy->clear(); 229 1.1 christos $testtype = NO_SIG_ALGS_EXT; 230 1.1.1.4 christos $proxy->clientflags("-no_tls1_3 -cipher DEFAULT:\@SECLEVEL=0"); 231 1.1 christos $proxy->serverflags("-cert " . srctop_file("test", "certs", 232 1.1 christos "server-ecdsa-cert.pem") . 233 1.1 christos " -key " . srctop_file("test", "certs", 234 1.1 christos "server-ecdsa-key.pem")), 235 1.1.1.4 christos $proxy->ciphers("ECDHE-ECDSA-AES128-SHA:\@SECLEVEL=0"); 236 1.1 christos $proxy->start(); 237 1.1 christos ok(TLSProxy::Message->success, "No TLSv1.2 sigalgs, ECDSA"); 238 1.1 christos } 239 1.1 christos 240 1.1 christos my ($dsa_status, $sha1_status, $sha224_status); 241 1.1 christos SKIP: { 242 1.1.1.4 christos skip "TLSv1.3 disabled", 2 243 1.1.1.4 christos if disabled("tls1_3") 244 1.1.1.4 christos || disabled("dsa") 245 1.1.1.4 christos || (disabled("ec") && disabled("dh")); 246 1.1.1.2 christos #Test 20: signature_algorithms with 1.3-only ClientHello 247 1.1 christos $testtype = PURE_SIGALGS; 248 1.1 christos $dsa_status = $sha1_status = $sha224_status = 0; 249 1.1 christos $proxy->clear(); 250 1.1 christos $proxy->clientflags("-tls1_3"); 251 1.1 christos $proxy->filter(\&modify_sigalgs_filter); 252 1.1 christos $proxy->start(); 253 1.1 christos ok($dsa_status && $sha1_status && $sha224_status, 254 1.1.1.4 christos "DSA and SHA1 sigalgs not sent for 1.3-only ClientHello"); 255 1.1 christos 256 1.1.1.2 christos #Test 21: signature_algorithms with backwards compatible ClientHello 257 1.1 christos SKIP: { 258 1.1 christos skip "TLSv1.2 disabled", 1 if disabled("tls1_2"); 259 1.1 christos $testtype = COMPAT_SIGALGS; 260 1.1 christos $dsa_status = $sha1_status = $sha224_status = 0; 261 1.1 christos $proxy->clear(); 262 1.1.1.4 christos $proxy->clientflags("-cipher AES128-SHA\@SECLEVEL=0"); 263 1.1 christos $proxy->filter(\&modify_sigalgs_filter); 264 1.1 christos $proxy->start(); 265 1.1 christos ok($dsa_status && $sha1_status && $sha224_status, 266 1.1.1.4 christos "backwards compatible sigalg sent for compat ClientHello"); 267 1.1 christos } 268 1.1 christos } 269 1.1 christos 270 1.1 christos SKIP: { 271 1.1.1.4 christos skip "TLSv1.3 disabled", 5 272 1.1.1.4 christos if disabled("tls1_3") || (disabled("ec") && disabled("dh")); 273 1.1.1.2 christos #Test 22: Insert signature_algorithms_cert that match normal sigalgs 274 1.1 christos $testtype = SIGALGS_CERT_ALL; 275 1.1 christos $proxy->clear(); 276 1.1 christos $proxy->filter(\&modify_sigalgs_cert_filter); 277 1.1 christos $proxy->start(); 278 1.1 christos ok(TLSProxy::Message->success, "sigalgs_cert in TLSv1.3"); 279 1.1 christos 280 1.1.1.2 christos #Test 23: Insert signature_algorithms_cert that forces PKCS#1 cert 281 1.1 christos $testtype = SIGALGS_CERT_PKCS; 282 1.1 christos $proxy->clear(); 283 1.1 christos $proxy->filter(\&modify_sigalgs_cert_filter); 284 1.1 christos $proxy->start(); 285 1.1 christos ok(TLSProxy::Message->success, "sigalgs_cert in TLSv1.3 with PKCS#1 cert"); 286 1.1 christos 287 1.1.1.2 christos #Test 24: Insert signature_algorithms_cert that fails 288 1.1 christos $testtype = SIGALGS_CERT_INVALID; 289 1.1 christos $proxy->clear(); 290 1.1 christos $proxy->filter(\&modify_sigalgs_cert_filter); 291 1.1 christos $proxy->start(); 292 1.1 christos ok(TLSProxy::Message->fail, "No matching certificate for sigalgs_cert"); 293 1.1 christos 294 1.1.1.3 christos #Test 25: Send an unrecognized signature_algorithms_cert 295 1.1.1.3 christos # We should be able to skip over the unrecognized value and use a 296 1.1.1.3 christos # valid one that appears later in the list. 297 1.1.1.3 christos $proxy->clear(); 298 1.1.1.3 christos $proxy->filter(\&inject_unrecognized_sigalg); 299 1.1.1.3 christos $proxy->clientflags("-tls1_3"); 300 1.1.1.3 christos # Use -xcert to get SSL_check_chain() to run in the cert_cb. This is 301 1.1.1.3 christos # needed to trigger (e.g.) CVE-2020-1967 302 1.1.1.3 christos $proxy->serverflags("" . 303 1.1.1.3 christos " -xcert " . srctop_file("test", "certs", "servercert.pem") . 304 1.1.1.3 christos " -xkey " . srctop_file("test", "certs", "serverkey.pem") . 305 1.1.1.3 christos " -xchain " . srctop_file("test", "certs", "rootcert.pem")); 306 1.1.1.3 christos $testtype = UNRECOGNIZED_SIGALGS_CERT; 307 1.1.1.3 christos $proxy->start(); 308 1.1.1.3 christos ok(TLSProxy::Message->success(), "Unrecognized sigalg_cert in ClientHello"); 309 1.1.1.3 christos 310 1.1.1.3 christos #Test 26: Send an unrecognized signature_algorithms 311 1.1.1.3 christos # We should be able to skip over the unrecognized value and use a 312 1.1.1.3 christos # valid one that appears later in the list. 313 1.1.1.3 christos $proxy->clear(); 314 1.1.1.3 christos $proxy->filter(\&inject_unrecognized_sigalg); 315 1.1.1.3 christos $proxy->clientflags("-tls1_3"); 316 1.1.1.3 christos $proxy->serverflags("" . 317 1.1.1.3 christos " -xcert " . srctop_file("test", "certs", "servercert.pem") . 318 1.1.1.3 christos " -xkey " . srctop_file("test", "certs", "serverkey.pem") . 319 1.1.1.3 christos " -xchain " . srctop_file("test", "certs", "rootcert.pem")); 320 1.1.1.3 christos $testtype = UNRECOGNIZED_SIGALG; 321 1.1.1.3 christos $proxy->start(); 322 1.1.1.3 christos ok(TLSProxy::Message->success(), "Unrecognized sigalg in ClientHello"); 323 1.1.1.3 christos } 324 1.1.1.3 christos 325 1.1 christos 326 1.1 christos 327 1.1 christos sub sigalgs_filter 328 1.1 christos { 329 1.1 christos my $proxy = shift; 330 1.1 christos 331 1.1 christos # We're only interested in the initial ClientHello 332 1.1 christos if ($proxy->flight != 0) { 333 1.1 christos return; 334 1.1 christos } 335 1.1 christos 336 1.1 christos foreach my $message (@{$proxy->message_list}) { 337 1.1 christos if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { 338 1.1 christos if ($testtype == NO_SIG_ALGS_EXT) { 339 1.1 christos $message->delete_extension(TLSProxy::Message::EXT_SIG_ALGS); 340 1.1 christos } else { 341 1.1 christos my $sigalg; 342 1.1 christos if ($testtype == EMPTY_SIG_ALGS_EXT) { 343 1.1 christos $sigalg = pack "C2", 0x00, 0x00; 344 1.1 christos } elsif ($testtype == NO_KNOWN_SIG_ALGS) { 345 1.1 christos $sigalg = pack "C4", 0x00, 0x02, 0xff, 0xff; 346 1.1 christos } elsif ($testtype == NO_PSS_SIG_ALGS) { 347 1.1 christos #No PSS sig algs - just send rsa_pkcs1_sha256 348 1.1 christos $sigalg = pack "C4", 0x00, 0x02, 0x04, 0x01; 349 1.1 christos } else { 350 1.1 christos #PSS sig algs only - just send rsa_pss_rsae_sha256 351 1.1 christos $sigalg = pack "C4", 0x00, 0x02, 0x08, 0x04; 352 1.1 christos } 353 1.1 christos $message->set_extension(TLSProxy::Message::EXT_SIG_ALGS, $sigalg); 354 1.1 christos } 355 1.1 christos 356 1.1 christos $message->repack(); 357 1.1 christos } 358 1.1 christos } 359 1.1 christos } 360 1.1 christos 361 1.1 christos sub modify_sigalgs_filter 362 1.1 christos { 363 1.1 christos my $proxy = shift; 364 1.1 christos 365 1.1 christos # We're only interested in the initial ClientHello 366 1.1 christos return if ($proxy->flight != 0); 367 1.1 christos 368 1.1 christos foreach my $message (@{$proxy->message_list}) { 369 1.1 christos my $ext; 370 1.1 christos my @algs; 371 1.1 christos 372 1.1 christos if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { 373 1.1 christos if ($testtype == PURE_SIGALGS) { 374 1.1 christos my $ok = 1; 375 1.1 christos $ext = $message->extension_data->{TLSProxy::Message::EXT_SIG_ALGS}; 376 1.1 christos @algs = unpack('S>*', $ext); 377 1.1 christos # unpack will unpack the length as well 378 1.1 christos shift @algs; 379 1.1 christos foreach (@algs) { 380 1.1 christos if ($_ == TLSProxy::Message::SIG_ALG_DSA_SHA256 381 1.1 christos || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA384 382 1.1 christos || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA512 383 1.1 christos || $_ == TLSProxy::Message::OSSL_SIG_ALG_DSA_SHA224 384 1.1 christos || $_ == TLSProxy::Message::SIG_ALG_RSA_PKCS1_SHA1 385 1.1 christos || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA1 386 1.1 christos || $_ == TLSProxy::Message::SIG_ALG_ECDSA_SHA1) { 387 1.1 christos $ok = 0; 388 1.1 christos } 389 1.1 christos } 390 1.1 christos $sha1_status = $dsa_status = $sha224_status = 1 if ($ok); 391 1.1 christos } elsif ($testtype == COMPAT_SIGALGS) { 392 1.1 christos $ext = $message->extension_data->{TLSProxy::Message::EXT_SIG_ALGS}; 393 1.1 christos @algs = unpack('S>*', $ext); 394 1.1 christos # unpack will unpack the length as well 395 1.1 christos shift @algs; 396 1.1 christos foreach (@algs) { 397 1.1 christos if ($_ == TLSProxy::Message::SIG_ALG_DSA_SHA256 398 1.1 christos || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA384 399 1.1 christos || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA512) { 400 1.1 christos $dsa_status = 1; 401 1.1 christos } 402 1.1 christos if ($_ == TLSProxy::Message::SIG_ALG_RSA_PKCS1_SHA1 403 1.1 christos || $_ == TLSProxy::Message::SIG_ALG_DSA_SHA1 404 1.1 christos || $_ == TLSProxy::Message::SIG_ALG_ECDSA_SHA1) { 405 1.1 christos $sha1_status = 1; 406 1.1 christos } 407 1.1 christos if ($_ == TLSProxy::Message::OSSL_SIG_ALG_RSA_PKCS1_SHA224 408 1.1 christos || $_ == TLSProxy::Message::OSSL_SIG_ALG_DSA_SHA224 409 1.1 christos || $_ == TLSProxy::Message::OSSL_SIG_ALG_ECDSA_SHA224) { 410 1.1 christos $sha224_status = 1; 411 1.1 christos } 412 1.1 christos } 413 1.1 christos } 414 1.1 christos } 415 1.1 christos } 416 1.1 christos } 417 1.1 christos 418 1.1 christos sub modify_sigalgs_cert_filter 419 1.1 christos { 420 1.1 christos my $proxy = shift; 421 1.1 christos 422 1.1 christos # We're only interested in the initial ClientHello 423 1.1 christos if ($proxy->flight != 0) { 424 1.1 christos return; 425 1.1 christos } 426 1.1 christos 427 1.1 christos foreach my $message (@{$proxy->message_list}) { 428 1.1 christos if ($message->mt == TLSProxy::Message::MT_CLIENT_HELLO) { 429 1.1 christos my $sigs; 430 1.1 christos # two byte length at front of sigs, then two-byte sigschemes 431 1.1 christos if ($testtype == SIGALGS_CERT_ALL) { 432 1.1 christos $sigs = pack "C26", 0x00, 0x18, 433 1.1 christos # rsa_pkcs_sha{256,512} rsa_pss_rsae_sha{256,512} 434 1.1 christos 0x04, 0x01, 0x06, 0x01, 0x08, 0x04, 0x08, 0x06, 435 1.1 christos # ed25518 ed448 rsa_pss_pss_sha{256,512} 436 1.1 christos 0x08, 0x07, 0x08, 0x08, 0x08, 0x09, 0x08, 0x0b, 437 1.1 christos # ecdsa_secp{256,512} rsa+sha1 ecdsa+sha1 438 1.1 christos 0x04, 0x03, 0x06, 0x03, 0x02, 0x01, 0x02, 0x03; 439 1.1 christos } elsif ($testtype == SIGALGS_CERT_PKCS) { 440 1.1 christos $sigs = pack "C10", 0x00, 0x08, 441 1.1 christos # rsa_pkcs_sha{256,384,512,1} 442 1.1 christos 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x01; 443 1.1 christos } elsif ($testtype == SIGALGS_CERT_INVALID) { 444 1.1 christos $sigs = pack "C4", 0x00, 0x02, 445 1.1 christos # unregistered codepoint 446 1.1 christos 0xb2, 0x6f; 447 1.1 christos } 448 1.1 christos $message->set_extension(TLSProxy::Message::EXT_SIG_ALGS_CERT, $sigs); 449 1.1 christos $message->repack(); 450 1.1 christos } 451 1.1 christos } 452 1.1 christos } 453 1.1 christos 454 1.1 christos sub modify_cert_verify_sigalg 455 1.1 christos { 456 1.1 christos my $proxy = shift; 457 1.1 christos 458 1.1 christos # We're only interested in the CertificateVerify 459 1.1 christos if ($proxy->flight != 1) { 460 1.1 christos return; 461 1.1 christos } 462 1.1 christos 463 1.1 christos foreach my $message (@{$proxy->message_list}) { 464 1.1 christos if ($message->mt == TLSProxy::Message::MT_CERTIFICATE_VERIFY) { 465 1.1 christos $message->sigalg(TLSProxy::Message::SIG_ALG_RSA_PSS_PSS_SHA256); 466 1.1 christos $message->repack(); 467 1.1 christos } 468 1.1 christos } 469 1.1 christos } 470 1.1.1.3 christos 471 1.1.1.3 christos sub inject_unrecognized_sigalg 472 1.1.1.3 christos { 473 1.1.1.3 christos my $proxy = shift; 474 1.1.1.3 christos my $type; 475 1.1.1.3 christos 476 1.1.1.3 christos # We're only interested in the initial ClientHello 477 1.1.1.3 christos if ($proxy->flight != 0) { 478 1.1.1.3 christos return; 479 1.1.1.3 christos } 480 1.1.1.3 christos if ($testtype == UNRECOGNIZED_SIGALGS_CERT) { 481 1.1.1.3 christos $type = TLSProxy::Message::EXT_SIG_ALGS_CERT; 482 1.1.1.3 christos } elsif ($testtype == UNRECOGNIZED_SIGALG) { 483 1.1.1.3 christos $type = TLSProxy::Message::EXT_SIG_ALGS; 484 1.1.1.3 christos } else { 485 1.1.1.3 christos return; 486 1.1.1.3 christos } 487 1.1.1.3 christos 488 1.1.1.3 christos my $ext = pack "C8", 489 1.1.1.3 christos 0x00, 0x06, #Extension length 490 1.1.1.3 christos 0xfe, 0x18, #private use 491 1.1.1.3 christos 0x04, 0x01, #rsa_pkcs1_sha256 492 1.1.1.3 christos 0x08, 0x04; #rsa_pss_rsae_sha256; 493 1.1.1.3 christos my $message = ${$proxy->message_list}[0]; 494 1.1.1.3 christos $message->set_extension($type, $ext); 495 1.1.1.3 christos $message->repack; 496 1.1.1.3 christos } 497