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 "bytes" 19 "fmt" 20 "strconv" 21) 22 23type stateMachineTestConfig struct { 24 protocol protocol 25 async bool 26 splitHandshake bool 27 packHandshake bool 28 implicitHandshake bool 29} 30 31// Adds tests that try to cover the range of the handshake state machine, under 32// various conditions. Some of these are redundant with other tests, but they 33// only cover the synchronous case. 34func addAllStateMachineCoverageTests() { 35 for _, async := range []bool{false, true} { 36 for _, protocol := range []protocol{tls, dtls, quic} { 37 addStateMachineCoverageTests(stateMachineTestConfig{ 38 protocol: protocol, 39 async: async, 40 }) 41 // QUIC doesn't work with the implicit handshake API. Additionally, 42 // splitting or packing handshake records is meaningless in QUIC. 43 if protocol != quic { 44 addStateMachineCoverageTests(stateMachineTestConfig{ 45 protocol: protocol, 46 async: async, 47 implicitHandshake: true, 48 }) 49 addStateMachineCoverageTests(stateMachineTestConfig{ 50 protocol: protocol, 51 async: async, 52 splitHandshake: true, 53 }) 54 addStateMachineCoverageTests(stateMachineTestConfig{ 55 protocol: protocol, 56 async: async, 57 packHandshake: true, 58 }) 59 } 60 } 61 } 62} 63 64func addStateMachineCoverageTests(config stateMachineTestConfig) { 65 var tests []testCase 66 67 // Basic handshake, with resumption. Client and server, 68 // session ID and session ticket. 69 // The following tests have a max version of 1.2, so they are not suitable 70 // for use with QUIC. 71 if config.protocol != quic { 72 tests = append(tests, testCase{ 73 name: "Basic-Client", 74 config: Config{ 75 MaxVersion: VersionTLS12, 76 }, 77 resumeSession: true, 78 // Ensure session tickets are used, not session IDs. 79 noSessionCache: true, 80 flags: []string{"-expect-no-hrr"}, 81 }) 82 tests = append(tests, testCase{ 83 name: "Basic-Client-RenewTicket", 84 config: Config{ 85 MaxVersion: VersionTLS12, 86 Bugs: ProtocolBugs{ 87 RenewTicketOnResume: true, 88 }, 89 }, 90 flags: []string{"-expect-ticket-renewal"}, 91 resumeSession: true, 92 resumeRenewedSession: true, 93 }) 94 tests = append(tests, testCase{ 95 name: "Basic-Client-NoTicket", 96 config: Config{ 97 MaxVersion: VersionTLS12, 98 SessionTicketsDisabled: true, 99 }, 100 resumeSession: true, 101 }) 102 tests = append(tests, testCase{ 103 testType: serverTest, 104 name: "Basic-Server", 105 config: Config{ 106 MaxVersion: VersionTLS12, 107 Bugs: ProtocolBugs{ 108 RequireSessionTickets: true, 109 }, 110 }, 111 resumeSession: true, 112 flags: []string{ 113 "-expect-no-session-id", 114 "-expect-no-hrr", 115 }, 116 }) 117 tests = append(tests, testCase{ 118 testType: serverTest, 119 name: "Basic-Server-NoTickets", 120 config: Config{ 121 MaxVersion: VersionTLS12, 122 SessionTicketsDisabled: true, 123 }, 124 resumeSession: true, 125 flags: []string{"-expect-session-id"}, 126 }) 127 tests = append(tests, testCase{ 128 testType: serverTest, 129 name: "Basic-Server-EarlyCallback", 130 config: Config{ 131 MaxVersion: VersionTLS12, 132 }, 133 flags: []string{"-use-early-callback"}, 134 resumeSession: true, 135 }) 136 } 137 138 // TLS 1.3 basic handshake shapes. 139 tests = append(tests, testCase{ 140 name: "TLS13-1RTT-Client", 141 config: Config{ 142 MaxVersion: VersionTLS13, 143 MinVersion: VersionTLS13, 144 }, 145 resumeSession: true, 146 resumeRenewedSession: true, 147 // 0-RTT being disabled overrides all other 0-RTT reasons. 148 flags: []string{"-expect-early-data-reason", "disabled"}, 149 }) 150 151 tests = append(tests, testCase{ 152 testType: serverTest, 153 name: "TLS13-1RTT-Server", 154 config: Config{ 155 MaxVersion: VersionTLS13, 156 MinVersion: VersionTLS13, 157 }, 158 resumeSession: true, 159 resumeRenewedSession: true, 160 flags: []string{ 161 // TLS 1.3 uses tickets, so the session should not be 162 // cached statefully. 163 "-expect-no-session-id", 164 // 0-RTT being disabled overrides all other 0-RTT reasons. 165 "-expect-early-data-reason", "disabled", 166 }, 167 }) 168 169 tests = append(tests, testCase{ 170 name: "TLS13-HelloRetryRequest-Client", 171 config: Config{ 172 MaxVersion: VersionTLS13, 173 MinVersion: VersionTLS13, 174 // P-384 requires a HelloRetryRequest against BoringSSL's default 175 // configuration. Assert this with ExpectMissingKeyShare. 176 CurvePreferences: []CurveID{CurveP384}, 177 Bugs: ProtocolBugs{ 178 ExpectMissingKeyShare: true, 179 }, 180 }, 181 // Cover HelloRetryRequest during an ECDHE-PSK resumption. 182 resumeSession: true, 183 flags: []string{"-expect-hrr"}, 184 }) 185 186 tests = append(tests, testCase{ 187 testType: serverTest, 188 name: "TLS13-HelloRetryRequest-Server", 189 config: Config{ 190 MaxVersion: VersionTLS13, 191 MinVersion: VersionTLS13, 192 // Require a HelloRetryRequest for every curve. 193 DefaultCurves: []CurveID{}, 194 }, 195 // Cover HelloRetryRequest during an ECDHE-PSK resumption. 196 resumeSession: true, 197 flags: []string{"-expect-hrr"}, 198 }) 199 200 // TLS 1.3 early data tests. DTLS 1.3 doesn't support early data yet. 201 // These tests are disabled for QUIC as well because they test features 202 // that do not apply to QUIC's use of TLS 1.3. 203 // 204 // TODO(crbug.com/381113363): Enable these tests for DTLS once we 205 // support early data in DTLS 1.3. 206 if config.protocol != dtls && config.protocol != quic { 207 tests = append(tests, testCase{ 208 testType: clientTest, 209 name: "TLS13-EarlyData-TooMuchData-Client", 210 config: Config{ 211 MaxVersion: VersionTLS13, 212 MinVersion: VersionTLS13, 213 MaxEarlyDataSize: 2, 214 }, 215 resumeConfig: &Config{ 216 MaxVersion: VersionTLS13, 217 MinVersion: VersionTLS13, 218 MaxEarlyDataSize: 2, 219 Bugs: ProtocolBugs{ 220 ExpectEarlyData: [][]byte{[]byte(shimInitialWrite[:2])}, 221 }, 222 }, 223 resumeShimPrefix: shimInitialWrite[2:], 224 resumeSession: true, 225 earlyData: true, 226 }) 227 228 // Unfinished writes can only be tested when operations are async. EarlyData 229 // can't be tested as part of an ImplicitHandshake in this case since 230 // otherwise the early data will be sent as normal data. 231 if config.async && !config.implicitHandshake { 232 tests = append(tests, testCase{ 233 testType: clientTest, 234 name: "TLS13-EarlyData-UnfinishedWrite-Client", 235 config: Config{ 236 MaxVersion: VersionTLS13, 237 MinVersion: VersionTLS13, 238 Bugs: ProtocolBugs{ 239 // Write the server response before expecting early data. 240 ExpectEarlyData: [][]byte{}, 241 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 242 }, 243 }, 244 resumeSession: true, 245 earlyData: true, 246 flags: []string{"-on-resume-read-with-unfinished-write"}, 247 }) 248 249 // Rejected unfinished writes are discarded (from the 250 // perspective of the calling application) on 0-RTT 251 // reject. 252 tests = append(tests, testCase{ 253 testType: clientTest, 254 name: "TLS13-EarlyData-RejectUnfinishedWrite-Client", 255 config: Config{ 256 MaxVersion: VersionTLS13, 257 MinVersion: VersionTLS13, 258 Bugs: ProtocolBugs{ 259 AlwaysRejectEarlyData: true, 260 }, 261 }, 262 resumeSession: true, 263 earlyData: true, 264 expectEarlyDataRejected: true, 265 flags: []string{"-on-resume-read-with-unfinished-write"}, 266 }) 267 } 268 269 // Early data has no size limit in QUIC. 270 tests = append(tests, testCase{ 271 testType: serverTest, 272 name: "TLS13-MaxEarlyData-Server", 273 config: Config{ 274 MaxVersion: VersionTLS13, 275 MinVersion: VersionTLS13, 276 Bugs: ProtocolBugs{ 277 SendEarlyData: [][]byte{bytes.Repeat([]byte{1}, 14336+1)}, 278 ExpectEarlyDataAccepted: true, 279 }, 280 }, 281 messageCount: 2, 282 resumeSession: true, 283 earlyData: true, 284 shouldFail: true, 285 expectedError: ":TOO_MUCH_READ_EARLY_DATA:", 286 }) 287 } 288 289 // Test that early data is disabled for DTLS 1.3. 290 if config.protocol == dtls { 291 tests = append(tests, testCase{ 292 testType: clientTest, 293 protocol: dtls, 294 name: "DTLS13-EarlyData", 295 config: Config{ 296 MaxVersion: VersionTLS13, 297 MinVersion: VersionTLS13, 298 }, 299 resumeSession: true, 300 earlyData: true, 301 }) 302 } 303 304 // TLS client auth. 305 // The following tests have a max version of 1.2, so they are not suitable 306 // for use with QUIC. 307 if config.protocol != quic { 308 tests = append(tests, testCase{ 309 testType: clientTest, 310 name: "ClientAuth-NoCertificate-Client", 311 config: Config{ 312 MaxVersion: VersionTLS12, 313 ClientAuth: RequestClientCert, 314 }, 315 }) 316 tests = append(tests, testCase{ 317 testType: serverTest, 318 name: "ClientAuth-NoCertificate-Server", 319 config: Config{ 320 MaxVersion: VersionTLS12, 321 }, 322 // Setting SSL_VERIFY_PEER allows anonymous clients. 323 flags: []string{"-verify-peer"}, 324 }) 325 } 326 if config.protocol != dtls { 327 tests = append(tests, testCase{ 328 testType: clientTest, 329 name: "ClientAuth-NoCertificate-Client-TLS13", 330 config: Config{ 331 MaxVersion: VersionTLS13, 332 ClientAuth: RequestClientCert, 333 }, 334 }) 335 tests = append(tests, testCase{ 336 testType: serverTest, 337 name: "ClientAuth-NoCertificate-Server-TLS13", 338 config: Config{ 339 MaxVersion: VersionTLS13, 340 }, 341 // Setting SSL_VERIFY_PEER allows anonymous clients. 342 flags: []string{"-verify-peer"}, 343 }) 344 } 345 if config.protocol != quic { 346 tests = append(tests, testCase{ 347 testType: clientTest, 348 name: "ClientAuth-RSA-Client", 349 config: Config{ 350 MaxVersion: VersionTLS12, 351 ClientAuth: RequireAnyClientCert, 352 }, 353 shimCertificate: &rsaCertificate, 354 }) 355 } 356 tests = append(tests, testCase{ 357 testType: clientTest, 358 name: "ClientAuth-RSA-Client-TLS13", 359 config: Config{ 360 MaxVersion: VersionTLS13, 361 ClientAuth: RequireAnyClientCert, 362 }, 363 shimCertificate: &rsaCertificate, 364 }) 365 if config.protocol != quic { 366 tests = append(tests, testCase{ 367 testType: clientTest, 368 name: "ClientAuth-ECDSA-Client", 369 config: Config{ 370 MaxVersion: VersionTLS12, 371 ClientAuth: RequireAnyClientCert, 372 }, 373 shimCertificate: &ecdsaP256Certificate, 374 }) 375 } 376 tests = append(tests, testCase{ 377 testType: clientTest, 378 name: "ClientAuth-ECDSA-Client-TLS13", 379 config: Config{ 380 MaxVersion: VersionTLS13, 381 ClientAuth: RequireAnyClientCert, 382 }, 383 shimCertificate: &ecdsaP256Certificate, 384 }) 385 if config.protocol != quic { 386 tests = append(tests, testCase{ 387 testType: clientTest, 388 name: "ClientAuth-NoCertificate-OldCallback", 389 config: Config{ 390 MaxVersion: VersionTLS12, 391 ClientAuth: RequestClientCert, 392 }, 393 flags: []string{"-use-old-client-cert-callback"}, 394 }) 395 } 396 tests = append(tests, testCase{ 397 testType: clientTest, 398 name: "ClientAuth-NoCertificate-OldCallback-TLS13", 399 config: Config{ 400 MaxVersion: VersionTLS13, 401 ClientAuth: RequestClientCert, 402 }, 403 flags: []string{"-use-old-client-cert-callback"}, 404 }) 405 if config.protocol != quic { 406 tests = append(tests, testCase{ 407 testType: clientTest, 408 name: "ClientAuth-OldCallback", 409 config: Config{ 410 MaxVersion: VersionTLS12, 411 ClientAuth: RequireAnyClientCert, 412 }, 413 shimCertificate: &rsaCertificate, 414 flags: []string{ 415 "-use-old-client-cert-callback", 416 }, 417 }) 418 } 419 tests = append(tests, testCase{ 420 testType: clientTest, 421 name: "ClientAuth-OldCallback-TLS13", 422 config: Config{ 423 MaxVersion: VersionTLS13, 424 ClientAuth: RequireAnyClientCert, 425 }, 426 shimCertificate: &rsaCertificate, 427 flags: []string{ 428 "-use-old-client-cert-callback", 429 }, 430 }) 431 if config.protocol != quic { 432 tests = append(tests, testCase{ 433 testType: serverTest, 434 name: "ClientAuth-Server", 435 config: Config{ 436 MaxVersion: VersionTLS12, 437 Credential: &rsaCertificate, 438 }, 439 flags: []string{"-require-any-client-certificate"}, 440 }) 441 } 442 tests = append(tests, testCase{ 443 testType: serverTest, 444 name: "ClientAuth-Server-TLS13", 445 config: Config{ 446 MaxVersion: VersionTLS13, 447 Credential: &rsaCertificate, 448 }, 449 flags: []string{"-require-any-client-certificate"}, 450 }) 451 452 // Test each key exchange on the server side for async keys. 453 if config.protocol != quic { 454 tests = append(tests, testCase{ 455 testType: serverTest, 456 name: "Basic-Server-RSA", 457 config: Config{ 458 MaxVersion: VersionTLS12, 459 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 460 }, 461 shimCertificate: &rsaCertificate, 462 }) 463 tests = append(tests, testCase{ 464 testType: serverTest, 465 name: "Basic-Server-ECDHE-RSA", 466 config: Config{ 467 MaxVersion: VersionTLS12, 468 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 469 }, 470 shimCertificate: &rsaCertificate, 471 }) 472 tests = append(tests, testCase{ 473 testType: serverTest, 474 name: "Basic-Server-ECDHE-ECDSA", 475 config: Config{ 476 MaxVersion: VersionTLS12, 477 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 478 }, 479 shimCertificate: &ecdsaP256Certificate, 480 }) 481 tests = append(tests, testCase{ 482 testType: serverTest, 483 name: "Basic-Server-Ed25519", 484 config: Config{ 485 MaxVersion: VersionTLS12, 486 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 487 }, 488 shimCertificate: &ed25519Certificate, 489 flags: []string{ 490 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 491 }, 492 }) 493 494 // No session ticket support; server doesn't send NewSessionTicket. 495 tests = append(tests, testCase{ 496 name: "SessionTicketsDisabled-Client", 497 config: Config{ 498 MaxVersion: VersionTLS12, 499 SessionTicketsDisabled: true, 500 }, 501 }) 502 tests = append(tests, testCase{ 503 testType: serverTest, 504 name: "SessionTicketsDisabled-Server", 505 config: Config{ 506 MaxVersion: VersionTLS12, 507 SessionTicketsDisabled: true, 508 }, 509 }) 510 511 // Skip ServerKeyExchange in PSK key exchange if there's no 512 // identity hint. 513 tests = append(tests, testCase{ 514 name: "EmptyPSKHint-Client", 515 config: Config{ 516 MaxVersion: VersionTLS12, 517 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 518 PreSharedKey: []byte("secret"), 519 }, 520 flags: []string{"-psk", "secret"}, 521 }) 522 tests = append(tests, testCase{ 523 testType: serverTest, 524 name: "EmptyPSKHint-Server", 525 config: Config{ 526 MaxVersion: VersionTLS12, 527 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 528 PreSharedKey: []byte("secret"), 529 }, 530 flags: []string{"-psk", "secret"}, 531 }) 532 } 533 534 // OCSP stapling tests. 535 for _, vers := range allVersions(config.protocol) { 536 tests = append(tests, testCase{ 537 testType: clientTest, 538 name: "OCSPStapling-Client-" + vers.name, 539 config: Config{ 540 MaxVersion: vers.version, 541 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 542 }, 543 flags: []string{ 544 "-enable-ocsp-stapling", 545 "-expect-ocsp-response", 546 base64FlagValue(testOCSPResponse), 547 "-verify-peer", 548 }, 549 resumeSession: true, 550 }) 551 tests = append(tests, testCase{ 552 testType: serverTest, 553 name: "OCSPStapling-Server-" + vers.name, 554 config: Config{ 555 MaxVersion: vers.version, 556 }, 557 expectations: connectionExpectations{ 558 peerCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 559 }, 560 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 561 resumeSession: true, 562 }) 563 564 // The client OCSP callback is an alternate certificate 565 // verification callback. 566 tests = append(tests, testCase{ 567 testType: clientTest, 568 name: "ClientOCSPCallback-Pass-" + vers.name, 569 config: Config{ 570 MaxVersion: vers.version, 571 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 572 }, 573 flags: []string{ 574 "-enable-ocsp-stapling", 575 "-use-ocsp-callback", 576 }, 577 }) 578 var expectedLocalError string 579 if !config.async { 580 // TODO(davidben): Asynchronous fatal alerts are never 581 // sent. https://crbug.com/boringssl/130. 582 expectedLocalError = "remote error: bad certificate status response" 583 } 584 tests = append(tests, testCase{ 585 testType: clientTest, 586 name: "ClientOCSPCallback-Fail-" + vers.name, 587 config: Config{ 588 MaxVersion: vers.version, 589 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 590 }, 591 flags: []string{ 592 "-enable-ocsp-stapling", 593 "-use-ocsp-callback", 594 "-fail-ocsp-callback", 595 }, 596 shouldFail: true, 597 expectedLocalError: expectedLocalError, 598 expectedError: ":OCSP_CB_ERROR:", 599 }) 600 // The callback still runs if the server does not send an OCSP 601 // response. 602 tests = append(tests, testCase{ 603 testType: clientTest, 604 name: "ClientOCSPCallback-FailNoStaple-" + vers.name, 605 config: Config{ 606 MaxVersion: vers.version, 607 Credential: &rsaCertificate, 608 }, 609 flags: []string{ 610 "-enable-ocsp-stapling", 611 "-use-ocsp-callback", 612 "-fail-ocsp-callback", 613 }, 614 shouldFail: true, 615 expectedLocalError: expectedLocalError, 616 expectedError: ":OCSP_CB_ERROR:", 617 }) 618 619 // The server OCSP callback is a legacy mechanism for 620 // configuring OCSP, used by unreliable server software. 621 tests = append(tests, testCase{ 622 testType: serverTest, 623 name: "ServerOCSPCallback-SetInCallback-" + vers.name, 624 config: Config{ 625 MaxVersion: vers.version, 626 }, 627 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 628 expectations: connectionExpectations{ 629 peerCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 630 }, 631 flags: []string{ 632 "-use-ocsp-callback", 633 "-set-ocsp-in-callback", 634 }, 635 resumeSession: true, 636 }) 637 638 // The callback may decline OCSP, in which case we act as if 639 // the client did not support it, even if a response was 640 // configured. 641 tests = append(tests, testCase{ 642 testType: serverTest, 643 name: "ServerOCSPCallback-Decline-" + vers.name, 644 config: Config{ 645 MaxVersion: vers.version, 646 }, 647 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 648 expectations: connectionExpectations{ 649 // There should be no OCSP response from the peer. 650 peerCertificate: &rsaCertificate, 651 }, 652 flags: []string{ 653 "-use-ocsp-callback", 654 "-decline-ocsp-callback", 655 }, 656 resumeSession: true, 657 }) 658 659 // The callback may also signal an internal error. 660 tests = append(tests, testCase{ 661 testType: serverTest, 662 name: "ServerOCSPCallback-Fail-" + vers.name, 663 config: Config{ 664 MaxVersion: vers.version, 665 }, 666 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 667 flags: []string{ 668 "-use-ocsp-callback", 669 "-fail-ocsp-callback", 670 }, 671 shouldFail: true, 672 expectedError: ":OCSP_CB_ERROR:", 673 }) 674 } 675 676 // Certificate verification tests. 677 for _, vers := range allVersions(config.protocol) { 678 for _, useCustomCallback := range []bool{false, true} { 679 for _, testType := range []testType{clientTest, serverTest} { 680 suffix := "-Client" 681 if testType == serverTest { 682 suffix = "-Server" 683 } 684 suffix += "-" + vers.name 685 if useCustomCallback { 686 suffix += "-CustomCallback" 687 } 688 689 // The custom callback and legacy callback have different default 690 // alerts. 691 verifyFailLocalError := "remote error: handshake failure" 692 if useCustomCallback { 693 verifyFailLocalError = "remote error: unknown certificate" 694 } 695 696 // We do not reliably send asynchronous fatal alerts. See 697 // https://crbug.com/boringssl/130. 698 if config.async { 699 verifyFailLocalError = "" 700 } 701 702 flags := []string{"-verify-peer"} 703 if testType == serverTest { 704 flags = append(flags, "-require-any-client-certificate") 705 } 706 if useCustomCallback { 707 flags = append(flags, "-use-custom-verify-callback") 708 } 709 710 tests = append(tests, testCase{ 711 testType: testType, 712 name: "CertificateVerificationSucceed" + suffix, 713 config: Config{ 714 MaxVersion: vers.version, 715 Credential: &rsaCertificate, 716 }, 717 flags: append([]string{"-expect-verify-result"}, flags...), 718 resumeSession: true, 719 }) 720 tests = append(tests, testCase{ 721 testType: testType, 722 name: "CertificateVerificationFail" + suffix, 723 config: Config{ 724 MaxVersion: vers.version, 725 Credential: &rsaCertificate, 726 }, 727 flags: append([]string{"-verify-fail"}, flags...), 728 shouldFail: true, 729 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 730 expectedLocalError: verifyFailLocalError, 731 }) 732 // Tests that although the verify callback fails on resumption, by default we don't call it. 733 tests = append(tests, testCase{ 734 testType: testType, 735 name: "CertificateVerificationDoesNotFailOnResume" + suffix, 736 config: Config{ 737 MaxVersion: vers.version, 738 Credential: &rsaCertificate, 739 }, 740 flags: append([]string{"-on-resume-verify-fail"}, flags...), 741 resumeSession: true, 742 }) 743 if testType == clientTest && useCustomCallback { 744 tests = append(tests, testCase{ 745 testType: testType, 746 name: "CertificateVerificationFailsOnResume" + suffix, 747 config: Config{ 748 MaxVersion: vers.version, 749 Credential: &rsaCertificate, 750 }, 751 flags: append([]string{ 752 "-on-resume-verify-fail", 753 "-reverify-on-resume", 754 }, flags...), 755 resumeSession: true, 756 shouldFail: true, 757 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 758 expectedLocalError: verifyFailLocalError, 759 }) 760 tests = append(tests, testCase{ 761 testType: testType, 762 name: "CertificateVerificationPassesOnResume" + suffix, 763 config: Config{ 764 MaxVersion: vers.version, 765 Credential: &rsaCertificate, 766 }, 767 flags: append([]string{ 768 "-reverify-on-resume", 769 }, flags...), 770 resumeSession: true, 771 }) 772 // TODO(crbug.com/381113363): Support 0-RTT in DTLS 1.3. 773 if vers.version >= VersionTLS13 && config.protocol != dtls { 774 tests = append(tests, testCase{ 775 testType: testType, 776 name: "EarlyData-RejectTicket-Client-Reverify" + suffix, 777 config: Config{ 778 MaxVersion: vers.version, 779 }, 780 resumeConfig: &Config{ 781 MaxVersion: vers.version, 782 SessionTicketsDisabled: true, 783 }, 784 resumeSession: true, 785 expectResumeRejected: true, 786 earlyData: true, 787 expectEarlyDataRejected: true, 788 flags: append([]string{ 789 "-reverify-on-resume", 790 // Session tickets are disabled, so the runner will not send a ticket. 791 "-on-retry-expect-no-session", 792 }, flags...), 793 }) 794 tests = append(tests, testCase{ 795 testType: testType, 796 name: "EarlyData-Reject0RTT-Client-Reverify" + suffix, 797 config: Config{ 798 MaxVersion: vers.version, 799 Bugs: ProtocolBugs{ 800 AlwaysRejectEarlyData: true, 801 }, 802 }, 803 resumeSession: true, 804 expectResumeRejected: false, 805 earlyData: true, 806 expectEarlyDataRejected: true, 807 flags: append([]string{ 808 "-reverify-on-resume", 809 }, flags...), 810 }) 811 tests = append(tests, testCase{ 812 testType: testType, 813 name: "EarlyData-RejectTicket-Client-ReverifyFails" + suffix, 814 config: Config{ 815 MaxVersion: vers.version, 816 }, 817 resumeConfig: &Config{ 818 MaxVersion: vers.version, 819 SessionTicketsDisabled: true, 820 }, 821 resumeSession: true, 822 expectResumeRejected: true, 823 earlyData: true, 824 expectEarlyDataRejected: true, 825 shouldFail: true, 826 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 827 flags: append([]string{ 828 "-reverify-on-resume", 829 // Session tickets are disabled, so the runner will not send a ticket. 830 "-on-retry-expect-no-session", 831 "-on-retry-verify-fail", 832 }, flags...), 833 }) 834 tests = append(tests, testCase{ 835 testType: testType, 836 name: "EarlyData-Reject0RTT-Client-ReverifyFails" + suffix, 837 config: Config{ 838 MaxVersion: vers.version, 839 Bugs: ProtocolBugs{ 840 AlwaysRejectEarlyData: true, 841 }, 842 }, 843 resumeSession: true, 844 expectResumeRejected: false, 845 earlyData: true, 846 expectEarlyDataRejected: true, 847 shouldFail: true, 848 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 849 expectedLocalError: verifyFailLocalError, 850 flags: append([]string{ 851 "-reverify-on-resume", 852 "-on-retry-verify-fail", 853 }, flags...), 854 }) 855 // This tests that we only call the verify callback once. 856 tests = append(tests, testCase{ 857 testType: testType, 858 name: "EarlyData-Accept0RTT-Client-Reverify" + suffix, 859 config: Config{ 860 MaxVersion: vers.version, 861 }, 862 resumeSession: true, 863 earlyData: true, 864 flags: append([]string{ 865 "-reverify-on-resume", 866 }, flags...), 867 }) 868 tests = append(tests, testCase{ 869 testType: testType, 870 name: "EarlyData-Accept0RTT-Client-ReverifyFails" + suffix, 871 config: Config{ 872 MaxVersion: vers.version, 873 }, 874 resumeSession: true, 875 earlyData: true, 876 shouldFail: true, 877 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 878 // We do not set expectedLocalError here because the shim rejects 879 // the connection without an alert. 880 flags: append([]string{ 881 "-reverify-on-resume", 882 "-on-resume-verify-fail", 883 }, flags...), 884 }) 885 } 886 } 887 } 888 } 889 890 // By default, the client is in a soft fail mode where the peer 891 // certificate is verified but failures are non-fatal. 892 tests = append(tests, testCase{ 893 testType: clientTest, 894 name: "CertificateVerificationSoftFail-" + vers.name, 895 config: Config{ 896 MaxVersion: vers.version, 897 Credential: &rsaCertificate, 898 }, 899 flags: []string{ 900 "-verify-fail", 901 "-expect-verify-result", 902 }, 903 resumeSession: true, 904 }) 905 } 906 907 tests = append(tests, testCase{ 908 name: "ShimSendAlert", 909 flags: []string{"-send-alert"}, 910 shimWritesFirst: true, 911 shouldFail: true, 912 expectedLocalError: "remote error: decompression failure", 913 }) 914 915 if config.protocol == tls { 916 tests = append(tests, testCase{ 917 name: "Renegotiate-Client", 918 config: Config{ 919 MaxVersion: VersionTLS12, 920 }, 921 renegotiate: 1, 922 flags: []string{ 923 "-renegotiate-freely", 924 "-expect-total-renegotiations", "1", 925 }, 926 }) 927 928 tests = append(tests, testCase{ 929 name: "Renegotiate-Client-Explicit", 930 config: Config{ 931 MaxVersion: VersionTLS12, 932 }, 933 renegotiate: 1, 934 flags: []string{ 935 "-renegotiate-explicit", 936 "-expect-total-renegotiations", "1", 937 }, 938 }) 939 940 halfHelloRequestError := ":UNEXPECTED_RECORD:" 941 if config.packHandshake { 942 // If the HelloRequest is sent in the same record as the server Finished, 943 // BoringSSL rejects it before the handshake completes. 944 halfHelloRequestError = ":EXCESS_HANDSHAKE_DATA:" 945 } 946 tests = append(tests, testCase{ 947 name: "SendHalfHelloRequest", 948 config: Config{ 949 MaxVersion: VersionTLS12, 950 Bugs: ProtocolBugs{ 951 PackHelloRequestWithFinished: config.packHandshake, 952 }, 953 }, 954 sendHalfHelloRequest: true, 955 flags: []string{"-renegotiate-ignore"}, 956 shouldFail: true, 957 expectedError: halfHelloRequestError, 958 }) 959 960 // NPN on client and server; results in post-ChangeCipherSpec message. 961 tests = append(tests, testCase{ 962 name: "NPN-Client", 963 config: Config{ 964 MaxVersion: VersionTLS12, 965 NextProtos: []string{"foo"}, 966 }, 967 flags: []string{"-select-next-proto", "foo"}, 968 resumeSession: true, 969 expectations: connectionExpectations{ 970 nextProto: "foo", 971 nextProtoType: npn, 972 }, 973 }) 974 tests = append(tests, testCase{ 975 testType: serverTest, 976 name: "NPN-Server", 977 config: Config{ 978 MaxVersion: VersionTLS12, 979 NextProtos: []string{"bar"}, 980 }, 981 flags: []string{ 982 "-advertise-npn", "\x03foo\x03bar\x03baz", 983 "-expect-next-proto", "bar", 984 }, 985 resumeSession: true, 986 expectations: connectionExpectations{ 987 nextProto: "bar", 988 nextProtoType: npn, 989 }, 990 }) 991 992 // The client may select no protocol after seeing the server list. 993 tests = append(tests, testCase{ 994 name: "NPN-Client-ClientSelectEmpty", 995 config: Config{ 996 MaxVersion: VersionTLS12, 997 NextProtos: []string{"foo"}, 998 }, 999 flags: []string{"-select-empty-next-proto"}, 1000 resumeSession: true, 1001 expectations: connectionExpectations{ 1002 noNextProto: true, 1003 nextProtoType: npn, 1004 }, 1005 }) 1006 tests = append(tests, testCase{ 1007 testType: serverTest, 1008 name: "NPN-Server-ClientSelectEmpty", 1009 config: Config{ 1010 MaxVersion: VersionTLS12, 1011 NextProtos: []string{"no-match"}, 1012 NoFallbackNextProto: true, 1013 }, 1014 flags: []string{ 1015 "-advertise-npn", "\x03foo\x03bar\x03baz", 1016 "-expect-no-next-proto", 1017 }, 1018 resumeSession: true, 1019 expectations: connectionExpectations{ 1020 noNextProto: true, 1021 nextProtoType: npn, 1022 }, 1023 }) 1024 1025 // The server may negotiate NPN, despite offering no protocols. In this 1026 // case, the server must still be prepared for the client to select a 1027 // fallback protocol. 1028 tests = append(tests, testCase{ 1029 name: "NPN-Client-ServerAdvertiseEmpty", 1030 config: Config{ 1031 MaxVersion: VersionTLS12, 1032 NegotiateNPNWithNoProtos: true, 1033 }, 1034 flags: []string{"-select-next-proto", "foo"}, 1035 resumeSession: true, 1036 expectations: connectionExpectations{ 1037 nextProto: "foo", 1038 nextProtoType: npn, 1039 }, 1040 }) 1041 tests = append(tests, testCase{ 1042 testType: serverTest, 1043 name: "NPN-Server-ServerAdvertiseEmpty", 1044 config: Config{ 1045 MaxVersion: VersionTLS12, 1046 NextProtos: []string{"foo"}, 1047 }, 1048 flags: []string{ 1049 "-advertise-empty-npn", 1050 "-expect-next-proto", "foo", 1051 }, 1052 resumeSession: true, 1053 expectations: connectionExpectations{ 1054 nextProto: "foo", 1055 nextProtoType: npn, 1056 }, 1057 }) 1058 1059 // Client does False Start and negotiates NPN. 1060 tests = append(tests, testCase{ 1061 name: "FalseStart", 1062 config: Config{ 1063 MaxVersion: VersionTLS12, 1064 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1065 NextProtos: []string{"foo"}, 1066 Bugs: ProtocolBugs{ 1067 ExpectFalseStart: true, 1068 }, 1069 }, 1070 flags: []string{ 1071 "-false-start", 1072 "-select-next-proto", "foo", 1073 }, 1074 shimWritesFirst: true, 1075 resumeSession: true, 1076 }) 1077 1078 // Client does False Start and negotiates ALPN. 1079 tests = append(tests, testCase{ 1080 name: "FalseStart-ALPN", 1081 config: Config{ 1082 MaxVersion: VersionTLS12, 1083 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1084 NextProtos: []string{"foo"}, 1085 Bugs: ProtocolBugs{ 1086 ExpectFalseStart: true, 1087 }, 1088 }, 1089 flags: []string{ 1090 "-false-start", 1091 "-advertise-alpn", "\x03foo", 1092 "-expect-alpn", "foo", 1093 }, 1094 shimWritesFirst: true, 1095 resumeSession: true, 1096 }) 1097 1098 // False Start without session tickets. 1099 tests = append(tests, testCase{ 1100 name: "FalseStart-SessionTicketsDisabled", 1101 config: Config{ 1102 MaxVersion: VersionTLS12, 1103 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1104 NextProtos: []string{"foo"}, 1105 SessionTicketsDisabled: true, 1106 Bugs: ProtocolBugs{ 1107 ExpectFalseStart: true, 1108 }, 1109 }, 1110 flags: []string{ 1111 "-false-start", 1112 "-select-next-proto", "foo", 1113 }, 1114 shimWritesFirst: true, 1115 }) 1116 1117 // Server parses a V2ClientHello. Test different lengths for the 1118 // challenge field. 1119 for _, challengeLength := range []int{16, 31, 32, 33, 48} { 1120 tests = append(tests, testCase{ 1121 testType: serverTest, 1122 name: fmt.Sprintf("SendV2ClientHello-%d", challengeLength), 1123 config: Config{ 1124 // Choose a cipher suite that does not involve 1125 // elliptic curves, so no extensions are 1126 // involved. 1127 MaxVersion: VersionTLS12, 1128 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 1129 Bugs: ProtocolBugs{ 1130 SendV2ClientHello: true, 1131 V2ClientHelloChallengeLength: challengeLength, 1132 }, 1133 }, 1134 flags: []string{ 1135 "-expect-msg-callback", 1136 `read v2clienthello 1137write hs 2 1138write hs 11 1139write hs 14 1140read hs 16 1141read ccs 1142read hs 20 1143write ccs 1144write hs 20 1145read alert 1 0 1146`, 1147 }, 1148 }) 1149 } 1150 1151 // Channel ID and NPN at the same time, to ensure their relative 1152 // ordering is correct. 1153 tests = append(tests, testCase{ 1154 name: "ChannelID-NPN-Client", 1155 config: Config{ 1156 MaxVersion: VersionTLS12, 1157 RequestChannelID: true, 1158 NextProtos: []string{"foo"}, 1159 }, 1160 flags: []string{ 1161 "-send-channel-id", channelIDKeyPath, 1162 "-select-next-proto", "foo", 1163 }, 1164 resumeSession: true, 1165 expectations: connectionExpectations{ 1166 channelID: true, 1167 nextProto: "foo", 1168 nextProtoType: npn, 1169 }, 1170 }) 1171 tests = append(tests, testCase{ 1172 testType: serverTest, 1173 name: "ChannelID-NPN-Server", 1174 config: Config{ 1175 MaxVersion: VersionTLS12, 1176 ChannelID: &channelIDKey, 1177 NextProtos: []string{"bar"}, 1178 }, 1179 flags: []string{ 1180 "-expect-channel-id", 1181 base64FlagValue(channelIDBytes), 1182 "-advertise-npn", "\x03foo\x03bar\x03baz", 1183 "-expect-next-proto", "bar", 1184 }, 1185 resumeSession: true, 1186 expectations: connectionExpectations{ 1187 channelID: true, 1188 nextProto: "bar", 1189 nextProtoType: npn, 1190 }, 1191 }) 1192 1193 // Bidirectional shutdown with the runner initiating. 1194 tests = append(tests, testCase{ 1195 name: "Shutdown-Runner", 1196 config: Config{ 1197 Bugs: ProtocolBugs{ 1198 ExpectCloseNotify: true, 1199 }, 1200 }, 1201 flags: []string{"-check-close-notify"}, 1202 }) 1203 } 1204 if config.protocol != dtls { 1205 // Test Channel ID 1206 for _, ver := range allVersions(config.protocol) { 1207 if ver.version < VersionTLS10 { 1208 continue 1209 } 1210 // Client sends a Channel ID. 1211 tests = append(tests, testCase{ 1212 name: "ChannelID-Client-" + ver.name, 1213 config: Config{ 1214 MaxVersion: ver.version, 1215 RequestChannelID: true, 1216 }, 1217 flags: []string{"-send-channel-id", channelIDKeyPath}, 1218 resumeSession: true, 1219 expectations: connectionExpectations{ 1220 channelID: true, 1221 }, 1222 }) 1223 1224 // Server accepts a Channel ID. 1225 tests = append(tests, testCase{ 1226 testType: serverTest, 1227 name: "ChannelID-Server-" + ver.name, 1228 config: Config{ 1229 MaxVersion: ver.version, 1230 ChannelID: &channelIDKey, 1231 }, 1232 flags: []string{ 1233 "-expect-channel-id", 1234 base64FlagValue(channelIDBytes), 1235 }, 1236 resumeSession: true, 1237 expectations: connectionExpectations{ 1238 channelID: true, 1239 }, 1240 }) 1241 1242 tests = append(tests, testCase{ 1243 testType: serverTest, 1244 name: "InvalidChannelIDSignature-" + ver.name, 1245 config: Config{ 1246 MaxVersion: ver.version, 1247 ChannelID: &channelIDKey, 1248 Bugs: ProtocolBugs{ 1249 InvalidChannelIDSignature: true, 1250 }, 1251 }, 1252 flags: []string{"-enable-channel-id"}, 1253 shouldFail: true, 1254 expectedError: ":CHANNEL_ID_SIGNATURE_INVALID:", 1255 }) 1256 1257 if ver.version < VersionTLS13 { 1258 // Channel ID requires ECDHE ciphers. 1259 tests = append(tests, testCase{ 1260 testType: serverTest, 1261 name: "ChannelID-NoECDHE-" + ver.name, 1262 config: Config{ 1263 MaxVersion: ver.version, 1264 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 1265 ChannelID: &channelIDKey, 1266 }, 1267 expectations: connectionExpectations{ 1268 channelID: false, 1269 }, 1270 flags: []string{"-enable-channel-id"}, 1271 }) 1272 1273 // Sanity-check setting expectations.channelID false works. 1274 tests = append(tests, testCase{ 1275 testType: serverTest, 1276 name: "ChannelID-ECDHE-" + ver.name, 1277 config: Config{ 1278 MaxVersion: ver.version, 1279 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 1280 ChannelID: &channelIDKey, 1281 }, 1282 expectations: connectionExpectations{ 1283 channelID: false, 1284 }, 1285 flags: []string{"-enable-channel-id"}, 1286 shouldFail: true, 1287 expectedLocalError: "channel ID unexpectedly negotiated", 1288 }) 1289 } 1290 } 1291 1292 if !config.implicitHandshake { 1293 // Bidirectional shutdown with the shim initiating. The runner, 1294 // in the meantime, sends garbage before the close_notify which 1295 // the shim must ignore. This test is disabled under implicit 1296 // handshake tests because the shim never reads or writes. 1297 1298 // Tests that require checking for a close notify alert don't work with 1299 // QUIC because alerts are handled outside of the TLS stack in QUIC. 1300 if config.protocol != quic { 1301 tests = append(tests, testCase{ 1302 name: "Shutdown-Shim", 1303 config: Config{ 1304 MaxVersion: VersionTLS12, 1305 Bugs: ProtocolBugs{ 1306 ExpectCloseNotify: true, 1307 }, 1308 }, 1309 shimShutsDown: true, 1310 sendEmptyRecords: 1, 1311 sendWarningAlerts: 1, 1312 flags: []string{"-check-close-notify"}, 1313 }) 1314 1315 // The shim should reject unexpected application data 1316 // when shutting down. 1317 tests = append(tests, testCase{ 1318 name: "Shutdown-Shim-ApplicationData", 1319 config: Config{ 1320 MaxVersion: VersionTLS12, 1321 Bugs: ProtocolBugs{ 1322 ExpectCloseNotify: true, 1323 }, 1324 }, 1325 shimShutsDown: true, 1326 messageCount: 1, 1327 sendEmptyRecords: 1, 1328 sendWarningAlerts: 1, 1329 flags: []string{"-check-close-notify"}, 1330 shouldFail: true, 1331 expectedError: ":APPLICATION_DATA_ON_SHUTDOWN:", 1332 }) 1333 1334 // Test that SSL_shutdown still processes KeyUpdate. 1335 tests = append(tests, testCase{ 1336 name: "Shutdown-Shim-KeyUpdate", 1337 config: Config{ 1338 MinVersion: VersionTLS13, 1339 MaxVersion: VersionTLS13, 1340 Bugs: ProtocolBugs{ 1341 ExpectCloseNotify: true, 1342 }, 1343 }, 1344 shimShutsDown: true, 1345 sendKeyUpdates: 1, 1346 keyUpdateRequest: keyUpdateRequested, 1347 flags: []string{"-check-close-notify"}, 1348 }) 1349 1350 // Test that SSL_shutdown processes HelloRequest 1351 // correctly. 1352 tests = append(tests, testCase{ 1353 name: "Shutdown-Shim-HelloRequest-Ignore", 1354 config: Config{ 1355 MinVersion: VersionTLS12, 1356 MaxVersion: VersionTLS12, 1357 Bugs: ProtocolBugs{ 1358 SendHelloRequestBeforeEveryAppDataRecord: true, 1359 ExpectCloseNotify: true, 1360 }, 1361 }, 1362 shimShutsDown: true, 1363 flags: []string{ 1364 "-renegotiate-ignore", 1365 "-check-close-notify", 1366 }, 1367 }) 1368 tests = append(tests, testCase{ 1369 name: "Shutdown-Shim-HelloRequest-Reject", 1370 config: Config{ 1371 MinVersion: VersionTLS12, 1372 MaxVersion: VersionTLS12, 1373 Bugs: ProtocolBugs{ 1374 ExpectCloseNotify: true, 1375 }, 1376 }, 1377 shimShutsDown: true, 1378 renegotiate: 1, 1379 shouldFail: true, 1380 expectedError: ":NO_RENEGOTIATION:", 1381 flags: []string{"-check-close-notify"}, 1382 }) 1383 tests = append(tests, testCase{ 1384 name: "Shutdown-Shim-HelloRequest-CannotHandshake", 1385 config: Config{ 1386 MinVersion: VersionTLS12, 1387 MaxVersion: VersionTLS12, 1388 Bugs: ProtocolBugs{ 1389 ExpectCloseNotify: true, 1390 }, 1391 }, 1392 shimShutsDown: true, 1393 renegotiate: 1, 1394 shouldFail: true, 1395 expectedError: ":NO_RENEGOTIATION:", 1396 flags: []string{ 1397 "-check-close-notify", 1398 "-renegotiate-freely", 1399 }, 1400 }) 1401 1402 tests = append(tests, testCase{ 1403 testType: serverTest, 1404 name: "Shutdown-Shim-Renegotiate-Server-Forbidden", 1405 config: Config{ 1406 MaxVersion: VersionTLS12, 1407 Bugs: ProtocolBugs{ 1408 ExpectCloseNotify: true, 1409 }, 1410 }, 1411 shimShutsDown: true, 1412 renegotiate: 1, 1413 shouldFail: true, 1414 expectedError: ":NO_RENEGOTIATION:", 1415 flags: []string{ 1416 "-check-close-notify", 1417 }, 1418 }) 1419 } 1420 } 1421 } 1422 if config.protocol == dtls { 1423 tests = append(tests, testCase{ 1424 name: "SkipHelloVerifyRequest", 1425 config: Config{ 1426 MaxVersion: VersionTLS12, 1427 Bugs: ProtocolBugs{ 1428 SkipHelloVerifyRequest: true, 1429 }, 1430 }, 1431 }) 1432 tests = append(tests, testCase{ 1433 name: "DTLS13-HelloVerifyRequest", 1434 config: Config{ 1435 MinVersion: VersionTLS13, 1436 Bugs: ProtocolBugs{ 1437 ForceHelloVerifyRequest: true, 1438 }, 1439 }, 1440 shouldFail: true, 1441 expectedError: ":INVALID_MESSAGE:", 1442 }) 1443 tests = append(tests, testCase{ 1444 name: "DTLS13-HelloVerifyRequestEmptyCookie", 1445 config: Config{ 1446 MinVersion: VersionTLS13, 1447 Bugs: ProtocolBugs{ 1448 ForceHelloVerifyRequest: true, 1449 EmptyHelloVerifyRequestCookie: true, 1450 }, 1451 }, 1452 shouldFail: true, 1453 expectedError: ":INVALID_MESSAGE:", 1454 }) 1455 } 1456 1457 for _, test := range tests { 1458 test.protocol = config.protocol 1459 test.name += "-" + config.protocol.String() 1460 if config.async { 1461 test.name += "-Async" 1462 test.flags = append(test.flags, "-async") 1463 } else { 1464 test.name += "-Sync" 1465 } 1466 if config.splitHandshake { 1467 test.name += "-SplitHandshakeRecords" 1468 test.config.Bugs.MaxHandshakeRecordLength = 1 1469 if config.protocol == dtls { 1470 test.config.Bugs.MaxPacketLength = 256 1471 test.flags = append(test.flags, "-mtu", "256") 1472 } 1473 } 1474 if config.packHandshake { 1475 test.name += "-PackHandshake" 1476 if config.protocol == dtls { 1477 test.config.Bugs.MaxHandshakeRecordLength = 2 1478 test.config.Bugs.PackHandshakeFragments = 20 1479 test.config.Bugs.PackHandshakeRecords = 1500 1480 test.config.Bugs.PackAppDataWithHandshake = true 1481 } else { 1482 test.config.Bugs.PackHandshakeFlight = true 1483 } 1484 } 1485 if config.implicitHandshake { 1486 test.name += "-ImplicitHandshake" 1487 test.flags = append(test.flags, "-implicit-handshake") 1488 } 1489 testCases = append(testCases, test) 1490 } 1491} 1492