1// Copyright 2025 The BoringSSL Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package runner 16 17import ( 18 "fmt" 19 "strconv" 20) 21 22var testSignatureAlgorithms = []struct { 23 name string 24 id signatureAlgorithm 25 baseCert *Credential 26 // If non-zero, the curve that must be supported in TLS 1.2 for cert to be 27 // accepted. 28 curve CurveID 29}{ 30 {"RSA_PKCS1_SHA1", signatureRSAPKCS1WithSHA1, &rsaCertificate, 0}, 31 {"RSA_PKCS1_SHA256", signatureRSAPKCS1WithSHA256, &rsaCertificate, 0}, 32 {"RSA_PKCS1_SHA256_LEGACY", signatureRSAPKCS1WithSHA256Legacy, &rsaCertificate, 0}, 33 {"RSA_PKCS1_SHA384", signatureRSAPKCS1WithSHA384, &rsaCertificate, 0}, 34 {"RSA_PKCS1_SHA512", signatureRSAPKCS1WithSHA512, &rsaCertificate, 0}, 35 {"ECDSA_SHA1", signatureECDSAWithSHA1, &ecdsaP256Certificate, CurveP256}, 36 {"ECDSA_P256_SHA256", signatureECDSAWithP256AndSHA256, &ecdsaP256Certificate, CurveP256}, 37 {"ECDSA_P384_SHA384", signatureECDSAWithP384AndSHA384, &ecdsaP384Certificate, CurveP384}, 38 {"ECDSA_P521_SHA512", signatureECDSAWithP521AndSHA512, &ecdsaP521Certificate, CurveP521}, 39 {"RSA_PSS_SHA256", signatureRSAPSSWithSHA256, &rsaCertificate, 0}, 40 {"RSA_PSS_SHA384", signatureRSAPSSWithSHA384, &rsaCertificate, 0}, 41 {"RSA_PSS_SHA512", signatureRSAPSSWithSHA512, &rsaCertificate, 0}, 42 {"Ed25519", signatureEd25519, &ed25519Certificate, 0}, 43 // Tests for key types prior to TLS 1.2. 44 {"RSA", 0, &rsaCertificate, 0}, 45 {"ECDSA", 0, &ecdsaP256Certificate, CurveP256}, 46} 47 48const ( 49 fakeSigAlg1 signatureAlgorithm = 0x2a01 50 fakeSigAlg2 signatureAlgorithm = 0xff01 51) 52 53func addSignatureAlgorithmTests() { 54 // Not all ciphers involve a signature. Advertise a list which gives all 55 // versions a signing cipher. 56 signingCiphers := []uint16{ 57 TLS_AES_256_GCM_SHA384, 58 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 59 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 60 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 61 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 62 } 63 64 var allAlgorithms []signatureAlgorithm 65 for _, alg := range testSignatureAlgorithms { 66 if alg.id != 0 { 67 allAlgorithms = append(allAlgorithms, alg.id) 68 } 69 } 70 71 // Make sure each signature algorithm works. Include some fake values in 72 // the list and ensure they're ignored. 73 for _, alg := range testSignatureAlgorithms { 74 // Make a version of the certificate that will not sign any other algorithm. 75 cert := alg.baseCert 76 if alg.id != 0 { 77 cert = cert.WithSignatureAlgorithms(alg.id) 78 } 79 80 for _, ver := range tlsVersions { 81 if (ver.version < VersionTLS12) != (alg.id == 0) { 82 continue 83 } 84 85 suffix := "-" + alg.name + "-" + ver.name 86 for _, signTestType := range []testType{clientTest, serverTest} { 87 signPrefix := "Client-" 88 verifyPrefix := "Server-" 89 verifyTestType := serverTest 90 if signTestType == serverTest { 91 verifyTestType = clientTest 92 signPrefix, verifyPrefix = verifyPrefix, signPrefix 93 } 94 95 var shouldFail bool 96 isTLS12PKCS1 := hasComponent(alg.name, "PKCS1") && !hasComponent(alg.name, "LEGACY") 97 isTLS13PKCS1 := hasComponent(alg.name, "PKCS1") && hasComponent(alg.name, "LEGACY") 98 99 // TLS 1.3 removes a number of signature algorithms. 100 if ver.version >= VersionTLS13 && (alg.id == signatureECDSAWithSHA1 || isTLS12PKCS1) { 101 shouldFail = true 102 } 103 104 // The backported RSA-PKCS1 code points only exist for TLS 1.3 105 // client certificates. 106 if (ver.version < VersionTLS13 || signTestType == serverTest) && isTLS13PKCS1 { 107 shouldFail = true 108 } 109 110 // By default, BoringSSL does not sign with these algorithms. 111 signDefault := !shouldFail 112 if isTLS13PKCS1 { 113 signDefault = false 114 } 115 116 // By default, BoringSSL does not accept these algorithms. 117 verifyDefault := !shouldFail 118 if alg.id == signatureECDSAWithSHA1 || alg.id == signatureECDSAWithP521AndSHA512 || alg.id == signatureEd25519 || isTLS13PKCS1 { 119 verifyDefault = false 120 } 121 122 var curveFlags []string 123 var runnerCurves []CurveID 124 if alg.curve != 0 && ver.version <= VersionTLS12 { 125 // In TLS 1.2, the ECDH curve list also constrains ECDSA keys. Ensure the 126 // corresponding curve is enabled. Also include X25519 to ensure the shim 127 // and runner have something in common for ECDH. 128 curveFlags = flagInts("-curves", []int{int(CurveX25519), int(alg.curve)}) 129 runnerCurves = []CurveID{CurveX25519, alg.curve} 130 } 131 132 signError := func(shouldFail bool) string { 133 if !shouldFail { 134 return "" 135 } 136 // In TLS 1.3, the shim should report no common signature algorithms if 137 // it cannot generate a signature. In TLS 1.2 servers, signature 138 // algorithm and cipher selection are integrated, so it is reported as 139 // no shared cipher. 140 if ver.version <= VersionTLS12 && signTestType == serverTest { 141 return ":NO_SHARED_CIPHER:" 142 } 143 return ":NO_COMMON_SIGNATURE_ALGORITHMS:" 144 } 145 signLocalError := func(shouldFail bool) string { 146 if !shouldFail { 147 return "" 148 } 149 // The shim should send handshake_failure when it cannot 150 // negotiate parameters. 151 return "remote error: handshake failure" 152 } 153 verifyError := func(shouldFail bool) string { 154 if !shouldFail { 155 return "" 156 } 157 // If the shim rejects the signature algorithm, but the 158 // runner forcibly selects it anyway, the shim should notice. 159 return ":WRONG_SIGNATURE_TYPE:" 160 } 161 verifyLocalError := func(shouldFail bool) string { 162 if !shouldFail { 163 return "" 164 } 165 // The shim should send an illegal_parameter alert if the runner 166 // uses a signature algorithm it isn't allowed to use. 167 return "remote error: illegal parameter" 168 } 169 170 // Test the shim using the algorithm for signing. 171 signTest := testCase{ 172 testType: signTestType, 173 name: signPrefix + "Sign" + suffix, 174 config: Config{ 175 MaxVersion: ver.version, 176 CurvePreferences: runnerCurves, 177 VerifySignatureAlgorithms: []signatureAlgorithm{ 178 fakeSigAlg1, 179 alg.id, 180 fakeSigAlg2, 181 }, 182 }, 183 shimCertificate: cert, 184 flags: curveFlags, 185 shouldFail: shouldFail, 186 expectedError: signError(shouldFail), 187 expectedLocalError: signLocalError(shouldFail), 188 expectations: connectionExpectations{ 189 peerSignatureAlgorithm: alg.id, 190 }, 191 } 192 193 // Test whether the shim enables the algorithm by default. 194 signDefaultTest := testCase{ 195 testType: signTestType, 196 name: signPrefix + "SignDefault" + suffix, 197 config: Config{ 198 MaxVersion: ver.version, 199 CurvePreferences: runnerCurves, 200 VerifySignatureAlgorithms: []signatureAlgorithm{ 201 fakeSigAlg1, 202 alg.id, 203 fakeSigAlg2, 204 }, 205 }, 206 // cert has been configured with the specified algorithm, 207 // while alg.baseCert uses the defaults. 208 shimCertificate: alg.baseCert, 209 flags: curveFlags, 210 shouldFail: !signDefault, 211 expectedError: signError(!signDefault), 212 expectedLocalError: signLocalError(!signDefault), 213 expectations: connectionExpectations{ 214 peerSignatureAlgorithm: alg.id, 215 }, 216 } 217 218 // Test that the shim will select the algorithm when configured to only 219 // support it. 220 negotiateTest := testCase{ 221 testType: signTestType, 222 name: signPrefix + "Sign-Negotiate" + suffix, 223 config: Config{ 224 MaxVersion: ver.version, 225 CurvePreferences: runnerCurves, 226 VerifySignatureAlgorithms: allAlgorithms, 227 }, 228 shimCertificate: cert, 229 flags: curveFlags, 230 expectations: connectionExpectations{ 231 peerSignatureAlgorithm: alg.id, 232 }, 233 } 234 235 if signTestType == serverTest { 236 // TLS 1.2 servers only sign on some cipher suites. 237 signTest.config.CipherSuites = signingCiphers 238 signDefaultTest.config.CipherSuites = signingCiphers 239 negotiateTest.config.CipherSuites = signingCiphers 240 } else { 241 // TLS 1.2 clients only sign when the server requests certificates. 242 signTest.config.ClientAuth = RequireAnyClientCert 243 signDefaultTest.config.ClientAuth = RequireAnyClientCert 244 negotiateTest.config.ClientAuth = RequireAnyClientCert 245 } 246 testCases = append(testCases, signTest, signDefaultTest) 247 if ver.version >= VersionTLS12 && !shouldFail { 248 testCases = append(testCases, negotiateTest) 249 } 250 251 // Test the shim using the algorithm for verifying. 252 verifyTest := testCase{ 253 testType: verifyTestType, 254 name: verifyPrefix + "Verify" + suffix, 255 config: Config{ 256 MaxVersion: ver.version, 257 Credential: cert, 258 Bugs: ProtocolBugs{ 259 SkipECDSACurveCheck: shouldFail, 260 IgnoreSignatureVersionChecks: shouldFail, 261 // Some signature algorithms may not be advertised. 262 IgnorePeerSignatureAlgorithmPreferences: shouldFail, 263 }, 264 }, 265 flags: curveFlags, 266 // Resume the session to assert the peer signature 267 // algorithm is reported on both handshakes. 268 resumeSession: !shouldFail, 269 shouldFail: shouldFail, 270 expectedError: verifyError(shouldFail), 271 expectedLocalError: verifyLocalError(shouldFail), 272 } 273 if alg.id != 0 { 274 verifyTest.flags = append(verifyTest.flags, "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))) 275 // The algorithm may be disabled by default, so explicitly enable it. 276 verifyTest.flags = append(verifyTest.flags, "-verify-prefs", strconv.Itoa(int(alg.id))) 277 } 278 279 // Test whether the shim expects the algorithm enabled by default. 280 defaultTest := testCase{ 281 testType: verifyTestType, 282 name: verifyPrefix + "VerifyDefault" + suffix, 283 config: Config{ 284 MaxVersion: ver.version, 285 Credential: cert, 286 Bugs: ProtocolBugs{ 287 SkipECDSACurveCheck: !verifyDefault, 288 IgnoreSignatureVersionChecks: !verifyDefault, 289 // Some signature algorithms may not be advertised. 290 IgnorePeerSignatureAlgorithmPreferences: !verifyDefault, 291 }, 292 }, 293 flags: append( 294 []string{"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))}, 295 curveFlags..., 296 ), 297 // Resume the session to assert the peer signature 298 // algorithm is reported on both handshakes. 299 resumeSession: verifyDefault, 300 shouldFail: !verifyDefault, 301 expectedError: verifyError(!verifyDefault), 302 expectedLocalError: verifyLocalError(!verifyDefault), 303 } 304 305 // Test whether the shim handles invalid signatures for this algorithm. 306 invalidTest := testCase{ 307 testType: verifyTestType, 308 name: verifyPrefix + "InvalidSignature" + suffix, 309 config: Config{ 310 MaxVersion: ver.version, 311 Credential: cert, 312 Bugs: ProtocolBugs{ 313 InvalidSignature: true, 314 }, 315 }, 316 flags: curveFlags, 317 shouldFail: true, 318 expectedError: ":BAD_SIGNATURE:", 319 } 320 if alg.id != 0 { 321 // The algorithm may be disabled by default, so explicitly enable it. 322 invalidTest.flags = append(invalidTest.flags, "-verify-prefs", strconv.Itoa(int(alg.id))) 323 } 324 325 if verifyTestType == serverTest { 326 // TLS 1.2 servers only verify when they request client certificates. 327 verifyTest.flags = append(verifyTest.flags, "-require-any-client-certificate") 328 defaultTest.flags = append(defaultTest.flags, "-require-any-client-certificate") 329 invalidTest.flags = append(invalidTest.flags, "-require-any-client-certificate") 330 } else { 331 // TLS 1.2 clients only verify on some cipher suites. 332 verifyTest.config.CipherSuites = signingCiphers 333 defaultTest.config.CipherSuites = signingCiphers 334 invalidTest.config.CipherSuites = signingCiphers 335 } 336 testCases = append(testCases, verifyTest, defaultTest) 337 if !shouldFail { 338 testCases = append(testCases, invalidTest) 339 } 340 } 341 } 342 } 343 344 // Test the peer's verify preferences are available. 345 for _, ver := range tlsVersions { 346 if ver.version < VersionTLS12 { 347 continue 348 } 349 testCases = append(testCases, testCase{ 350 name: "ClientAuth-PeerVerifyPrefs-" + ver.name, 351 config: Config{ 352 MaxVersion: ver.version, 353 ClientAuth: RequireAnyClientCert, 354 VerifySignatureAlgorithms: []signatureAlgorithm{ 355 signatureRSAPSSWithSHA256, 356 signatureEd25519, 357 signatureECDSAWithP256AndSHA256, 358 }, 359 }, 360 shimCertificate: &rsaCertificate, 361 flags: []string{ 362 "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 363 "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), 364 "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 365 }, 366 }) 367 368 testCases = append(testCases, testCase{ 369 testType: serverTest, 370 name: "ServerAuth-PeerVerifyPrefs-" + ver.name, 371 config: Config{ 372 MaxVersion: ver.version, 373 VerifySignatureAlgorithms: []signatureAlgorithm{ 374 signatureRSAPSSWithSHA256, 375 signatureEd25519, 376 signatureECDSAWithP256AndSHA256, 377 }, 378 }, 379 shimCertificate: &rsaCertificate, 380 flags: []string{ 381 "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 382 "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), 383 "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 384 }, 385 }) 386 387 } 388 389 // Test that algorithm selection takes the key type into account. 390 testCases = append(testCases, testCase{ 391 name: "ClientAuth-SignatureType", 392 config: Config{ 393 ClientAuth: RequireAnyClientCert, 394 MaxVersion: VersionTLS12, 395 VerifySignatureAlgorithms: []signatureAlgorithm{ 396 signatureECDSAWithP521AndSHA512, 397 signatureRSAPKCS1WithSHA384, 398 signatureECDSAWithSHA1, 399 }, 400 }, 401 shimCertificate: &rsaCertificate, 402 expectations: connectionExpectations{ 403 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, 404 }, 405 }) 406 407 testCases = append(testCases, testCase{ 408 name: "ClientAuth-SignatureType-TLS13", 409 config: Config{ 410 ClientAuth: RequireAnyClientCert, 411 MaxVersion: VersionTLS13, 412 VerifySignatureAlgorithms: []signatureAlgorithm{ 413 signatureECDSAWithP521AndSHA512, 414 signatureRSAPKCS1WithSHA384, 415 signatureRSAPSSWithSHA384, 416 signatureECDSAWithSHA1, 417 }, 418 }, 419 shimCertificate: &rsaCertificate, 420 expectations: connectionExpectations{ 421 peerSignatureAlgorithm: signatureRSAPSSWithSHA384, 422 }, 423 }) 424 425 testCases = append(testCases, testCase{ 426 testType: serverTest, 427 name: "ServerAuth-SignatureType", 428 config: Config{ 429 MaxVersion: VersionTLS12, 430 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 431 VerifySignatureAlgorithms: []signatureAlgorithm{ 432 signatureECDSAWithP521AndSHA512, 433 signatureRSAPKCS1WithSHA384, 434 signatureECDSAWithSHA1, 435 }, 436 }, 437 expectations: connectionExpectations{ 438 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, 439 }, 440 }) 441 442 testCases = append(testCases, testCase{ 443 testType: serverTest, 444 name: "ServerAuth-SignatureType-TLS13", 445 config: Config{ 446 MaxVersion: VersionTLS13, 447 VerifySignatureAlgorithms: []signatureAlgorithm{ 448 signatureECDSAWithP521AndSHA512, 449 signatureRSAPKCS1WithSHA384, 450 signatureRSAPSSWithSHA384, 451 signatureECDSAWithSHA1, 452 }, 453 }, 454 expectations: connectionExpectations{ 455 peerSignatureAlgorithm: signatureRSAPSSWithSHA384, 456 }, 457 }) 458 459 // Test that signature verification takes the key type into account. 460 testCases = append(testCases, testCase{ 461 testType: serverTest, 462 name: "Verify-ClientAuth-SignatureType", 463 config: Config{ 464 MaxVersion: VersionTLS12, 465 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithSHA256), 466 Bugs: ProtocolBugs{ 467 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 468 }, 469 }, 470 flags: []string{ 471 "-require-any-client-certificate", 472 }, 473 shouldFail: true, 474 expectedError: ":WRONG_SIGNATURE_TYPE:", 475 }) 476 477 testCases = append(testCases, testCase{ 478 testType: serverTest, 479 name: "Verify-ClientAuth-SignatureType-TLS13", 480 config: Config{ 481 MaxVersion: VersionTLS13, 482 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 483 Bugs: ProtocolBugs{ 484 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 485 }, 486 }, 487 flags: []string{ 488 "-require-any-client-certificate", 489 }, 490 shouldFail: true, 491 expectedError: ":WRONG_SIGNATURE_TYPE:", 492 }) 493 494 testCases = append(testCases, testCase{ 495 name: "Verify-ServerAuth-SignatureType", 496 config: Config{ 497 MaxVersion: VersionTLS12, 498 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 499 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithSHA256), 500 Bugs: ProtocolBugs{ 501 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 502 }, 503 }, 504 shouldFail: true, 505 expectedError: ":WRONG_SIGNATURE_TYPE:", 506 }) 507 508 testCases = append(testCases, testCase{ 509 name: "Verify-ServerAuth-SignatureType-TLS13", 510 config: Config{ 511 MaxVersion: VersionTLS13, 512 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 513 Bugs: ProtocolBugs{ 514 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 515 }, 516 }, 517 shouldFail: true, 518 expectedError: ":WRONG_SIGNATURE_TYPE:", 519 }) 520 521 // Test that, if the ClientHello list is missing, the server falls back 522 // to SHA-1 in TLS 1.2, but not TLS 1.3. 523 testCases = append(testCases, testCase{ 524 testType: serverTest, 525 name: "ServerAuth-SHA1-Fallback-RSA", 526 config: Config{ 527 MaxVersion: VersionTLS12, 528 VerifySignatureAlgorithms: []signatureAlgorithm{ 529 signatureRSAPKCS1WithSHA1, 530 }, 531 Bugs: ProtocolBugs{ 532 NoSignatureAlgorithms: true, 533 }, 534 }, 535 shimCertificate: &rsaCertificate, 536 }) 537 538 testCases = append(testCases, testCase{ 539 testType: serverTest, 540 name: "ServerAuth-SHA1-Fallback-ECDSA", 541 config: Config{ 542 MaxVersion: VersionTLS12, 543 VerifySignatureAlgorithms: []signatureAlgorithm{ 544 signatureECDSAWithSHA1, 545 }, 546 Bugs: ProtocolBugs{ 547 NoSignatureAlgorithms: true, 548 }, 549 }, 550 shimCertificate: &ecdsaP256Certificate, 551 }) 552 553 testCases = append(testCases, testCase{ 554 testType: serverTest, 555 name: "ServerAuth-NoFallback-TLS13", 556 config: Config{ 557 MaxVersion: VersionTLS13, 558 VerifySignatureAlgorithms: []signatureAlgorithm{ 559 signatureRSAPKCS1WithSHA1, 560 }, 561 Bugs: ProtocolBugs{ 562 NoSignatureAlgorithms: true, 563 }, 564 }, 565 shouldFail: true, 566 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 567 }) 568 569 // The CertificateRequest list, however, may never be omitted. It is a 570 // syntax error for it to be empty. 571 testCases = append(testCases, testCase{ 572 name: "ClientAuth-NoFallback-RSA", 573 config: Config{ 574 MaxVersion: VersionTLS12, 575 ClientAuth: RequireAnyClientCert, 576 VerifySignatureAlgorithms: []signatureAlgorithm{ 577 signatureRSAPKCS1WithSHA1, 578 }, 579 Bugs: ProtocolBugs{ 580 NoSignatureAlgorithms: true, 581 }, 582 }, 583 shimCertificate: &rsaCertificate, 584 shouldFail: true, 585 expectedError: ":DECODE_ERROR:", 586 expectedLocalError: "remote error: error decoding message", 587 }) 588 589 testCases = append(testCases, testCase{ 590 name: "ClientAuth-NoFallback-ECDSA", 591 config: Config{ 592 MaxVersion: VersionTLS12, 593 ClientAuth: RequireAnyClientCert, 594 VerifySignatureAlgorithms: []signatureAlgorithm{ 595 signatureECDSAWithSHA1, 596 }, 597 Bugs: ProtocolBugs{ 598 NoSignatureAlgorithms: true, 599 }, 600 }, 601 shimCertificate: &ecdsaP256Certificate, 602 shouldFail: true, 603 expectedError: ":DECODE_ERROR:", 604 expectedLocalError: "remote error: error decoding message", 605 }) 606 607 testCases = append(testCases, testCase{ 608 name: "ClientAuth-NoFallback-TLS13", 609 config: Config{ 610 MaxVersion: VersionTLS13, 611 ClientAuth: RequireAnyClientCert, 612 VerifySignatureAlgorithms: []signatureAlgorithm{ 613 signatureRSAPKCS1WithSHA1, 614 }, 615 Bugs: ProtocolBugs{ 616 NoSignatureAlgorithms: true, 617 }, 618 }, 619 shimCertificate: &rsaCertificate, 620 shouldFail: true, 621 expectedError: ":DECODE_ERROR:", 622 expectedLocalError: "remote error: error decoding message", 623 }) 624 625 // Test that signature preferences are enforced. BoringSSL does not 626 // implement MD5 signatures. 627 testCases = append(testCases, testCase{ 628 testType: serverTest, 629 name: "ClientAuth-Enforced", 630 config: Config{ 631 MaxVersion: VersionTLS12, 632 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 633 Bugs: ProtocolBugs{ 634 IgnorePeerSignatureAlgorithmPreferences: true, 635 }, 636 }, 637 flags: []string{"-require-any-client-certificate"}, 638 shouldFail: true, 639 expectedError: ":WRONG_SIGNATURE_TYPE:", 640 }) 641 642 testCases = append(testCases, testCase{ 643 name: "ServerAuth-Enforced", 644 config: Config{ 645 MaxVersion: VersionTLS12, 646 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 647 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 648 Bugs: ProtocolBugs{ 649 IgnorePeerSignatureAlgorithmPreferences: true, 650 }, 651 }, 652 shouldFail: true, 653 expectedError: ":WRONG_SIGNATURE_TYPE:", 654 }) 655 testCases = append(testCases, testCase{ 656 testType: serverTest, 657 name: "ClientAuth-Enforced-TLS13", 658 config: Config{ 659 MaxVersion: VersionTLS13, 660 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 661 Bugs: ProtocolBugs{ 662 IgnorePeerSignatureAlgorithmPreferences: true, 663 IgnoreSignatureVersionChecks: true, 664 }, 665 }, 666 flags: []string{"-require-any-client-certificate"}, 667 shouldFail: true, 668 expectedError: ":WRONG_SIGNATURE_TYPE:", 669 }) 670 671 testCases = append(testCases, testCase{ 672 name: "ServerAuth-Enforced-TLS13", 673 config: Config{ 674 MaxVersion: VersionTLS13, 675 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 676 Bugs: ProtocolBugs{ 677 IgnorePeerSignatureAlgorithmPreferences: true, 678 IgnoreSignatureVersionChecks: true, 679 }, 680 }, 681 shouldFail: true, 682 expectedError: ":WRONG_SIGNATURE_TYPE:", 683 }) 684 685 // Test that the negotiated signature algorithm respects the client and 686 // server preferences. 687 testCases = append(testCases, testCase{ 688 name: "NoCommonAlgorithms", 689 config: Config{ 690 MaxVersion: VersionTLS12, 691 ClientAuth: RequireAnyClientCert, 692 VerifySignatureAlgorithms: []signatureAlgorithm{ 693 signatureRSAPKCS1WithSHA512, 694 signatureRSAPKCS1WithSHA1, 695 }, 696 }, 697 shimCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithSHA256), 698 shouldFail: true, 699 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 700 }) 701 testCases = append(testCases, testCase{ 702 name: "NoCommonAlgorithms-TLS13", 703 config: Config{ 704 MaxVersion: VersionTLS13, 705 ClientAuth: RequireAnyClientCert, 706 VerifySignatureAlgorithms: []signatureAlgorithm{ 707 signatureRSAPSSWithSHA512, 708 signatureRSAPSSWithSHA384, 709 }, 710 }, 711 shimCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 712 shouldFail: true, 713 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 714 }) 715 testCases = append(testCases, testCase{ 716 name: "Agree-Digest-SHA256", 717 config: Config{ 718 MaxVersion: VersionTLS12, 719 ClientAuth: RequireAnyClientCert, 720 VerifySignatureAlgorithms: []signatureAlgorithm{ 721 signatureRSAPKCS1WithSHA1, 722 signatureRSAPKCS1WithSHA256, 723 }, 724 }, 725 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 726 signatureRSAPKCS1WithSHA256, 727 signatureRSAPKCS1WithSHA1, 728 ), 729 expectations: connectionExpectations{ 730 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 731 }, 732 }) 733 testCases = append(testCases, testCase{ 734 name: "Agree-Digest-SHA1", 735 config: Config{ 736 MaxVersion: VersionTLS12, 737 ClientAuth: RequireAnyClientCert, 738 VerifySignatureAlgorithms: []signatureAlgorithm{ 739 signatureRSAPKCS1WithSHA1, 740 }, 741 }, 742 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 743 signatureRSAPKCS1WithSHA512, 744 signatureRSAPKCS1WithSHA256, 745 signatureRSAPKCS1WithSHA1, 746 ), 747 expectations: connectionExpectations{ 748 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA1, 749 }, 750 }) 751 testCases = append(testCases, testCase{ 752 name: "Agree-Digest-Default", 753 config: Config{ 754 MaxVersion: VersionTLS12, 755 ClientAuth: RequireAnyClientCert, 756 VerifySignatureAlgorithms: []signatureAlgorithm{ 757 signatureRSAPKCS1WithSHA256, 758 signatureECDSAWithP256AndSHA256, 759 signatureRSAPKCS1WithSHA1, 760 signatureECDSAWithSHA1, 761 }, 762 }, 763 shimCertificate: &rsaCertificate, 764 expectations: connectionExpectations{ 765 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 766 }, 767 }) 768 769 // Test that the signing preference list may include extra algorithms 770 // without negotiation problems. 771 testCases = append(testCases, testCase{ 772 testType: serverTest, 773 name: "FilterExtraAlgorithms", 774 config: Config{ 775 MaxVersion: VersionTLS12, 776 VerifySignatureAlgorithms: []signatureAlgorithm{ 777 signatureRSAPKCS1WithSHA256, 778 }, 779 }, 780 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 781 signatureECDSAWithP256AndSHA256, 782 signatureRSAPKCS1WithSHA256, 783 ), 784 expectations: connectionExpectations{ 785 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 786 }, 787 }) 788 789 // In TLS 1.2 and below, ECDSA uses the curve list rather than the 790 // signature algorithms. 791 testCases = append(testCases, testCase{ 792 name: "CheckLeafCurve", 793 config: Config{ 794 MaxVersion: VersionTLS12, 795 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 796 Credential: &ecdsaP256Certificate, 797 }, 798 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 799 shouldFail: true, 800 expectedError: ":BAD_ECC_CERT:", 801 }) 802 803 // In TLS 1.3, ECDSA does not use the ECDHE curve list. 804 testCases = append(testCases, testCase{ 805 name: "CheckLeafCurve-TLS13", 806 config: Config{ 807 MaxVersion: VersionTLS13, 808 Credential: &ecdsaP256Certificate, 809 }, 810 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 811 }) 812 813 // In TLS 1.2, the ECDSA curve is not in the signature algorithm, so the 814 // shim should accept P-256 with SHA-384. 815 testCases = append(testCases, testCase{ 816 name: "ECDSACurveMismatch-Verify-TLS12", 817 config: Config{ 818 MaxVersion: VersionTLS12, 819 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 820 Credential: ecdsaP256Certificate.WithSignatureAlgorithms(signatureECDSAWithP384AndSHA384), 821 }, 822 }) 823 824 // In TLS 1.3, the ECDSA curve comes from the signature algorithm, so the 825 // shim should reject P-256 with SHA-384. 826 testCases = append(testCases, testCase{ 827 name: "ECDSACurveMismatch-Verify-TLS13", 828 config: Config{ 829 MaxVersion: VersionTLS13, 830 Credential: ecdsaP256Certificate.WithSignatureAlgorithms(signatureECDSAWithP384AndSHA384), 831 Bugs: ProtocolBugs{ 832 SkipECDSACurveCheck: true, 833 }, 834 }, 835 shouldFail: true, 836 expectedError: ":WRONG_SIGNATURE_TYPE:", 837 }) 838 839 // Signature algorithm selection in TLS 1.3 should take the curve into 840 // account. 841 testCases = append(testCases, testCase{ 842 testType: serverTest, 843 name: "ECDSACurveMismatch-Sign-TLS13", 844 config: Config{ 845 MaxVersion: VersionTLS13, 846 VerifySignatureAlgorithms: []signatureAlgorithm{ 847 signatureECDSAWithP384AndSHA384, 848 signatureECDSAWithP256AndSHA256, 849 }, 850 }, 851 shimCertificate: &ecdsaP256Certificate, 852 expectations: connectionExpectations{ 853 peerSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 854 }, 855 }) 856 857 // RSASSA-PSS with SHA-512 is too large for 1024-bit RSA. Test that the 858 // server does not attempt to sign in that case. 859 testCases = append(testCases, testCase{ 860 testType: serverTest, 861 name: "RSA-PSS-Large", 862 config: Config{ 863 MaxVersion: VersionTLS13, 864 VerifySignatureAlgorithms: []signatureAlgorithm{ 865 signatureRSAPSSWithSHA512, 866 }, 867 }, 868 shimCertificate: &rsa1024Certificate, 869 shouldFail: true, 870 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 871 }) 872 873 // Test that RSA-PSS is enabled by default for TLS 1.2. 874 testCases = append(testCases, testCase{ 875 testType: clientTest, 876 name: "RSA-PSS-Default-Verify", 877 config: Config{ 878 MaxVersion: VersionTLS12, 879 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 880 }, 881 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 882 }) 883 884 testCases = append(testCases, testCase{ 885 testType: serverTest, 886 name: "RSA-PSS-Default-Sign", 887 config: Config{ 888 MaxVersion: VersionTLS12, 889 VerifySignatureAlgorithms: []signatureAlgorithm{ 890 signatureRSAPSSWithSHA256, 891 }, 892 }, 893 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 894 }) 895 896 // TLS 1.1 and below has no way to advertise support for or negotiate 897 // Ed25519's signature algorithm. 898 testCases = append(testCases, testCase{ 899 testType: clientTest, 900 name: "NoEd25519-TLS11-ServerAuth-Verify", 901 config: Config{ 902 MaxVersion: VersionTLS11, 903 Credential: &ed25519Certificate, 904 Bugs: ProtocolBugs{ 905 // Sign with Ed25519 even though it is TLS 1.1. 906 SigningAlgorithmForLegacyVersions: signatureEd25519, 907 }, 908 }, 909 flags: []string{"-verify-prefs", strconv.Itoa(int(signatureEd25519))}, 910 shouldFail: true, 911 expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:", 912 }) 913 testCases = append(testCases, testCase{ 914 testType: serverTest, 915 name: "NoEd25519-TLS11-ServerAuth-Sign", 916 config: Config{ 917 MaxVersion: VersionTLS11, 918 }, 919 shimCertificate: &ed25519Certificate, 920 shouldFail: true, 921 expectedError: ":NO_SHARED_CIPHER:", 922 }) 923 testCases = append(testCases, testCase{ 924 testType: serverTest, 925 name: "NoEd25519-TLS11-ClientAuth-Verify", 926 config: Config{ 927 MaxVersion: VersionTLS11, 928 Credential: &ed25519Certificate, 929 Bugs: ProtocolBugs{ 930 // Sign with Ed25519 even though it is TLS 1.1. 931 SigningAlgorithmForLegacyVersions: signatureEd25519, 932 }, 933 }, 934 flags: []string{ 935 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 936 "-require-any-client-certificate", 937 }, 938 shouldFail: true, 939 expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:", 940 }) 941 testCases = append(testCases, testCase{ 942 testType: clientTest, 943 name: "NoEd25519-TLS11-ClientAuth-Sign", 944 config: Config{ 945 MaxVersion: VersionTLS11, 946 ClientAuth: RequireAnyClientCert, 947 }, 948 shimCertificate: &ed25519Certificate, 949 shouldFail: true, 950 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 951 }) 952 953 // Test Ed25519 is not advertised by default. 954 testCases = append(testCases, testCase{ 955 testType: clientTest, 956 name: "Ed25519DefaultDisable-NoAdvertise", 957 config: Config{ 958 Credential: &ed25519Certificate, 959 }, 960 shouldFail: true, 961 expectedLocalError: "tls: no common signature algorithms", 962 }) 963 964 // Test Ed25519, when disabled, is not accepted if the peer ignores our 965 // preferences. 966 testCases = append(testCases, testCase{ 967 testType: clientTest, 968 name: "Ed25519DefaultDisable-NoAccept", 969 config: Config{ 970 Credential: &ed25519Certificate, 971 Bugs: ProtocolBugs{ 972 IgnorePeerSignatureAlgorithmPreferences: true, 973 }, 974 }, 975 shouldFail: true, 976 expectedLocalError: "remote error: illegal parameter", 977 expectedError: ":WRONG_SIGNATURE_TYPE:", 978 }) 979 980 // Test that configuring verify preferences changes what the client 981 // advertises. 982 testCases = append(testCases, testCase{ 983 name: "VerifyPreferences-Advertised", 984 config: Config{ 985 Credential: rsaCertificate.WithSignatureAlgorithms( 986 signatureRSAPSSWithSHA256, 987 signatureRSAPSSWithSHA384, 988 signatureRSAPSSWithSHA512, 989 ), 990 }, 991 flags: []string{ 992 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 993 "-expect-peer-signature-algorithm", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 994 }, 995 }) 996 997 // Test that the client advertises a set which the runner can find 998 // nothing in common with. 999 testCases = append(testCases, testCase{ 1000 name: "VerifyPreferences-NoCommonAlgorithms", 1001 config: Config{ 1002 Credential: rsaCertificate.WithSignatureAlgorithms( 1003 signatureRSAPSSWithSHA256, 1004 signatureRSAPSSWithSHA512, 1005 ), 1006 }, 1007 flags: []string{ 1008 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 1009 }, 1010 shouldFail: true, 1011 expectedLocalError: "tls: no common signature algorithms", 1012 }) 1013 1014 // Test that the client enforces its preferences when configured. 1015 testCases = append(testCases, testCase{ 1016 name: "VerifyPreferences-Enforced", 1017 config: Config{ 1018 Credential: rsaCertificate.WithSignatureAlgorithms( 1019 signatureRSAPSSWithSHA256, 1020 signatureRSAPSSWithSHA512, 1021 ), 1022 Bugs: ProtocolBugs{ 1023 IgnorePeerSignatureAlgorithmPreferences: true, 1024 }, 1025 }, 1026 flags: []string{ 1027 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 1028 }, 1029 shouldFail: true, 1030 expectedLocalError: "remote error: illegal parameter", 1031 expectedError: ":WRONG_SIGNATURE_TYPE:", 1032 }) 1033 1034 // Test that explicitly configuring Ed25519 is as good as changing the 1035 // boolean toggle. 1036 testCases = append(testCases, testCase{ 1037 name: "VerifyPreferences-Ed25519", 1038 config: Config{ 1039 Credential: &ed25519Certificate, 1040 }, 1041 flags: []string{ 1042 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 1043 }, 1044 }) 1045 1046 for _, testType := range []testType{clientTest, serverTest} { 1047 for _, ver := range tlsVersions { 1048 if ver.version < VersionTLS12 { 1049 continue 1050 } 1051 1052 prefix := "Client-" + ver.name + "-" 1053 noCommonAlgorithmsError := ":NO_COMMON_SIGNATURE_ALGORITHMS:" 1054 if testType == serverTest { 1055 prefix = "Server-" + ver.name + "-" 1056 // In TLS 1.2 servers, cipher selection and algorithm 1057 // selection are linked. 1058 if ver.version <= VersionTLS12 { 1059 noCommonAlgorithmsError = ":NO_SHARED_CIPHER:" 1060 } 1061 } 1062 1063 // Test that the shim will not sign MD5/SHA1 with RSA at TLS 1.2, 1064 // even if specified in signing preferences. 1065 testCases = append(testCases, testCase{ 1066 testType: testType, 1067 name: prefix + "NoSign-RSA_PKCS1_MD5_SHA1", 1068 config: Config{ 1069 MaxVersion: ver.version, 1070 CipherSuites: signingCiphers, 1071 ClientAuth: RequireAnyClientCert, 1072 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPKCS1WithMD5AndSHA1}, 1073 }, 1074 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 1075 signatureRSAPKCS1WithMD5AndSHA1, 1076 // Include a valid algorithm as well, to avoid an empty list 1077 // if filtered out. 1078 signatureRSAPKCS1WithSHA256, 1079 ), 1080 shouldFail: true, 1081 expectedError: noCommonAlgorithmsError, 1082 }) 1083 1084 // Test that the shim will not accept MD5/SHA1 with RSA at TLS 1.2, 1085 // even if specified in verify preferences. 1086 testCases = append(testCases, testCase{ 1087 testType: testType, 1088 name: prefix + "NoVerify-RSA_PKCS1_MD5_SHA1", 1089 config: Config{ 1090 MaxVersion: ver.version, 1091 Credential: &rsaCertificate, 1092 Bugs: ProtocolBugs{ 1093 IgnorePeerSignatureAlgorithmPreferences: true, 1094 AlwaysSignAsLegacyVersion: true, 1095 SendSignatureAlgorithm: signatureRSAPKCS1WithMD5AndSHA1, 1096 }, 1097 }, 1098 shimCertificate: &rsaCertificate, 1099 flags: []string{ 1100 "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithMD5AndSHA1)), 1101 // Include a valid algorithm as well, to avoid an empty list 1102 // if filtered out. 1103 "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 1104 "-require-any-client-certificate", 1105 }, 1106 shouldFail: true, 1107 expectedError: ":WRONG_SIGNATURE_TYPE:", 1108 }) 1109 } 1110 } 1111 1112 // Test that, when there are no signature algorithms in common in TLS 1113 // 1.2, the server will still consider the legacy RSA key exchange. 1114 testCases = append(testCases, testCase{ 1115 testType: serverTest, 1116 name: "NoCommonSignatureAlgorithms-TLS12-Fallback", 1117 config: Config{ 1118 MaxVersion: VersionTLS12, 1119 CipherSuites: []uint16{ 1120 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 1121 TLS_RSA_WITH_AES_128_GCM_SHA256, 1122 }, 1123 VerifySignatureAlgorithms: []signatureAlgorithm{ 1124 signatureECDSAWithP256AndSHA256, 1125 }, 1126 }, 1127 expectations: connectionExpectations{ 1128 cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, 1129 }, 1130 }) 1131 1132 // id-RSASSA-PSS certificates are not accepted for use with rsa_pss_rsae_* 1133 // algorithms. There are separate codepoints, which we do not support, for 1134 // id-RSASSA-PSS. 1135 for _, ver := range tlsVersions { 1136 testCases = append(testCases, testCase{ 1137 testType: clientTest, 1138 name: "RejectPSSKeyType-Client-" + ver.name, 1139 config: Config{ 1140 MinVersion: ver.version, 1141 MaxVersion: ver.version, 1142 Credential: pssCertificate.WithSignatureAlgorithms( 1143 signatureRSAPSSWithSHA256, 1144 ), 1145 }, 1146 shouldFail: true, 1147 expectedError: ":UNSUPPORTED_ALGORITHM:", 1148 }) 1149 testCases = append(testCases, testCase{ 1150 testType: serverTest, 1151 name: "RejectPSSKeyType-Server-" + ver.name, 1152 config: Config{ 1153 MinVersion: ver.version, 1154 MaxVersion: ver.version, 1155 Credential: pssCertificate.WithSignatureAlgorithms( 1156 signatureRSAPSSWithSHA256, 1157 ), 1158 }, 1159 flags: []string{"-require-any-client-certificate"}, 1160 shouldFail: true, 1161 expectedError: ":UNSUPPORTED_ALGORITHM:", 1162 }) 1163 } 1164} 1165 1166func addBadECDSASignatureTests() { 1167 for badR := BadValue(1); badR < NumBadValues; badR++ { 1168 for badS := BadValue(1); badS < NumBadValues; badS++ { 1169 testCases = append(testCases, testCase{ 1170 name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS), 1171 config: Config{ 1172 MaxVersion: VersionTLS12, 1173 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 1174 Credential: &ecdsaP256Certificate, 1175 Bugs: ProtocolBugs{ 1176 BadECDSAR: badR, 1177 BadECDSAS: badS, 1178 }, 1179 }, 1180 shouldFail: true, 1181 expectedError: ":BAD_SIGNATURE:", 1182 }) 1183 testCases = append(testCases, testCase{ 1184 name: fmt.Sprintf("BadECDSA-%d-%d-TLS13", badR, badS), 1185 config: Config{ 1186 MaxVersion: VersionTLS13, 1187 Credential: &ecdsaP256Certificate, 1188 Bugs: ProtocolBugs{ 1189 BadECDSAR: badR, 1190 BadECDSAS: badS, 1191 }, 1192 }, 1193 shouldFail: true, 1194 expectedError: ":BAD_SIGNATURE:", 1195 }) 1196 } 1197 } 1198} 1199