1// Copyright (c) 2016, Google Inc. 2// 3// Permission to use, copy, modify, and/or distribute this software for any 4// purpose with or without fee is hereby granted, provided that the above 5// copyright notice and this permission notice appear in all copies. 6// 7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 15package runner 16 17import ( 18 "bytes" 19 "crypto" 20 "crypto/ecdsa" 21 "crypto/elliptic" 22 "crypto/rand" 23 "crypto/rsa" 24 "crypto/x509" 25 "crypto/x509/pkix" 26 "encoding/base64" 27 "encoding/binary" 28 "encoding/hex" 29 "encoding/json" 30 "encoding/pem" 31 "errors" 32 "flag" 33 "fmt" 34 "io" 35 "math/big" 36 "net" 37 "os" 38 "os/exec" 39 "path" 40 "path/filepath" 41 "runtime" 42 "strconv" 43 "strings" 44 "sync" 45 "syscall" 46 "time" 47 48 "boringssl.googlesource.com/boringssl/ssl/test/runner/hpke" 49 "boringssl.googlesource.com/boringssl/util/testresult" 50 "golang.org/x/crypto/cryptobyte" 51) 52 53var ( 54 useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind") 55 useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb") 56 useLLDB = flag.Bool("lldb", false, "If true, run BoringSSL code under lldb") 57 useRR = flag.Bool("rr-record", false, "If true, run BoringSSL code under `rr record`.") 58 waitForDebugger = flag.Bool("wait-for-debugger", false, "If true, jobs will run one at a time and pause for a debugger to attach") 59 flagDebug = flag.Bool("debug", false, "Hexdump the contents of the connection") 60 mallocTest = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.") 61 mallocTestDebug = flag.Bool("malloc-test-debug", false, "If true, ask bssl_shim to abort rather than fail a malloc. This can be used with a specific value for --malloc-test to identity the malloc failing that is causing problems.") 62 jsonOutput = flag.String("json-output", "", "The file to output JSON results to.") 63 pipe = flag.Bool("pipe", false, "If true, print status output suitable for piping into another program.") 64 testToRun = flag.String("test", "", "Semicolon-separated patterns of tests to run, or empty to run all tests") 65 skipTest = flag.String("skip", "", "Semicolon-separated patterns of tests to skip") 66 allowHintMismatch = flag.String("allow-hint-mismatch", "", "Semicolon-separated patterns of tests where hints may mismatch") 67 numWorkersFlag = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.") 68 shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.") 69 shimExtraFlags = flag.String("shim-extra-flags", "", "Semicolon-separated extra flags to pass to the shim binary on each invocation.") 70 handshakerPath = flag.String("handshaker-path", "../../../build/ssl/test/handshaker", "The location of the handshaker binary.") 71 resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.") 72 fuzzer = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.") 73 transcriptDir = flag.String("transcript-dir", "", "The directory in which to write transcripts.") 74 idleTimeout = flag.Duration("idle-timeout", 15*time.Second, "The number of seconds to wait for a read or write to bssl_shim.") 75 deterministic = flag.Bool("deterministic", false, "If true, uses a deterministic PRNG in the runner.") 76 allowUnimplemented = flag.Bool("allow-unimplemented", false, "If true, report pass even if some tests are unimplemented.") 77 looseErrors = flag.Bool("loose-errors", false, "If true, allow shims to report an untranslated error code.") 78 shimConfigFile = flag.String("shim-config", "", "A config file to use to configure the tests for this shim.") 79 includeDisabled = flag.Bool("include-disabled", false, "If true, also runs disabled tests.") 80 repeatUntilFailure = flag.Bool("repeat-until-failure", false, "If true, the first selected test will be run repeatedly until failure.") 81) 82 83// ShimConfigurations is used with the “json” package and represents a shim 84// config file. 85type ShimConfiguration struct { 86 // DisabledTests maps from a glob-based pattern to a freeform string. 87 // The glob pattern is used to exclude tests from being run and the 88 // freeform string is unparsed but expected to explain why the test is 89 // disabled. 90 DisabledTests map[string]string 91 92 // ErrorMap maps from expected error strings to the correct error 93 // string for the shim in question. For example, it might map 94 // “:NO_SHARED_CIPHER:” (a BoringSSL error string) to something 95 // like “SSL_ERROR_NO_CYPHER_OVERLAP”. 96 ErrorMap map[string]string 97 98 // HalfRTTTickets is the number of half-RTT tickets the client should 99 // expect before half-RTT data when testing 0-RTT. 100 HalfRTTTickets int 101 102 // AllCurves is the list of all curve code points supported by the shim. 103 // This is currently used to control tests that enable all curves but may 104 // automatically disable tests in the future. 105 AllCurves []int 106} 107 108// Setup shimConfig defaults aligning with BoringSSL. 109var shimConfig ShimConfiguration = ShimConfiguration{ 110 HalfRTTTickets: 2, 111} 112 113type testCert int 114 115const ( 116 testCertRSA testCert = iota 117 testCertRSA1024 118 testCertRSAChain 119 testCertECDSAP224 120 testCertECDSAP256 121 testCertECDSAP384 122 testCertECDSAP521 123 testCertEd25519 124) 125 126const ( 127 rsaCertificateFile = "cert.pem" 128 rsa1024CertificateFile = "rsa_1024_cert.pem" 129 rsaChainCertificateFile = "rsa_chain_cert.pem" 130 ecdsaP224CertificateFile = "ecdsa_p224_cert.pem" 131 ecdsaP256CertificateFile = "ecdsa_p256_cert.pem" 132 ecdsaP384CertificateFile = "ecdsa_p384_cert.pem" 133 ecdsaP521CertificateFile = "ecdsa_p521_cert.pem" 134 ed25519CertificateFile = "ed25519_cert.pem" 135) 136 137const ( 138 rsaKeyFile = "key.pem" 139 rsa1024KeyFile = "rsa_1024_key.pem" 140 rsaChainKeyFile = "rsa_chain_key.pem" 141 ecdsaP224KeyFile = "ecdsa_p224_key.pem" 142 ecdsaP256KeyFile = "ecdsa_p256_key.pem" 143 ecdsaP384KeyFile = "ecdsa_p384_key.pem" 144 ecdsaP521KeyFile = "ecdsa_p521_key.pem" 145 ed25519KeyFile = "ed25519_key.pem" 146 channelIDKeyFile = "channel_id_key.pem" 147) 148 149var ( 150 rsaCertificate Certificate 151 rsa1024Certificate Certificate 152 rsaChainCertificate Certificate 153 ecdsaP224Certificate Certificate 154 ecdsaP256Certificate Certificate 155 ecdsaP384Certificate Certificate 156 ecdsaP521Certificate Certificate 157 ed25519Certificate Certificate 158 garbageCertificate Certificate 159) 160 161var testCerts = []struct { 162 id testCert 163 certFile, keyFile string 164 cert *Certificate 165}{ 166 { 167 id: testCertRSA, 168 certFile: rsaCertificateFile, 169 keyFile: rsaKeyFile, 170 cert: &rsaCertificate, 171 }, 172 { 173 id: testCertRSA1024, 174 certFile: rsa1024CertificateFile, 175 keyFile: rsa1024KeyFile, 176 cert: &rsa1024Certificate, 177 }, 178 { 179 id: testCertRSAChain, 180 certFile: rsaChainCertificateFile, 181 keyFile: rsaChainKeyFile, 182 cert: &rsaChainCertificate, 183 }, 184 { 185 id: testCertECDSAP224, 186 certFile: ecdsaP224CertificateFile, 187 keyFile: ecdsaP224KeyFile, 188 cert: &ecdsaP224Certificate, 189 }, 190 { 191 id: testCertECDSAP256, 192 certFile: ecdsaP256CertificateFile, 193 keyFile: ecdsaP256KeyFile, 194 cert: &ecdsaP256Certificate, 195 }, 196 { 197 id: testCertECDSAP384, 198 certFile: ecdsaP384CertificateFile, 199 keyFile: ecdsaP384KeyFile, 200 cert: &ecdsaP384Certificate, 201 }, 202 { 203 id: testCertECDSAP521, 204 certFile: ecdsaP521CertificateFile, 205 keyFile: ecdsaP521KeyFile, 206 cert: &ecdsaP521Certificate, 207 }, 208 { 209 id: testCertEd25519, 210 certFile: ed25519CertificateFile, 211 keyFile: ed25519KeyFile, 212 cert: &ed25519Certificate, 213 }, 214} 215 216var channelIDKey *ecdsa.PrivateKey 217var channelIDBytes []byte 218 219var testOCSPResponse = []byte{1, 2, 3, 4} 220var testOCSPResponse2 = []byte{5, 6, 7, 8} 221var testSCTList = []byte{0, 6, 0, 4, 5, 6, 7, 8} 222var testSCTList2 = []byte{0, 6, 0, 4, 1, 2, 3, 4} 223 224var testOCSPExtension = append([]byte{byte(extensionStatusRequest) >> 8, byte(extensionStatusRequest), 0, 8, statusTypeOCSP, 0, 0, 4}, testOCSPResponse...) 225var testSCTExtension = append([]byte{byte(extensionSignedCertificateTimestamp) >> 8, byte(extensionSignedCertificateTimestamp), 0, byte(len(testSCTList))}, testSCTList...) 226 227func initCertificates() { 228 for i := range testCerts { 229 cert, err := LoadX509KeyPair(path.Join(*resourceDir, testCerts[i].certFile), path.Join(*resourceDir, testCerts[i].keyFile)) 230 if err != nil { 231 panic(err) 232 } 233 cert.OCSPStaple = testOCSPResponse 234 cert.SignedCertificateTimestampList = testSCTList 235 *testCerts[i].cert = cert 236 } 237 238 channelIDPEMBlock, err := os.ReadFile(path.Join(*resourceDir, channelIDKeyFile)) 239 if err != nil { 240 panic(err) 241 } 242 channelIDDERBlock, _ := pem.Decode(channelIDPEMBlock) 243 if channelIDDERBlock.Type != "EC PRIVATE KEY" { 244 panic("bad key type") 245 } 246 channelIDKey, err = x509.ParseECPrivateKey(channelIDDERBlock.Bytes) 247 if err != nil { 248 panic(err) 249 } 250 if channelIDKey.Curve != elliptic.P256() { 251 panic("bad curve") 252 } 253 254 channelIDBytes = make([]byte, 64) 255 writeIntPadded(channelIDBytes[:32], channelIDKey.X) 256 writeIntPadded(channelIDBytes[32:], channelIDKey.Y) 257 258 garbageCertificate.Certificate = [][]byte{[]byte("GARBAGE")} 259 garbageCertificate.PrivateKey = rsaCertificate.PrivateKey 260} 261 262func flagInts(flagName string, vals []int) []string { 263 ret := make([]string, 0, 2*len(vals)) 264 for _, val := range vals { 265 ret = append(ret, flagName, strconv.Itoa(val)) 266 } 267 return ret 268} 269 270func base64FlagValue(in []byte) string { 271 return base64.StdEncoding.EncodeToString(in) 272} 273 274func useDebugger() bool { 275 return *useGDB || *useLLDB || *useRR || *waitForDebugger 276} 277 278// delegatedCredentialConfig specifies the shape of a delegated credential, not 279// including the keys themselves. 280type delegatedCredentialConfig struct { 281 // lifetime is the amount of time, from the notBefore of the parent 282 // certificate, that the delegated credential is valid for. If zero, then 24 283 // hours is assumed. 284 lifetime time.Duration 285 // expectedAlgo is the signature scheme that should be used with this 286 // delegated credential. If zero, ECDSA with P-256 is assumed. 287 expectedAlgo signatureAlgorithm 288 // tlsVersion is the version of TLS that should be used with this delegated 289 // credential. If zero, TLS 1.3 is assumed. 290 tlsVersion uint16 291 // algo is the signature algorithm that the delegated credential itself is 292 // signed with. Cannot be zero. 293 algo signatureAlgorithm 294} 295 296func loadRSAPrivateKey(filename string) (priv *rsa.PrivateKey, privPKCS8 []byte, err error) { 297 pemPath := path.Join(*resourceDir, filename) 298 pemBytes, err := os.ReadFile(pemPath) 299 if err != nil { 300 return nil, nil, err 301 } 302 303 block, _ := pem.Decode(pemBytes) 304 if block == nil { 305 return nil, nil, fmt.Errorf("no PEM block found in %q", pemPath) 306 } 307 privPKCS8 = block.Bytes 308 309 parsed, err := x509.ParsePKCS8PrivateKey(privPKCS8) 310 if err != nil { 311 return nil, nil, fmt.Errorf("failed to parse PKCS#8 key from %q", pemPath) 312 } 313 314 priv, ok := parsed.(*rsa.PrivateKey) 315 if !ok { 316 return nil, nil, fmt.Errorf("found %T in %q rather than an RSA private key", parsed, pemPath) 317 } 318 319 return priv, privPKCS8, nil 320} 321 322func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byte, parentPriv crypto.PrivateKey) (dc, privPKCS8 []uint8, err error) { 323 expectedAlgo := config.expectedAlgo 324 if expectedAlgo == signatureAlgorithm(0) { 325 expectedAlgo = signatureECDSAWithP256AndSHA256 326 } 327 328 var pub crypto.PublicKey 329 330 switch expectedAlgo { 331 case signatureRSAPKCS1WithMD5, signatureRSAPKCS1WithSHA1, signatureRSAPKCS1WithSHA256, signatureRSAPKCS1WithSHA384, signatureRSAPKCS1WithSHA512, signatureRSAPSSWithSHA256, signatureRSAPSSWithSHA384, signatureRSAPSSWithSHA512: 332 // RSA keys are expensive to generate so load from disk instead. 333 var priv *rsa.PrivateKey 334 if priv, privPKCS8, err = loadRSAPrivateKey(rsaKeyFile); err != nil { 335 return nil, nil, err 336 } 337 338 pub = &priv.PublicKey 339 340 case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256, signatureECDSAWithP384AndSHA384, signatureECDSAWithP521AndSHA512: 341 var curve elliptic.Curve 342 switch expectedAlgo { 343 case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256: 344 curve = elliptic.P256() 345 case signatureECDSAWithP384AndSHA384: 346 curve = elliptic.P384() 347 case signatureECDSAWithP521AndSHA512: 348 curve = elliptic.P521() 349 default: 350 panic("internal error") 351 } 352 353 priv, err := ecdsa.GenerateKey(curve, rand.Reader) 354 if err != nil { 355 return nil, nil, err 356 } 357 358 if privPKCS8, err = x509.MarshalPKCS8PrivateKey(priv); err != nil { 359 return nil, nil, err 360 } 361 362 pub = &priv.PublicKey 363 364 default: 365 return nil, nil, fmt.Errorf("unsupported expected signature algorithm: %x", expectedAlgo) 366 } 367 368 lifetime := config.lifetime 369 if lifetime == 0 { 370 lifetime = 24 * time.Hour 371 } 372 lifetimeSecs := int64(lifetime.Seconds()) 373 if lifetimeSecs > 1<<32 { 374 return nil, nil, fmt.Errorf("lifetime %s is too long to be expressed", lifetime) 375 } 376 tlsVersion := config.tlsVersion 377 if tlsVersion == 0 { 378 tlsVersion = VersionTLS13 379 } 380 381 if tlsVersion < VersionTLS13 { 382 return nil, nil, fmt.Errorf("delegated credentials require TLS 1.3") 383 } 384 385 // https://tools.ietf.org/html/draft-ietf-tls-subcerts-03#section-3 386 dc = append(dc, byte(lifetimeSecs>>24), byte(lifetimeSecs>>16), byte(lifetimeSecs>>8), byte(lifetimeSecs)) 387 dc = append(dc, byte(expectedAlgo>>8), byte(expectedAlgo)) 388 389 pubBytes, err := x509.MarshalPKIXPublicKey(pub) 390 if err != nil { 391 return nil, nil, err 392 } 393 394 dc = append(dc, byte(len(pubBytes)>>16), byte(len(pubBytes)>>8), byte(len(pubBytes))) 395 dc = append(dc, pubBytes...) 396 397 var dummyConfig Config 398 parentSigner, err := getSigner(tlsVersion, parentPriv, &dummyConfig, config.algo, false /* not for verification */) 399 if err != nil { 400 return nil, nil, err 401 } 402 403 parentSignature, err := parentSigner.signMessage(parentPriv, &dummyConfig, delegatedCredentialSignedMessage(dc, config.algo, parentDER)) 404 if err != nil { 405 return nil, nil, err 406 } 407 408 dc = append(dc, byte(config.algo>>8), byte(config.algo)) 409 dc = append(dc, byte(len(parentSignature)>>8), byte(len(parentSignature))) 410 dc = append(dc, parentSignature...) 411 412 return dc, privPKCS8, nil 413} 414 415func getRunnerCertificate(t testCert) Certificate { 416 for _, cert := range testCerts { 417 if cert.id == t { 418 return *cert.cert 419 } 420 } 421 panic("Unknown test certificate") 422} 423 424func getShimCertificate(t testCert) string { 425 for _, cert := range testCerts { 426 if cert.id == t { 427 return cert.certFile 428 } 429 } 430 panic("Unknown test certificate") 431} 432 433func getShimKey(t testCert) string { 434 for _, cert := range testCerts { 435 if cert.id == t { 436 return cert.keyFile 437 } 438 } 439 panic("Unknown test certificate") 440} 441 442// recordVersionToWire maps a record-layer protocol version to its wire 443// representation. 444func recordVersionToWire(vers uint16, protocol protocol) uint16 { 445 if protocol == dtls { 446 switch vers { 447 case VersionTLS12: 448 return VersionDTLS12 449 case VersionTLS10: 450 return VersionDTLS10 451 } 452 } else { 453 switch vers { 454 case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12: 455 return vers 456 } 457 } 458 459 panic("unknown version") 460} 461 462// encodeDERValues encodes a series of bytestrings in comma-separated-hex form. 463func encodeDERValues(values [][]byte) string { 464 var ret string 465 for i, v := range values { 466 if i > 0 { 467 ret += "," 468 } 469 ret += hex.EncodeToString(v) 470 } 471 472 return ret 473} 474 475func decodeHexOrPanic(in string) []byte { 476 ret, err := hex.DecodeString(in) 477 if err != nil { 478 panic(err) 479 } 480 return ret 481} 482 483type testType int 484 485const ( 486 clientTest testType = iota 487 serverTest 488) 489 490type protocol int 491 492const ( 493 tls protocol = iota 494 dtls 495 quic 496) 497 498func (p protocol) String() string { 499 switch p { 500 case tls: 501 return "TLS" 502 case dtls: 503 return "DTLS" 504 case quic: 505 return "QUIC" 506 } 507 return "unknown protocol" 508} 509 510const ( 511 alpn = 1 512 npn = 2 513) 514 515// connectionExpectations contains connection-level test expectations to check 516// on the runner side. 517type connectionExpectations struct { 518 // version, if non-zero, specifies the TLS version that must be negotiated. 519 version uint16 520 // cipher, if non-zero, specifies the TLS cipher suite that should be 521 // negotiated. 522 cipher uint16 523 // channelID controls whether the connection should have negotiated a 524 // Channel ID with channelIDKey. 525 channelID bool 526 // nextProto controls whether the connection should negotiate a next 527 // protocol via NPN or ALPN. 528 nextProto string 529 // noNextProto, if true, means that no next protocol should be negotiated. 530 noNextProto bool 531 // nextProtoType, if non-zero, is the next protocol negotiation mechanism. 532 nextProtoType int 533 // srtpProtectionProfile is the DTLS-SRTP profile that should be negotiated. 534 // If zero, none should be negotiated. 535 srtpProtectionProfile uint16 536 // ocspResponse, if not nil, is the OCSP response to be received. 537 ocspResponse []uint8 538 // sctList, if not nil, is the SCT list to be received. 539 sctList []uint8 540 // peerSignatureAlgorithm, if not zero, is the signature algorithm that the 541 // peer should have used in the handshake. 542 peerSignatureAlgorithm signatureAlgorithm 543 // curveID, if not zero, is the curve that the handshake should have used. 544 curveID CurveID 545 // peerCertificate, if not nil, is the certificate chain the peer is 546 // expected to send. 547 peerCertificate *Certificate 548 // quicTransportParams contains the QUIC transport parameters that are to be 549 // sent by the peer using codepoint 57. 550 quicTransportParams []byte 551 // quicTransportParamsLegacy contains the QUIC transport parameters that are 552 // to be sent by the peer using legacy codepoint 0xffa5. 553 quicTransportParamsLegacy []byte 554 // peerApplicationSettings are the expected application settings for the 555 // connection. If nil, no application settings are expected. 556 peerApplicationSettings []byte 557 // peerApplicationSettingsOld are the expected application settings for 558 // the connection that are to be sent by the peer using old codepoint. 559 // If nil, no application settings are expected. 560 peerApplicationSettingsOld []byte 561 // echAccepted is whether ECH should have been accepted on this connection. 562 echAccepted bool 563} 564 565type testCase struct { 566 testType testType 567 protocol protocol 568 name string 569 config Config 570 shouldFail bool 571 expectedError string 572 // expectedLocalError, if not empty, contains a substring that must be 573 // found in the local error. 574 expectedLocalError string 575 // expectations contains test expectations for the initial 576 // connection. 577 expectations connectionExpectations 578 // resumeExpectations, if non-nil, contains test expectations for the 579 // resumption connection. If nil, |expectations| is used. 580 resumeExpectations *connectionExpectations 581 // messageLen is the length, in bytes, of the test message that will be 582 // sent. 583 messageLen int 584 // messageCount is the number of test messages that will be sent. 585 messageCount int 586 // certFile is the path to the certificate to use for the server. 587 certFile string 588 // keyFile is the path to the private key to use for the server. 589 keyFile string 590 // resumeSession controls whether a second connection should be tested 591 // which attempts to resume the first session. 592 resumeSession bool 593 // resumeRenewedSession controls whether a third connection should be 594 // tested which attempts to resume the second connection's session. 595 resumeRenewedSession bool 596 // expectResumeRejected, if true, specifies that the attempted 597 // resumption must be rejected by the client. This is only valid for a 598 // serverTest. 599 expectResumeRejected bool 600 // resumeConfig, if not nil, points to a Config to be used on 601 // resumption. Unless newSessionsOnResume is set, 602 // SessionTicketKey, ServerSessionCache, and 603 // ClientSessionCache are copied from the initial connection's 604 // config. If nil, the initial connection's config is used. 605 resumeConfig *Config 606 // newSessionsOnResume, if true, will cause resumeConfig to 607 // use a different session resumption context. 608 newSessionsOnResume bool 609 // noSessionCache, if true, will cause the server to run without a 610 // session cache. 611 noSessionCache bool 612 // sendPrefix sends a prefix on the socket before actually performing a 613 // handshake. 614 sendPrefix string 615 // shimWritesFirst controls whether the shim sends an initial "hello" 616 // message before doing a roundtrip with the runner. 617 shimWritesFirst bool 618 // readWithUnfinishedWrite behaves like shimWritesFirst, but the shim 619 // does not complete the write until responding to the first runner 620 // message. 621 readWithUnfinishedWrite bool 622 // shimShutsDown, if true, runs a test where the shim shuts down the 623 // connection immediately after the handshake rather than echoing 624 // messages from the runner. The runner will default to not sending 625 // application data. 626 shimShutsDown bool 627 // renegotiate indicates the number of times the connection should be 628 // renegotiated during the exchange. 629 renegotiate int 630 // sendHalfHelloRequest, if true, causes the server to send half a 631 // HelloRequest when the handshake completes. 632 sendHalfHelloRequest bool 633 // renegotiateCiphers is a list of ciphersuite ids that will be 634 // switched in just before renegotiation. 635 renegotiateCiphers []uint16 636 // replayWrites, if true, configures the underlying transport 637 // to replay every write it makes in DTLS tests. 638 replayWrites bool 639 // damageFirstWrite, if true, configures the underlying transport to 640 // damage the final byte of the first application data write. 641 damageFirstWrite bool 642 // exportKeyingMaterial, if non-zero, configures the test to exchange 643 // keying material and verify they match. 644 exportKeyingMaterial int 645 exportLabel string 646 exportContext string 647 useExportContext bool 648 // flags, if not empty, contains a list of command-line flags that will 649 // be passed to the shim program. 650 flags []string 651 // testTLSUnique, if true, causes the shim to send the tls-unique value 652 // which will be compared against the expected value. 653 testTLSUnique bool 654 // sendEmptyRecords is the number of consecutive empty records to send 655 // before each test message. 656 sendEmptyRecords int 657 // sendWarningAlerts is the number of consecutive warning alerts to send 658 // before each test message. 659 sendWarningAlerts int 660 // sendUserCanceledAlerts is the number of consecutive user_canceled alerts to 661 // send before each test message. 662 sendUserCanceledAlerts int 663 // sendBogusAlertType, if true, causes a bogus alert of invalid type to 664 // be sent before each test message. 665 sendBogusAlertType bool 666 // sendKeyUpdates is the number of consecutive key updates to send 667 // before and after the test message. 668 sendKeyUpdates int 669 // keyUpdateRequest is the KeyUpdateRequest value to send in KeyUpdate messages. 670 keyUpdateRequest byte 671 // expectUnsolicitedKeyUpdate makes the test expect a one or more KeyUpdate 672 // messages while reading data from the shim. Don't use this in combination 673 // with any of the fields that send a KeyUpdate otherwise any received 674 // KeyUpdate might not be as unsolicited as expected. 675 expectUnsolicitedKeyUpdate bool 676 // expectMessageDropped, if true, means the test message is expected to 677 // be dropped by the client rather than echoed back. 678 expectMessageDropped bool 679 // shimPrefix is the prefix that the shim will send to the server. 680 shimPrefix string 681 // resumeShimPrefix is the prefix that the shim will send to the server on a 682 // resumption. 683 resumeShimPrefix string 684 // exportTrafficSecrets, if true, configures the test to export the TLS 1.3 685 // traffic secrets and confirms that they match. 686 exportTrafficSecrets bool 687 // skipTransportParamsConfig, if true, will skip automatic configuration of 688 // sending QUIC transport parameters when protocol == quic. 689 skipTransportParamsConfig bool 690 // skipQUICALPNConfig, if true, will skip automatic configuration of 691 // sending a fake ALPN when protocol == quic. 692 skipQUICALPNConfig bool 693 // earlyData, if true, configures default settings for an early data test. 694 // expectEarlyDataRejected controls whether the test is for early data 695 // accept or reject. In a client test, the shim will be configured to send 696 // an initial write in early data which, on accept, the runner will enforce. 697 // In a server test, the runner will send some default message in early 698 // data, which the shim is expected to echo in half-RTT. 699 earlyData bool 700 // expectEarlyDataRejected, if earlyData is true, is whether early data is 701 // expected to be rejected. In a client test, this controls whether the shim 702 // should retry for early rejection. In a server test, this is whether the 703 // test expects the shim to reject early data. 704 expectEarlyDataRejected bool 705 // skipSplitHandshake, if true, will skip the generation of a split 706 // handshake copy of the test. 707 skipSplitHandshake bool 708 // skipVersionNameCheck, if true, will skip the consistency check between 709 // test name and the versions. 710 skipVersionNameCheck bool 711} 712 713var testCases []testCase 714 715func appendTranscript(path string, data []byte) error { 716 if len(data) == 0 { 717 return nil 718 } 719 720 settings, err := os.ReadFile(path) 721 if err != nil { 722 if !os.IsNotExist(err) { 723 return err 724 } 725 // If the shim aborted before writing a file, use a default 726 // settings block, so the transcript is still somewhat valid. 727 settings = []byte{0, 0} // kDataTag 728 } 729 730 settings = append(settings, data...) 731 return os.WriteFile(path, settings, 0644) 732} 733 734// A timeoutConn implements an idle timeout on each Read and Write operation. 735type timeoutConn struct { 736 net.Conn 737 timeout time.Duration 738} 739 740func (t *timeoutConn) Read(b []byte) (int, error) { 741 if !*useGDB { 742 if err := t.SetReadDeadline(time.Now().Add(t.timeout)); err != nil { 743 return 0, err 744 } 745 } 746 return t.Conn.Read(b) 747} 748 749func (t *timeoutConn) Write(b []byte) (int, error) { 750 if !*useGDB { 751 if err := t.SetWriteDeadline(time.Now().Add(t.timeout)); err != nil { 752 return 0, err 753 } 754 } 755 return t.Conn.Write(b) 756} 757 758func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool, transcripts *[][]byte, num int) error { 759 if !test.noSessionCache { 760 if config.ClientSessionCache == nil { 761 config.ClientSessionCache = NewLRUClientSessionCache(1) 762 } 763 if config.ServerSessionCache == nil { 764 config.ServerSessionCache = NewLRUServerSessionCache(1) 765 } 766 } 767 if test.testType == clientTest { 768 if len(config.Certificates) == 0 { 769 config.Certificates = []Certificate{rsaCertificate} 770 } 771 } else { 772 // Supply a ServerName to ensure a constant session cache key, 773 // rather than falling back to net.Conn.RemoteAddr. 774 if len(config.ServerName) == 0 { 775 config.ServerName = "test" 776 } 777 } 778 if *fuzzer { 779 config.Bugs.NullAllCiphers = true 780 } 781 if *deterministic { 782 config.Time = func() time.Time { return time.Unix(1234, 1234) } 783 } 784 785 if !useDebugger() { 786 conn = &timeoutConn{conn, *idleTimeout} 787 } 788 789 if test.protocol == dtls { 790 config.Bugs.PacketAdaptor = newPacketAdaptor(conn) 791 conn = config.Bugs.PacketAdaptor 792 } 793 794 if *flagDebug || len(*transcriptDir) != 0 { 795 local, peer := "client", "server" 796 if test.testType == clientTest { 797 local, peer = peer, local 798 } 799 connDebug := &recordingConn{ 800 Conn: conn, 801 isDatagram: test.protocol == dtls, 802 local: local, 803 peer: peer, 804 } 805 conn = connDebug 806 if *flagDebug { 807 defer connDebug.WriteTo(os.Stdout) 808 } 809 if len(*transcriptDir) != 0 { 810 defer func() { 811 if num == len(*transcripts) { 812 *transcripts = append(*transcripts, connDebug.Transcript()) 813 } else { 814 panic("transcripts are out of sync") 815 } 816 }() 817 818 // Record ClientHellos for the decode_client_hello_inner fuzzer. 819 var clientHelloCount int 820 config.Bugs.RecordClientHelloInner = func(encodedInner, outer []byte) error { 821 name := fmt.Sprintf("%s-%d-%d", test.name, num, clientHelloCount) 822 clientHelloCount++ 823 dir := filepath.Join(*transcriptDir, "decode_client_hello_inner") 824 if err := os.MkdirAll(dir, 0755); err != nil { 825 return err 826 } 827 bb := cryptobyte.NewBuilder(nil) 828 addUint24LengthPrefixedBytes(bb, encodedInner) 829 bb.AddBytes(outer) 830 return os.WriteFile(filepath.Join(dir, name), bb.BytesOrPanic(), 0644) 831 } 832 } 833 834 if config.Bugs.PacketAdaptor != nil { 835 config.Bugs.PacketAdaptor.debug = connDebug 836 } 837 } 838 if test.protocol == quic { 839 config.Bugs.MockQUICTransport = newMockQUICTransport(conn) 840 // The MockQUICTransport will panic if Read or Write is 841 // called. When a MockQUICTransport is set, separate 842 // methods should be used to actually read and write 843 // records. By setting the conn to it here, it ensures 844 // Read or Write aren't accidentally used instead of the 845 // methods provided by MockQUICTransport. 846 conn = config.Bugs.MockQUICTransport 847 } 848 849 if test.replayWrites { 850 conn = newReplayAdaptor(conn) 851 } 852 853 var connDamage *damageAdaptor 854 if test.damageFirstWrite { 855 connDamage = newDamageAdaptor(conn) 856 conn = connDamage 857 } 858 859 if test.sendPrefix != "" { 860 if _, err := conn.Write([]byte(test.sendPrefix)); err != nil { 861 return err 862 } 863 } 864 865 var tlsConn *Conn 866 if test.testType == clientTest { 867 if test.protocol == dtls { 868 tlsConn = DTLSServer(conn, config) 869 } else { 870 tlsConn = Server(conn, config) 871 } 872 } else { 873 config.InsecureSkipVerify = true 874 if test.protocol == dtls { 875 tlsConn = DTLSClient(conn, config) 876 } else { 877 tlsConn = Client(conn, config) 878 } 879 } 880 defer tlsConn.Close() 881 882 if err := tlsConn.Handshake(); err != nil { 883 return err 884 } 885 886 expectations := &test.expectations 887 if isResume && test.resumeExpectations != nil { 888 expectations = test.resumeExpectations 889 } 890 connState := tlsConn.ConnectionState() 891 if vers := connState.Version; expectations.version != 0 && vers != expectations.version { 892 return fmt.Errorf("got version %x, expected %x", vers, expectations.version) 893 } 894 895 if cipher := connState.CipherSuite; expectations.cipher != 0 && cipher != expectations.cipher { 896 return fmt.Errorf("got cipher %x, expected %x", cipher, expectations.cipher) 897 } 898 if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected { 899 return fmt.Errorf("didResume is %t, but we expected the opposite", didResume) 900 } 901 902 if expectations.channelID { 903 channelID := connState.ChannelID 904 if channelID == nil { 905 return fmt.Errorf("no channel ID negotiated") 906 } 907 if channelID.Curve != channelIDKey.Curve || 908 channelIDKey.X.Cmp(channelIDKey.X) != 0 || 909 channelIDKey.Y.Cmp(channelIDKey.Y) != 0 { 910 return fmt.Errorf("incorrect channel ID") 911 } 912 } else if connState.ChannelID != nil { 913 return fmt.Errorf("channel ID unexpectedly negotiated") 914 } 915 916 if expected := expectations.nextProto; expected != "" { 917 if actual := connState.NegotiatedProtocol; actual != expected { 918 return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected) 919 } 920 } 921 922 if expectations.noNextProto { 923 if actual := connState.NegotiatedProtocol; actual != "" { 924 return fmt.Errorf("got unexpected next proto %s", actual) 925 } 926 } 927 928 if expectations.nextProtoType != 0 { 929 if (expectations.nextProtoType == alpn) != connState.NegotiatedProtocolFromALPN { 930 return fmt.Errorf("next proto type mismatch") 931 } 932 } 933 934 if expectations.peerApplicationSettings != nil { 935 if !connState.HasApplicationSettings { 936 return errors.New("application settings should have been negotiated") 937 } 938 if !bytes.Equal(connState.PeerApplicationSettings, expectations.peerApplicationSettings) { 939 return fmt.Errorf("peer application settings mismatch: got %q, wanted %q", connState.PeerApplicationSettings, expectations.peerApplicationSettings) 940 } 941 } else if connState.HasApplicationSettings { 942 return errors.New("application settings unexpectedly negotiated") 943 } 944 945 if expectations.peerApplicationSettingsOld != nil { 946 if !connState.HasApplicationSettingsOld { 947 return errors.New("old application settings should have been negotiated") 948 } 949 if !bytes.Equal(connState.PeerApplicationSettingsOld, expectations.peerApplicationSettingsOld) { 950 return fmt.Errorf("old peer application settings mismatch: got %q, wanted %q", connState.PeerApplicationSettingsOld, expectations.peerApplicationSettingsOld) 951 } 952 } else if connState.HasApplicationSettingsOld { 953 return errors.New("old application settings unexpectedly negotiated") 954 } 955 956 if p := connState.SRTPProtectionProfile; p != expectations.srtpProtectionProfile { 957 return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, expectations.srtpProtectionProfile) 958 } 959 960 if expectations.ocspResponse != nil && !bytes.Equal(expectations.ocspResponse, connState.OCSPResponse) { 961 return fmt.Errorf("OCSP Response mismatch: got %x, wanted %x", connState.OCSPResponse, expectations.ocspResponse) 962 } 963 964 if expectations.sctList != nil && !bytes.Equal(expectations.sctList, connState.SCTList) { 965 return fmt.Errorf("SCT list mismatch") 966 } 967 968 if expected := expectations.peerSignatureAlgorithm; expected != 0 && expected != connState.PeerSignatureAlgorithm { 969 return fmt.Errorf("expected peer to use signature algorithm %04x, but got %04x", expected, connState.PeerSignatureAlgorithm) 970 } 971 972 if expected := expectations.curveID; expected != 0 && expected != connState.CurveID { 973 return fmt.Errorf("expected peer to use curve %04x, but got %04x", expected, connState.CurveID) 974 } 975 976 if expectations.peerCertificate != nil { 977 if len(connState.PeerCertificates) != len(expectations.peerCertificate.Certificate) { 978 return fmt.Errorf("expected peer to send %d certificates, but got %d", len(connState.PeerCertificates), len(expectations.peerCertificate.Certificate)) 979 } 980 for i, cert := range connState.PeerCertificates { 981 if !bytes.Equal(cert.Raw, expectations.peerCertificate.Certificate[i]) { 982 return fmt.Errorf("peer certificate %d did not match", i+1) 983 } 984 } 985 } 986 987 if len(expectations.quicTransportParams) > 0 { 988 if !bytes.Equal(expectations.quicTransportParams, connState.QUICTransportParams) { 989 return errors.New("Peer did not send expected QUIC transport params") 990 } 991 } 992 993 if len(expectations.quicTransportParamsLegacy) > 0 { 994 if !bytes.Equal(expectations.quicTransportParamsLegacy, connState.QUICTransportParamsLegacy) { 995 return errors.New("Peer did not send expected legacy QUIC transport params") 996 } 997 } 998 999 if expectations.echAccepted { 1000 if !connState.ECHAccepted { 1001 return errors.New("tls: server did not accept ECH") 1002 } 1003 } else { 1004 if connState.ECHAccepted { 1005 return errors.New("tls: server unexpectedly accepted ECH") 1006 } 1007 } 1008 1009 if test.exportKeyingMaterial > 0 { 1010 actual := make([]byte, test.exportKeyingMaterial) 1011 if _, err := io.ReadFull(tlsConn, actual); err != nil { 1012 return err 1013 } 1014 expected, err := tlsConn.ExportKeyingMaterial(test.exportKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext), test.useExportContext) 1015 if err != nil { 1016 return err 1017 } 1018 if !bytes.Equal(actual, expected) { 1019 return fmt.Errorf("keying material mismatch; got %x, wanted %x", actual, expected) 1020 } 1021 } 1022 1023 if test.exportTrafficSecrets { 1024 secretLenBytes := make([]byte, 2) 1025 if _, err := io.ReadFull(tlsConn, secretLenBytes); err != nil { 1026 return err 1027 } 1028 secretLen := binary.LittleEndian.Uint16(secretLenBytes) 1029 1030 theirReadSecret := make([]byte, secretLen) 1031 theirWriteSecret := make([]byte, secretLen) 1032 if _, err := io.ReadFull(tlsConn, theirReadSecret); err != nil { 1033 return err 1034 } 1035 if _, err := io.ReadFull(tlsConn, theirWriteSecret); err != nil { 1036 return err 1037 } 1038 1039 myReadSecret := tlsConn.in.trafficSecret 1040 myWriteSecret := tlsConn.out.trafficSecret 1041 if !bytes.Equal(myWriteSecret, theirReadSecret) { 1042 return fmt.Errorf("read traffic-secret mismatch; got %x, wanted %x", theirReadSecret, myWriteSecret) 1043 } 1044 if !bytes.Equal(myReadSecret, theirWriteSecret) { 1045 return fmt.Errorf("write traffic-secret mismatch; got %x, wanted %x", theirWriteSecret, myReadSecret) 1046 } 1047 } 1048 1049 if test.testTLSUnique { 1050 var peersValue [12]byte 1051 if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil { 1052 return err 1053 } 1054 expected := tlsConn.ConnectionState().TLSUnique 1055 if !bytes.Equal(peersValue[:], expected) { 1056 return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected) 1057 } 1058 } 1059 1060 if test.sendHalfHelloRequest { 1061 tlsConn.SendHalfHelloRequest() 1062 } 1063 1064 shimPrefix := test.shimPrefix 1065 if isResume { 1066 shimPrefix = test.resumeShimPrefix 1067 } 1068 if test.shimWritesFirst || test.readWithUnfinishedWrite { 1069 shimPrefix = shimInitialWrite 1070 } 1071 if test.renegotiate > 0 { 1072 // If readWithUnfinishedWrite is set, the shim prefix will be 1073 // available later. 1074 if shimPrefix != "" && !test.readWithUnfinishedWrite { 1075 var buf = make([]byte, len(shimPrefix)) 1076 _, err := io.ReadFull(tlsConn, buf) 1077 if err != nil { 1078 return err 1079 } 1080 if string(buf) != shimPrefix { 1081 return fmt.Errorf("bad initial message %v vs %v", string(buf), shimPrefix) 1082 } 1083 shimPrefix = "" 1084 } 1085 1086 if test.renegotiateCiphers != nil { 1087 config.CipherSuites = test.renegotiateCiphers 1088 } 1089 for i := 0; i < test.renegotiate; i++ { 1090 if err := tlsConn.Renegotiate(); err != nil { 1091 return err 1092 } 1093 } 1094 } else if test.renegotiateCiphers != nil { 1095 panic("renegotiateCiphers without renegotiate") 1096 } 1097 1098 if test.damageFirstWrite { 1099 connDamage.setDamage(true) 1100 tlsConn.Write([]byte("DAMAGED WRITE")) 1101 connDamage.setDamage(false) 1102 } 1103 1104 messageLen := test.messageLen 1105 if messageLen < 0 { 1106 if test.protocol == dtls { 1107 return fmt.Errorf("messageLen < 0 not supported for DTLS tests") 1108 } 1109 // Read until EOF. 1110 _, err := io.Copy(io.Discard, tlsConn) 1111 return err 1112 } 1113 if messageLen == 0 { 1114 messageLen = 32 1115 } 1116 1117 messageCount := test.messageCount 1118 // shimShutsDown sets the default message count to zero. 1119 if messageCount == 0 && !test.shimShutsDown { 1120 messageCount = 1 1121 } 1122 1123 for j := 0; j < messageCount; j++ { 1124 for i := 0; i < test.sendKeyUpdates; i++ { 1125 tlsConn.SendKeyUpdate(test.keyUpdateRequest) 1126 } 1127 1128 for i := 0; i < test.sendEmptyRecords; i++ { 1129 tlsConn.Write(nil) 1130 } 1131 1132 for i := 0; i < test.sendWarningAlerts; i++ { 1133 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage) 1134 } 1135 1136 for i := 0; i < test.sendUserCanceledAlerts; i++ { 1137 tlsConn.SendAlert(alertLevelWarning, alertUserCanceled) 1138 } 1139 1140 if test.sendBogusAlertType { 1141 tlsConn.SendAlert(0x42, alertUnexpectedMessage) 1142 } 1143 1144 testMessage := make([]byte, messageLen) 1145 for i := range testMessage { 1146 testMessage[i] = 0x42 ^ byte(j) 1147 } 1148 tlsConn.Write(testMessage) 1149 1150 // Consume the shim prefix if needed. 1151 if shimPrefix != "" { 1152 var buf = make([]byte, len(shimPrefix)) 1153 _, err := io.ReadFull(tlsConn, buf) 1154 if err != nil { 1155 return err 1156 } 1157 if string(buf) != shimPrefix { 1158 return fmt.Errorf("bad initial message %v vs %v", string(buf), shimPrefix) 1159 } 1160 shimPrefix = "" 1161 } 1162 1163 if test.shimShutsDown || test.expectMessageDropped { 1164 // The shim will not respond. 1165 continue 1166 } 1167 1168 // Process the KeyUpdate ACK. However many KeyUpdates the runner 1169 // sends, the shim should respond only once. 1170 if test.sendKeyUpdates > 0 && test.keyUpdateRequest == keyUpdateRequested { 1171 if err := tlsConn.ReadKeyUpdateACK(); err != nil { 1172 return err 1173 } 1174 } 1175 1176 buf := make([]byte, len(testMessage)) 1177 if test.protocol == dtls { 1178 bufTmp := make([]byte, len(buf)+1) 1179 n, err := tlsConn.Read(bufTmp) 1180 if err != nil { 1181 return err 1182 } 1183 if config.Bugs.SplitAndPackAppData { 1184 m, err := tlsConn.Read(bufTmp[n:]) 1185 if err != nil { 1186 return err 1187 } 1188 n += m 1189 } 1190 if n != len(buf) { 1191 return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf)) 1192 } 1193 copy(buf, bufTmp) 1194 } else { 1195 _, err := io.ReadFull(tlsConn, buf) 1196 if err != nil { 1197 return err 1198 } 1199 } 1200 1201 for i, v := range buf { 1202 if v != testMessage[i]^0xff { 1203 return fmt.Errorf("bad reply contents at byte %d; got %q and wanted %q", i, buf, testMessage) 1204 } 1205 } 1206 1207 if seen := tlsConn.keyUpdateSeen; seen != test.expectUnsolicitedKeyUpdate { 1208 return fmt.Errorf("keyUpdateSeen (%t) != expectUnsolicitedKeyUpdate", seen) 1209 } 1210 } 1211 1212 return nil 1213} 1214 1215const xtermSize = "140x50" 1216 1217func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd { 1218 valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full", "--quiet"} 1219 if dbAttach { 1220 valgrindArgs = append(valgrindArgs, "--db-attach=yes", "--db-command=xterm -geometry "+xtermSize+" -e gdb -nw %f %p") 1221 } 1222 valgrindArgs = append(valgrindArgs, path) 1223 valgrindArgs = append(valgrindArgs, args...) 1224 1225 return exec.Command("valgrind", valgrindArgs...) 1226} 1227 1228func gdbOf(path string, args ...string) *exec.Cmd { 1229 xtermArgs := []string{"-geometry", xtermSize, "-e", "gdb", "--args"} 1230 xtermArgs = append(xtermArgs, path) 1231 xtermArgs = append(xtermArgs, args...) 1232 1233 return exec.Command("xterm", xtermArgs...) 1234} 1235 1236func lldbOf(path string, args ...string) *exec.Cmd { 1237 xtermArgs := []string{"-geometry", xtermSize, "-e", "lldb", "--"} 1238 xtermArgs = append(xtermArgs, path) 1239 xtermArgs = append(xtermArgs, args...) 1240 1241 return exec.Command("xterm", xtermArgs...) 1242} 1243 1244func rrOf(path string, args ...string) *exec.Cmd { 1245 rrArgs := []string{"record", path} 1246 rrArgs = append(rrArgs, args...) 1247 return exec.Command("rr", rrArgs...) 1248} 1249 1250func removeFirstLineIfSuffix(s, suffix string) string { 1251 idx := strings.IndexByte(s, '\n') 1252 if idx < 0 { 1253 return s 1254 } 1255 if strings.HasSuffix(s[:idx], suffix) { 1256 return s[idx+1:] 1257 } 1258 return s 1259} 1260 1261var ( 1262 errMoreMallocs = errors.New("child process did not exhaust all allocation calls") 1263 errUnimplemented = errors.New("child process does not implement needed flags") 1264) 1265 1266type shimProcess struct { 1267 cmd *exec.Cmd 1268 // done is closed when the process has exited. At that point, childErr may be 1269 // read for the result. 1270 done chan struct{} 1271 childErr error 1272 listener *shimListener 1273 stdout, stderr bytes.Buffer 1274} 1275 1276// newShimProcess starts a new shim with the specified executable, flags, and 1277// environment. It internally creates a TCP listener and adds the the -port 1278// flag. 1279func newShimProcess(dispatcher *shimDispatcher, shimPath string, flags []string, env []string) (*shimProcess, error) { 1280 listener, err := dispatcher.NewShim() 1281 if err != nil { 1282 return nil, err 1283 } 1284 1285 shim := &shimProcess{listener: listener} 1286 cmdFlags := []string{ 1287 "-port", strconv.Itoa(listener.Port()), 1288 "-shim-id", strconv.FormatUint(listener.ShimID(), 10), 1289 } 1290 if listener.IsIPv6() { 1291 cmdFlags = append(cmdFlags, "-ipv6") 1292 } 1293 cmdFlags = append(cmdFlags, flags...) 1294 1295 if *useValgrind { 1296 shim.cmd = valgrindOf(false, shimPath, cmdFlags...) 1297 } else if *useGDB { 1298 shim.cmd = gdbOf(shimPath, cmdFlags...) 1299 } else if *useLLDB { 1300 shim.cmd = lldbOf(shimPath, cmdFlags...) 1301 } else if *useRR { 1302 shim.cmd = rrOf(shimPath, cmdFlags...) 1303 } else { 1304 shim.cmd = exec.Command(shimPath, cmdFlags...) 1305 } 1306 shim.cmd.Stdin = os.Stdin 1307 shim.cmd.Stdout = &shim.stdout 1308 shim.cmd.Stderr = &shim.stderr 1309 shim.cmd.Env = env 1310 1311 if err := shim.cmd.Start(); err != nil { 1312 shim.listener.Close() 1313 return nil, err 1314 } 1315 1316 shim.done = make(chan struct{}) 1317 go func() { 1318 shim.childErr = shim.cmd.Wait() 1319 shim.listener.Close() 1320 close(shim.done) 1321 }() 1322 return shim, nil 1323} 1324 1325// accept returns a new TCP connection with the shim process, or returns an 1326// error on timeout or shim exit. 1327func (s *shimProcess) accept() (net.Conn, error) { 1328 var deadline time.Time 1329 if !useDebugger() { 1330 deadline = time.Now().Add(*idleTimeout) 1331 } 1332 return s.listener.Accept(deadline) 1333} 1334 1335// wait finishes the test and waits for the shim process to exit. 1336func (s *shimProcess) wait() error { 1337 // Close the listener now. This is to avoid hangs if the shim tries to open 1338 // more connections than expected. 1339 s.listener.Close() 1340 1341 if !useDebugger() { 1342 waitTimeout := time.AfterFunc(*idleTimeout, func() { 1343 s.cmd.Process.Kill() 1344 }) 1345 defer waitTimeout.Stop() 1346 } 1347 1348 <-s.done 1349 return s.childErr 1350} 1351 1352// close releases resources associated with the shimProcess. This is safe to 1353// call before or after |wait|. 1354func (s *shimProcess) close() { 1355 s.listener.Close() 1356 s.cmd.Process.Kill() 1357} 1358 1359func doExchanges(test *testCase, shim *shimProcess, resumeCount int, transcripts *[][]byte) error { 1360 config := test.config 1361 if *deterministic { 1362 config.Rand = &deterministicRand{} 1363 } 1364 1365 conn, err := shim.accept() 1366 if err != nil { 1367 return err 1368 } 1369 err = doExchange(test, &config, conn, false /* not a resumption */, transcripts, 0) 1370 conn.Close() 1371 if err != nil { 1372 return err 1373 } 1374 1375 nextTicketKey := config.SessionTicketKey 1376 for i := 0; i < resumeCount; i++ { 1377 var resumeConfig Config 1378 if test.resumeConfig != nil { 1379 resumeConfig = *test.resumeConfig 1380 resumeConfig.Rand = config.Rand 1381 } else { 1382 resumeConfig = config 1383 } 1384 1385 if test.newSessionsOnResume { 1386 resumeConfig.ClientSessionCache = nil 1387 resumeConfig.ServerSessionCache = nil 1388 if _, err := resumeConfig.rand().Read(resumeConfig.SessionTicketKey[:]); err != nil { 1389 return err 1390 } 1391 } else { 1392 resumeConfig.ClientSessionCache = config.ClientSessionCache 1393 resumeConfig.ServerSessionCache = config.ServerSessionCache 1394 // Rotate the ticket keys between each connection, with each connection 1395 // encrypting with next connection's keys. This ensures that we test 1396 // the renewed sessions. 1397 resumeConfig.SessionTicketKey = nextTicketKey 1398 if _, err := resumeConfig.rand().Read(nextTicketKey[:]); err != nil { 1399 return err 1400 } 1401 resumeConfig.Bugs.EncryptSessionTicketKey = &nextTicketKey 1402 } 1403 1404 var connResume net.Conn 1405 connResume, err = shim.accept() 1406 if err != nil { 1407 return err 1408 } 1409 err = doExchange(test, &resumeConfig, connResume, true /* resumption */, transcripts, i+1) 1410 connResume.Close() 1411 if err != nil { 1412 return err 1413 } 1414 } 1415 1416 return nil 1417} 1418 1419func translateExpectedError(errorStr string) string { 1420 if translated, ok := shimConfig.ErrorMap[errorStr]; ok { 1421 return translated 1422 } 1423 1424 if *looseErrors { 1425 return "" 1426 } 1427 1428 return errorStr 1429} 1430 1431// shimInitialWrite is the data we expect from the shim when the 1432// -shim-writes-first flag is used. 1433const shimInitialWrite = "hello" 1434 1435func runTest(dispatcher *shimDispatcher, statusChan chan statusMsg, test *testCase, shimPath string, mallocNumToFail int64) error { 1436 // Help debugging panics on the Go side. 1437 defer func() { 1438 if r := recover(); r != nil { 1439 fmt.Fprintf(os.Stderr, "Test '%s' panicked.\n", test.name) 1440 panic(r) 1441 } 1442 }() 1443 1444 var flags []string 1445 if len(*shimExtraFlags) > 0 { 1446 flags = strings.Split(*shimExtraFlags, ";") 1447 } 1448 if test.testType == serverTest { 1449 flags = append(flags, "-server") 1450 1451 flags = append(flags, "-key-file") 1452 if test.keyFile == "" { 1453 flags = append(flags, path.Join(*resourceDir, rsaKeyFile)) 1454 } else { 1455 flags = append(flags, path.Join(*resourceDir, test.keyFile)) 1456 } 1457 1458 flags = append(flags, "-cert-file") 1459 if test.certFile == "" { 1460 flags = append(flags, path.Join(*resourceDir, rsaCertificateFile)) 1461 } else { 1462 flags = append(flags, path.Join(*resourceDir, test.certFile)) 1463 } 1464 } 1465 1466 if test.protocol == dtls { 1467 flags = append(flags, "-dtls") 1468 } else if test.protocol == quic { 1469 flags = append(flags, "-quic") 1470 if !test.skipTransportParamsConfig { 1471 test.config.QUICTransportParams = []byte{1, 2} 1472 test.config.QUICTransportParamsUseLegacyCodepoint = QUICUseCodepointStandard 1473 if test.resumeConfig != nil { 1474 test.resumeConfig.QUICTransportParams = []byte{1, 2} 1475 test.resumeConfig.QUICTransportParamsUseLegacyCodepoint = QUICUseCodepointStandard 1476 } 1477 test.expectations.quicTransportParams = []byte{3, 4} 1478 if test.resumeExpectations != nil { 1479 test.resumeExpectations.quicTransportParams = []byte{3, 4} 1480 } 1481 useCodepointFlag := "0" 1482 if test.config.QUICTransportParamsUseLegacyCodepoint == QUICUseCodepointLegacy { 1483 useCodepointFlag = "1" 1484 } 1485 flags = append(flags, 1486 "-quic-transport-params", 1487 base64FlagValue([]byte{3, 4}), 1488 "-expect-quic-transport-params", 1489 base64FlagValue([]byte{1, 2}), 1490 "-quic-use-legacy-codepoint", useCodepointFlag) 1491 } 1492 if !test.skipQUICALPNConfig { 1493 flags = append(flags, 1494 []string{ 1495 "-advertise-alpn", "\x03foo", 1496 "-select-alpn", "foo", 1497 "-expect-alpn", "foo", 1498 }...) 1499 test.config.NextProtos = []string{"foo"} 1500 if test.resumeConfig != nil { 1501 test.resumeConfig.NextProtos = []string{"foo"} 1502 } 1503 test.expectations.nextProto = "foo" 1504 test.expectations.nextProtoType = alpn 1505 if test.resumeExpectations != nil { 1506 test.resumeExpectations.nextProto = "foo" 1507 test.resumeExpectations.nextProtoType = alpn 1508 } 1509 } 1510 } 1511 1512 if test.earlyData { 1513 if !test.resumeSession { 1514 panic("earlyData set without resumeSession in " + test.name) 1515 } 1516 1517 resumeConfig := test.resumeConfig 1518 if resumeConfig == nil { 1519 resumeConfig = &test.config 1520 } 1521 if test.expectEarlyDataRejected { 1522 flags = append(flags, "-on-resume-expect-reject-early-data") 1523 } else { 1524 flags = append(flags, "-on-resume-expect-accept-early-data") 1525 } 1526 1527 if test.protocol == quic { 1528 // QUIC requires an early data context string. 1529 flags = append(flags, "-quic-early-data-context", "context") 1530 } 1531 1532 flags = append(flags, "-enable-early-data") 1533 if test.testType == clientTest { 1534 // Configure the runner with default maximum early data. 1535 flags = append(flags, "-expect-ticket-supports-early-data") 1536 if test.config.MaxEarlyDataSize == 0 { 1537 test.config.MaxEarlyDataSize = 16384 1538 } 1539 if resumeConfig.MaxEarlyDataSize == 0 { 1540 resumeConfig.MaxEarlyDataSize = 16384 1541 } 1542 1543 // Configure the shim to send some data in early data. 1544 flags = append(flags, "-on-resume-shim-writes-first") 1545 if resumeConfig.Bugs.ExpectEarlyData == nil { 1546 resumeConfig.Bugs.ExpectEarlyData = [][]byte{[]byte(shimInitialWrite)} 1547 } 1548 } else { 1549 // By default, send some early data and expect half-RTT data response. 1550 if resumeConfig.Bugs.SendEarlyData == nil { 1551 resumeConfig.Bugs.SendEarlyData = [][]byte{{1, 2, 3, 4}} 1552 } 1553 if resumeConfig.Bugs.ExpectHalfRTTData == nil { 1554 resumeConfig.Bugs.ExpectHalfRTTData = [][]byte{{254, 253, 252, 251}} 1555 } 1556 resumeConfig.Bugs.ExpectEarlyDataAccepted = !test.expectEarlyDataRejected 1557 } 1558 } 1559 1560 var resumeCount int 1561 if test.resumeSession { 1562 resumeCount++ 1563 if test.resumeRenewedSession { 1564 resumeCount++ 1565 } 1566 } 1567 1568 if resumeCount > 0 { 1569 flags = append(flags, "-resume-count", strconv.Itoa(resumeCount)) 1570 } 1571 1572 if test.shimWritesFirst { 1573 flags = append(flags, "-shim-writes-first") 1574 } 1575 1576 if test.readWithUnfinishedWrite { 1577 flags = append(flags, "-read-with-unfinished-write") 1578 } 1579 1580 if test.shimShutsDown { 1581 flags = append(flags, "-shim-shuts-down") 1582 } 1583 1584 if test.exportKeyingMaterial > 0 { 1585 flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial)) 1586 if test.useExportContext { 1587 flags = append(flags, "-use-export-context") 1588 } 1589 } 1590 if test.exportKeyingMaterial > 0 { 1591 flags = append(flags, "-export-label", test.exportLabel) 1592 flags = append(flags, "-export-context", test.exportContext) 1593 } 1594 1595 if test.exportTrafficSecrets { 1596 flags = append(flags, "-export-traffic-secrets") 1597 } 1598 1599 if test.expectResumeRejected { 1600 flags = append(flags, "-expect-session-miss") 1601 } 1602 1603 if test.testTLSUnique { 1604 flags = append(flags, "-tls-unique") 1605 } 1606 1607 if *waitForDebugger { 1608 flags = append(flags, "-wait-for-debugger") 1609 } 1610 1611 var transcriptPrefix string 1612 var transcripts [][]byte 1613 if len(*transcriptDir) != 0 { 1614 protocol := "tls" 1615 if test.protocol == dtls { 1616 protocol = "dtls" 1617 } else if test.protocol == quic { 1618 protocol = "quic" 1619 } 1620 1621 side := "client" 1622 if test.testType == serverTest { 1623 side = "server" 1624 } 1625 1626 dir := filepath.Join(*transcriptDir, protocol, side) 1627 if err := os.MkdirAll(dir, 0755); err != nil { 1628 return err 1629 } 1630 transcriptPrefix = filepath.Join(dir, test.name+"-") 1631 flags = append(flags, "-write-settings", transcriptPrefix) 1632 } 1633 1634 flags = append(flags, test.flags...) 1635 1636 var env []string 1637 if mallocNumToFail >= 0 { 1638 env = os.Environ() 1639 env = append(env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10)) 1640 if *mallocTestDebug { 1641 env = append(env, "MALLOC_BREAK_ON_FAIL=1") 1642 } 1643 env = append(env, "_MALLOC_CHECK=1") 1644 } 1645 1646 shim, err := newShimProcess(dispatcher, shimPath, flags, env) 1647 if err != nil { 1648 return err 1649 } 1650 statusChan <- statusMsg{test: test, statusType: statusShimStarted, pid: shim.cmd.Process.Pid} 1651 defer shim.close() 1652 1653 localErr := doExchanges(test, shim, resumeCount, &transcripts) 1654 childErr := shim.wait() 1655 1656 // Now that the shim has exited, all the settings files have been 1657 // written. Append the saved transcripts. 1658 for i, transcript := range transcripts { 1659 if err := appendTranscript(transcriptPrefix+strconv.Itoa(i), transcript); err != nil { 1660 return err 1661 } 1662 } 1663 1664 var isValgrindError, mustFail bool 1665 if exitError, ok := childErr.(*exec.ExitError); ok { 1666 switch exitError.Sys().(syscall.WaitStatus).ExitStatus() { 1667 case 88: 1668 return errMoreMallocs 1669 case 89: 1670 return errUnimplemented 1671 case 90: 1672 mustFail = true 1673 case 99: 1674 isValgrindError = true 1675 } 1676 } 1677 1678 // Account for Windows line endings. 1679 stdout := strings.Replace(shim.stdout.String(), "\r\n", "\n", -1) 1680 stderr := strings.Replace(shim.stderr.String(), "\r\n", "\n", -1) 1681 1682 // Work around an NDK / Android bug. The NDK r16 sometimes generates 1683 // binaries with the DF_1_PIE, which the runtime linker on Android N 1684 // complains about. The next NDK revision should work around this but, 1685 // in the meantime, strip its error out. 1686 // 1687 // https://github.com/android-ndk/ndk/issues/602 1688 // https://android-review.googlesource.com/c/platform/bionic/+/259790 1689 // https://android-review.googlesource.com/c/toolchain/binutils/+/571550 1690 // 1691 // Remove this after switching to the r17 NDK. 1692 stderr = removeFirstLineIfSuffix(stderr, ": unsupported flags DT_FLAGS_1=0x8000001") 1693 1694 // Separate the errors from the shim and those from tools like 1695 // AddressSanitizer. 1696 var extraStderr string 1697 if stderrParts := strings.SplitN(stderr, "--- DONE ---\n", 2); len(stderrParts) == 2 { 1698 stderr = stderrParts[0] 1699 extraStderr = stderrParts[1] 1700 } 1701 1702 failed := localErr != nil || childErr != nil 1703 expectedError := translateExpectedError(test.expectedError) 1704 correctFailure := len(expectedError) == 0 || strings.Contains(stderr, expectedError) 1705 1706 localErrString := "none" 1707 if localErr != nil { 1708 localErrString = localErr.Error() 1709 } 1710 if len(test.expectedLocalError) != 0 { 1711 correctFailure = correctFailure && strings.Contains(localErrString, test.expectedLocalError) 1712 } 1713 1714 if failed != test.shouldFail || failed && !correctFailure || mustFail { 1715 childErrString := "none" 1716 if childErr != nil { 1717 childErrString = childErr.Error() 1718 } 1719 1720 var msg string 1721 switch { 1722 case failed && !test.shouldFail: 1723 msg = "unexpected failure" 1724 case !failed && test.shouldFail: 1725 msg = "unexpected success" 1726 case failed && !correctFailure: 1727 msg = "bad error (wanted '" + expectedError + "' / '" + test.expectedLocalError + "')" 1728 case mustFail: 1729 msg = "test failure" 1730 default: 1731 panic("internal error") 1732 } 1733 1734 return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s\n%s", msg, localErrString, childErrString, stdout, stderr, extraStderr) 1735 } 1736 1737 if len(extraStderr) > 0 || (!failed && len(stderr) > 0) { 1738 return fmt.Errorf("unexpected error output:\n%s\n%s", stderr, extraStderr) 1739 } 1740 1741 if *useValgrind && isValgrindError { 1742 return fmt.Errorf("valgrind error:\n%s\n%s", stderr, extraStderr) 1743 } 1744 1745 return nil 1746} 1747 1748type tlsVersion struct { 1749 name string 1750 // version is the protocol version. 1751 version uint16 1752 // excludeFlag is the legacy shim flag to disable the version. 1753 excludeFlag string 1754 hasDTLS bool 1755 hasQUIC bool 1756 // versionDTLS, if non-zero, is the DTLS-specific representation of the version. 1757 versionDTLS uint16 1758 // versionWire, if non-zero, is the wire representation of the 1759 // version. Otherwise the wire version is the protocol version or 1760 // versionDTLS. 1761 versionWire uint16 1762} 1763 1764func (vers tlsVersion) shimFlag(protocol protocol) string { 1765 // The shim uses the protocol version in its public API, but uses the 1766 // DTLS-specific version if it exists. 1767 if protocol == dtls && vers.versionDTLS != 0 { 1768 return strconv.Itoa(int(vers.versionDTLS)) 1769 } 1770 return strconv.Itoa(int(vers.version)) 1771} 1772 1773func (vers tlsVersion) wire(protocol protocol) uint16 { 1774 if protocol == dtls && vers.versionDTLS != 0 { 1775 return vers.versionDTLS 1776 } 1777 if vers.versionWire != 0 { 1778 return vers.versionWire 1779 } 1780 return vers.version 1781} 1782 1783func (vers tlsVersion) supportsProtocol(protocol protocol) bool { 1784 if protocol == dtls { 1785 return vers.hasDTLS 1786 } 1787 if protocol == quic { 1788 return vers.hasQUIC 1789 } 1790 return true 1791} 1792 1793var tlsVersions = []tlsVersion{ 1794 { 1795 name: "TLS1", 1796 version: VersionTLS10, 1797 excludeFlag: "-no-tls1", 1798 hasDTLS: true, 1799 versionDTLS: VersionDTLS10, 1800 }, 1801 { 1802 name: "TLS11", 1803 version: VersionTLS11, 1804 excludeFlag: "-no-tls11", 1805 }, 1806 { 1807 name: "TLS12", 1808 version: VersionTLS12, 1809 excludeFlag: "-no-tls12", 1810 hasDTLS: true, 1811 versionDTLS: VersionDTLS12, 1812 }, 1813 { 1814 name: "TLS13", 1815 version: VersionTLS13, 1816 excludeFlag: "-no-tls13", 1817 hasQUIC: true, 1818 versionWire: VersionTLS13, 1819 }, 1820} 1821 1822func allVersions(protocol protocol) []tlsVersion { 1823 if protocol == tls { 1824 return tlsVersions 1825 } 1826 1827 var ret []tlsVersion 1828 for _, vers := range tlsVersions { 1829 if vers.supportsProtocol(protocol) { 1830 ret = append(ret, vers) 1831 } 1832 } 1833 return ret 1834} 1835 1836type testCipherSuite struct { 1837 name string 1838 id uint16 1839} 1840 1841var testCipherSuites = []testCipherSuite{ 1842 {"RSA_WITH_3DES_EDE_CBC_SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 1843 {"RSA_WITH_AES_128_GCM_SHA256", TLS_RSA_WITH_AES_128_GCM_SHA256}, 1844 {"RSA_WITH_AES_128_CBC_SHA", TLS_RSA_WITH_AES_128_CBC_SHA}, 1845 {"RSA_WITH_AES_256_GCM_SHA384", TLS_RSA_WITH_AES_256_GCM_SHA384}, 1846 {"RSA_WITH_AES_256_CBC_SHA", TLS_RSA_WITH_AES_256_CBC_SHA}, 1847 {"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 1848 {"ECDHE_ECDSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA}, 1849 {"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}, 1850 {"ECDHE_ECDSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}, 1851 {"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, 1852 {"ECDHE_RSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1853 {"ECDHE_RSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 1854 {"ECDHE_RSA_WITH_AES_128_CBC_SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256}, 1855 {"ECDHE_RSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, 1856 {"ECDHE_RSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, 1857 {"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 1858 {"PSK_WITH_AES_128_CBC_SHA", TLS_PSK_WITH_AES_128_CBC_SHA}, 1859 {"PSK_WITH_AES_256_CBC_SHA", TLS_PSK_WITH_AES_256_CBC_SHA}, 1860 {"ECDHE_PSK_WITH_AES_128_CBC_SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 1861 {"ECDHE_PSK_WITH_AES_256_CBC_SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA}, 1862 {"ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256}, 1863 {"CHACHA20_POLY1305_SHA256", TLS_CHACHA20_POLY1305_SHA256}, 1864 {"AES_128_GCM_SHA256", TLS_AES_128_GCM_SHA256}, 1865 {"AES_256_GCM_SHA384", TLS_AES_256_GCM_SHA384}, 1866} 1867 1868func hasComponent(suiteName, component string) bool { 1869 return strings.Contains("_"+suiteName+"_", "_"+component+"_") 1870} 1871 1872func isTLS12Only(suiteName string) bool { 1873 return hasComponent(suiteName, "GCM") || 1874 hasComponent(suiteName, "SHA256") || 1875 hasComponent(suiteName, "SHA384") || 1876 hasComponent(suiteName, "POLY1305") 1877} 1878 1879func isTLS13Suite(suiteName string) bool { 1880 return !hasComponent(suiteName, "WITH") 1881} 1882 1883func bigFromHex(hex string) *big.Int { 1884 ret, ok := new(big.Int).SetString(hex, 16) 1885 if !ok { 1886 panic("failed to parse hex number 0x" + hex) 1887 } 1888 return ret 1889} 1890 1891func convertToSplitHandshakeTests(tests []testCase) (splitHandshakeTests []testCase, err error) { 1892 var stdout bytes.Buffer 1893 var flags []string 1894 if len(*shimExtraFlags) > 0 { 1895 flags = strings.Split(*shimExtraFlags, ";") 1896 } 1897 flags = append(flags, "-is-handshaker-supported") 1898 shim := exec.Command(*shimPath, flags...) 1899 shim.Stdout = &stdout 1900 if err := shim.Run(); err != nil { 1901 return nil, err 1902 } 1903 1904 switch strings.TrimSpace(string(stdout.Bytes())) { 1905 case "No": 1906 return 1907 case "Yes": 1908 break 1909 default: 1910 return nil, fmt.Errorf("unknown output from shim: %q", stdout.Bytes()) 1911 } 1912 1913 var allowHintMismatchPattern []string 1914 if len(*allowHintMismatch) > 0 { 1915 allowHintMismatchPattern = strings.Split(*allowHintMismatch, ";") 1916 } 1917 1918NextTest: 1919 for _, test := range tests { 1920 if test.protocol != tls || 1921 test.testType != serverTest || 1922 strings.Contains(test.name, "DelegatedCredentials") || 1923 strings.Contains(test.name, "ECH-Server") || 1924 test.skipSplitHandshake { 1925 continue 1926 } 1927 1928 for _, flag := range test.flags { 1929 if flag == "-implicit-handshake" { 1930 continue NextTest 1931 } 1932 } 1933 1934 shTest := test 1935 shTest.name += "-Split" 1936 shTest.flags = make([]string, len(test.flags), len(test.flags)+3) 1937 copy(shTest.flags, test.flags) 1938 shTest.flags = append(shTest.flags, "-handoff", "-handshaker-path", *handshakerPath) 1939 1940 splitHandshakeTests = append(splitHandshakeTests, shTest) 1941 } 1942 1943 for _, test := range tests { 1944 if test.protocol == dtls || 1945 test.testType != serverTest { 1946 continue 1947 } 1948 1949 var matched bool 1950 if len(allowHintMismatchPattern) > 0 { 1951 matched, err = match(allowHintMismatchPattern, nil, test.name) 1952 if err != nil { 1953 return nil, fmt.Errorf("error matching pattern: %s", err) 1954 } 1955 } 1956 1957 shTest := test 1958 shTest.name += "-Hints" 1959 shTest.flags = make([]string, len(test.flags), len(test.flags)+3) 1960 copy(shTest.flags, test.flags) 1961 shTest.flags = append(shTest.flags, "-handshake-hints", "-handshaker-path", *handshakerPath) 1962 if matched { 1963 shTest.flags = append(shTest.flags, "-allow-hint-mismatch") 1964 } 1965 1966 splitHandshakeTests = append(splitHandshakeTests, shTest) 1967 } 1968 1969 return splitHandshakeTests, nil 1970} 1971 1972func addBasicTests() { 1973 basicTests := []testCase{ 1974 { 1975 name: "NoFallbackSCSV", 1976 config: Config{ 1977 Bugs: ProtocolBugs{ 1978 FailIfNotFallbackSCSV: true, 1979 }, 1980 }, 1981 shouldFail: true, 1982 expectedLocalError: "no fallback SCSV found", 1983 }, 1984 { 1985 name: "SendFallbackSCSV", 1986 config: Config{ 1987 Bugs: ProtocolBugs{ 1988 FailIfNotFallbackSCSV: true, 1989 }, 1990 }, 1991 flags: []string{"-fallback-scsv"}, 1992 }, 1993 { 1994 name: "ClientCertificateTypes", 1995 config: Config{ 1996 MaxVersion: VersionTLS12, 1997 ClientAuth: RequestClientCert, 1998 ClientCertificateTypes: []byte{ 1999 CertTypeDSSSign, 2000 CertTypeRSASign, 2001 CertTypeECDSASign, 2002 }, 2003 }, 2004 flags: []string{ 2005 "-expect-certificate-types", 2006 base64FlagValue([]byte{ 2007 CertTypeDSSSign, 2008 CertTypeRSASign, 2009 CertTypeECDSASign, 2010 }), 2011 }, 2012 }, 2013 { 2014 name: "UnauthenticatedECDH", 2015 config: Config{ 2016 MaxVersion: VersionTLS12, 2017 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2018 Bugs: ProtocolBugs{ 2019 UnauthenticatedECDH: true, 2020 }, 2021 }, 2022 shouldFail: true, 2023 expectedError: ":UNEXPECTED_MESSAGE:", 2024 }, 2025 { 2026 name: "SkipCertificateStatus", 2027 config: Config{ 2028 MaxVersion: VersionTLS12, 2029 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2030 Bugs: ProtocolBugs{ 2031 SkipCertificateStatus: true, 2032 }, 2033 }, 2034 flags: []string{ 2035 "-enable-ocsp-stapling", 2036 // This test involves an optional message. Test the message callback 2037 // trace to ensure we do not miss or double-report any. 2038 "-expect-msg-callback", 2039 `write hs 1 2040read hs 2 2041read hs 11 2042read hs 12 2043read hs 14 2044write hs 16 2045write ccs 2046write hs 20 2047read hs 4 2048read ccs 2049read hs 20 2050read alert 1 0 2051`, 2052 }, 2053 }, 2054 { 2055 protocol: dtls, 2056 name: "SkipCertificateStatus-DTLS", 2057 config: Config{ 2058 MaxVersion: VersionTLS12, 2059 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2060 Bugs: ProtocolBugs{ 2061 SkipCertificateStatus: true, 2062 }, 2063 }, 2064 flags: []string{ 2065 "-enable-ocsp-stapling", 2066 // This test involves an optional message. Test the message callback 2067 // trace to ensure we do not miss or double-report any. 2068 "-expect-msg-callback", 2069 `write hs 1 2070read hs 3 2071write hs 1 2072read hs 2 2073read hs 11 2074read hs 12 2075read hs 14 2076write hs 16 2077write ccs 2078write hs 20 2079read hs 4 2080read ccs 2081read hs 20 2082read alert 1 0 2083`, 2084 }, 2085 }, 2086 { 2087 name: "SkipServerKeyExchange", 2088 config: Config{ 2089 MaxVersion: VersionTLS12, 2090 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2091 Bugs: ProtocolBugs{ 2092 SkipServerKeyExchange: true, 2093 }, 2094 }, 2095 shouldFail: true, 2096 expectedError: ":UNEXPECTED_MESSAGE:", 2097 }, 2098 { 2099 testType: serverTest, 2100 name: "ServerSkipCertificateVerify", 2101 config: Config{ 2102 MaxVersion: VersionTLS12, 2103 Certificates: []Certificate{rsaChainCertificate}, 2104 Bugs: ProtocolBugs{ 2105 SkipCertificateVerify: true, 2106 }, 2107 }, 2108 expectations: connectionExpectations{ 2109 peerCertificate: &rsaChainCertificate, 2110 }, 2111 flags: []string{ 2112 "-require-any-client-certificate", 2113 }, 2114 shouldFail: true, 2115 expectedError: ":UNEXPECTED_RECORD:", 2116 expectedLocalError: "remote error: unexpected message", 2117 }, 2118 { 2119 testType: serverTest, 2120 name: "Alert", 2121 config: Config{ 2122 Bugs: ProtocolBugs{ 2123 SendSpuriousAlert: alertRecordOverflow, 2124 }, 2125 }, 2126 shouldFail: true, 2127 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2128 }, 2129 { 2130 protocol: dtls, 2131 testType: serverTest, 2132 name: "Alert-DTLS", 2133 config: Config{ 2134 Bugs: ProtocolBugs{ 2135 SendSpuriousAlert: alertRecordOverflow, 2136 }, 2137 }, 2138 shouldFail: true, 2139 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2140 }, 2141 { 2142 testType: serverTest, 2143 name: "FragmentAlert", 2144 config: Config{ 2145 Bugs: ProtocolBugs{ 2146 FragmentAlert: true, 2147 SendSpuriousAlert: alertRecordOverflow, 2148 }, 2149 }, 2150 shouldFail: true, 2151 expectedError: ":BAD_ALERT:", 2152 }, 2153 { 2154 protocol: dtls, 2155 testType: serverTest, 2156 name: "FragmentAlert-DTLS", 2157 config: Config{ 2158 Bugs: ProtocolBugs{ 2159 FragmentAlert: true, 2160 SendSpuriousAlert: alertRecordOverflow, 2161 }, 2162 }, 2163 shouldFail: true, 2164 expectedError: ":BAD_ALERT:", 2165 }, 2166 { 2167 testType: serverTest, 2168 name: "DoubleAlert", 2169 config: Config{ 2170 Bugs: ProtocolBugs{ 2171 DoubleAlert: true, 2172 SendSpuriousAlert: alertRecordOverflow, 2173 }, 2174 }, 2175 shouldFail: true, 2176 expectedError: ":BAD_ALERT:", 2177 }, 2178 { 2179 protocol: dtls, 2180 testType: serverTest, 2181 name: "DoubleAlert-DTLS", 2182 config: Config{ 2183 Bugs: ProtocolBugs{ 2184 DoubleAlert: true, 2185 SendSpuriousAlert: alertRecordOverflow, 2186 }, 2187 }, 2188 shouldFail: true, 2189 expectedError: ":BAD_ALERT:", 2190 }, 2191 { 2192 name: "SkipNewSessionTicket", 2193 config: Config{ 2194 MaxVersion: VersionTLS12, 2195 Bugs: ProtocolBugs{ 2196 SkipNewSessionTicket: true, 2197 }, 2198 }, 2199 shouldFail: true, 2200 expectedError: ":UNEXPECTED_RECORD:", 2201 }, 2202 { 2203 testType: serverTest, 2204 name: "FallbackSCSV", 2205 config: Config{ 2206 MaxVersion: VersionTLS11, 2207 Bugs: ProtocolBugs{ 2208 SendFallbackSCSV: true, 2209 }, 2210 }, 2211 shouldFail: true, 2212 expectedError: ":INAPPROPRIATE_FALLBACK:", 2213 expectedLocalError: "remote error: inappropriate fallback", 2214 }, 2215 { 2216 testType: serverTest, 2217 name: "FallbackSCSV-VersionMatch-TLS13", 2218 config: Config{ 2219 MaxVersion: VersionTLS13, 2220 Bugs: ProtocolBugs{ 2221 SendFallbackSCSV: true, 2222 }, 2223 }, 2224 }, 2225 { 2226 testType: serverTest, 2227 name: "FallbackSCSV-VersionMatch-TLS12", 2228 config: Config{ 2229 MaxVersion: VersionTLS12, 2230 Bugs: ProtocolBugs{ 2231 SendFallbackSCSV: true, 2232 }, 2233 }, 2234 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 2235 }, 2236 { 2237 testType: serverTest, 2238 name: "FragmentedClientVersion", 2239 config: Config{ 2240 Bugs: ProtocolBugs{ 2241 MaxHandshakeRecordLength: 1, 2242 FragmentClientVersion: true, 2243 }, 2244 }, 2245 expectations: connectionExpectations{ 2246 version: VersionTLS13, 2247 }, 2248 }, 2249 { 2250 testType: serverTest, 2251 name: "HttpGET", 2252 sendPrefix: "GET / HTTP/1.0\n", 2253 shouldFail: true, 2254 expectedError: ":HTTP_REQUEST:", 2255 }, 2256 { 2257 testType: serverTest, 2258 name: "HttpPOST", 2259 sendPrefix: "POST / HTTP/1.0\n", 2260 shouldFail: true, 2261 expectedError: ":HTTP_REQUEST:", 2262 }, 2263 { 2264 testType: serverTest, 2265 name: "HttpHEAD", 2266 sendPrefix: "HEAD / HTTP/1.0\n", 2267 shouldFail: true, 2268 expectedError: ":HTTP_REQUEST:", 2269 }, 2270 { 2271 testType: serverTest, 2272 name: "HttpPUT", 2273 sendPrefix: "PUT / HTTP/1.0\n", 2274 shouldFail: true, 2275 expectedError: ":HTTP_REQUEST:", 2276 }, 2277 { 2278 testType: serverTest, 2279 name: "HttpCONNECT", 2280 sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n", 2281 shouldFail: true, 2282 expectedError: ":HTTPS_PROXY_REQUEST:", 2283 }, 2284 { 2285 testType: serverTest, 2286 name: "Garbage", 2287 sendPrefix: "blah", 2288 shouldFail: true, 2289 expectedError: ":WRONG_VERSION_NUMBER:", 2290 }, 2291 { 2292 name: "RSAEphemeralKey", 2293 config: Config{ 2294 MaxVersion: VersionTLS12, 2295 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 2296 Bugs: ProtocolBugs{ 2297 RSAEphemeralKey: true, 2298 }, 2299 }, 2300 shouldFail: true, 2301 expectedError: ":UNEXPECTED_MESSAGE:", 2302 }, 2303 { 2304 name: "DisableEverything", 2305 flags: []string{"-no-tls13", "-no-tls12", "-no-tls11", "-no-tls1"}, 2306 shouldFail: true, 2307 expectedError: ":NO_SUPPORTED_VERSIONS_ENABLED:", 2308 }, 2309 { 2310 protocol: dtls, 2311 name: "DisableEverything-DTLS", 2312 flags: []string{"-no-tls12", "-no-tls1"}, 2313 shouldFail: true, 2314 expectedError: ":NO_SUPPORTED_VERSIONS_ENABLED:", 2315 }, 2316 { 2317 protocol: dtls, 2318 testType: serverTest, 2319 name: "MTU", 2320 config: Config{ 2321 Bugs: ProtocolBugs{ 2322 MaxPacketLength: 256, 2323 }, 2324 }, 2325 flags: []string{"-mtu", "256"}, 2326 }, 2327 { 2328 protocol: dtls, 2329 testType: serverTest, 2330 name: "MTUExceeded", 2331 config: Config{ 2332 Bugs: ProtocolBugs{ 2333 MaxPacketLength: 255, 2334 }, 2335 }, 2336 flags: []string{"-mtu", "256"}, 2337 shouldFail: true, 2338 expectedLocalError: "dtls: exceeded maximum packet length", 2339 }, 2340 { 2341 name: "EmptyCertificateList", 2342 config: Config{ 2343 MaxVersion: VersionTLS12, 2344 Bugs: ProtocolBugs{ 2345 EmptyCertificateList: true, 2346 }, 2347 }, 2348 shouldFail: true, 2349 expectedError: ":DECODE_ERROR:", 2350 }, 2351 { 2352 name: "EmptyCertificateList-TLS13", 2353 config: Config{ 2354 MaxVersion: VersionTLS13, 2355 Bugs: ProtocolBugs{ 2356 EmptyCertificateList: true, 2357 }, 2358 }, 2359 shouldFail: true, 2360 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 2361 }, 2362 { 2363 name: "TLSFatalBadPackets", 2364 damageFirstWrite: true, 2365 shouldFail: true, 2366 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 2367 }, 2368 { 2369 protocol: dtls, 2370 name: "DTLSIgnoreBadPackets", 2371 damageFirstWrite: true, 2372 }, 2373 { 2374 protocol: dtls, 2375 name: "DTLSIgnoreBadPackets-Async", 2376 damageFirstWrite: true, 2377 flags: []string{"-async"}, 2378 }, 2379 { 2380 name: "AppDataBeforeHandshake", 2381 config: Config{ 2382 Bugs: ProtocolBugs{ 2383 AppDataBeforeHandshake: []byte("TEST MESSAGE"), 2384 }, 2385 }, 2386 shouldFail: true, 2387 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2388 }, 2389 { 2390 name: "AppDataBeforeHandshake-Empty", 2391 config: Config{ 2392 Bugs: ProtocolBugs{ 2393 AppDataBeforeHandshake: []byte{}, 2394 }, 2395 }, 2396 shouldFail: true, 2397 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2398 }, 2399 { 2400 protocol: dtls, 2401 name: "AppDataBeforeHandshake-DTLS", 2402 config: Config{ 2403 Bugs: ProtocolBugs{ 2404 AppDataBeforeHandshake: []byte("TEST MESSAGE"), 2405 }, 2406 }, 2407 shouldFail: true, 2408 expectedError: ":UNEXPECTED_RECORD:", 2409 }, 2410 { 2411 protocol: dtls, 2412 name: "AppDataBeforeHandshake-DTLS-Empty", 2413 config: Config{ 2414 Bugs: ProtocolBugs{ 2415 AppDataBeforeHandshake: []byte{}, 2416 }, 2417 }, 2418 shouldFail: true, 2419 expectedError: ":UNEXPECTED_RECORD:", 2420 }, 2421 { 2422 name: "AppDataAfterChangeCipherSpec", 2423 config: Config{ 2424 MaxVersion: VersionTLS12, 2425 Bugs: ProtocolBugs{ 2426 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"), 2427 }, 2428 }, 2429 shouldFail: true, 2430 expectedError: ":UNEXPECTED_RECORD:", 2431 }, 2432 { 2433 name: "AppDataAfterChangeCipherSpec-Empty", 2434 config: Config{ 2435 MaxVersion: VersionTLS12, 2436 Bugs: ProtocolBugs{ 2437 AppDataAfterChangeCipherSpec: []byte{}, 2438 }, 2439 }, 2440 shouldFail: true, 2441 expectedError: ":UNEXPECTED_RECORD:", 2442 }, 2443 { 2444 protocol: dtls, 2445 name: "AppDataAfterChangeCipherSpec-DTLS", 2446 config: Config{ 2447 MaxVersion: VersionTLS12, 2448 Bugs: ProtocolBugs{ 2449 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"), 2450 }, 2451 }, 2452 // BoringSSL's DTLS implementation will drop the out-of-order 2453 // application data. 2454 }, 2455 { 2456 protocol: dtls, 2457 name: "AppDataAfterChangeCipherSpec-DTLS-Empty", 2458 config: Config{ 2459 MaxVersion: VersionTLS12, 2460 Bugs: ProtocolBugs{ 2461 AppDataAfterChangeCipherSpec: []byte{}, 2462 }, 2463 }, 2464 // BoringSSL's DTLS implementation will drop the out-of-order 2465 // application data. 2466 }, 2467 { 2468 name: "AlertAfterChangeCipherSpec", 2469 config: Config{ 2470 MaxVersion: VersionTLS12, 2471 Bugs: ProtocolBugs{ 2472 AlertAfterChangeCipherSpec: alertRecordOverflow, 2473 }, 2474 }, 2475 shouldFail: true, 2476 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2477 }, 2478 { 2479 protocol: dtls, 2480 name: "AlertAfterChangeCipherSpec-DTLS", 2481 config: Config{ 2482 MaxVersion: VersionTLS12, 2483 Bugs: ProtocolBugs{ 2484 AlertAfterChangeCipherSpec: alertRecordOverflow, 2485 }, 2486 }, 2487 shouldFail: true, 2488 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2489 }, 2490 { 2491 protocol: dtls, 2492 name: "ReorderHandshakeFragments-Small-DTLS", 2493 config: Config{ 2494 Bugs: ProtocolBugs{ 2495 ReorderHandshakeFragments: true, 2496 // Small enough that every handshake message is 2497 // fragmented. 2498 MaxHandshakeRecordLength: 2, 2499 }, 2500 }, 2501 }, 2502 { 2503 protocol: dtls, 2504 name: "ReorderHandshakeFragments-Large-DTLS", 2505 config: Config{ 2506 Bugs: ProtocolBugs{ 2507 ReorderHandshakeFragments: true, 2508 // Large enough that no handshake message is 2509 // fragmented. 2510 MaxHandshakeRecordLength: 2048, 2511 }, 2512 }, 2513 }, 2514 { 2515 protocol: dtls, 2516 name: "MixCompleteMessageWithFragments-DTLS", 2517 config: Config{ 2518 Bugs: ProtocolBugs{ 2519 ReorderHandshakeFragments: true, 2520 MixCompleteMessageWithFragments: true, 2521 MaxHandshakeRecordLength: 2, 2522 }, 2523 }, 2524 }, 2525 { 2526 name: "SendInvalidRecordType", 2527 config: Config{ 2528 Bugs: ProtocolBugs{ 2529 SendInvalidRecordType: true, 2530 }, 2531 }, 2532 shouldFail: true, 2533 expectedError: ":UNEXPECTED_RECORD:", 2534 }, 2535 { 2536 protocol: dtls, 2537 name: "SendInvalidRecordType-DTLS", 2538 config: Config{ 2539 Bugs: ProtocolBugs{ 2540 SendInvalidRecordType: true, 2541 }, 2542 }, 2543 shouldFail: true, 2544 expectedError: ":UNEXPECTED_RECORD:", 2545 }, 2546 { 2547 name: "FalseStart-SkipServerSecondLeg", 2548 config: Config{ 2549 MaxVersion: VersionTLS12, 2550 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2551 NextProtos: []string{"foo"}, 2552 Bugs: ProtocolBugs{ 2553 SkipNewSessionTicket: true, 2554 SkipChangeCipherSpec: true, 2555 SkipFinished: true, 2556 ExpectFalseStart: true, 2557 }, 2558 }, 2559 flags: []string{ 2560 "-false-start", 2561 "-handshake-never-done", 2562 "-advertise-alpn", "\x03foo", 2563 "-expect-alpn", "foo", 2564 }, 2565 shimWritesFirst: true, 2566 shouldFail: true, 2567 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2568 }, 2569 { 2570 name: "FalseStart-SkipServerSecondLeg-Implicit", 2571 config: Config{ 2572 MaxVersion: VersionTLS12, 2573 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2574 NextProtos: []string{"foo"}, 2575 Bugs: ProtocolBugs{ 2576 SkipNewSessionTicket: true, 2577 SkipChangeCipherSpec: true, 2578 SkipFinished: true, 2579 }, 2580 }, 2581 flags: []string{ 2582 "-implicit-handshake", 2583 "-false-start", 2584 "-handshake-never-done", 2585 "-advertise-alpn", "\x03foo", 2586 }, 2587 shouldFail: true, 2588 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2589 }, 2590 { 2591 testType: serverTest, 2592 name: "FailEarlyCallback", 2593 flags: []string{"-fail-early-callback"}, 2594 shouldFail: true, 2595 expectedError: ":CONNECTION_REJECTED:", 2596 expectedLocalError: "remote error: handshake failure", 2597 }, 2598 { 2599 name: "FailCertCallback-Client-TLS12", 2600 config: Config{ 2601 MaxVersion: VersionTLS12, 2602 ClientAuth: RequestClientCert, 2603 }, 2604 flags: []string{"-fail-cert-callback"}, 2605 shouldFail: true, 2606 expectedError: ":CERT_CB_ERROR:", 2607 expectedLocalError: "remote error: internal error", 2608 }, 2609 { 2610 testType: serverTest, 2611 name: "FailCertCallback-Server-TLS12", 2612 config: Config{ 2613 MaxVersion: VersionTLS12, 2614 }, 2615 flags: []string{"-fail-cert-callback"}, 2616 shouldFail: true, 2617 expectedError: ":CERT_CB_ERROR:", 2618 expectedLocalError: "remote error: internal error", 2619 }, 2620 { 2621 name: "FailCertCallback-Client-TLS13", 2622 config: Config{ 2623 MaxVersion: VersionTLS13, 2624 ClientAuth: RequestClientCert, 2625 }, 2626 flags: []string{"-fail-cert-callback"}, 2627 shouldFail: true, 2628 expectedError: ":CERT_CB_ERROR:", 2629 expectedLocalError: "remote error: internal error", 2630 }, 2631 { 2632 testType: serverTest, 2633 name: "FailCertCallback-Server-TLS13", 2634 config: Config{ 2635 MaxVersion: VersionTLS13, 2636 }, 2637 flags: []string{"-fail-cert-callback"}, 2638 shouldFail: true, 2639 expectedError: ":CERT_CB_ERROR:", 2640 expectedLocalError: "remote error: internal error", 2641 }, 2642 { 2643 protocol: dtls, 2644 name: "FragmentMessageTypeMismatch-DTLS", 2645 config: Config{ 2646 Bugs: ProtocolBugs{ 2647 MaxHandshakeRecordLength: 2, 2648 FragmentMessageTypeMismatch: true, 2649 }, 2650 }, 2651 shouldFail: true, 2652 expectedError: ":FRAGMENT_MISMATCH:", 2653 }, 2654 { 2655 protocol: dtls, 2656 name: "FragmentMessageLengthMismatch-DTLS", 2657 config: Config{ 2658 Bugs: ProtocolBugs{ 2659 MaxHandshakeRecordLength: 2, 2660 FragmentMessageLengthMismatch: true, 2661 }, 2662 }, 2663 shouldFail: true, 2664 expectedError: ":FRAGMENT_MISMATCH:", 2665 }, 2666 { 2667 protocol: dtls, 2668 name: "SplitFragments-Header-DTLS", 2669 config: Config{ 2670 Bugs: ProtocolBugs{ 2671 SplitFragments: 2, 2672 }, 2673 }, 2674 shouldFail: true, 2675 expectedError: ":BAD_HANDSHAKE_RECORD:", 2676 }, 2677 { 2678 protocol: dtls, 2679 name: "SplitFragments-Boundary-DTLS", 2680 config: Config{ 2681 Bugs: ProtocolBugs{ 2682 SplitFragments: dtlsRecordHeaderLen, 2683 }, 2684 }, 2685 shouldFail: true, 2686 expectedError: ":BAD_HANDSHAKE_RECORD:", 2687 }, 2688 { 2689 protocol: dtls, 2690 name: "SplitFragments-Body-DTLS", 2691 config: Config{ 2692 Bugs: ProtocolBugs{ 2693 SplitFragments: dtlsRecordHeaderLen + 1, 2694 }, 2695 }, 2696 shouldFail: true, 2697 expectedError: ":BAD_HANDSHAKE_RECORD:", 2698 }, 2699 { 2700 protocol: dtls, 2701 name: "SendEmptyFragments-DTLS", 2702 config: Config{ 2703 Bugs: ProtocolBugs{ 2704 SendEmptyFragments: true, 2705 }, 2706 }, 2707 }, 2708 { 2709 testType: serverTest, 2710 protocol: dtls, 2711 name: "SendEmptyFragments-Padded-DTLS", 2712 config: Config{ 2713 Bugs: ProtocolBugs{ 2714 // Test empty fragments for a message with a 2715 // nice power-of-two length. 2716 PadClientHello: 64, 2717 SendEmptyFragments: true, 2718 }, 2719 }, 2720 }, 2721 { 2722 name: "BadFinished-Client", 2723 config: Config{ 2724 MaxVersion: VersionTLS12, 2725 Bugs: ProtocolBugs{ 2726 BadFinished: true, 2727 }, 2728 }, 2729 shouldFail: true, 2730 expectedError: ":DIGEST_CHECK_FAILED:", 2731 }, 2732 { 2733 name: "BadFinished-Client-TLS13", 2734 config: Config{ 2735 MaxVersion: VersionTLS13, 2736 Bugs: ProtocolBugs{ 2737 BadFinished: true, 2738 }, 2739 }, 2740 shouldFail: true, 2741 expectedError: ":DIGEST_CHECK_FAILED:", 2742 }, 2743 { 2744 testType: serverTest, 2745 name: "BadFinished-Server", 2746 config: Config{ 2747 MaxVersion: VersionTLS12, 2748 Bugs: ProtocolBugs{ 2749 BadFinished: true, 2750 }, 2751 }, 2752 shouldFail: true, 2753 expectedError: ":DIGEST_CHECK_FAILED:", 2754 }, 2755 { 2756 testType: serverTest, 2757 name: "BadFinished-Server-TLS13", 2758 config: Config{ 2759 MaxVersion: VersionTLS13, 2760 Bugs: ProtocolBugs{ 2761 BadFinished: true, 2762 }, 2763 }, 2764 shouldFail: true, 2765 expectedError: ":DIGEST_CHECK_FAILED:", 2766 }, 2767 { 2768 name: "FalseStart-BadFinished", 2769 config: Config{ 2770 MaxVersion: VersionTLS12, 2771 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2772 NextProtos: []string{"foo"}, 2773 Bugs: ProtocolBugs{ 2774 BadFinished: true, 2775 ExpectFalseStart: true, 2776 }, 2777 }, 2778 flags: []string{ 2779 "-false-start", 2780 "-handshake-never-done", 2781 "-advertise-alpn", "\x03foo", 2782 "-expect-alpn", "foo", 2783 }, 2784 shimWritesFirst: true, 2785 shouldFail: true, 2786 expectedError: ":DIGEST_CHECK_FAILED:", 2787 }, 2788 { 2789 name: "NoFalseStart-NoALPN", 2790 config: Config{ 2791 MaxVersion: VersionTLS12, 2792 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2793 Bugs: ProtocolBugs{ 2794 ExpectFalseStart: true, 2795 AlertBeforeFalseStartTest: alertAccessDenied, 2796 }, 2797 }, 2798 flags: []string{ 2799 "-false-start", 2800 }, 2801 shimWritesFirst: true, 2802 shouldFail: true, 2803 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 2804 expectedLocalError: "tls: peer did not false start: EOF", 2805 }, 2806 { 2807 name: "FalseStart-NoALPNAllowed", 2808 config: Config{ 2809 MaxVersion: VersionTLS12, 2810 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2811 Bugs: ProtocolBugs{ 2812 ExpectFalseStart: true, 2813 }, 2814 }, 2815 flags: []string{ 2816 "-false-start", 2817 "-allow-false-start-without-alpn", 2818 }, 2819 shimWritesFirst: true, 2820 }, 2821 { 2822 name: "NoFalseStart-NoAEAD", 2823 config: Config{ 2824 MaxVersion: VersionTLS12, 2825 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 2826 NextProtos: []string{"foo"}, 2827 Bugs: ProtocolBugs{ 2828 ExpectFalseStart: true, 2829 AlertBeforeFalseStartTest: alertAccessDenied, 2830 }, 2831 }, 2832 flags: []string{ 2833 "-false-start", 2834 "-advertise-alpn", "\x03foo", 2835 }, 2836 shimWritesFirst: true, 2837 shouldFail: true, 2838 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 2839 expectedLocalError: "tls: peer did not false start: EOF", 2840 }, 2841 { 2842 name: "NoFalseStart-RSA", 2843 config: Config{ 2844 MaxVersion: VersionTLS12, 2845 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 2846 NextProtos: []string{"foo"}, 2847 Bugs: ProtocolBugs{ 2848 ExpectFalseStart: true, 2849 AlertBeforeFalseStartTest: alertAccessDenied, 2850 }, 2851 }, 2852 flags: []string{ 2853 "-false-start", 2854 "-advertise-alpn", "\x03foo", 2855 }, 2856 shimWritesFirst: true, 2857 shouldFail: true, 2858 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 2859 expectedLocalError: "tls: peer did not false start: EOF", 2860 }, 2861 { 2862 protocol: dtls, 2863 name: "SendSplitAlert-Sync", 2864 config: Config{ 2865 Bugs: ProtocolBugs{ 2866 SendSplitAlert: true, 2867 }, 2868 }, 2869 }, 2870 { 2871 protocol: dtls, 2872 name: "SendSplitAlert-Async", 2873 config: Config{ 2874 Bugs: ProtocolBugs{ 2875 SendSplitAlert: true, 2876 }, 2877 }, 2878 flags: []string{"-async"}, 2879 }, 2880 { 2881 name: "SendEmptyRecords-Pass", 2882 sendEmptyRecords: 32, 2883 }, 2884 { 2885 name: "SendEmptyRecords", 2886 sendEmptyRecords: 33, 2887 shouldFail: true, 2888 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 2889 }, 2890 { 2891 name: "SendEmptyRecords-Async", 2892 sendEmptyRecords: 33, 2893 flags: []string{"-async"}, 2894 shouldFail: true, 2895 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 2896 }, 2897 { 2898 name: "SendWarningAlerts-Pass", 2899 config: Config{ 2900 MaxVersion: VersionTLS12, 2901 }, 2902 sendWarningAlerts: 4, 2903 }, 2904 { 2905 protocol: dtls, 2906 name: "SendWarningAlerts-DTLS-Pass", 2907 config: Config{ 2908 MaxVersion: VersionTLS12, 2909 }, 2910 sendWarningAlerts: 4, 2911 }, 2912 { 2913 name: "SendWarningAlerts-TLS13", 2914 config: Config{ 2915 MaxVersion: VersionTLS13, 2916 }, 2917 sendWarningAlerts: 4, 2918 shouldFail: true, 2919 expectedError: ":BAD_ALERT:", 2920 expectedLocalError: "remote error: error decoding message", 2921 }, 2922 // Although TLS 1.3 intended to remove warning alerts, it left in 2923 // user_canceled. JDK11 misuses this alert as a post-handshake 2924 // full-duplex signal. As a workaround, skip user_canceled as in 2925 // TLS 1.2, which is consistent with NSS and OpenSSL. 2926 { 2927 name: "SendUserCanceledAlerts-TLS13", 2928 config: Config{ 2929 MaxVersion: VersionTLS13, 2930 }, 2931 sendUserCanceledAlerts: 4, 2932 }, 2933 { 2934 name: "SendUserCanceledAlerts-TooMany-TLS13", 2935 config: Config{ 2936 MaxVersion: VersionTLS13, 2937 }, 2938 sendUserCanceledAlerts: 5, 2939 shouldFail: true, 2940 expectedError: ":TOO_MANY_WARNING_ALERTS:", 2941 }, 2942 { 2943 name: "SendWarningAlerts-TooMany", 2944 config: Config{ 2945 MaxVersion: VersionTLS12, 2946 }, 2947 sendWarningAlerts: 5, 2948 shouldFail: true, 2949 expectedError: ":TOO_MANY_WARNING_ALERTS:", 2950 }, 2951 { 2952 name: "SendWarningAlerts-TooMany-Async", 2953 config: Config{ 2954 MaxVersion: VersionTLS12, 2955 }, 2956 sendWarningAlerts: 5, 2957 flags: []string{"-async"}, 2958 shouldFail: true, 2959 expectedError: ":TOO_MANY_WARNING_ALERTS:", 2960 }, 2961 { 2962 name: "SendBogusAlertType", 2963 sendBogusAlertType: true, 2964 shouldFail: true, 2965 expectedError: ":UNKNOWN_ALERT_TYPE:", 2966 expectedLocalError: "remote error: illegal parameter", 2967 }, 2968 { 2969 protocol: dtls, 2970 name: "SendBogusAlertType-DTLS", 2971 sendBogusAlertType: true, 2972 shouldFail: true, 2973 expectedError: ":UNKNOWN_ALERT_TYPE:", 2974 expectedLocalError: "remote error: illegal parameter", 2975 }, 2976 { 2977 name: "TooManyKeyUpdates", 2978 config: Config{ 2979 MaxVersion: VersionTLS13, 2980 }, 2981 sendKeyUpdates: 33, 2982 keyUpdateRequest: keyUpdateNotRequested, 2983 shouldFail: true, 2984 expectedError: ":TOO_MANY_KEY_UPDATES:", 2985 }, 2986 { 2987 name: "EmptySessionID", 2988 config: Config{ 2989 MaxVersion: VersionTLS12, 2990 SessionTicketsDisabled: true, 2991 }, 2992 noSessionCache: true, 2993 flags: []string{"-expect-no-session"}, 2994 }, 2995 { 2996 name: "Unclean-Shutdown", 2997 config: Config{ 2998 Bugs: ProtocolBugs{ 2999 NoCloseNotify: true, 3000 ExpectCloseNotify: true, 3001 }, 3002 }, 3003 shimShutsDown: true, 3004 flags: []string{"-check-close-notify"}, 3005 shouldFail: true, 3006 expectedError: "Unexpected SSL_shutdown result: -1 != 1", 3007 }, 3008 { 3009 name: "Unclean-Shutdown-Ignored", 3010 config: Config{ 3011 Bugs: ProtocolBugs{ 3012 NoCloseNotify: true, 3013 }, 3014 }, 3015 shimShutsDown: true, 3016 }, 3017 { 3018 name: "Unclean-Shutdown-Alert", 3019 config: Config{ 3020 Bugs: ProtocolBugs{ 3021 SendAlertOnShutdown: alertDecompressionFailure, 3022 ExpectCloseNotify: true, 3023 }, 3024 }, 3025 shimShutsDown: true, 3026 flags: []string{"-check-close-notify"}, 3027 shouldFail: true, 3028 expectedError: ":SSLV3_ALERT_DECOMPRESSION_FAILURE:", 3029 }, 3030 { 3031 name: "LargePlaintext", 3032 config: Config{ 3033 Bugs: ProtocolBugs{ 3034 SendLargeRecords: true, 3035 }, 3036 }, 3037 messageLen: maxPlaintext + 1, 3038 shouldFail: true, 3039 expectedError: ":DATA_LENGTH_TOO_LONG:", 3040 expectedLocalError: "remote error: record overflow", 3041 }, 3042 { 3043 protocol: dtls, 3044 name: "LargePlaintext-DTLS", 3045 config: Config{ 3046 Bugs: ProtocolBugs{ 3047 SendLargeRecords: true, 3048 }, 3049 }, 3050 messageLen: maxPlaintext + 1, 3051 shouldFail: true, 3052 expectedError: ":DATA_LENGTH_TOO_LONG:", 3053 expectedLocalError: "remote error: record overflow", 3054 }, 3055 { 3056 name: "LargePlaintext-TLS13-Padded-8192-8192", 3057 config: Config{ 3058 MinVersion: VersionTLS13, 3059 MaxVersion: VersionTLS13, 3060 Bugs: ProtocolBugs{ 3061 RecordPadding: 8192, 3062 SendLargeRecords: true, 3063 }, 3064 }, 3065 messageLen: 8192, 3066 }, 3067 { 3068 name: "LargePlaintext-TLS13-Padded-8193-8192", 3069 config: Config{ 3070 MinVersion: VersionTLS13, 3071 MaxVersion: VersionTLS13, 3072 Bugs: ProtocolBugs{ 3073 RecordPadding: 8193, 3074 SendLargeRecords: true, 3075 }, 3076 }, 3077 messageLen: 8192, 3078 shouldFail: true, 3079 expectedError: ":DATA_LENGTH_TOO_LONG:", 3080 expectedLocalError: "remote error: record overflow", 3081 }, 3082 { 3083 name: "LargePlaintext-TLS13-Padded-16383-1", 3084 config: Config{ 3085 MinVersion: VersionTLS13, 3086 MaxVersion: VersionTLS13, 3087 Bugs: ProtocolBugs{ 3088 RecordPadding: 1, 3089 SendLargeRecords: true, 3090 }, 3091 }, 3092 messageLen: 16383, 3093 }, 3094 { 3095 name: "LargePlaintext-TLS13-Padded-16384-1", 3096 config: Config{ 3097 MinVersion: VersionTLS13, 3098 MaxVersion: VersionTLS13, 3099 Bugs: ProtocolBugs{ 3100 RecordPadding: 1, 3101 SendLargeRecords: true, 3102 }, 3103 }, 3104 messageLen: 16384, 3105 shouldFail: true, 3106 expectedError: ":DATA_LENGTH_TOO_LONG:", 3107 expectedLocalError: "remote error: record overflow", 3108 }, 3109 { 3110 name: "LargeCiphertext", 3111 config: Config{ 3112 Bugs: ProtocolBugs{ 3113 SendLargeRecords: true, 3114 }, 3115 }, 3116 messageLen: maxPlaintext * 2, 3117 shouldFail: true, 3118 expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:", 3119 }, 3120 { 3121 protocol: dtls, 3122 name: "LargeCiphertext-DTLS", 3123 config: Config{ 3124 Bugs: ProtocolBugs{ 3125 SendLargeRecords: true, 3126 }, 3127 }, 3128 messageLen: maxPlaintext * 2, 3129 // Unlike the other four cases, DTLS drops records which 3130 // are invalid before authentication, so the connection 3131 // does not fail. 3132 expectMessageDropped: true, 3133 }, 3134 { 3135 name: "BadHelloRequest-1", 3136 renegotiate: 1, 3137 config: Config{ 3138 MaxVersion: VersionTLS12, 3139 Bugs: ProtocolBugs{ 3140 BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1}, 3141 }, 3142 }, 3143 flags: []string{ 3144 "-renegotiate-freely", 3145 "-expect-total-renegotiations", "1", 3146 }, 3147 shouldFail: true, 3148 expectedError: ":BAD_HELLO_REQUEST:", 3149 }, 3150 { 3151 name: "BadHelloRequest-2", 3152 renegotiate: 1, 3153 config: Config{ 3154 MaxVersion: VersionTLS12, 3155 Bugs: ProtocolBugs{ 3156 BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0}, 3157 }, 3158 }, 3159 flags: []string{ 3160 "-renegotiate-freely", 3161 "-expect-total-renegotiations", "1", 3162 }, 3163 shouldFail: true, 3164 expectedError: ":BAD_HELLO_REQUEST:", 3165 }, 3166 { 3167 testType: serverTest, 3168 name: "SupportTicketsWithSessionID", 3169 config: Config{ 3170 MaxVersion: VersionTLS12, 3171 SessionTicketsDisabled: true, 3172 }, 3173 resumeConfig: &Config{ 3174 MaxVersion: VersionTLS12, 3175 }, 3176 resumeSession: true, 3177 }, 3178 { 3179 protocol: dtls, 3180 name: "DTLS-SendExtraFinished", 3181 config: Config{ 3182 Bugs: ProtocolBugs{ 3183 SendExtraFinished: true, 3184 }, 3185 }, 3186 shouldFail: true, 3187 expectedError: ":UNEXPECTED_RECORD:", 3188 }, 3189 { 3190 protocol: dtls, 3191 name: "DTLS-SendExtraFinished-Reordered", 3192 config: Config{ 3193 Bugs: ProtocolBugs{ 3194 MaxHandshakeRecordLength: 2, 3195 ReorderHandshakeFragments: true, 3196 SendExtraFinished: true, 3197 }, 3198 }, 3199 shouldFail: true, 3200 expectedError: ":UNEXPECTED_RECORD:", 3201 }, 3202 { 3203 testType: serverTest, 3204 name: "V2ClientHello-EmptyRecordPrefix", 3205 config: Config{ 3206 // Choose a cipher suite that does not involve 3207 // elliptic curves, so no extensions are 3208 // involved. 3209 MaxVersion: VersionTLS12, 3210 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 3211 Bugs: ProtocolBugs{ 3212 SendV2ClientHello: true, 3213 }, 3214 }, 3215 sendPrefix: string([]byte{ 3216 byte(recordTypeHandshake), 3217 3, 1, // version 3218 0, 0, // length 3219 }), 3220 // A no-op empty record may not be sent before V2ClientHello. 3221 shouldFail: true, 3222 expectedError: ":WRONG_VERSION_NUMBER:", 3223 }, 3224 { 3225 testType: serverTest, 3226 name: "V2ClientHello-WarningAlertPrefix", 3227 config: Config{ 3228 // Choose a cipher suite that does not involve 3229 // elliptic curves, so no extensions are 3230 // involved. 3231 MaxVersion: VersionTLS12, 3232 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 3233 Bugs: ProtocolBugs{ 3234 SendV2ClientHello: true, 3235 }, 3236 }, 3237 sendPrefix: string([]byte{ 3238 byte(recordTypeAlert), 3239 3, 1, // version 3240 0, 2, // length 3241 alertLevelWarning, byte(alertDecompressionFailure), 3242 }), 3243 // A no-op warning alert may not be sent before V2ClientHello. 3244 shouldFail: true, 3245 expectedError: ":WRONG_VERSION_NUMBER:", 3246 }, 3247 { 3248 name: "KeyUpdate-ToClient", 3249 config: Config{ 3250 MaxVersion: VersionTLS13, 3251 }, 3252 sendKeyUpdates: 1, 3253 keyUpdateRequest: keyUpdateNotRequested, 3254 }, 3255 { 3256 testType: serverTest, 3257 name: "KeyUpdate-ToServer", 3258 config: Config{ 3259 MaxVersion: VersionTLS13, 3260 }, 3261 sendKeyUpdates: 1, 3262 keyUpdateRequest: keyUpdateNotRequested, 3263 }, 3264 { 3265 name: "KeyUpdate-FromClient", 3266 config: Config{ 3267 MaxVersion: VersionTLS13, 3268 }, 3269 expectUnsolicitedKeyUpdate: true, 3270 flags: []string{"-key-update"}, 3271 }, 3272 { 3273 testType: serverTest, 3274 name: "KeyUpdate-FromServer", 3275 config: Config{ 3276 MaxVersion: VersionTLS13, 3277 }, 3278 expectUnsolicitedKeyUpdate: true, 3279 flags: []string{"-key-update"}, 3280 }, 3281 { 3282 name: "KeyUpdate-InvalidRequestMode", 3283 config: Config{ 3284 MaxVersion: VersionTLS13, 3285 }, 3286 sendKeyUpdates: 1, 3287 keyUpdateRequest: 42, 3288 shouldFail: true, 3289 expectedError: ":DECODE_ERROR:", 3290 }, 3291 { 3292 // Test that KeyUpdates are acknowledged properly. 3293 name: "KeyUpdate-RequestACK", 3294 config: Config{ 3295 MaxVersion: VersionTLS13, 3296 Bugs: ProtocolBugs{ 3297 RejectUnsolicitedKeyUpdate: true, 3298 }, 3299 }, 3300 // Test the shim receiving many KeyUpdates in a row. 3301 sendKeyUpdates: 5, 3302 messageCount: 5, 3303 keyUpdateRequest: keyUpdateRequested, 3304 }, 3305 { 3306 // Test that KeyUpdates are acknowledged properly if the 3307 // peer's KeyUpdate is discovered while a write is 3308 // pending. 3309 name: "KeyUpdate-RequestACK-UnfinishedWrite", 3310 config: Config{ 3311 MaxVersion: VersionTLS13, 3312 Bugs: ProtocolBugs{ 3313 RejectUnsolicitedKeyUpdate: true, 3314 }, 3315 }, 3316 // Test the shim receiving many KeyUpdates in a row. 3317 sendKeyUpdates: 5, 3318 messageCount: 5, 3319 keyUpdateRequest: keyUpdateRequested, 3320 readWithUnfinishedWrite: true, 3321 flags: []string{"-async"}, 3322 }, 3323 { 3324 name: "SendSNIWarningAlert", 3325 config: Config{ 3326 MaxVersion: VersionTLS12, 3327 Bugs: ProtocolBugs{ 3328 SendSNIWarningAlert: true, 3329 }, 3330 }, 3331 }, 3332 { 3333 testType: serverTest, 3334 name: "ExtraCompressionMethods-TLS12", 3335 config: Config{ 3336 MaxVersion: VersionTLS12, 3337 Bugs: ProtocolBugs{ 3338 SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6}, 3339 }, 3340 }, 3341 }, 3342 { 3343 testType: serverTest, 3344 name: "ExtraCompressionMethods-TLS13", 3345 config: Config{ 3346 MaxVersion: VersionTLS13, 3347 Bugs: ProtocolBugs{ 3348 SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6}, 3349 }, 3350 }, 3351 shouldFail: true, 3352 expectedError: ":INVALID_COMPRESSION_LIST:", 3353 expectedLocalError: "remote error: illegal parameter", 3354 }, 3355 { 3356 testType: serverTest, 3357 name: "NoNullCompression-TLS12", 3358 config: Config{ 3359 MaxVersion: VersionTLS12, 3360 Bugs: ProtocolBugs{ 3361 SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6}, 3362 }, 3363 }, 3364 shouldFail: true, 3365 expectedError: ":INVALID_COMPRESSION_LIST:", 3366 expectedLocalError: "remote error: illegal parameter", 3367 }, 3368 { 3369 testType: serverTest, 3370 name: "NoNullCompression-TLS13", 3371 config: Config{ 3372 MaxVersion: VersionTLS13, 3373 Bugs: ProtocolBugs{ 3374 SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6}, 3375 }, 3376 }, 3377 shouldFail: true, 3378 expectedError: ":INVALID_COMPRESSION_LIST:", 3379 expectedLocalError: "remote error: illegal parameter", 3380 }, 3381 // Test that the client rejects invalid compression methods 3382 // from the server. 3383 { 3384 testType: clientTest, 3385 name: "InvalidCompressionMethod", 3386 config: Config{ 3387 MaxVersion: VersionTLS12, 3388 Bugs: ProtocolBugs{ 3389 SendCompressionMethod: 1, 3390 }, 3391 }, 3392 shouldFail: true, 3393 expectedError: ":UNSUPPORTED_COMPRESSION_ALGORITHM:", 3394 expectedLocalError: "remote error: illegal parameter", 3395 }, 3396 { 3397 testType: clientTest, 3398 name: "TLS13-InvalidCompressionMethod", 3399 config: Config{ 3400 MaxVersion: VersionTLS13, 3401 Bugs: ProtocolBugs{ 3402 SendCompressionMethod: 1, 3403 }, 3404 }, 3405 shouldFail: true, 3406 expectedError: ":DECODE_ERROR:", 3407 }, 3408 { 3409 testType: clientTest, 3410 name: "TLS13-HRR-InvalidCompressionMethod", 3411 config: Config{ 3412 MaxVersion: VersionTLS13, 3413 CurvePreferences: []CurveID{CurveP384}, 3414 Bugs: ProtocolBugs{ 3415 SendCompressionMethod: 1, 3416 }, 3417 }, 3418 shouldFail: true, 3419 expectedError: ":DECODE_ERROR:", 3420 expectedLocalError: "remote error: error decoding message", 3421 }, 3422 { 3423 name: "GREASE-Client-TLS12", 3424 config: Config{ 3425 MaxVersion: VersionTLS12, 3426 Bugs: ProtocolBugs{ 3427 ExpectGREASE: true, 3428 }, 3429 }, 3430 flags: []string{"-enable-grease"}, 3431 }, 3432 { 3433 name: "GREASE-Client-TLS13", 3434 config: Config{ 3435 MaxVersion: VersionTLS13, 3436 Bugs: ProtocolBugs{ 3437 ExpectGREASE: true, 3438 }, 3439 }, 3440 flags: []string{"-enable-grease"}, 3441 }, 3442 { 3443 testType: serverTest, 3444 name: "GREASE-Server-TLS13", 3445 config: Config{ 3446 MaxVersion: VersionTLS13, 3447 Bugs: ProtocolBugs{ 3448 // TLS 1.3 servers are expected to 3449 // always enable GREASE. TLS 1.3 is new, 3450 // so there is no existing ecosystem to 3451 // worry about. 3452 ExpectGREASE: true, 3453 }, 3454 }, 3455 }, 3456 { 3457 // Test the TLS 1.2 server so there is a large 3458 // unencrypted certificate as well as application data. 3459 testType: serverTest, 3460 name: "MaxSendFragment-TLS12", 3461 config: Config{ 3462 MaxVersion: VersionTLS12, 3463 Bugs: ProtocolBugs{ 3464 MaxReceivePlaintext: 512, 3465 }, 3466 }, 3467 messageLen: 1024, 3468 flags: []string{ 3469 "-max-send-fragment", "512", 3470 "-read-size", "1024", 3471 }, 3472 }, 3473 { 3474 // Test the TLS 1.2 server so there is a large 3475 // unencrypted certificate as well as application data. 3476 testType: serverTest, 3477 name: "MaxSendFragment-TLS12-TooLarge", 3478 config: Config{ 3479 MaxVersion: VersionTLS12, 3480 Bugs: ProtocolBugs{ 3481 // Ensure that some of the records are 3482 // 512. 3483 MaxReceivePlaintext: 511, 3484 }, 3485 }, 3486 messageLen: 1024, 3487 flags: []string{ 3488 "-max-send-fragment", "512", 3489 "-read-size", "1024", 3490 }, 3491 shouldFail: true, 3492 expectedLocalError: "local error: record overflow", 3493 }, 3494 { 3495 // Test the TLS 1.3 server so there is a large encrypted 3496 // certificate as well as application data. 3497 testType: serverTest, 3498 name: "MaxSendFragment-TLS13", 3499 config: Config{ 3500 MaxVersion: VersionTLS13, 3501 Bugs: ProtocolBugs{ 3502 MaxReceivePlaintext: 512, 3503 ExpectPackedEncryptedHandshake: 512, 3504 }, 3505 }, 3506 messageLen: 1024, 3507 flags: []string{ 3508 "-max-send-fragment", "512", 3509 "-read-size", "1024", 3510 }, 3511 }, 3512 { 3513 // Test the TLS 1.3 server so there is a large encrypted 3514 // certificate as well as application data. 3515 testType: serverTest, 3516 name: "MaxSendFragment-TLS13-TooLarge", 3517 config: Config{ 3518 MaxVersion: VersionTLS13, 3519 Bugs: ProtocolBugs{ 3520 // Ensure that some of the records are 3521 // 512. 3522 MaxReceivePlaintext: 511, 3523 }, 3524 }, 3525 messageLen: 1024, 3526 flags: []string{ 3527 "-max-send-fragment", "512", 3528 "-read-size", "1024", 3529 }, 3530 shouldFail: true, 3531 expectedLocalError: "local error: record overflow", 3532 }, 3533 { 3534 // Test that handshake data is tightly packed in TLS 1.3. 3535 testType: serverTest, 3536 name: "PackedEncryptedHandshake-TLS13", 3537 config: Config{ 3538 MaxVersion: VersionTLS13, 3539 Bugs: ProtocolBugs{ 3540 ExpectPackedEncryptedHandshake: 16384, 3541 }, 3542 }, 3543 }, 3544 { 3545 // Test that DTLS can handle multiple application data 3546 // records in a single packet. 3547 protocol: dtls, 3548 name: "SplitAndPackAppData-DTLS", 3549 config: Config{ 3550 Bugs: ProtocolBugs{ 3551 SplitAndPackAppData: true, 3552 }, 3553 }, 3554 }, 3555 { 3556 protocol: dtls, 3557 name: "SplitAndPackAppData-DTLS-Async", 3558 config: Config{ 3559 Bugs: ProtocolBugs{ 3560 SplitAndPackAppData: true, 3561 }, 3562 }, 3563 flags: []string{"-async"}, 3564 }, 3565 { 3566 // DTLS 1.2 allows up to a 255-byte HelloVerifyRequest cookie, which 3567 // is the largest encodable value. 3568 protocol: dtls, 3569 name: "DTLS-HelloVerifyRequest-255", 3570 config: Config{ 3571 MaxVersion: VersionTLS12, 3572 Bugs: ProtocolBugs{ 3573 HelloVerifyRequestCookieLength: 255, 3574 }, 3575 }, 3576 }, 3577 { 3578 // DTLS 1.2 allows up to a 0-byte HelloVerifyRequest cookie, which 3579 // was probably a mistake in the spec but test that it works 3580 // nonetheless. 3581 protocol: dtls, 3582 name: "DTLS-HelloVerifyRequest-0", 3583 config: Config{ 3584 MaxVersion: VersionTLS12, 3585 Bugs: ProtocolBugs{ 3586 EmptyHelloVerifyRequestCookie: true, 3587 }, 3588 }, 3589 }, 3590 } 3591 testCases = append(testCases, basicTests...) 3592 3593 // Test that very large messages can be received. 3594 cert := rsaCertificate 3595 for i := 0; i < 50; i++ { 3596 cert.Certificate = append(cert.Certificate, cert.Certificate[0]) 3597 } 3598 testCases = append(testCases, testCase{ 3599 name: "LargeMessage", 3600 config: Config{ 3601 Certificates: []Certificate{cert}, 3602 }, 3603 }) 3604 testCases = append(testCases, testCase{ 3605 protocol: dtls, 3606 name: "LargeMessage-DTLS", 3607 config: Config{ 3608 Certificates: []Certificate{cert}, 3609 }, 3610 }) 3611 3612 // They are rejected if the maximum certificate chain length is capped. 3613 testCases = append(testCases, testCase{ 3614 name: "LargeMessage-Reject", 3615 config: Config{ 3616 Certificates: []Certificate{cert}, 3617 }, 3618 flags: []string{"-max-cert-list", "16384"}, 3619 shouldFail: true, 3620 expectedError: ":EXCESSIVE_MESSAGE_SIZE:", 3621 }) 3622 testCases = append(testCases, testCase{ 3623 protocol: dtls, 3624 name: "LargeMessage-Reject-DTLS", 3625 config: Config{ 3626 Certificates: []Certificate{cert}, 3627 }, 3628 flags: []string{"-max-cert-list", "16384"}, 3629 shouldFail: true, 3630 expectedError: ":EXCESSIVE_MESSAGE_SIZE:", 3631 }) 3632 3633 // Servers echoing the TLS 1.3 compatibility mode session ID should be 3634 // rejected. 3635 testCases = append(testCases, testCase{ 3636 name: "EchoTLS13CompatibilitySessionID", 3637 config: Config{ 3638 MaxVersion: VersionTLS12, 3639 Bugs: ProtocolBugs{ 3640 EchoSessionIDInFullHandshake: true, 3641 }, 3642 }, 3643 shouldFail: true, 3644 expectedError: ":SERVER_ECHOED_INVALID_SESSION_ID:", 3645 expectedLocalError: "remote error: illegal parameter", 3646 }) 3647 3648 // Servers should reject QUIC client hellos that have a legacy 3649 // session ID. 3650 testCases = append(testCases, testCase{ 3651 name: "QUICCompatibilityMode", 3652 testType: serverTest, 3653 protocol: quic, 3654 config: Config{ 3655 MinVersion: VersionTLS13, 3656 Bugs: ProtocolBugs{ 3657 CompatModeWithQUIC: true, 3658 }, 3659 }, 3660 shouldFail: true, 3661 expectedError: ":UNEXPECTED_COMPATIBILITY_MODE:", 3662 }) 3663} 3664 3665func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol protocol) { 3666 const psk = "12345" 3667 const pskIdentity = "luggage combo" 3668 3669 if !ver.supportsProtocol(protocol) { 3670 return 3671 } 3672 prefix := protocol.String() + "-" 3673 3674 var cert Certificate 3675 var certFile string 3676 var keyFile string 3677 if hasComponent(suite.name, "ECDSA") { 3678 cert = ecdsaP256Certificate 3679 certFile = ecdsaP256CertificateFile 3680 keyFile = ecdsaP256KeyFile 3681 } else { 3682 cert = rsaCertificate 3683 certFile = rsaCertificateFile 3684 keyFile = rsaKeyFile 3685 } 3686 3687 var flags []string 3688 if hasComponent(suite.name, "PSK") { 3689 flags = append(flags, 3690 "-psk", psk, 3691 "-psk-identity", pskIdentity) 3692 } 3693 3694 if hasComponent(suite.name, "3DES") { 3695 // BoringSSL disables 3DES ciphers by default. 3696 flags = append(flags, "-cipher", "3DES") 3697 } 3698 3699 var shouldFail bool 3700 if isTLS12Only(suite.name) && ver.version < VersionTLS12 { 3701 shouldFail = true 3702 } 3703 if !isTLS13Suite(suite.name) && ver.version >= VersionTLS13 { 3704 shouldFail = true 3705 } 3706 if isTLS13Suite(suite.name) && ver.version < VersionTLS13 { 3707 shouldFail = true 3708 } 3709 3710 var sendCipherSuite uint16 3711 var expectedServerError, expectedClientError string 3712 serverCipherSuites := []uint16{suite.id} 3713 if shouldFail { 3714 expectedServerError = ":NO_SHARED_CIPHER:" 3715 expectedClientError = ":WRONG_CIPHER_RETURNED:" 3716 // Configure the server to select ciphers as normal but 3717 // select an incompatible cipher in ServerHello. 3718 serverCipherSuites = nil 3719 sendCipherSuite = suite.id 3720 } 3721 3722 // Verify exporters interoperate. 3723 exportKeyingMaterial := 1024 3724 3725 testCases = append(testCases, testCase{ 3726 testType: serverTest, 3727 protocol: protocol, 3728 name: prefix + ver.name + "-" + suite.name + "-server", 3729 config: Config{ 3730 MinVersion: ver.version, 3731 MaxVersion: ver.version, 3732 CipherSuites: []uint16{suite.id}, 3733 Certificates: []Certificate{cert}, 3734 PreSharedKey: []byte(psk), 3735 PreSharedKeyIdentity: pskIdentity, 3736 Bugs: ProtocolBugs{ 3737 AdvertiseAllConfiguredCiphers: true, 3738 }, 3739 }, 3740 certFile: certFile, 3741 keyFile: keyFile, 3742 flags: flags, 3743 resumeSession: true, 3744 shouldFail: shouldFail, 3745 expectedError: expectedServerError, 3746 exportKeyingMaterial: exportKeyingMaterial, 3747 }) 3748 3749 testCases = append(testCases, testCase{ 3750 testType: clientTest, 3751 protocol: protocol, 3752 name: prefix + ver.name + "-" + suite.name + "-client", 3753 config: Config{ 3754 MinVersion: ver.version, 3755 MaxVersion: ver.version, 3756 CipherSuites: serverCipherSuites, 3757 Certificates: []Certificate{cert}, 3758 PreSharedKey: []byte(psk), 3759 PreSharedKeyIdentity: pskIdentity, 3760 Bugs: ProtocolBugs{ 3761 IgnorePeerCipherPreferences: shouldFail, 3762 SendCipherSuite: sendCipherSuite, 3763 }, 3764 }, 3765 flags: flags, 3766 resumeSession: true, 3767 shouldFail: shouldFail, 3768 expectedError: expectedClientError, 3769 exportKeyingMaterial: exportKeyingMaterial, 3770 }) 3771 3772 if shouldFail { 3773 return 3774 } 3775 3776 // Ensure the maximum record size is accepted. 3777 testCases = append(testCases, testCase{ 3778 protocol: protocol, 3779 name: prefix + ver.name + "-" + suite.name + "-LargeRecord", 3780 config: Config{ 3781 MinVersion: ver.version, 3782 MaxVersion: ver.version, 3783 CipherSuites: []uint16{suite.id}, 3784 Certificates: []Certificate{cert}, 3785 PreSharedKey: []byte(psk), 3786 PreSharedKeyIdentity: pskIdentity, 3787 }, 3788 flags: flags, 3789 messageLen: maxPlaintext, 3790 }) 3791 3792 // Test bad records for all ciphers. Bad records are fatal in TLS 3793 // and ignored in DTLS. 3794 shouldFail = protocol == tls 3795 var expectedError string 3796 if shouldFail { 3797 expectedError = ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:" 3798 } 3799 3800 // When QUIC is used, the QUIC stack handles record encryption/decryption. 3801 // Thus it is not possible for the TLS stack in QUIC mode to receive a 3802 // bad record (i.e. one that fails to decrypt). 3803 if protocol != quic { 3804 testCases = append(testCases, testCase{ 3805 protocol: protocol, 3806 name: prefix + ver.name + "-" + suite.name + "-BadRecord", 3807 config: Config{ 3808 MinVersion: ver.version, 3809 MaxVersion: ver.version, 3810 CipherSuites: []uint16{suite.id}, 3811 Certificates: []Certificate{cert}, 3812 PreSharedKey: []byte(psk), 3813 PreSharedKeyIdentity: pskIdentity, 3814 }, 3815 flags: flags, 3816 damageFirstWrite: true, 3817 messageLen: maxPlaintext, 3818 shouldFail: shouldFail, 3819 expectedError: expectedError, 3820 }) 3821 } 3822} 3823 3824func addCipherSuiteTests() { 3825 const bogusCipher = 0xfe00 3826 3827 for _, suite := range testCipherSuites { 3828 for _, ver := range tlsVersions { 3829 for _, protocol := range []protocol{tls, dtls, quic} { 3830 addTestForCipherSuite(suite, ver, protocol) 3831 } 3832 } 3833 } 3834 3835 testCases = append(testCases, testCase{ 3836 name: "NoSharedCipher", 3837 config: Config{ 3838 MaxVersion: VersionTLS12, 3839 CipherSuites: []uint16{}, 3840 }, 3841 shouldFail: true, 3842 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:", 3843 }) 3844 3845 testCases = append(testCases, testCase{ 3846 name: "NoSharedCipher-TLS13", 3847 config: Config{ 3848 MaxVersion: VersionTLS13, 3849 CipherSuites: []uint16{}, 3850 }, 3851 shouldFail: true, 3852 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:", 3853 }) 3854 3855 testCases = append(testCases, testCase{ 3856 name: "UnsupportedCipherSuite", 3857 config: Config{ 3858 MaxVersion: VersionTLS12, 3859 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 3860 Bugs: ProtocolBugs{ 3861 IgnorePeerCipherPreferences: true, 3862 }, 3863 }, 3864 flags: []string{"-cipher", "DEFAULT:!AES"}, 3865 shouldFail: true, 3866 expectedError: ":WRONG_CIPHER_RETURNED:", 3867 }) 3868 3869 testCases = append(testCases, testCase{ 3870 name: "ServerHelloBogusCipher", 3871 config: Config{ 3872 MaxVersion: VersionTLS12, 3873 Bugs: ProtocolBugs{ 3874 SendCipherSuite: bogusCipher, 3875 }, 3876 }, 3877 shouldFail: true, 3878 expectedError: ":WRONG_CIPHER_RETURNED:", 3879 }) 3880 testCases = append(testCases, testCase{ 3881 name: "ServerHelloBogusCipher-TLS13", 3882 config: Config{ 3883 MaxVersion: VersionTLS13, 3884 Bugs: ProtocolBugs{ 3885 SendCipherSuite: bogusCipher, 3886 }, 3887 }, 3888 shouldFail: true, 3889 expectedError: ":WRONG_CIPHER_RETURNED:", 3890 }) 3891 3892 // The server must be tolerant to bogus ciphers. 3893 testCases = append(testCases, testCase{ 3894 testType: serverTest, 3895 name: "UnknownCipher", 3896 config: Config{ 3897 MaxVersion: VersionTLS12, 3898 CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3899 Bugs: ProtocolBugs{ 3900 AdvertiseAllConfiguredCiphers: true, 3901 }, 3902 }, 3903 }) 3904 3905 // The server must be tolerant to bogus ciphers. 3906 testCases = append(testCases, testCase{ 3907 testType: serverTest, 3908 name: "UnknownCipher-TLS13", 3909 config: Config{ 3910 MaxVersion: VersionTLS13, 3911 CipherSuites: []uint16{bogusCipher, TLS_AES_128_GCM_SHA256}, 3912 Bugs: ProtocolBugs{ 3913 AdvertiseAllConfiguredCiphers: true, 3914 }, 3915 }, 3916 }) 3917 3918 // Test empty ECDHE_PSK identity hints work as expected. 3919 testCases = append(testCases, testCase{ 3920 name: "EmptyECDHEPSKHint", 3921 config: Config{ 3922 MaxVersion: VersionTLS12, 3923 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 3924 PreSharedKey: []byte("secret"), 3925 }, 3926 flags: []string{"-psk", "secret"}, 3927 }) 3928 3929 // Test empty PSK identity hints work as expected, even if an explicit 3930 // ServerKeyExchange is sent. 3931 testCases = append(testCases, testCase{ 3932 name: "ExplicitEmptyPSKHint", 3933 config: Config{ 3934 MaxVersion: VersionTLS12, 3935 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 3936 PreSharedKey: []byte("secret"), 3937 Bugs: ProtocolBugs{ 3938 AlwaysSendPreSharedKeyIdentityHint: true, 3939 }, 3940 }, 3941 flags: []string{"-psk", "secret"}, 3942 }) 3943 3944 // Test that clients enforce that the server-sent certificate and cipher 3945 // suite match in TLS 1.2. 3946 testCases = append(testCases, testCase{ 3947 name: "CertificateCipherMismatch-RSA", 3948 config: Config{ 3949 MaxVersion: VersionTLS12, 3950 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3951 Certificates: []Certificate{rsaCertificate}, 3952 Bugs: ProtocolBugs{ 3953 SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 3954 }, 3955 }, 3956 shouldFail: true, 3957 expectedError: ":WRONG_CERTIFICATE_TYPE:", 3958 }) 3959 testCases = append(testCases, testCase{ 3960 name: "CertificateCipherMismatch-ECDSA", 3961 config: Config{ 3962 MaxVersion: VersionTLS12, 3963 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 3964 Certificates: []Certificate{ecdsaP256Certificate}, 3965 Bugs: ProtocolBugs{ 3966 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 3967 }, 3968 }, 3969 shouldFail: true, 3970 expectedError: ":WRONG_CERTIFICATE_TYPE:", 3971 }) 3972 testCases = append(testCases, testCase{ 3973 name: "CertificateCipherMismatch-Ed25519", 3974 config: Config{ 3975 MaxVersion: VersionTLS12, 3976 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 3977 Certificates: []Certificate{ed25519Certificate}, 3978 Bugs: ProtocolBugs{ 3979 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 3980 }, 3981 }, 3982 shouldFail: true, 3983 expectedError: ":WRONG_CERTIFICATE_TYPE:", 3984 }) 3985 3986 // Test that servers decline to select a cipher suite which is 3987 // inconsistent with their configured certificate. 3988 testCases = append(testCases, testCase{ 3989 testType: serverTest, 3990 name: "ServerCipherFilter-RSA", 3991 config: Config{ 3992 MaxVersion: VersionTLS12, 3993 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 3994 }, 3995 flags: []string{ 3996 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 3997 "-key-file", path.Join(*resourceDir, rsaKeyFile), 3998 }, 3999 shouldFail: true, 4000 expectedError: ":NO_SHARED_CIPHER:", 4001 }) 4002 testCases = append(testCases, testCase{ 4003 testType: serverTest, 4004 name: "ServerCipherFilter-ECDSA", 4005 config: Config{ 4006 MaxVersion: VersionTLS12, 4007 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4008 }, 4009 flags: []string{ 4010 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 4011 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 4012 }, 4013 shouldFail: true, 4014 expectedError: ":NO_SHARED_CIPHER:", 4015 }) 4016 testCases = append(testCases, testCase{ 4017 testType: serverTest, 4018 name: "ServerCipherFilter-Ed25519", 4019 config: Config{ 4020 MaxVersion: VersionTLS12, 4021 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4022 }, 4023 flags: []string{ 4024 "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), 4025 "-key-file", path.Join(*resourceDir, ed25519KeyFile), 4026 }, 4027 shouldFail: true, 4028 expectedError: ":NO_SHARED_CIPHER:", 4029 }) 4030 4031 // Test cipher suite negotiation works as expected. Configure a 4032 // complicated cipher suite configuration. 4033 const negotiationTestCiphers = "" + 4034 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:" + 4035 "[TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384|TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256|TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]:" + 4036 "TLS_RSA_WITH_AES_128_GCM_SHA256:" + 4037 "TLS_RSA_WITH_AES_128_CBC_SHA:" + 4038 "[TLS_RSA_WITH_AES_256_GCM_SHA384|TLS_RSA_WITH_AES_256_CBC_SHA]" 4039 negotiationTests := []struct { 4040 ciphers []uint16 4041 expected uint16 4042 }{ 4043 // Server preferences are honored, including when 4044 // equipreference groups are involved. 4045 { 4046 []uint16{ 4047 TLS_RSA_WITH_AES_256_GCM_SHA384, 4048 TLS_RSA_WITH_AES_128_CBC_SHA, 4049 TLS_RSA_WITH_AES_128_GCM_SHA256, 4050 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4051 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 4052 }, 4053 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 4054 }, 4055 { 4056 []uint16{ 4057 TLS_RSA_WITH_AES_256_GCM_SHA384, 4058 TLS_RSA_WITH_AES_128_CBC_SHA, 4059 TLS_RSA_WITH_AES_128_GCM_SHA256, 4060 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4061 }, 4062 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4063 }, 4064 { 4065 []uint16{ 4066 TLS_RSA_WITH_AES_256_GCM_SHA384, 4067 TLS_RSA_WITH_AES_128_CBC_SHA, 4068 TLS_RSA_WITH_AES_128_GCM_SHA256, 4069 }, 4070 TLS_RSA_WITH_AES_128_GCM_SHA256, 4071 }, 4072 { 4073 []uint16{ 4074 TLS_RSA_WITH_AES_256_GCM_SHA384, 4075 TLS_RSA_WITH_AES_128_CBC_SHA, 4076 }, 4077 TLS_RSA_WITH_AES_128_CBC_SHA, 4078 }, 4079 // Equipreference groups use the client preference. 4080 { 4081 []uint16{ 4082 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4083 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4084 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4085 }, 4086 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4087 }, 4088 { 4089 []uint16{ 4090 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4091 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4092 }, 4093 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4094 }, 4095 { 4096 []uint16{ 4097 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4098 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4099 }, 4100 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4101 }, 4102 { 4103 []uint16{ 4104 TLS_RSA_WITH_AES_256_GCM_SHA384, 4105 TLS_RSA_WITH_AES_256_CBC_SHA, 4106 }, 4107 TLS_RSA_WITH_AES_256_GCM_SHA384, 4108 }, 4109 { 4110 []uint16{ 4111 TLS_RSA_WITH_AES_256_CBC_SHA, 4112 TLS_RSA_WITH_AES_256_GCM_SHA384, 4113 }, 4114 TLS_RSA_WITH_AES_256_CBC_SHA, 4115 }, 4116 // If there are two equipreference groups, the preferred one 4117 // takes precedence. 4118 { 4119 []uint16{ 4120 TLS_RSA_WITH_AES_256_GCM_SHA384, 4121 TLS_RSA_WITH_AES_256_CBC_SHA, 4122 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4123 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4124 }, 4125 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4126 }, 4127 } 4128 for i, t := range negotiationTests { 4129 testCases = append(testCases, testCase{ 4130 testType: serverTest, 4131 name: "CipherNegotiation-" + strconv.Itoa(i), 4132 config: Config{ 4133 MaxVersion: VersionTLS12, 4134 CipherSuites: t.ciphers, 4135 }, 4136 flags: []string{"-cipher", negotiationTestCiphers}, 4137 expectations: connectionExpectations{ 4138 cipher: t.expected, 4139 }, 4140 }) 4141 } 4142} 4143 4144func addBadECDSASignatureTests() { 4145 for badR := BadValue(1); badR < NumBadValues; badR++ { 4146 for badS := BadValue(1); badS < NumBadValues; badS++ { 4147 testCases = append(testCases, testCase{ 4148 name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS), 4149 config: Config{ 4150 MaxVersion: VersionTLS12, 4151 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 4152 Certificates: []Certificate{ecdsaP256Certificate}, 4153 Bugs: ProtocolBugs{ 4154 BadECDSAR: badR, 4155 BadECDSAS: badS, 4156 }, 4157 }, 4158 shouldFail: true, 4159 expectedError: ":BAD_SIGNATURE:", 4160 }) 4161 testCases = append(testCases, testCase{ 4162 name: fmt.Sprintf("BadECDSA-%d-%d-TLS13", badR, badS), 4163 config: Config{ 4164 MaxVersion: VersionTLS13, 4165 Certificates: []Certificate{ecdsaP256Certificate}, 4166 Bugs: ProtocolBugs{ 4167 BadECDSAR: badR, 4168 BadECDSAS: badS, 4169 }, 4170 }, 4171 shouldFail: true, 4172 expectedError: ":BAD_SIGNATURE:", 4173 }) 4174 } 4175 } 4176} 4177 4178func addCBCPaddingTests() { 4179 testCases = append(testCases, testCase{ 4180 name: "MaxCBCPadding", 4181 config: Config{ 4182 MaxVersion: VersionTLS12, 4183 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4184 Bugs: ProtocolBugs{ 4185 MaxPadding: true, 4186 }, 4187 }, 4188 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size 4189 }) 4190 testCases = append(testCases, testCase{ 4191 name: "BadCBCPadding", 4192 config: Config{ 4193 MaxVersion: VersionTLS12, 4194 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4195 Bugs: ProtocolBugs{ 4196 PaddingFirstByteBad: true, 4197 }, 4198 }, 4199 shouldFail: true, 4200 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 4201 }) 4202 // OpenSSL previously had an issue where the first byte of padding in 4203 // 255 bytes of padding wasn't checked. 4204 testCases = append(testCases, testCase{ 4205 name: "BadCBCPadding255", 4206 config: Config{ 4207 MaxVersion: VersionTLS12, 4208 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4209 Bugs: ProtocolBugs{ 4210 MaxPadding: true, 4211 PaddingFirstByteBadIf255: true, 4212 }, 4213 }, 4214 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size 4215 shouldFail: true, 4216 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 4217 }) 4218} 4219 4220func addCBCSplittingTests() { 4221 var cbcCiphers = []struct { 4222 name string 4223 cipher uint16 4224 }{ 4225 {"3DES", TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 4226 {"AES128", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4227 {"AES256", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, 4228 } 4229 for _, t := range cbcCiphers { 4230 testCases = append(testCases, testCase{ 4231 name: "CBCRecordSplitting-" + t.name, 4232 config: Config{ 4233 MaxVersion: VersionTLS10, 4234 MinVersion: VersionTLS10, 4235 CipherSuites: []uint16{t.cipher}, 4236 Bugs: ProtocolBugs{ 4237 ExpectRecordSplitting: true, 4238 }, 4239 }, 4240 messageLen: -1, // read until EOF 4241 resumeSession: true, 4242 flags: []string{ 4243 "-async", 4244 "-write-different-record-sizes", 4245 "-cbc-record-splitting", 4246 // BoringSSL disables 3DES by default. 4247 "-cipher", "ALL:3DES", 4248 }, 4249 }) 4250 testCases = append(testCases, testCase{ 4251 name: "CBCRecordSplittingPartialWrite-" + t.name, 4252 config: Config{ 4253 MaxVersion: VersionTLS10, 4254 MinVersion: VersionTLS10, 4255 CipherSuites: []uint16{t.cipher}, 4256 Bugs: ProtocolBugs{ 4257 ExpectRecordSplitting: true, 4258 }, 4259 }, 4260 messageLen: -1, // read until EOF 4261 flags: []string{ 4262 "-async", 4263 "-write-different-record-sizes", 4264 "-cbc-record-splitting", 4265 "-partial-write", 4266 // BoringSSL disables 3DES by default. 4267 "-cipher", "ALL:3DES", 4268 }, 4269 }) 4270 } 4271} 4272 4273func addClientAuthTests() { 4274 // Add a dummy cert pool to stress certificate authority parsing. 4275 certPool := x509.NewCertPool() 4276 for _, cert := range []Certificate{rsaCertificate, rsa1024Certificate} { 4277 cert, err := x509.ParseCertificate(cert.Certificate[0]) 4278 if err != nil { 4279 panic(err) 4280 } 4281 certPool.AddCert(cert) 4282 } 4283 caNames := certPool.Subjects() 4284 4285 for _, ver := range tlsVersions { 4286 testCases = append(testCases, testCase{ 4287 testType: clientTest, 4288 name: ver.name + "-Client-ClientAuth-RSA", 4289 config: Config{ 4290 MinVersion: ver.version, 4291 MaxVersion: ver.version, 4292 ClientAuth: RequireAnyClientCert, 4293 ClientCAs: certPool, 4294 }, 4295 flags: []string{ 4296 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4297 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4298 }, 4299 }) 4300 testCases = append(testCases, testCase{ 4301 testType: serverTest, 4302 name: ver.name + "-Server-ClientAuth-RSA", 4303 config: Config{ 4304 MinVersion: ver.version, 4305 MaxVersion: ver.version, 4306 Certificates: []Certificate{rsaCertificate}, 4307 }, 4308 flags: []string{"-require-any-client-certificate"}, 4309 }) 4310 testCases = append(testCases, testCase{ 4311 testType: serverTest, 4312 name: ver.name + "-Server-ClientAuth-ECDSA", 4313 config: Config{ 4314 MinVersion: ver.version, 4315 MaxVersion: ver.version, 4316 Certificates: []Certificate{ecdsaP256Certificate}, 4317 }, 4318 flags: []string{"-require-any-client-certificate"}, 4319 }) 4320 testCases = append(testCases, testCase{ 4321 testType: clientTest, 4322 name: ver.name + "-Client-ClientAuth-ECDSA", 4323 config: Config{ 4324 MinVersion: ver.version, 4325 MaxVersion: ver.version, 4326 ClientAuth: RequireAnyClientCert, 4327 ClientCAs: certPool, 4328 }, 4329 flags: []string{ 4330 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 4331 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 4332 }, 4333 }) 4334 4335 testCases = append(testCases, testCase{ 4336 name: "NoClientCertificate-" + ver.name, 4337 config: Config{ 4338 MinVersion: ver.version, 4339 MaxVersion: ver.version, 4340 ClientAuth: RequireAnyClientCert, 4341 }, 4342 shouldFail: true, 4343 expectedLocalError: "client didn't provide a certificate", 4344 }) 4345 4346 testCases = append(testCases, testCase{ 4347 // Even if not configured to expect a certificate, OpenSSL will 4348 // return X509_V_OK as the verify_result. 4349 testType: serverTest, 4350 name: "NoClientCertificateRequested-Server-" + ver.name, 4351 config: Config{ 4352 MinVersion: ver.version, 4353 MaxVersion: ver.version, 4354 }, 4355 flags: []string{ 4356 "-expect-verify-result", 4357 }, 4358 resumeSession: true, 4359 }) 4360 4361 testCases = append(testCases, testCase{ 4362 // If a client certificate is not provided, OpenSSL will still 4363 // return X509_V_OK as the verify_result. 4364 testType: serverTest, 4365 name: "NoClientCertificate-Server-" + ver.name, 4366 config: Config{ 4367 MinVersion: ver.version, 4368 MaxVersion: ver.version, 4369 }, 4370 flags: []string{ 4371 "-expect-verify-result", 4372 "-verify-peer", 4373 }, 4374 resumeSession: true, 4375 }) 4376 4377 certificateRequired := "remote error: certificate required" 4378 if ver.version < VersionTLS13 { 4379 // Prior to TLS 1.3, the generic handshake_failure alert 4380 // was used. 4381 certificateRequired = "remote error: handshake failure" 4382 } 4383 testCases = append(testCases, testCase{ 4384 testType: serverTest, 4385 name: "RequireAnyClientCertificate-" + ver.name, 4386 config: Config{ 4387 MinVersion: ver.version, 4388 MaxVersion: ver.version, 4389 }, 4390 flags: []string{"-require-any-client-certificate"}, 4391 shouldFail: true, 4392 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 4393 expectedLocalError: certificateRequired, 4394 }) 4395 4396 testCases = append(testCases, testCase{ 4397 testType: serverTest, 4398 name: "SkipClientCertificate-" + ver.name, 4399 config: Config{ 4400 MinVersion: ver.version, 4401 MaxVersion: ver.version, 4402 Bugs: ProtocolBugs{ 4403 SkipClientCertificate: true, 4404 }, 4405 }, 4406 // Setting SSL_VERIFY_PEER allows anonymous clients. 4407 flags: []string{"-verify-peer"}, 4408 shouldFail: true, 4409 expectedError: ":UNEXPECTED_MESSAGE:", 4410 }) 4411 4412 testCases = append(testCases, testCase{ 4413 testType: serverTest, 4414 name: "VerifyPeerIfNoOBC-NoChannelID-" + ver.name, 4415 config: Config{ 4416 MinVersion: ver.version, 4417 MaxVersion: ver.version, 4418 }, 4419 flags: []string{ 4420 "-enable-channel-id", 4421 "-verify-peer-if-no-obc", 4422 }, 4423 shouldFail: true, 4424 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 4425 expectedLocalError: certificateRequired, 4426 }) 4427 4428 testCases = append(testCases, testCase{ 4429 testType: serverTest, 4430 name: "VerifyPeerIfNoOBC-ChannelID-" + ver.name, 4431 config: Config{ 4432 MinVersion: ver.version, 4433 MaxVersion: ver.version, 4434 ChannelID: channelIDKey, 4435 }, 4436 expectations: connectionExpectations{ 4437 channelID: true, 4438 }, 4439 flags: []string{ 4440 "-enable-channel-id", 4441 "-verify-peer-if-no-obc", 4442 }, 4443 }) 4444 4445 testCases = append(testCases, testCase{ 4446 testType: serverTest, 4447 name: ver.name + "-Server-CertReq-CA-List", 4448 config: Config{ 4449 MinVersion: ver.version, 4450 MaxVersion: ver.version, 4451 Certificates: []Certificate{rsaCertificate}, 4452 Bugs: ProtocolBugs{ 4453 ExpectCertificateReqNames: caNames, 4454 }, 4455 }, 4456 flags: []string{ 4457 "-require-any-client-certificate", 4458 "-use-client-ca-list", encodeDERValues(caNames), 4459 }, 4460 }) 4461 4462 testCases = append(testCases, testCase{ 4463 testType: clientTest, 4464 name: ver.name + "-Client-CertReq-CA-List", 4465 config: Config{ 4466 MinVersion: ver.version, 4467 MaxVersion: ver.version, 4468 Certificates: []Certificate{rsaCertificate}, 4469 ClientAuth: RequireAnyClientCert, 4470 ClientCAs: certPool, 4471 }, 4472 flags: []string{ 4473 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4474 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4475 "-expect-client-ca-list", encodeDERValues(caNames), 4476 }, 4477 }) 4478 } 4479 4480 // Client auth is only legal in certificate-based ciphers. 4481 testCases = append(testCases, testCase{ 4482 testType: clientTest, 4483 name: "ClientAuth-PSK", 4484 config: Config{ 4485 MaxVersion: VersionTLS12, 4486 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 4487 PreSharedKey: []byte("secret"), 4488 ClientAuth: RequireAnyClientCert, 4489 }, 4490 flags: []string{ 4491 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4492 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4493 "-psk", "secret", 4494 }, 4495 shouldFail: true, 4496 expectedError: ":UNEXPECTED_MESSAGE:", 4497 }) 4498 testCases = append(testCases, testCase{ 4499 testType: clientTest, 4500 name: "ClientAuth-ECDHE_PSK", 4501 config: Config{ 4502 MaxVersion: VersionTLS12, 4503 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 4504 PreSharedKey: []byte("secret"), 4505 ClientAuth: RequireAnyClientCert, 4506 }, 4507 flags: []string{ 4508 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4509 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4510 "-psk", "secret", 4511 }, 4512 shouldFail: true, 4513 expectedError: ":UNEXPECTED_MESSAGE:", 4514 }) 4515 4516 // Regression test for a bug where the client CA list, if explicitly 4517 // set to NULL, was mis-encoded. 4518 testCases = append(testCases, testCase{ 4519 testType: serverTest, 4520 name: "Null-Client-CA-List", 4521 config: Config{ 4522 MaxVersion: VersionTLS12, 4523 Certificates: []Certificate{rsaCertificate}, 4524 Bugs: ProtocolBugs{ 4525 ExpectCertificateReqNames: [][]byte{}, 4526 }, 4527 }, 4528 flags: []string{ 4529 "-require-any-client-certificate", 4530 "-use-client-ca-list", "<NULL>", 4531 }, 4532 }) 4533 4534 // Test that an empty client CA list doesn't send a CA extension. 4535 testCases = append(testCases, testCase{ 4536 testType: serverTest, 4537 name: "TLS13-Empty-Client-CA-List", 4538 config: Config{ 4539 MaxVersion: VersionTLS13, 4540 Certificates: []Certificate{rsaCertificate}, 4541 Bugs: ProtocolBugs{ 4542 ExpectNoCertificateAuthoritiesExtension: true, 4543 }, 4544 }, 4545 flags: []string{ 4546 "-require-any-client-certificate", 4547 "-use-client-ca-list", "<EMPTY>", 4548 }, 4549 }) 4550 4551} 4552 4553func addExtendedMasterSecretTests() { 4554 const expectEMSFlag = "-expect-extended-master-secret" 4555 4556 for _, with := range []bool{false, true} { 4557 prefix := "No" 4558 if with { 4559 prefix = "" 4560 } 4561 4562 for _, isClient := range []bool{false, true} { 4563 suffix := "-Server" 4564 testType := serverTest 4565 if isClient { 4566 suffix = "-Client" 4567 testType = clientTest 4568 } 4569 4570 for _, ver := range tlsVersions { 4571 // In TLS 1.3, the extension is irrelevant and 4572 // always reports as enabled. 4573 var flags []string 4574 if with || ver.version >= VersionTLS13 { 4575 flags = []string{expectEMSFlag} 4576 } 4577 4578 testCases = append(testCases, testCase{ 4579 testType: testType, 4580 name: prefix + "ExtendedMasterSecret-" + ver.name + suffix, 4581 config: Config{ 4582 MinVersion: ver.version, 4583 MaxVersion: ver.version, 4584 Bugs: ProtocolBugs{ 4585 NoExtendedMasterSecret: !with, 4586 RequireExtendedMasterSecret: with, 4587 }, 4588 }, 4589 flags: flags, 4590 }) 4591 } 4592 } 4593 } 4594 4595 for _, isClient := range []bool{false, true} { 4596 for _, supportedInFirstConnection := range []bool{false, true} { 4597 for _, supportedInResumeConnection := range []bool{false, true} { 4598 boolToWord := func(b bool) string { 4599 if b { 4600 return "Yes" 4601 } 4602 return "No" 4603 } 4604 suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-" 4605 if isClient { 4606 suffix += "Client" 4607 } else { 4608 suffix += "Server" 4609 } 4610 4611 supportedConfig := Config{ 4612 MaxVersion: VersionTLS12, 4613 Bugs: ProtocolBugs{ 4614 RequireExtendedMasterSecret: true, 4615 }, 4616 } 4617 4618 noSupportConfig := Config{ 4619 MaxVersion: VersionTLS12, 4620 Bugs: ProtocolBugs{ 4621 NoExtendedMasterSecret: true, 4622 }, 4623 } 4624 4625 test := testCase{ 4626 name: "ExtendedMasterSecret-" + suffix, 4627 resumeSession: true, 4628 } 4629 4630 if !isClient { 4631 test.testType = serverTest 4632 } 4633 4634 if supportedInFirstConnection { 4635 test.config = supportedConfig 4636 } else { 4637 test.config = noSupportConfig 4638 } 4639 4640 if supportedInResumeConnection { 4641 test.resumeConfig = &supportedConfig 4642 } else { 4643 test.resumeConfig = &noSupportConfig 4644 } 4645 4646 switch suffix { 4647 case "YesToYes-Client", "YesToYes-Server": 4648 // When a session is resumed, it should 4649 // still be aware that its master 4650 // secret was generated via EMS and 4651 // thus it's safe to use tls-unique. 4652 test.flags = []string{expectEMSFlag} 4653 case "NoToYes-Server": 4654 // If an original connection did not 4655 // contain EMS, but a resumption 4656 // handshake does, then a server should 4657 // not resume the session. 4658 test.expectResumeRejected = true 4659 case "YesToNo-Server": 4660 // Resuming an EMS session without the 4661 // EMS extension should cause the 4662 // server to abort the connection. 4663 test.shouldFail = true 4664 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" 4665 case "NoToYes-Client": 4666 // A client should abort a connection 4667 // where the server resumed a non-EMS 4668 // session but echoed the EMS 4669 // extension. 4670 test.shouldFail = true 4671 test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:" 4672 case "YesToNo-Client": 4673 // A client should abort a connection 4674 // where the server didn't echo EMS 4675 // when the session used it. 4676 test.shouldFail = true 4677 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" 4678 } 4679 4680 testCases = append(testCases, test) 4681 } 4682 } 4683 } 4684 4685 // Switching EMS on renegotiation is forbidden. 4686 testCases = append(testCases, testCase{ 4687 name: "ExtendedMasterSecret-Renego-NoEMS", 4688 config: Config{ 4689 MaxVersion: VersionTLS12, 4690 Bugs: ProtocolBugs{ 4691 NoExtendedMasterSecret: true, 4692 NoExtendedMasterSecretOnRenegotiation: true, 4693 }, 4694 }, 4695 renegotiate: 1, 4696 flags: []string{ 4697 "-renegotiate-freely", 4698 "-expect-total-renegotiations", "1", 4699 }, 4700 }) 4701 4702 testCases = append(testCases, testCase{ 4703 name: "ExtendedMasterSecret-Renego-Upgrade", 4704 config: Config{ 4705 MaxVersion: VersionTLS12, 4706 Bugs: ProtocolBugs{ 4707 NoExtendedMasterSecret: true, 4708 }, 4709 }, 4710 renegotiate: 1, 4711 flags: []string{ 4712 "-renegotiate-freely", 4713 "-expect-total-renegotiations", "1", 4714 }, 4715 shouldFail: true, 4716 expectedError: ":RENEGOTIATION_EMS_MISMATCH:", 4717 }) 4718 4719 testCases = append(testCases, testCase{ 4720 name: "ExtendedMasterSecret-Renego-Downgrade", 4721 config: Config{ 4722 MaxVersion: VersionTLS12, 4723 Bugs: ProtocolBugs{ 4724 NoExtendedMasterSecretOnRenegotiation: true, 4725 }, 4726 }, 4727 renegotiate: 1, 4728 flags: []string{ 4729 "-renegotiate-freely", 4730 "-expect-total-renegotiations", "1", 4731 }, 4732 shouldFail: true, 4733 expectedError: ":RENEGOTIATION_EMS_MISMATCH:", 4734 }) 4735} 4736 4737type stateMachineTestConfig struct { 4738 protocol protocol 4739 async bool 4740 splitHandshake bool 4741 packHandshake bool 4742 implicitHandshake bool 4743} 4744 4745// Adds tests that try to cover the range of the handshake state machine, under 4746// various conditions. Some of these are redundant with other tests, but they 4747// only cover the synchronous case. 4748func addAllStateMachineCoverageTests() { 4749 for _, async := range []bool{false, true} { 4750 for _, protocol := range []protocol{tls, dtls, quic} { 4751 addStateMachineCoverageTests(stateMachineTestConfig{ 4752 protocol: protocol, 4753 async: async, 4754 }) 4755 // QUIC doesn't work with the implicit handshake API. Additionally, 4756 // splitting or packing handshake records is meaningless in QUIC. 4757 if protocol != quic { 4758 addStateMachineCoverageTests(stateMachineTestConfig{ 4759 protocol: protocol, 4760 async: async, 4761 implicitHandshake: true, 4762 }) 4763 addStateMachineCoverageTests(stateMachineTestConfig{ 4764 protocol: protocol, 4765 async: async, 4766 splitHandshake: true, 4767 }) 4768 addStateMachineCoverageTests(stateMachineTestConfig{ 4769 protocol: protocol, 4770 async: async, 4771 packHandshake: true, 4772 }) 4773 } 4774 } 4775 } 4776} 4777 4778func addStateMachineCoverageTests(config stateMachineTestConfig) { 4779 var tests []testCase 4780 4781 // Basic handshake, with resumption. Client and server, 4782 // session ID and session ticket. 4783 // The following tests have a max version of 1.2, so they are not suitable 4784 // for use with QUIC. 4785 if config.protocol != quic { 4786 tests = append(tests, testCase{ 4787 name: "Basic-Client", 4788 config: Config{ 4789 MaxVersion: VersionTLS12, 4790 }, 4791 resumeSession: true, 4792 // Ensure session tickets are used, not session IDs. 4793 noSessionCache: true, 4794 flags: []string{"-expect-no-hrr"}, 4795 }) 4796 tests = append(tests, testCase{ 4797 name: "Basic-Client-RenewTicket", 4798 config: Config{ 4799 MaxVersion: VersionTLS12, 4800 Bugs: ProtocolBugs{ 4801 RenewTicketOnResume: true, 4802 }, 4803 }, 4804 flags: []string{"-expect-ticket-renewal"}, 4805 resumeSession: true, 4806 resumeRenewedSession: true, 4807 }) 4808 tests = append(tests, testCase{ 4809 name: "Basic-Client-NoTicket", 4810 config: Config{ 4811 MaxVersion: VersionTLS12, 4812 SessionTicketsDisabled: true, 4813 }, 4814 resumeSession: true, 4815 }) 4816 tests = append(tests, testCase{ 4817 testType: serverTest, 4818 name: "Basic-Server", 4819 config: Config{ 4820 MaxVersion: VersionTLS12, 4821 Bugs: ProtocolBugs{ 4822 RequireSessionTickets: true, 4823 }, 4824 }, 4825 resumeSession: true, 4826 flags: []string{ 4827 "-expect-no-session-id", 4828 "-expect-no-hrr", 4829 }, 4830 }) 4831 tests = append(tests, testCase{ 4832 testType: serverTest, 4833 name: "Basic-Server-NoTickets", 4834 config: Config{ 4835 MaxVersion: VersionTLS12, 4836 SessionTicketsDisabled: true, 4837 }, 4838 resumeSession: true, 4839 flags: []string{"-expect-session-id"}, 4840 }) 4841 tests = append(tests, testCase{ 4842 testType: serverTest, 4843 name: "Basic-Server-EarlyCallback", 4844 config: Config{ 4845 MaxVersion: VersionTLS12, 4846 }, 4847 flags: []string{"-use-early-callback"}, 4848 resumeSession: true, 4849 }) 4850 } 4851 4852 // TLS 1.3 basic handshake shapes. DTLS 1.3 isn't supported yet. 4853 if config.protocol != dtls { 4854 tests = append(tests, testCase{ 4855 name: "TLS13-1RTT-Client", 4856 config: Config{ 4857 MaxVersion: VersionTLS13, 4858 MinVersion: VersionTLS13, 4859 }, 4860 resumeSession: true, 4861 resumeRenewedSession: true, 4862 // 0-RTT being disabled overrides all other 0-RTT reasons. 4863 flags: []string{"-expect-early-data-reason", "disabled"}, 4864 }) 4865 4866 tests = append(tests, testCase{ 4867 testType: serverTest, 4868 name: "TLS13-1RTT-Server", 4869 config: Config{ 4870 MaxVersion: VersionTLS13, 4871 MinVersion: VersionTLS13, 4872 }, 4873 resumeSession: true, 4874 resumeRenewedSession: true, 4875 flags: []string{ 4876 // TLS 1.3 uses tickets, so the session should not be 4877 // cached statefully. 4878 "-expect-no-session-id", 4879 // 0-RTT being disabled overrides all other 0-RTT reasons. 4880 "-expect-early-data-reason", "disabled", 4881 }, 4882 }) 4883 4884 tests = append(tests, testCase{ 4885 name: "TLS13-HelloRetryRequest-Client", 4886 config: Config{ 4887 MaxVersion: VersionTLS13, 4888 MinVersion: VersionTLS13, 4889 // P-384 requires a HelloRetryRequest against BoringSSL's default 4890 // configuration. Assert this with ExpectMissingKeyShare. 4891 CurvePreferences: []CurveID{CurveP384}, 4892 Bugs: ProtocolBugs{ 4893 ExpectMissingKeyShare: true, 4894 }, 4895 }, 4896 // Cover HelloRetryRequest during an ECDHE-PSK resumption. 4897 resumeSession: true, 4898 flags: []string{"-expect-hrr"}, 4899 }) 4900 4901 tests = append(tests, testCase{ 4902 testType: serverTest, 4903 name: "TLS13-HelloRetryRequest-Server", 4904 config: Config{ 4905 MaxVersion: VersionTLS13, 4906 MinVersion: VersionTLS13, 4907 // Require a HelloRetryRequest for every curve. 4908 DefaultCurves: []CurveID{}, 4909 }, 4910 // Cover HelloRetryRequest during an ECDHE-PSK resumption. 4911 resumeSession: true, 4912 flags: []string{"-expect-hrr"}, 4913 }) 4914 4915 // Tests that specify a MaxEarlyDataSize don't work with QUIC. 4916 if config.protocol != quic { 4917 tests = append(tests, testCase{ 4918 testType: clientTest, 4919 name: "TLS13-EarlyData-TooMuchData-Client", 4920 config: Config{ 4921 MaxVersion: VersionTLS13, 4922 MinVersion: VersionTLS13, 4923 MaxEarlyDataSize: 2, 4924 }, 4925 resumeConfig: &Config{ 4926 MaxVersion: VersionTLS13, 4927 MinVersion: VersionTLS13, 4928 MaxEarlyDataSize: 2, 4929 Bugs: ProtocolBugs{ 4930 ExpectEarlyData: [][]byte{[]byte(shimInitialWrite[:2])}, 4931 }, 4932 }, 4933 resumeShimPrefix: shimInitialWrite[2:], 4934 resumeSession: true, 4935 earlyData: true, 4936 }) 4937 } 4938 4939 // Unfinished writes can only be tested when operations are async. EarlyData 4940 // can't be tested as part of an ImplicitHandshake in this case since 4941 // otherwise the early data will be sent as normal data. 4942 // 4943 // Note application data is external in QUIC, so unfinished writes do not 4944 // apply. 4945 if config.async && !config.implicitHandshake && config.protocol != quic { 4946 tests = append(tests, testCase{ 4947 testType: clientTest, 4948 name: "TLS13-EarlyData-UnfinishedWrite-Client", 4949 config: Config{ 4950 MaxVersion: VersionTLS13, 4951 MinVersion: VersionTLS13, 4952 Bugs: ProtocolBugs{ 4953 // Write the server response before expecting early data. 4954 ExpectEarlyData: [][]byte{}, 4955 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 4956 }, 4957 }, 4958 resumeSession: true, 4959 earlyData: true, 4960 flags: []string{"-on-resume-read-with-unfinished-write"}, 4961 }) 4962 4963 // Rejected unfinished writes are discarded (from the 4964 // perspective of the calling application) on 0-RTT 4965 // reject. 4966 tests = append(tests, testCase{ 4967 testType: clientTest, 4968 name: "TLS13-EarlyData-RejectUnfinishedWrite-Client", 4969 config: Config{ 4970 MaxVersion: VersionTLS13, 4971 MinVersion: VersionTLS13, 4972 Bugs: ProtocolBugs{ 4973 AlwaysRejectEarlyData: true, 4974 }, 4975 }, 4976 resumeSession: true, 4977 earlyData: true, 4978 expectEarlyDataRejected: true, 4979 flags: []string{"-on-resume-read-with-unfinished-write"}, 4980 }) 4981 } 4982 4983 // Early data has no size limit in QUIC. 4984 if config.protocol != quic { 4985 tests = append(tests, testCase{ 4986 testType: serverTest, 4987 name: "TLS13-MaxEarlyData-Server", 4988 config: Config{ 4989 MaxVersion: VersionTLS13, 4990 MinVersion: VersionTLS13, 4991 Bugs: ProtocolBugs{ 4992 SendEarlyData: [][]byte{bytes.Repeat([]byte{1}, 14336+1)}, 4993 ExpectEarlyDataAccepted: true, 4994 }, 4995 }, 4996 messageCount: 2, 4997 resumeSession: true, 4998 earlyData: true, 4999 shouldFail: true, 5000 expectedError: ":TOO_MUCH_READ_EARLY_DATA:", 5001 }) 5002 } 5003 } 5004 5005 // TLS client auth. 5006 // The following tests have a max version of 1.2, so they are not suitable 5007 // for use with QUIC. 5008 if config.protocol != quic { 5009 tests = append(tests, testCase{ 5010 testType: clientTest, 5011 name: "ClientAuth-NoCertificate-Client", 5012 config: Config{ 5013 MaxVersion: VersionTLS12, 5014 ClientAuth: RequestClientCert, 5015 }, 5016 }) 5017 tests = append(tests, testCase{ 5018 testType: serverTest, 5019 name: "ClientAuth-NoCertificate-Server", 5020 config: Config{ 5021 MaxVersion: VersionTLS12, 5022 }, 5023 // Setting SSL_VERIFY_PEER allows anonymous clients. 5024 flags: []string{"-verify-peer"}, 5025 }) 5026 } 5027 if config.protocol != dtls { 5028 tests = append(tests, testCase{ 5029 testType: clientTest, 5030 name: "ClientAuth-NoCertificate-Client-TLS13", 5031 config: Config{ 5032 MaxVersion: VersionTLS13, 5033 ClientAuth: RequestClientCert, 5034 }, 5035 }) 5036 tests = append(tests, testCase{ 5037 testType: serverTest, 5038 name: "ClientAuth-NoCertificate-Server-TLS13", 5039 config: Config{ 5040 MaxVersion: VersionTLS13, 5041 }, 5042 // Setting SSL_VERIFY_PEER allows anonymous clients. 5043 flags: []string{"-verify-peer"}, 5044 }) 5045 } 5046 if config.protocol != quic { 5047 tests = append(tests, testCase{ 5048 testType: clientTest, 5049 name: "ClientAuth-RSA-Client", 5050 config: Config{ 5051 MaxVersion: VersionTLS12, 5052 ClientAuth: RequireAnyClientCert, 5053 }, 5054 flags: []string{ 5055 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5056 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5057 }, 5058 }) 5059 } 5060 tests = append(tests, testCase{ 5061 testType: clientTest, 5062 name: "ClientAuth-RSA-Client-TLS13", 5063 config: Config{ 5064 MaxVersion: VersionTLS13, 5065 ClientAuth: RequireAnyClientCert, 5066 }, 5067 flags: []string{ 5068 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5069 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5070 }, 5071 }) 5072 if config.protocol != quic { 5073 tests = append(tests, testCase{ 5074 testType: clientTest, 5075 name: "ClientAuth-ECDSA-Client", 5076 config: Config{ 5077 MaxVersion: VersionTLS12, 5078 ClientAuth: RequireAnyClientCert, 5079 }, 5080 flags: []string{ 5081 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 5082 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 5083 }, 5084 }) 5085 } 5086 tests = append(tests, testCase{ 5087 testType: clientTest, 5088 name: "ClientAuth-ECDSA-Client-TLS13", 5089 config: Config{ 5090 MaxVersion: VersionTLS13, 5091 ClientAuth: RequireAnyClientCert, 5092 }, 5093 flags: []string{ 5094 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 5095 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 5096 }, 5097 }) 5098 if config.protocol != quic { 5099 tests = append(tests, testCase{ 5100 testType: clientTest, 5101 name: "ClientAuth-NoCertificate-OldCallback", 5102 config: Config{ 5103 MaxVersion: VersionTLS12, 5104 ClientAuth: RequestClientCert, 5105 }, 5106 flags: []string{"-use-old-client-cert-callback"}, 5107 }) 5108 } 5109 tests = append(tests, testCase{ 5110 testType: clientTest, 5111 name: "ClientAuth-NoCertificate-OldCallback-TLS13", 5112 config: Config{ 5113 MaxVersion: VersionTLS13, 5114 ClientAuth: RequestClientCert, 5115 }, 5116 flags: []string{"-use-old-client-cert-callback"}, 5117 }) 5118 if config.protocol != quic { 5119 tests = append(tests, testCase{ 5120 testType: clientTest, 5121 name: "ClientAuth-OldCallback", 5122 config: Config{ 5123 MaxVersion: VersionTLS12, 5124 ClientAuth: RequireAnyClientCert, 5125 }, 5126 flags: []string{ 5127 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5128 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5129 "-use-old-client-cert-callback", 5130 }, 5131 }) 5132 } 5133 tests = append(tests, testCase{ 5134 testType: clientTest, 5135 name: "ClientAuth-OldCallback-TLS13", 5136 config: Config{ 5137 MaxVersion: VersionTLS13, 5138 ClientAuth: RequireAnyClientCert, 5139 }, 5140 flags: []string{ 5141 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5142 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5143 "-use-old-client-cert-callback", 5144 }, 5145 }) 5146 if config.protocol != quic { 5147 tests = append(tests, testCase{ 5148 testType: serverTest, 5149 name: "ClientAuth-Server", 5150 config: Config{ 5151 MaxVersion: VersionTLS12, 5152 Certificates: []Certificate{rsaCertificate}, 5153 }, 5154 flags: []string{"-require-any-client-certificate"}, 5155 }) 5156 } 5157 tests = append(tests, testCase{ 5158 testType: serverTest, 5159 name: "ClientAuth-Server-TLS13", 5160 config: Config{ 5161 MaxVersion: VersionTLS13, 5162 Certificates: []Certificate{rsaCertificate}, 5163 }, 5164 flags: []string{"-require-any-client-certificate"}, 5165 }) 5166 5167 // Test each key exchange on the server side for async keys. 5168 if config.protocol != quic { 5169 tests = append(tests, testCase{ 5170 testType: serverTest, 5171 name: "Basic-Server-RSA", 5172 config: Config{ 5173 MaxVersion: VersionTLS12, 5174 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 5175 }, 5176 flags: []string{ 5177 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5178 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5179 }, 5180 }) 5181 tests = append(tests, testCase{ 5182 testType: serverTest, 5183 name: "Basic-Server-ECDHE-RSA", 5184 config: Config{ 5185 MaxVersion: VersionTLS12, 5186 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5187 }, 5188 flags: []string{ 5189 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5190 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5191 }, 5192 }) 5193 tests = append(tests, testCase{ 5194 testType: serverTest, 5195 name: "Basic-Server-ECDHE-ECDSA", 5196 config: Config{ 5197 MaxVersion: VersionTLS12, 5198 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 5199 }, 5200 flags: []string{ 5201 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 5202 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 5203 }, 5204 }) 5205 tests = append(tests, testCase{ 5206 testType: serverTest, 5207 name: "Basic-Server-Ed25519", 5208 config: Config{ 5209 MaxVersion: VersionTLS12, 5210 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 5211 }, 5212 flags: []string{ 5213 "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), 5214 "-key-file", path.Join(*resourceDir, ed25519KeyFile), 5215 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 5216 }, 5217 }) 5218 5219 // No session ticket support; server doesn't send NewSessionTicket. 5220 tests = append(tests, testCase{ 5221 name: "SessionTicketsDisabled-Client", 5222 config: Config{ 5223 MaxVersion: VersionTLS12, 5224 SessionTicketsDisabled: true, 5225 }, 5226 }) 5227 tests = append(tests, testCase{ 5228 testType: serverTest, 5229 name: "SessionTicketsDisabled-Server", 5230 config: Config{ 5231 MaxVersion: VersionTLS12, 5232 SessionTicketsDisabled: true, 5233 }, 5234 }) 5235 5236 // Skip ServerKeyExchange in PSK key exchange if there's no 5237 // identity hint. 5238 tests = append(tests, testCase{ 5239 name: "EmptyPSKHint-Client", 5240 config: Config{ 5241 MaxVersion: VersionTLS12, 5242 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 5243 PreSharedKey: []byte("secret"), 5244 }, 5245 flags: []string{"-psk", "secret"}, 5246 }) 5247 tests = append(tests, testCase{ 5248 testType: serverTest, 5249 name: "EmptyPSKHint-Server", 5250 config: Config{ 5251 MaxVersion: VersionTLS12, 5252 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 5253 PreSharedKey: []byte("secret"), 5254 }, 5255 flags: []string{"-psk", "secret"}, 5256 }) 5257 } 5258 5259 // OCSP stapling tests. 5260 for _, vers := range allVersions(config.protocol) { 5261 tests = append(tests, testCase{ 5262 testType: clientTest, 5263 name: "OCSPStapling-Client-" + vers.name, 5264 config: Config{ 5265 MaxVersion: vers.version, 5266 }, 5267 flags: []string{ 5268 "-enable-ocsp-stapling", 5269 "-expect-ocsp-response", 5270 base64FlagValue(testOCSPResponse), 5271 "-verify-peer", 5272 }, 5273 resumeSession: true, 5274 }) 5275 tests = append(tests, testCase{ 5276 testType: serverTest, 5277 name: "OCSPStapling-Server-" + vers.name, 5278 config: Config{ 5279 MaxVersion: vers.version, 5280 }, 5281 expectations: connectionExpectations{ 5282 ocspResponse: testOCSPResponse, 5283 }, 5284 flags: []string{ 5285 "-ocsp-response", 5286 base64FlagValue(testOCSPResponse), 5287 }, 5288 resumeSession: true, 5289 }) 5290 5291 // The client OCSP callback is an alternate certificate 5292 // verification callback. 5293 tests = append(tests, testCase{ 5294 testType: clientTest, 5295 name: "ClientOCSPCallback-Pass-" + vers.name, 5296 config: Config{ 5297 MaxVersion: vers.version, 5298 Certificates: []Certificate{rsaCertificate}, 5299 }, 5300 flags: []string{ 5301 "-enable-ocsp-stapling", 5302 "-use-ocsp-callback", 5303 }, 5304 }) 5305 var expectedLocalError string 5306 if !config.async { 5307 // TODO(davidben): Asynchronous fatal alerts are never 5308 // sent. https://crbug.com/boringssl/130. 5309 expectedLocalError = "remote error: bad certificate status response" 5310 } 5311 tests = append(tests, testCase{ 5312 testType: clientTest, 5313 name: "ClientOCSPCallback-Fail-" + vers.name, 5314 config: Config{ 5315 MaxVersion: vers.version, 5316 Certificates: []Certificate{rsaCertificate}, 5317 }, 5318 flags: []string{ 5319 "-enable-ocsp-stapling", 5320 "-use-ocsp-callback", 5321 "-fail-ocsp-callback", 5322 }, 5323 shouldFail: true, 5324 expectedLocalError: expectedLocalError, 5325 expectedError: ":OCSP_CB_ERROR:", 5326 }) 5327 // The callback still runs if the server does not send an OCSP 5328 // response. 5329 certNoStaple := rsaCertificate 5330 certNoStaple.OCSPStaple = nil 5331 tests = append(tests, testCase{ 5332 testType: clientTest, 5333 name: "ClientOCSPCallback-FailNoStaple-" + vers.name, 5334 config: Config{ 5335 MaxVersion: vers.version, 5336 Certificates: []Certificate{certNoStaple}, 5337 }, 5338 flags: []string{ 5339 "-enable-ocsp-stapling", 5340 "-use-ocsp-callback", 5341 "-fail-ocsp-callback", 5342 }, 5343 shouldFail: true, 5344 expectedLocalError: expectedLocalError, 5345 expectedError: ":OCSP_CB_ERROR:", 5346 }) 5347 5348 // The server OCSP callback is a legacy mechanism for 5349 // configuring OCSP, used by unreliable server software. 5350 tests = append(tests, testCase{ 5351 testType: serverTest, 5352 name: "ServerOCSPCallback-SetInCallback-" + vers.name, 5353 config: Config{ 5354 MaxVersion: vers.version, 5355 }, 5356 expectations: connectionExpectations{ 5357 ocspResponse: testOCSPResponse, 5358 }, 5359 flags: []string{ 5360 "-use-ocsp-callback", 5361 "-set-ocsp-in-callback", 5362 "-ocsp-response", 5363 base64FlagValue(testOCSPResponse), 5364 }, 5365 resumeSession: true, 5366 }) 5367 5368 // The callback may decline OCSP, in which case we act as if 5369 // the client did not support it, even if a response was 5370 // configured. 5371 tests = append(tests, testCase{ 5372 testType: serverTest, 5373 name: "ServerOCSPCallback-Decline-" + vers.name, 5374 config: Config{ 5375 MaxVersion: vers.version, 5376 }, 5377 expectations: connectionExpectations{ 5378 ocspResponse: []byte{}, 5379 }, 5380 flags: []string{ 5381 "-use-ocsp-callback", 5382 "-decline-ocsp-callback", 5383 "-ocsp-response", 5384 base64FlagValue(testOCSPResponse), 5385 }, 5386 resumeSession: true, 5387 }) 5388 5389 // The callback may also signal an internal error. 5390 tests = append(tests, testCase{ 5391 testType: serverTest, 5392 name: "ServerOCSPCallback-Fail-" + vers.name, 5393 config: Config{ 5394 MaxVersion: vers.version, 5395 }, 5396 flags: []string{ 5397 "-use-ocsp-callback", 5398 "-fail-ocsp-callback", 5399 "-ocsp-response", 5400 base64FlagValue(testOCSPResponse), 5401 }, 5402 shouldFail: true, 5403 expectedError: ":OCSP_CB_ERROR:", 5404 }) 5405 } 5406 5407 // Certificate verification tests. 5408 for _, vers := range allVersions(config.protocol) { 5409 for _, useCustomCallback := range []bool{false, true} { 5410 for _, testType := range []testType{clientTest, serverTest} { 5411 suffix := "-Client" 5412 if testType == serverTest { 5413 suffix = "-Server" 5414 } 5415 suffix += "-" + vers.name 5416 if useCustomCallback { 5417 suffix += "-CustomCallback" 5418 } 5419 5420 // The custom callback and legacy callback have different default 5421 // alerts. 5422 verifyFailLocalError := "remote error: handshake failure" 5423 if useCustomCallback { 5424 verifyFailLocalError = "remote error: unknown certificate" 5425 } 5426 5427 // We do not reliably send asynchronous fatal alerts. See 5428 // https://crbug.com/boringssl/130. 5429 if config.async { 5430 verifyFailLocalError = "" 5431 } 5432 5433 flags := []string{"-verify-peer"} 5434 if testType == serverTest { 5435 flags = append(flags, "-require-any-client-certificate") 5436 } 5437 if useCustomCallback { 5438 flags = append(flags, "-use-custom-verify-callback") 5439 } 5440 5441 tests = append(tests, testCase{ 5442 testType: testType, 5443 name: "CertificateVerificationSucceed" + suffix, 5444 config: Config{ 5445 MaxVersion: vers.version, 5446 Certificates: []Certificate{rsaCertificate}, 5447 }, 5448 flags: append([]string{"-expect-verify-result"}, flags...), 5449 resumeSession: true, 5450 }) 5451 tests = append(tests, testCase{ 5452 testType: testType, 5453 name: "CertificateVerificationFail" + suffix, 5454 config: Config{ 5455 MaxVersion: vers.version, 5456 Certificates: []Certificate{rsaCertificate}, 5457 }, 5458 flags: append([]string{"-verify-fail"}, flags...), 5459 shouldFail: true, 5460 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5461 expectedLocalError: verifyFailLocalError, 5462 }) 5463 // Tests that although the verify callback fails on resumption, by default we don't call it. 5464 tests = append(tests, testCase{ 5465 testType: testType, 5466 name: "CertificateVerificationDoesNotFailOnResume" + suffix, 5467 config: Config{ 5468 MaxVersion: vers.version, 5469 Certificates: []Certificate{rsaCertificate}, 5470 }, 5471 flags: append([]string{"-on-resume-verify-fail"}, flags...), 5472 resumeSession: true, 5473 }) 5474 if testType == clientTest && useCustomCallback { 5475 tests = append(tests, testCase{ 5476 testType: testType, 5477 name: "CertificateVerificationFailsOnResume" + suffix, 5478 config: Config{ 5479 MaxVersion: vers.version, 5480 Certificates: []Certificate{rsaCertificate}, 5481 }, 5482 flags: append([]string{ 5483 "-on-resume-verify-fail", 5484 "-reverify-on-resume", 5485 }, flags...), 5486 resumeSession: true, 5487 shouldFail: true, 5488 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5489 expectedLocalError: verifyFailLocalError, 5490 }) 5491 tests = append(tests, testCase{ 5492 testType: testType, 5493 name: "CertificateVerificationPassesOnResume" + suffix, 5494 config: Config{ 5495 MaxVersion: vers.version, 5496 Certificates: []Certificate{rsaCertificate}, 5497 }, 5498 flags: append([]string{ 5499 "-reverify-on-resume", 5500 }, flags...), 5501 resumeSession: true, 5502 }) 5503 if vers.version >= VersionTLS13 { 5504 tests = append(tests, testCase{ 5505 testType: testType, 5506 name: "EarlyData-RejectTicket-Client-Reverify" + suffix, 5507 config: Config{ 5508 MaxVersion: vers.version, 5509 }, 5510 resumeConfig: &Config{ 5511 MaxVersion: vers.version, 5512 SessionTicketsDisabled: true, 5513 }, 5514 resumeSession: true, 5515 expectResumeRejected: true, 5516 earlyData: true, 5517 expectEarlyDataRejected: true, 5518 flags: append([]string{ 5519 "-reverify-on-resume", 5520 // Session tickets are disabled, so the runner will not send a ticket. 5521 "-on-retry-expect-no-session", 5522 }, flags...), 5523 }) 5524 tests = append(tests, testCase{ 5525 testType: testType, 5526 name: "EarlyData-Reject0RTT-Client-Reverify" + suffix, 5527 config: Config{ 5528 MaxVersion: vers.version, 5529 Bugs: ProtocolBugs{ 5530 AlwaysRejectEarlyData: true, 5531 }, 5532 }, 5533 resumeSession: true, 5534 expectResumeRejected: false, 5535 earlyData: true, 5536 expectEarlyDataRejected: true, 5537 flags: append([]string{ 5538 "-reverify-on-resume", 5539 }, flags...), 5540 }) 5541 tests = append(tests, testCase{ 5542 testType: testType, 5543 name: "EarlyData-RejectTicket-Client-ReverifyFails" + suffix, 5544 config: Config{ 5545 MaxVersion: vers.version, 5546 }, 5547 resumeConfig: &Config{ 5548 MaxVersion: vers.version, 5549 SessionTicketsDisabled: true, 5550 }, 5551 resumeSession: true, 5552 expectResumeRejected: true, 5553 earlyData: true, 5554 expectEarlyDataRejected: true, 5555 shouldFail: true, 5556 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5557 flags: append([]string{ 5558 "-reverify-on-resume", 5559 // Session tickets are disabled, so the runner will not send a ticket. 5560 "-on-retry-expect-no-session", 5561 "-on-retry-verify-fail", 5562 }, flags...), 5563 }) 5564 tests = append(tests, testCase{ 5565 testType: testType, 5566 name: "EarlyData-Reject0RTT-Client-ReverifyFails" + suffix, 5567 config: Config{ 5568 MaxVersion: vers.version, 5569 Bugs: ProtocolBugs{ 5570 AlwaysRejectEarlyData: true, 5571 }, 5572 }, 5573 resumeSession: true, 5574 expectResumeRejected: false, 5575 earlyData: true, 5576 expectEarlyDataRejected: true, 5577 shouldFail: true, 5578 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5579 expectedLocalError: verifyFailLocalError, 5580 flags: append([]string{ 5581 "-reverify-on-resume", 5582 "-on-retry-verify-fail", 5583 }, flags...), 5584 }) 5585 // This tests that we only call the verify callback once. 5586 tests = append(tests, testCase{ 5587 testType: testType, 5588 name: "EarlyData-Accept0RTT-Client-Reverify" + suffix, 5589 config: Config{ 5590 MaxVersion: vers.version, 5591 }, 5592 resumeSession: true, 5593 earlyData: true, 5594 flags: append([]string{ 5595 "-reverify-on-resume", 5596 }, flags...), 5597 }) 5598 tests = append(tests, testCase{ 5599 testType: testType, 5600 name: "EarlyData-Accept0RTT-Client-ReverifyFails" + suffix, 5601 config: Config{ 5602 MaxVersion: vers.version, 5603 }, 5604 resumeSession: true, 5605 earlyData: true, 5606 shouldFail: true, 5607 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5608 // We do not set expectedLocalError here because the shim rejects 5609 // the connection without an alert. 5610 flags: append([]string{ 5611 "-reverify-on-resume", 5612 "-on-resume-verify-fail", 5613 }, flags...), 5614 }) 5615 } 5616 } 5617 } 5618 } 5619 5620 // By default, the client is in a soft fail mode where the peer 5621 // certificate is verified but failures are non-fatal. 5622 tests = append(tests, testCase{ 5623 testType: clientTest, 5624 name: "CertificateVerificationSoftFail-" + vers.name, 5625 config: Config{ 5626 MaxVersion: vers.version, 5627 Certificates: []Certificate{rsaCertificate}, 5628 }, 5629 flags: []string{ 5630 "-verify-fail", 5631 "-expect-verify-result", 5632 }, 5633 resumeSession: true, 5634 }) 5635 } 5636 5637 tests = append(tests, testCase{ 5638 name: "ShimSendAlert", 5639 flags: []string{"-send-alert"}, 5640 shimWritesFirst: true, 5641 shouldFail: true, 5642 expectedLocalError: "remote error: decompression failure", 5643 }) 5644 5645 if config.protocol == tls { 5646 tests = append(tests, testCase{ 5647 name: "Renegotiate-Client", 5648 config: Config{ 5649 MaxVersion: VersionTLS12, 5650 }, 5651 renegotiate: 1, 5652 flags: []string{ 5653 "-renegotiate-freely", 5654 "-expect-total-renegotiations", "1", 5655 }, 5656 }) 5657 5658 tests = append(tests, testCase{ 5659 name: "Renegotiate-Client-Explicit", 5660 config: Config{ 5661 MaxVersion: VersionTLS12, 5662 }, 5663 renegotiate: 1, 5664 flags: []string{ 5665 "-renegotiate-explicit", 5666 "-expect-total-renegotiations", "1", 5667 }, 5668 }) 5669 5670 halfHelloRequestError := ":UNEXPECTED_RECORD:" 5671 if config.packHandshake { 5672 // If the HelloRequest is sent in the same record as the server Finished, 5673 // BoringSSL rejects it before the handshake completes. 5674 halfHelloRequestError = ":EXCESS_HANDSHAKE_DATA:" 5675 } 5676 tests = append(tests, testCase{ 5677 name: "SendHalfHelloRequest", 5678 config: Config{ 5679 MaxVersion: VersionTLS12, 5680 Bugs: ProtocolBugs{ 5681 PackHelloRequestWithFinished: config.packHandshake, 5682 }, 5683 }, 5684 sendHalfHelloRequest: true, 5685 flags: []string{"-renegotiate-ignore"}, 5686 shouldFail: true, 5687 expectedError: halfHelloRequestError, 5688 }) 5689 5690 // NPN on client and server; results in post-handshake message. 5691 tests = append(tests, testCase{ 5692 name: "NPN-Client", 5693 config: Config{ 5694 MaxVersion: VersionTLS12, 5695 NextProtos: []string{"foo"}, 5696 }, 5697 flags: []string{"-select-next-proto", "foo"}, 5698 resumeSession: true, 5699 expectations: connectionExpectations{ 5700 nextProto: "foo", 5701 nextProtoType: npn, 5702 }, 5703 }) 5704 tests = append(tests, testCase{ 5705 testType: serverTest, 5706 name: "NPN-Server", 5707 config: Config{ 5708 MaxVersion: VersionTLS12, 5709 NextProtos: []string{"bar"}, 5710 }, 5711 flags: []string{ 5712 "-advertise-npn", "\x03foo\x03bar\x03baz", 5713 "-expect-next-proto", "bar", 5714 }, 5715 resumeSession: true, 5716 expectations: connectionExpectations{ 5717 nextProto: "bar", 5718 nextProtoType: npn, 5719 }, 5720 }) 5721 5722 // Client does False Start and negotiates NPN. 5723 tests = append(tests, testCase{ 5724 name: "FalseStart", 5725 config: Config{ 5726 MaxVersion: VersionTLS12, 5727 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5728 NextProtos: []string{"foo"}, 5729 Bugs: ProtocolBugs{ 5730 ExpectFalseStart: true, 5731 }, 5732 }, 5733 flags: []string{ 5734 "-false-start", 5735 "-select-next-proto", "foo", 5736 }, 5737 shimWritesFirst: true, 5738 resumeSession: true, 5739 }) 5740 5741 // Client does False Start and negotiates ALPN. 5742 tests = append(tests, testCase{ 5743 name: "FalseStart-ALPN", 5744 config: Config{ 5745 MaxVersion: VersionTLS12, 5746 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5747 NextProtos: []string{"foo"}, 5748 Bugs: ProtocolBugs{ 5749 ExpectFalseStart: true, 5750 }, 5751 }, 5752 flags: []string{ 5753 "-false-start", 5754 "-advertise-alpn", "\x03foo", 5755 "-expect-alpn", "foo", 5756 }, 5757 shimWritesFirst: true, 5758 resumeSession: true, 5759 }) 5760 5761 // False Start without session tickets. 5762 tests = append(tests, testCase{ 5763 name: "FalseStart-SessionTicketsDisabled", 5764 config: Config{ 5765 MaxVersion: VersionTLS12, 5766 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5767 NextProtos: []string{"foo"}, 5768 SessionTicketsDisabled: true, 5769 Bugs: ProtocolBugs{ 5770 ExpectFalseStart: true, 5771 }, 5772 }, 5773 flags: []string{ 5774 "-false-start", 5775 "-select-next-proto", "foo", 5776 }, 5777 shimWritesFirst: true, 5778 }) 5779 5780 // Server parses a V2ClientHello. Test different lengths for the 5781 // challenge field. 5782 for _, challengeLength := range []int{16, 31, 32, 33, 48} { 5783 tests = append(tests, testCase{ 5784 testType: serverTest, 5785 name: fmt.Sprintf("SendV2ClientHello-%d", challengeLength), 5786 config: Config{ 5787 // Choose a cipher suite that does not involve 5788 // elliptic curves, so no extensions are 5789 // involved. 5790 MaxVersion: VersionTLS12, 5791 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 5792 Bugs: ProtocolBugs{ 5793 SendV2ClientHello: true, 5794 V2ClientHelloChallengeLength: challengeLength, 5795 }, 5796 }, 5797 flags: []string{ 5798 "-expect-msg-callback", 5799 `read v2clienthello 5800write hs 2 5801write hs 11 5802write hs 14 5803read hs 16 5804read ccs 5805read hs 20 5806write ccs 5807write hs 20 5808read alert 1 0 5809`, 5810 }, 5811 }) 5812 } 5813 5814 // Channel ID and NPN at the same time, to ensure their relative 5815 // ordering is correct. 5816 tests = append(tests, testCase{ 5817 name: "ChannelID-NPN-Client", 5818 config: Config{ 5819 MaxVersion: VersionTLS12, 5820 RequestChannelID: true, 5821 NextProtos: []string{"foo"}, 5822 }, 5823 flags: []string{ 5824 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 5825 "-select-next-proto", "foo", 5826 }, 5827 resumeSession: true, 5828 expectations: connectionExpectations{ 5829 channelID: true, 5830 nextProto: "foo", 5831 nextProtoType: npn, 5832 }, 5833 }) 5834 tests = append(tests, testCase{ 5835 testType: serverTest, 5836 name: "ChannelID-NPN-Server", 5837 config: Config{ 5838 MaxVersion: VersionTLS12, 5839 ChannelID: channelIDKey, 5840 NextProtos: []string{"bar"}, 5841 }, 5842 flags: []string{ 5843 "-expect-channel-id", 5844 base64FlagValue(channelIDBytes), 5845 "-advertise-npn", "\x03foo\x03bar\x03baz", 5846 "-expect-next-proto", "bar", 5847 }, 5848 resumeSession: true, 5849 expectations: connectionExpectations{ 5850 channelID: true, 5851 nextProto: "bar", 5852 nextProtoType: npn, 5853 }, 5854 }) 5855 5856 // Bidirectional shutdown with the runner initiating. 5857 tests = append(tests, testCase{ 5858 name: "Shutdown-Runner", 5859 config: Config{ 5860 Bugs: ProtocolBugs{ 5861 ExpectCloseNotify: true, 5862 }, 5863 }, 5864 flags: []string{"-check-close-notify"}, 5865 }) 5866 } 5867 if config.protocol != dtls { 5868 // Test Channel ID 5869 for _, ver := range allVersions(config.protocol) { 5870 if ver.version < VersionTLS10 { 5871 continue 5872 } 5873 // Client sends a Channel ID. 5874 tests = append(tests, testCase{ 5875 name: "ChannelID-Client-" + ver.name, 5876 config: Config{ 5877 MaxVersion: ver.version, 5878 RequestChannelID: true, 5879 }, 5880 flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)}, 5881 resumeSession: true, 5882 expectations: connectionExpectations{ 5883 channelID: true, 5884 }, 5885 }) 5886 5887 // Server accepts a Channel ID. 5888 tests = append(tests, testCase{ 5889 testType: serverTest, 5890 name: "ChannelID-Server-" + ver.name, 5891 config: Config{ 5892 MaxVersion: ver.version, 5893 ChannelID: channelIDKey, 5894 }, 5895 flags: []string{ 5896 "-expect-channel-id", 5897 base64FlagValue(channelIDBytes), 5898 }, 5899 resumeSession: true, 5900 expectations: connectionExpectations{ 5901 channelID: true, 5902 }, 5903 }) 5904 5905 tests = append(tests, testCase{ 5906 testType: serverTest, 5907 name: "InvalidChannelIDSignature-" + ver.name, 5908 config: Config{ 5909 MaxVersion: ver.version, 5910 ChannelID: channelIDKey, 5911 Bugs: ProtocolBugs{ 5912 InvalidChannelIDSignature: true, 5913 }, 5914 }, 5915 flags: []string{"-enable-channel-id"}, 5916 shouldFail: true, 5917 expectedError: ":CHANNEL_ID_SIGNATURE_INVALID:", 5918 }) 5919 5920 if ver.version < VersionTLS13 { 5921 // Channel ID requires ECDHE ciphers. 5922 tests = append(tests, testCase{ 5923 testType: serverTest, 5924 name: "ChannelID-NoECDHE-" + ver.name, 5925 config: Config{ 5926 MaxVersion: ver.version, 5927 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 5928 ChannelID: channelIDKey, 5929 }, 5930 expectations: connectionExpectations{ 5931 channelID: false, 5932 }, 5933 flags: []string{"-enable-channel-id"}, 5934 }) 5935 5936 // Sanity-check setting expectations.channelID false works. 5937 tests = append(tests, testCase{ 5938 testType: serverTest, 5939 name: "ChannelID-ECDHE-" + ver.name, 5940 config: Config{ 5941 MaxVersion: ver.version, 5942 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 5943 ChannelID: channelIDKey, 5944 }, 5945 expectations: connectionExpectations{ 5946 channelID: false, 5947 }, 5948 flags: []string{"-enable-channel-id"}, 5949 shouldFail: true, 5950 expectedLocalError: "channel ID unexpectedly negotiated", 5951 }) 5952 } 5953 } 5954 5955 if !config.implicitHandshake { 5956 // Bidirectional shutdown with the shim initiating. The runner, 5957 // in the meantime, sends garbage before the close_notify which 5958 // the shim must ignore. This test is disabled under implicit 5959 // handshake tests because the shim never reads or writes. 5960 5961 // Tests that require checking for a close notify alert don't work with 5962 // QUIC because alerts are handled outside of the TLS stack in QUIC. 5963 if config.protocol != quic { 5964 tests = append(tests, testCase{ 5965 name: "Shutdown-Shim", 5966 config: Config{ 5967 MaxVersion: VersionTLS12, 5968 Bugs: ProtocolBugs{ 5969 ExpectCloseNotify: true, 5970 }, 5971 }, 5972 shimShutsDown: true, 5973 sendEmptyRecords: 1, 5974 sendWarningAlerts: 1, 5975 flags: []string{"-check-close-notify"}, 5976 }) 5977 5978 // The shim should reject unexpected application data 5979 // when shutting down. 5980 tests = append(tests, testCase{ 5981 name: "Shutdown-Shim-ApplicationData", 5982 config: Config{ 5983 MaxVersion: VersionTLS12, 5984 Bugs: ProtocolBugs{ 5985 ExpectCloseNotify: true, 5986 }, 5987 }, 5988 shimShutsDown: true, 5989 messageCount: 1, 5990 sendEmptyRecords: 1, 5991 sendWarningAlerts: 1, 5992 flags: []string{"-check-close-notify"}, 5993 shouldFail: true, 5994 expectedError: ":APPLICATION_DATA_ON_SHUTDOWN:", 5995 }) 5996 5997 // Test that SSL_shutdown still processes KeyUpdate. 5998 tests = append(tests, testCase{ 5999 name: "Shutdown-Shim-KeyUpdate", 6000 config: Config{ 6001 MinVersion: VersionTLS13, 6002 MaxVersion: VersionTLS13, 6003 Bugs: ProtocolBugs{ 6004 ExpectCloseNotify: true, 6005 }, 6006 }, 6007 shimShutsDown: true, 6008 sendKeyUpdates: 1, 6009 keyUpdateRequest: keyUpdateRequested, 6010 flags: []string{"-check-close-notify"}, 6011 }) 6012 6013 // Test that SSL_shutdown processes HelloRequest 6014 // correctly. 6015 tests = append(tests, testCase{ 6016 name: "Shutdown-Shim-HelloRequest-Ignore", 6017 config: Config{ 6018 MinVersion: VersionTLS12, 6019 MaxVersion: VersionTLS12, 6020 Bugs: ProtocolBugs{ 6021 SendHelloRequestBeforeEveryAppDataRecord: true, 6022 ExpectCloseNotify: true, 6023 }, 6024 }, 6025 shimShutsDown: true, 6026 flags: []string{ 6027 "-renegotiate-ignore", 6028 "-check-close-notify", 6029 }, 6030 }) 6031 tests = append(tests, testCase{ 6032 name: "Shutdown-Shim-HelloRequest-Reject", 6033 config: Config{ 6034 MinVersion: VersionTLS12, 6035 MaxVersion: VersionTLS12, 6036 Bugs: ProtocolBugs{ 6037 ExpectCloseNotify: true, 6038 }, 6039 }, 6040 shimShutsDown: true, 6041 renegotiate: 1, 6042 shouldFail: true, 6043 expectedError: ":NO_RENEGOTIATION:", 6044 flags: []string{"-check-close-notify"}, 6045 }) 6046 tests = append(tests, testCase{ 6047 name: "Shutdown-Shim-HelloRequest-CannotHandshake", 6048 config: Config{ 6049 MinVersion: VersionTLS12, 6050 MaxVersion: VersionTLS12, 6051 Bugs: ProtocolBugs{ 6052 ExpectCloseNotify: true, 6053 }, 6054 }, 6055 shimShutsDown: true, 6056 renegotiate: 1, 6057 shouldFail: true, 6058 expectedError: ":NO_RENEGOTIATION:", 6059 flags: []string{ 6060 "-check-close-notify", 6061 "-renegotiate-freely", 6062 }, 6063 }) 6064 6065 tests = append(tests, testCase{ 6066 testType: serverTest, 6067 name: "Shutdown-Shim-Renegotiate-Server-Forbidden", 6068 config: Config{ 6069 MaxVersion: VersionTLS12, 6070 Bugs: ProtocolBugs{ 6071 ExpectCloseNotify: true, 6072 }, 6073 }, 6074 shimShutsDown: true, 6075 renegotiate: 1, 6076 shouldFail: true, 6077 expectedError: ":NO_RENEGOTIATION:", 6078 flags: []string{ 6079 "-check-close-notify", 6080 }, 6081 }) 6082 } 6083 } 6084 } 6085 if config.protocol == dtls { 6086 // TODO(davidben): DTLS 1.3 will want a similar thing for 6087 // HelloRetryRequest. 6088 tests = append(tests, testCase{ 6089 name: "SkipHelloVerifyRequest", 6090 config: Config{ 6091 MaxVersion: VersionTLS12, 6092 Bugs: ProtocolBugs{ 6093 SkipHelloVerifyRequest: true, 6094 }, 6095 }, 6096 }) 6097 } 6098 6099 for _, test := range tests { 6100 test.protocol = config.protocol 6101 test.name += "-" + config.protocol.String() 6102 if config.async { 6103 test.name += "-Async" 6104 test.flags = append(test.flags, "-async") 6105 } else { 6106 test.name += "-Sync" 6107 } 6108 if config.splitHandshake { 6109 test.name += "-SplitHandshakeRecords" 6110 test.config.Bugs.MaxHandshakeRecordLength = 1 6111 if config.protocol == dtls { 6112 test.config.Bugs.MaxPacketLength = 256 6113 test.flags = append(test.flags, "-mtu", "256") 6114 } 6115 } 6116 if config.packHandshake { 6117 test.name += "-PackHandshake" 6118 if config.protocol == dtls { 6119 test.config.Bugs.MaxHandshakeRecordLength = 2 6120 test.config.Bugs.PackHandshakeFragments = 20 6121 test.config.Bugs.PackHandshakeRecords = 1500 6122 test.config.Bugs.PackAppDataWithHandshake = true 6123 } else { 6124 test.config.Bugs.PackHandshakeFlight = true 6125 } 6126 } 6127 if config.implicitHandshake { 6128 test.name += "-ImplicitHandshake" 6129 test.flags = append(test.flags, "-implicit-handshake") 6130 } 6131 testCases = append(testCases, test) 6132 } 6133} 6134 6135func addDDoSCallbackTests() { 6136 // DDoS callback. 6137 for _, resume := range []bool{false, true} { 6138 suffix := "Resume" 6139 if resume { 6140 suffix = "No" + suffix 6141 } 6142 6143 testCases = append(testCases, testCase{ 6144 testType: serverTest, 6145 name: "Server-DDoS-OK-" + suffix, 6146 config: Config{ 6147 MaxVersion: VersionTLS12, 6148 }, 6149 flags: []string{"-install-ddos-callback"}, 6150 resumeSession: resume, 6151 }) 6152 testCases = append(testCases, testCase{ 6153 testType: serverTest, 6154 name: "Server-DDoS-OK-" + suffix + "-TLS13", 6155 config: Config{ 6156 MaxVersion: VersionTLS13, 6157 }, 6158 flags: []string{"-install-ddos-callback"}, 6159 resumeSession: resume, 6160 }) 6161 6162 failFlag := "-fail-ddos-callback" 6163 if resume { 6164 failFlag = "-on-resume-fail-ddos-callback" 6165 } 6166 testCases = append(testCases, testCase{ 6167 testType: serverTest, 6168 name: "Server-DDoS-Reject-" + suffix, 6169 config: Config{ 6170 MaxVersion: VersionTLS12, 6171 }, 6172 flags: []string{"-install-ddos-callback", failFlag}, 6173 resumeSession: resume, 6174 shouldFail: true, 6175 expectedError: ":CONNECTION_REJECTED:", 6176 expectedLocalError: "remote error: internal error", 6177 }) 6178 testCases = append(testCases, testCase{ 6179 testType: serverTest, 6180 name: "Server-DDoS-Reject-" + suffix + "-TLS13", 6181 config: Config{ 6182 MaxVersion: VersionTLS13, 6183 }, 6184 flags: []string{"-install-ddos-callback", failFlag}, 6185 resumeSession: resume, 6186 shouldFail: true, 6187 expectedError: ":CONNECTION_REJECTED:", 6188 expectedLocalError: "remote error: internal error", 6189 }) 6190 } 6191} 6192 6193func addVersionNegotiationTests() { 6194 for _, protocol := range []protocol{tls, dtls, quic} { 6195 for _, shimVers := range allVersions(protocol) { 6196 // Assemble flags to disable all newer versions on the shim. 6197 var flags []string 6198 for _, vers := range allVersions(protocol) { 6199 if vers.version > shimVers.version { 6200 flags = append(flags, vers.excludeFlag) 6201 } 6202 } 6203 6204 flags2 := []string{"-max-version", shimVers.shimFlag(protocol)} 6205 6206 // Test configuring the runner's maximum version. 6207 for _, runnerVers := range allVersions(protocol) { 6208 expectedVersion := shimVers.version 6209 if runnerVers.version < shimVers.version { 6210 expectedVersion = runnerVers.version 6211 } 6212 6213 suffix := shimVers.name + "-" + runnerVers.name 6214 suffix += "-" + protocol.String() 6215 6216 // Determine the expected initial record-layer versions. 6217 clientVers := shimVers.version 6218 if clientVers > VersionTLS10 { 6219 clientVers = VersionTLS10 6220 } 6221 clientVers = recordVersionToWire(clientVers, protocol) 6222 serverVers := expectedVersion 6223 if expectedVersion >= VersionTLS13 { 6224 serverVers = VersionTLS12 6225 } 6226 serverVers = recordVersionToWire(serverVers, protocol) 6227 6228 testCases = append(testCases, testCase{ 6229 protocol: protocol, 6230 testType: clientTest, 6231 name: "VersionNegotiation-Client-" + suffix, 6232 config: Config{ 6233 MaxVersion: runnerVers.version, 6234 Bugs: ProtocolBugs{ 6235 ExpectInitialRecordVersion: clientVers, 6236 }, 6237 }, 6238 flags: flags, 6239 expectations: connectionExpectations{ 6240 version: expectedVersion, 6241 }, 6242 // The version name check does not recognize the 6243 // |excludeFlag| construction in |flags|. 6244 skipVersionNameCheck: true, 6245 }) 6246 testCases = append(testCases, testCase{ 6247 protocol: protocol, 6248 testType: clientTest, 6249 name: "VersionNegotiation-Client2-" + suffix, 6250 config: Config{ 6251 MaxVersion: runnerVers.version, 6252 Bugs: ProtocolBugs{ 6253 ExpectInitialRecordVersion: clientVers, 6254 }, 6255 }, 6256 flags: flags2, 6257 expectations: connectionExpectations{ 6258 version: expectedVersion, 6259 }, 6260 }) 6261 6262 testCases = append(testCases, testCase{ 6263 protocol: protocol, 6264 testType: serverTest, 6265 name: "VersionNegotiation-Server-" + suffix, 6266 config: Config{ 6267 MaxVersion: runnerVers.version, 6268 Bugs: ProtocolBugs{ 6269 ExpectInitialRecordVersion: serverVers, 6270 }, 6271 }, 6272 flags: flags, 6273 expectations: connectionExpectations{ 6274 version: expectedVersion, 6275 }, 6276 // The version name check does not recognize the 6277 // |excludeFlag| construction in |flags|. 6278 skipVersionNameCheck: true, 6279 }) 6280 testCases = append(testCases, testCase{ 6281 protocol: protocol, 6282 testType: serverTest, 6283 name: "VersionNegotiation-Server2-" + suffix, 6284 config: Config{ 6285 MaxVersion: runnerVers.version, 6286 Bugs: ProtocolBugs{ 6287 ExpectInitialRecordVersion: serverVers, 6288 }, 6289 }, 6290 flags: flags2, 6291 expectations: connectionExpectations{ 6292 version: expectedVersion, 6293 }, 6294 }) 6295 } 6296 } 6297 } 6298 6299 // Test the version extension at all versions. 6300 for _, protocol := range []protocol{tls, dtls, quic} { 6301 for _, vers := range allVersions(protocol) { 6302 suffix := vers.name + "-" + protocol.String() 6303 6304 testCases = append(testCases, testCase{ 6305 protocol: protocol, 6306 testType: serverTest, 6307 name: "VersionNegotiationExtension-" + suffix, 6308 config: Config{ 6309 Bugs: ProtocolBugs{ 6310 SendSupportedVersions: []uint16{0x1111, vers.wire(protocol), 0x2222}, 6311 IgnoreTLS13DowngradeRandom: true, 6312 }, 6313 }, 6314 expectations: connectionExpectations{ 6315 version: vers.version, 6316 }, 6317 }) 6318 } 6319 } 6320 6321 // If all versions are unknown, negotiation fails. 6322 testCases = append(testCases, testCase{ 6323 testType: serverTest, 6324 name: "NoSupportedVersions", 6325 config: Config{ 6326 Bugs: ProtocolBugs{ 6327 SendSupportedVersions: []uint16{0x1111}, 6328 }, 6329 }, 6330 shouldFail: true, 6331 expectedError: ":UNSUPPORTED_PROTOCOL:", 6332 }) 6333 testCases = append(testCases, testCase{ 6334 protocol: dtls, 6335 testType: serverTest, 6336 name: "NoSupportedVersions-DTLS", 6337 config: Config{ 6338 Bugs: ProtocolBugs{ 6339 SendSupportedVersions: []uint16{0x1111}, 6340 }, 6341 }, 6342 shouldFail: true, 6343 expectedError: ":UNSUPPORTED_PROTOCOL:", 6344 }) 6345 6346 testCases = append(testCases, testCase{ 6347 testType: serverTest, 6348 name: "ClientHelloVersionTooHigh", 6349 config: Config{ 6350 MaxVersion: VersionTLS13, 6351 Bugs: ProtocolBugs{ 6352 SendClientVersion: 0x0304, 6353 OmitSupportedVersions: true, 6354 IgnoreTLS13DowngradeRandom: true, 6355 }, 6356 }, 6357 expectations: connectionExpectations{ 6358 version: VersionTLS12, 6359 }, 6360 }) 6361 6362 testCases = append(testCases, testCase{ 6363 testType: serverTest, 6364 name: "ConflictingVersionNegotiation", 6365 config: Config{ 6366 Bugs: ProtocolBugs{ 6367 SendClientVersion: VersionTLS12, 6368 SendSupportedVersions: []uint16{VersionTLS11}, 6369 IgnoreTLS13DowngradeRandom: true, 6370 }, 6371 }, 6372 // The extension takes precedence over the ClientHello version. 6373 expectations: connectionExpectations{ 6374 version: VersionTLS11, 6375 }, 6376 }) 6377 6378 testCases = append(testCases, testCase{ 6379 testType: serverTest, 6380 name: "ConflictingVersionNegotiation-2", 6381 config: Config{ 6382 Bugs: ProtocolBugs{ 6383 SendClientVersion: VersionTLS11, 6384 SendSupportedVersions: []uint16{VersionTLS12}, 6385 IgnoreTLS13DowngradeRandom: true, 6386 }, 6387 }, 6388 // The extension takes precedence over the ClientHello version. 6389 expectations: connectionExpectations{ 6390 version: VersionTLS12, 6391 }, 6392 }) 6393 6394 // Test that TLS 1.2 isn't negotiated by the supported_versions extension in 6395 // the ServerHello. 6396 testCases = append(testCases, testCase{ 6397 testType: clientTest, 6398 name: "SupportedVersionSelection-TLS12", 6399 config: Config{ 6400 MaxVersion: VersionTLS12, 6401 Bugs: ProtocolBugs{ 6402 SendServerSupportedVersionExtension: VersionTLS12, 6403 }, 6404 }, 6405 shouldFail: true, 6406 expectedError: ":UNEXPECTED_EXTENSION:", 6407 }) 6408 6409 // Test that the maximum version is selected regardless of the 6410 // client-sent order. 6411 testCases = append(testCases, testCase{ 6412 testType: serverTest, 6413 name: "IgnoreClientVersionOrder", 6414 config: Config{ 6415 Bugs: ProtocolBugs{ 6416 SendSupportedVersions: []uint16{VersionTLS12, VersionTLS13}, 6417 }, 6418 }, 6419 expectations: connectionExpectations{ 6420 version: VersionTLS13, 6421 }, 6422 }) 6423 6424 // Test for version tolerance. 6425 testCases = append(testCases, testCase{ 6426 testType: serverTest, 6427 name: "MinorVersionTolerance", 6428 config: Config{ 6429 Bugs: ProtocolBugs{ 6430 SendClientVersion: 0x03ff, 6431 OmitSupportedVersions: true, 6432 IgnoreTLS13DowngradeRandom: true, 6433 }, 6434 }, 6435 expectations: connectionExpectations{ 6436 version: VersionTLS12, 6437 }, 6438 }) 6439 testCases = append(testCases, testCase{ 6440 testType: serverTest, 6441 name: "MajorVersionTolerance", 6442 config: Config{ 6443 Bugs: ProtocolBugs{ 6444 SendClientVersion: 0x0400, 6445 OmitSupportedVersions: true, 6446 IgnoreTLS13DowngradeRandom: true, 6447 }, 6448 }, 6449 // TLS 1.3 must be negotiated with the supported_versions 6450 // extension, not ClientHello.version. 6451 expectations: connectionExpectations{ 6452 version: VersionTLS12, 6453 }, 6454 }) 6455 testCases = append(testCases, testCase{ 6456 testType: serverTest, 6457 name: "VersionTolerance-TLS13", 6458 config: Config{ 6459 Bugs: ProtocolBugs{ 6460 // Although TLS 1.3 does not use 6461 // ClientHello.version, it still tolerates high 6462 // values there. 6463 SendClientVersion: 0x0400, 6464 }, 6465 }, 6466 expectations: connectionExpectations{ 6467 version: VersionTLS13, 6468 }, 6469 }) 6470 6471 testCases = append(testCases, testCase{ 6472 protocol: dtls, 6473 testType: serverTest, 6474 name: "MinorVersionTolerance-DTLS", 6475 config: Config{ 6476 Bugs: ProtocolBugs{ 6477 SendClientVersion: 0xfe00, 6478 OmitSupportedVersions: true, 6479 }, 6480 }, 6481 expectations: connectionExpectations{ 6482 version: VersionTLS12, 6483 }, 6484 }) 6485 testCases = append(testCases, testCase{ 6486 protocol: dtls, 6487 testType: serverTest, 6488 name: "MajorVersionTolerance-DTLS", 6489 config: Config{ 6490 Bugs: ProtocolBugs{ 6491 SendClientVersion: 0xfdff, 6492 OmitSupportedVersions: true, 6493 }, 6494 }, 6495 expectations: connectionExpectations{ 6496 version: VersionTLS12, 6497 }, 6498 }) 6499 6500 // Test that versions below 3.0 are rejected. 6501 testCases = append(testCases, testCase{ 6502 testType: serverTest, 6503 name: "VersionTooLow", 6504 config: Config{ 6505 Bugs: ProtocolBugs{ 6506 SendClientVersion: 0x0200, 6507 OmitSupportedVersions: true, 6508 }, 6509 }, 6510 shouldFail: true, 6511 expectedError: ":UNSUPPORTED_PROTOCOL:", 6512 }) 6513 testCases = append(testCases, testCase{ 6514 protocol: dtls, 6515 testType: serverTest, 6516 name: "VersionTooLow-DTLS", 6517 config: Config{ 6518 Bugs: ProtocolBugs{ 6519 SendClientVersion: 0xffff, 6520 }, 6521 }, 6522 shouldFail: true, 6523 expectedError: ":UNSUPPORTED_PROTOCOL:", 6524 }) 6525 6526 testCases = append(testCases, testCase{ 6527 name: "ServerBogusVersion", 6528 config: Config{ 6529 Bugs: ProtocolBugs{ 6530 SendServerHelloVersion: 0x1234, 6531 }, 6532 }, 6533 shouldFail: true, 6534 expectedError: ":UNSUPPORTED_PROTOCOL:", 6535 }) 6536 6537 // Test TLS 1.3's downgrade signal. 6538 var downgradeTests = []struct { 6539 name string 6540 version uint16 6541 clientShimError string 6542 }{ 6543 {"TLS12", VersionTLS12, "tls: downgrade from TLS 1.3 detected"}, 6544 {"TLS11", VersionTLS11, "tls: downgrade from TLS 1.2 detected"}, 6545 // TLS 1.0 does not have a dedicated value. 6546 {"TLS10", VersionTLS10, "tls: downgrade from TLS 1.2 detected"}, 6547 } 6548 6549 for _, test := range downgradeTests { 6550 // The client should enforce the downgrade sentinel. 6551 testCases = append(testCases, testCase{ 6552 name: "Downgrade-" + test.name + "-Client", 6553 config: Config{ 6554 Bugs: ProtocolBugs{ 6555 NegotiateVersion: test.version, 6556 }, 6557 }, 6558 expectations: connectionExpectations{ 6559 version: test.version, 6560 }, 6561 shouldFail: true, 6562 expectedError: ":TLS13_DOWNGRADE:", 6563 expectedLocalError: "remote error: illegal parameter", 6564 }) 6565 6566 // The server should emit the downgrade signal. 6567 testCases = append(testCases, testCase{ 6568 testType: serverTest, 6569 name: "Downgrade-" + test.name + "-Server", 6570 config: Config{ 6571 Bugs: ProtocolBugs{ 6572 SendSupportedVersions: []uint16{test.version}, 6573 }, 6574 }, 6575 expectations: connectionExpectations{ 6576 version: test.version, 6577 }, 6578 shouldFail: true, 6579 expectedLocalError: test.clientShimError, 6580 }) 6581 } 6582 6583 // SSL 3.0 support has been removed. Test that the shim does not 6584 // support it. 6585 testCases = append(testCases, testCase{ 6586 name: "NoSSL3-Client", 6587 config: Config{ 6588 MinVersion: VersionSSL30, 6589 MaxVersion: VersionSSL30, 6590 }, 6591 shouldFail: true, 6592 expectedLocalError: "tls: client did not offer any supported protocol versions", 6593 }) 6594 testCases = append(testCases, testCase{ 6595 name: "NoSSL3-Client-Unsolicited", 6596 config: Config{ 6597 MinVersion: VersionSSL30, 6598 MaxVersion: VersionSSL30, 6599 Bugs: ProtocolBugs{ 6600 // The above test asserts the client does not 6601 // offer SSL 3.0 in the supported_versions 6602 // list. Additionally assert that it rejects an 6603 // unsolicited SSL 3.0 ServerHello. 6604 NegotiateVersion: VersionSSL30, 6605 }, 6606 }, 6607 shouldFail: true, 6608 expectedError: ":UNSUPPORTED_PROTOCOL:", 6609 expectedLocalError: "remote error: protocol version not supported", 6610 }) 6611 testCases = append(testCases, testCase{ 6612 testType: serverTest, 6613 name: "NoSSL3-Server", 6614 config: Config{ 6615 MinVersion: VersionSSL30, 6616 MaxVersion: VersionSSL30, 6617 }, 6618 shouldFail: true, 6619 expectedError: ":UNSUPPORTED_PROTOCOL:", 6620 expectedLocalError: "remote error: protocol version not supported", 6621 }) 6622} 6623 6624func addMinimumVersionTests() { 6625 for _, protocol := range []protocol{tls, dtls, quic} { 6626 for _, shimVers := range allVersions(protocol) { 6627 // Assemble flags to disable all older versions on the shim. 6628 var flags []string 6629 for _, vers := range allVersions(protocol) { 6630 if vers.version < shimVers.version { 6631 flags = append(flags, vers.excludeFlag) 6632 } 6633 } 6634 6635 flags2 := []string{"-min-version", shimVers.shimFlag(protocol)} 6636 6637 for _, runnerVers := range allVersions(protocol) { 6638 suffix := shimVers.name + "-" + runnerVers.name 6639 suffix += "-" + protocol.String() 6640 6641 var expectedVersion uint16 6642 var shouldFail bool 6643 var expectedError, expectedLocalError string 6644 if runnerVers.version >= shimVers.version { 6645 expectedVersion = runnerVers.version 6646 } else { 6647 shouldFail = true 6648 expectedError = ":UNSUPPORTED_PROTOCOL:" 6649 expectedLocalError = "remote error: protocol version not supported" 6650 } 6651 6652 testCases = append(testCases, testCase{ 6653 protocol: protocol, 6654 testType: clientTest, 6655 name: "MinimumVersion-Client-" + suffix, 6656 config: Config{ 6657 MaxVersion: runnerVers.version, 6658 Bugs: ProtocolBugs{ 6659 // Ensure the server does not decline to 6660 // select a version (versions extension) or 6661 // cipher (some ciphers depend on versions). 6662 NegotiateVersion: runnerVers.wire(protocol), 6663 IgnorePeerCipherPreferences: shouldFail, 6664 }, 6665 }, 6666 flags: flags, 6667 expectations: connectionExpectations{ 6668 version: expectedVersion, 6669 }, 6670 shouldFail: shouldFail, 6671 expectedError: expectedError, 6672 expectedLocalError: expectedLocalError, 6673 // The version name check does not recognize the 6674 // |excludeFlag| construction in |flags|. 6675 skipVersionNameCheck: true, 6676 }) 6677 testCases = append(testCases, testCase{ 6678 protocol: protocol, 6679 testType: clientTest, 6680 name: "MinimumVersion-Client2-" + suffix, 6681 config: Config{ 6682 MaxVersion: runnerVers.version, 6683 Bugs: ProtocolBugs{ 6684 // Ensure the server does not decline to 6685 // select a version (versions extension) or 6686 // cipher (some ciphers depend on versions). 6687 NegotiateVersion: runnerVers.wire(protocol), 6688 IgnorePeerCipherPreferences: shouldFail, 6689 }, 6690 }, 6691 flags: flags2, 6692 expectations: connectionExpectations{ 6693 version: expectedVersion, 6694 }, 6695 shouldFail: shouldFail, 6696 expectedError: expectedError, 6697 expectedLocalError: expectedLocalError, 6698 }) 6699 6700 testCases = append(testCases, testCase{ 6701 protocol: protocol, 6702 testType: serverTest, 6703 name: "MinimumVersion-Server-" + suffix, 6704 config: Config{ 6705 MaxVersion: runnerVers.version, 6706 }, 6707 flags: flags, 6708 expectations: connectionExpectations{ 6709 version: expectedVersion, 6710 }, 6711 shouldFail: shouldFail, 6712 expectedError: expectedError, 6713 expectedLocalError: expectedLocalError, 6714 // The version name check does not recognize the 6715 // |excludeFlag| construction in |flags|. 6716 skipVersionNameCheck: true, 6717 }) 6718 testCases = append(testCases, testCase{ 6719 protocol: protocol, 6720 testType: serverTest, 6721 name: "MinimumVersion-Server2-" + suffix, 6722 config: Config{ 6723 MaxVersion: runnerVers.version, 6724 }, 6725 flags: flags2, 6726 expectations: connectionExpectations{ 6727 version: expectedVersion, 6728 }, 6729 shouldFail: shouldFail, 6730 expectedError: expectedError, 6731 expectedLocalError: expectedLocalError, 6732 }) 6733 } 6734 } 6735 } 6736} 6737 6738func addExtensionTests() { 6739 // Repeat extensions tests at all versions. 6740 for _, protocol := range []protocol{tls, dtls, quic} { 6741 for _, ver := range allVersions(protocol) { 6742 suffix := fmt.Sprintf("%s-%s", protocol.String(), ver.name) 6743 6744 // Test that duplicate extensions are rejected. 6745 testCases = append(testCases, testCase{ 6746 protocol: protocol, 6747 testType: clientTest, 6748 name: "DuplicateExtensionClient-" + suffix, 6749 config: Config{ 6750 MaxVersion: ver.version, 6751 Bugs: ProtocolBugs{ 6752 DuplicateExtension: true, 6753 }, 6754 }, 6755 shouldFail: true, 6756 expectedLocalError: "remote error: error decoding message", 6757 }) 6758 testCases = append(testCases, testCase{ 6759 protocol: protocol, 6760 testType: serverTest, 6761 name: "DuplicateExtensionServer-" + suffix, 6762 config: Config{ 6763 MaxVersion: ver.version, 6764 Bugs: ProtocolBugs{ 6765 DuplicateExtension: true, 6766 }, 6767 }, 6768 shouldFail: true, 6769 expectedLocalError: "remote error: error decoding message", 6770 }) 6771 6772 // Test SNI. 6773 testCases = append(testCases, testCase{ 6774 protocol: protocol, 6775 testType: clientTest, 6776 name: "ServerNameExtensionClient-" + suffix, 6777 config: Config{ 6778 MaxVersion: ver.version, 6779 Bugs: ProtocolBugs{ 6780 ExpectServerName: "example.com", 6781 }, 6782 }, 6783 flags: []string{"-host-name", "example.com"}, 6784 }) 6785 testCases = append(testCases, testCase{ 6786 protocol: protocol, 6787 testType: clientTest, 6788 name: "ServerNameExtensionClientMismatch-" + suffix, 6789 config: Config{ 6790 MaxVersion: ver.version, 6791 Bugs: ProtocolBugs{ 6792 ExpectServerName: "mismatch.com", 6793 }, 6794 }, 6795 flags: []string{"-host-name", "example.com"}, 6796 shouldFail: true, 6797 expectedLocalError: "tls: unexpected server name", 6798 }) 6799 testCases = append(testCases, testCase{ 6800 protocol: protocol, 6801 testType: clientTest, 6802 name: "ServerNameExtensionClientMissing-" + suffix, 6803 config: Config{ 6804 MaxVersion: ver.version, 6805 Bugs: ProtocolBugs{ 6806 ExpectServerName: "missing.com", 6807 }, 6808 }, 6809 shouldFail: true, 6810 expectedLocalError: "tls: unexpected server name", 6811 }) 6812 testCases = append(testCases, testCase{ 6813 protocol: protocol, 6814 testType: clientTest, 6815 name: "TolerateServerNameAck-" + suffix, 6816 config: Config{ 6817 MaxVersion: ver.version, 6818 Bugs: ProtocolBugs{ 6819 SendServerNameAck: true, 6820 }, 6821 }, 6822 flags: []string{"-host-name", "example.com"}, 6823 resumeSession: true, 6824 }) 6825 testCases = append(testCases, testCase{ 6826 protocol: protocol, 6827 testType: clientTest, 6828 name: "UnsolicitedServerNameAck-" + suffix, 6829 config: Config{ 6830 MaxVersion: ver.version, 6831 Bugs: ProtocolBugs{ 6832 SendServerNameAck: true, 6833 }, 6834 }, 6835 shouldFail: true, 6836 expectedError: ":UNEXPECTED_EXTENSION:", 6837 expectedLocalError: "remote error: unsupported extension", 6838 }) 6839 testCases = append(testCases, testCase{ 6840 protocol: protocol, 6841 testType: serverTest, 6842 name: "ServerNameExtensionServer-" + suffix, 6843 config: Config{ 6844 MaxVersion: ver.version, 6845 ServerName: "example.com", 6846 }, 6847 flags: []string{"-expect-server-name", "example.com"}, 6848 resumeSession: true, 6849 }) 6850 6851 // Test ALPN. 6852 testCases = append(testCases, testCase{ 6853 protocol: protocol, 6854 testType: clientTest, 6855 skipQUICALPNConfig: true, 6856 name: "ALPNClient-" + suffix, 6857 config: Config{ 6858 MaxVersion: ver.version, 6859 NextProtos: []string{"foo"}, 6860 }, 6861 flags: []string{ 6862 "-advertise-alpn", "\x03foo\x03bar\x03baz", 6863 "-expect-alpn", "foo", 6864 }, 6865 expectations: connectionExpectations{ 6866 nextProto: "foo", 6867 nextProtoType: alpn, 6868 }, 6869 resumeSession: true, 6870 }) 6871 testCases = append(testCases, testCase{ 6872 protocol: protocol, 6873 testType: clientTest, 6874 skipQUICALPNConfig: true, 6875 name: "ALPNClient-RejectUnknown-" + suffix, 6876 config: Config{ 6877 MaxVersion: ver.version, 6878 Bugs: ProtocolBugs{ 6879 SendALPN: "baz", 6880 }, 6881 }, 6882 flags: []string{ 6883 "-advertise-alpn", "\x03foo\x03bar", 6884 }, 6885 shouldFail: true, 6886 expectedError: ":INVALID_ALPN_PROTOCOL:", 6887 expectedLocalError: "remote error: illegal parameter", 6888 }) 6889 testCases = append(testCases, testCase{ 6890 protocol: protocol, 6891 testType: clientTest, 6892 skipQUICALPNConfig: true, 6893 name: "ALPNClient-AllowUnknown-" + suffix, 6894 config: Config{ 6895 MaxVersion: ver.version, 6896 Bugs: ProtocolBugs{ 6897 SendALPN: "baz", 6898 }, 6899 }, 6900 flags: []string{ 6901 "-advertise-alpn", "\x03foo\x03bar", 6902 "-allow-unknown-alpn-protos", 6903 "-expect-alpn", "baz", 6904 }, 6905 }) 6906 testCases = append(testCases, testCase{ 6907 protocol: protocol, 6908 testType: serverTest, 6909 skipQUICALPNConfig: true, 6910 name: "ALPNServer-" + suffix, 6911 config: Config{ 6912 MaxVersion: ver.version, 6913 NextProtos: []string{"foo", "bar", "baz"}, 6914 }, 6915 flags: []string{ 6916 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 6917 "-select-alpn", "foo", 6918 }, 6919 expectations: connectionExpectations{ 6920 nextProto: "foo", 6921 nextProtoType: alpn, 6922 }, 6923 resumeSession: true, 6924 }) 6925 6926 var shouldDeclineALPNFail bool 6927 var declineALPNError, declineALPNLocalError string 6928 if protocol == quic { 6929 // ALPN is mandatory in QUIC. 6930 shouldDeclineALPNFail = true 6931 declineALPNError = ":NO_APPLICATION_PROTOCOL:" 6932 declineALPNLocalError = "remote error: no application protocol" 6933 } 6934 testCases = append(testCases, testCase{ 6935 protocol: protocol, 6936 testType: serverTest, 6937 skipQUICALPNConfig: true, 6938 name: "ALPNServer-Decline-" + suffix, 6939 config: Config{ 6940 MaxVersion: ver.version, 6941 NextProtos: []string{"foo", "bar", "baz"}, 6942 }, 6943 flags: []string{"-decline-alpn"}, 6944 expectations: connectionExpectations{ 6945 noNextProto: true, 6946 }, 6947 resumeSession: true, 6948 shouldFail: shouldDeclineALPNFail, 6949 expectedError: declineALPNError, 6950 expectedLocalError: declineALPNLocalError, 6951 }) 6952 6953 testCases = append(testCases, testCase{ 6954 protocol: protocol, 6955 testType: serverTest, 6956 skipQUICALPNConfig: true, 6957 name: "ALPNServer-Reject-" + suffix, 6958 config: Config{ 6959 MaxVersion: ver.version, 6960 NextProtos: []string{"foo", "bar", "baz"}, 6961 }, 6962 flags: []string{"-reject-alpn"}, 6963 shouldFail: true, 6964 expectedError: ":NO_APPLICATION_PROTOCOL:", 6965 expectedLocalError: "remote error: no application protocol", 6966 }) 6967 6968 // Test that the server implementation catches itself if the 6969 // callback tries to return an invalid empty ALPN protocol. 6970 testCases = append(testCases, testCase{ 6971 protocol: protocol, 6972 testType: serverTest, 6973 skipQUICALPNConfig: true, 6974 name: "ALPNServer-SelectEmpty-" + suffix, 6975 config: Config{ 6976 MaxVersion: ver.version, 6977 NextProtos: []string{"foo", "bar", "baz"}, 6978 }, 6979 flags: []string{ 6980 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 6981 "-select-empty-alpn", 6982 }, 6983 shouldFail: true, 6984 expectedLocalError: "remote error: internal error", 6985 expectedError: ":INVALID_ALPN_PROTOCOL:", 6986 }) 6987 6988 // Test ALPN in async mode as well to ensure that extensions callbacks are only 6989 // called once. 6990 testCases = append(testCases, testCase{ 6991 protocol: protocol, 6992 testType: serverTest, 6993 skipQUICALPNConfig: true, 6994 name: "ALPNServer-Async-" + suffix, 6995 config: Config{ 6996 MaxVersion: ver.version, 6997 NextProtos: []string{"foo", "bar", "baz"}, 6998 // Prior to TLS 1.3, exercise the asynchronous session callback. 6999 SessionTicketsDisabled: ver.version < VersionTLS13, 7000 }, 7001 flags: []string{ 7002 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7003 "-select-alpn", "foo", 7004 "-async", 7005 }, 7006 expectations: connectionExpectations{ 7007 nextProto: "foo", 7008 nextProtoType: alpn, 7009 }, 7010 resumeSession: true, 7011 }) 7012 7013 var emptyString string 7014 testCases = append(testCases, testCase{ 7015 protocol: protocol, 7016 testType: clientTest, 7017 skipQUICALPNConfig: true, 7018 name: "ALPNClient-EmptyProtocolName-" + suffix, 7019 config: Config{ 7020 MaxVersion: ver.version, 7021 NextProtos: []string{""}, 7022 Bugs: ProtocolBugs{ 7023 // A server returning an empty ALPN protocol 7024 // should be rejected. 7025 ALPNProtocol: &emptyString, 7026 }, 7027 }, 7028 flags: []string{ 7029 "-advertise-alpn", "\x03foo", 7030 }, 7031 shouldFail: true, 7032 expectedError: ":PARSE_TLSEXT:", 7033 }) 7034 testCases = append(testCases, testCase{ 7035 protocol: protocol, 7036 testType: serverTest, 7037 skipQUICALPNConfig: true, 7038 name: "ALPNServer-EmptyProtocolName-" + suffix, 7039 config: Config{ 7040 MaxVersion: ver.version, 7041 // A ClientHello containing an empty ALPN protocol 7042 // should be rejected. 7043 NextProtos: []string{"foo", "", "baz"}, 7044 }, 7045 flags: []string{ 7046 "-select-alpn", "foo", 7047 }, 7048 shouldFail: true, 7049 expectedError: ":PARSE_TLSEXT:", 7050 }) 7051 7052 // Test NPN and the interaction with ALPN. 7053 if ver.version < VersionTLS13 && protocol == tls { 7054 // Test that the server prefers ALPN over NPN. 7055 testCases = append(testCases, testCase{ 7056 protocol: protocol, 7057 testType: serverTest, 7058 name: "ALPNServer-Preferred-" + suffix, 7059 config: Config{ 7060 MaxVersion: ver.version, 7061 NextProtos: []string{"foo", "bar", "baz"}, 7062 }, 7063 flags: []string{ 7064 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7065 "-select-alpn", "foo", 7066 "-advertise-npn", "\x03foo\x03bar\x03baz", 7067 }, 7068 expectations: connectionExpectations{ 7069 nextProto: "foo", 7070 nextProtoType: alpn, 7071 }, 7072 resumeSession: true, 7073 }) 7074 testCases = append(testCases, testCase{ 7075 protocol: protocol, 7076 testType: serverTest, 7077 name: "ALPNServer-Preferred-Swapped-" + suffix, 7078 config: Config{ 7079 MaxVersion: ver.version, 7080 NextProtos: []string{"foo", "bar", "baz"}, 7081 Bugs: ProtocolBugs{ 7082 SwapNPNAndALPN: true, 7083 }, 7084 }, 7085 flags: []string{ 7086 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7087 "-select-alpn", "foo", 7088 "-advertise-npn", "\x03foo\x03bar\x03baz", 7089 }, 7090 expectations: connectionExpectations{ 7091 nextProto: "foo", 7092 nextProtoType: alpn, 7093 }, 7094 resumeSession: true, 7095 }) 7096 7097 // Test that negotiating both NPN and ALPN is forbidden. 7098 testCases = append(testCases, testCase{ 7099 protocol: protocol, 7100 name: "NegotiateALPNAndNPN-" + suffix, 7101 config: Config{ 7102 MaxVersion: ver.version, 7103 NextProtos: []string{"foo", "bar", "baz"}, 7104 Bugs: ProtocolBugs{ 7105 NegotiateALPNAndNPN: true, 7106 }, 7107 }, 7108 flags: []string{ 7109 "-advertise-alpn", "\x03foo", 7110 "-select-next-proto", "foo", 7111 }, 7112 shouldFail: true, 7113 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:", 7114 }) 7115 testCases = append(testCases, testCase{ 7116 protocol: protocol, 7117 name: "NegotiateALPNAndNPN-Swapped-" + suffix, 7118 config: Config{ 7119 MaxVersion: ver.version, 7120 NextProtos: []string{"foo", "bar", "baz"}, 7121 Bugs: ProtocolBugs{ 7122 NegotiateALPNAndNPN: true, 7123 SwapNPNAndALPN: true, 7124 }, 7125 }, 7126 flags: []string{ 7127 "-advertise-alpn", "\x03foo", 7128 "-select-next-proto", "foo", 7129 }, 7130 shouldFail: true, 7131 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:", 7132 }) 7133 } 7134 7135 // Test missing ALPN in QUIC 7136 if protocol == quic { 7137 testCases = append(testCases, testCase{ 7138 testType: clientTest, 7139 protocol: protocol, 7140 name: "Client-ALPNMissingFromConfig-" + suffix, 7141 config: Config{ 7142 MinVersion: ver.version, 7143 MaxVersion: ver.version, 7144 }, 7145 skipQUICALPNConfig: true, 7146 shouldFail: true, 7147 expectedError: ":NO_APPLICATION_PROTOCOL:", 7148 }) 7149 testCases = append(testCases, testCase{ 7150 testType: clientTest, 7151 protocol: protocol, 7152 name: "Client-ALPNMissing-" + suffix, 7153 config: Config{ 7154 MinVersion: ver.version, 7155 MaxVersion: ver.version, 7156 }, 7157 flags: []string{ 7158 "-advertise-alpn", "\x03foo", 7159 }, 7160 skipQUICALPNConfig: true, 7161 shouldFail: true, 7162 expectedError: ":NO_APPLICATION_PROTOCOL:", 7163 expectedLocalError: "remote error: no application protocol", 7164 }) 7165 testCases = append(testCases, testCase{ 7166 testType: serverTest, 7167 protocol: protocol, 7168 name: "Server-ALPNMissing-" + suffix, 7169 config: Config{ 7170 MinVersion: ver.version, 7171 MaxVersion: ver.version, 7172 }, 7173 skipQUICALPNConfig: true, 7174 shouldFail: true, 7175 expectedError: ":NO_APPLICATION_PROTOCOL:", 7176 expectedLocalError: "remote error: no application protocol", 7177 }) 7178 testCases = append(testCases, testCase{ 7179 testType: serverTest, 7180 protocol: protocol, 7181 name: "Server-ALPNMismatch-" + suffix, 7182 config: Config{ 7183 MinVersion: ver.version, 7184 MaxVersion: ver.version, 7185 NextProtos: []string{"foo"}, 7186 }, 7187 flags: []string{ 7188 "-decline-alpn", 7189 }, 7190 skipQUICALPNConfig: true, 7191 shouldFail: true, 7192 expectedError: ":NO_APPLICATION_PROTOCOL:", 7193 expectedLocalError: "remote error: no application protocol", 7194 }) 7195 } 7196 7197 // Test ALPS. 7198 if ver.version >= VersionTLS13 { 7199 // Test basic client with different ALPS codepoint. 7200 for _, alpsCodePoint := range []ALPSUseCodepoint{ALPSUseCodepointNew, ALPSUseCodepointOld} { 7201 flags := []string{} 7202 expectations := connectionExpectations{ 7203 peerApplicationSettingsOld: []byte("shim1"), 7204 } 7205 resumeExpectations := &connectionExpectations{ 7206 peerApplicationSettingsOld: []byte("shim2"), 7207 } 7208 7209 if alpsCodePoint == ALPSUseCodepointNew { 7210 flags = append(flags, "-alps-use-new-codepoint") 7211 expectations = connectionExpectations{ 7212 peerApplicationSettings: []byte("shim1"), 7213 } 7214 resumeExpectations = &connectionExpectations{ 7215 peerApplicationSettings: []byte("shim2"), 7216 } 7217 } 7218 7219 flags = append(flags, 7220 "-advertise-alpn", "\x05proto", 7221 "-expect-alpn", "proto", 7222 "-on-initial-application-settings", "proto,shim1", 7223 "-on-initial-expect-peer-application-settings", "runner1", 7224 "-on-resume-application-settings", "proto,shim2", 7225 "-on-resume-expect-peer-application-settings", "runner2") 7226 7227 // Test that server can negotiate ALPS, including different values 7228 // on resumption. 7229 testCases = append(testCases, testCase{ 7230 protocol: protocol, 7231 testType: clientTest, 7232 name: fmt.Sprintf("ALPS-Basic-Client-%s-%s", alpsCodePoint, suffix), 7233 skipQUICALPNConfig: true, 7234 config: Config{ 7235 MaxVersion: ver.version, 7236 NextProtos: []string{"proto"}, 7237 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7238 ALPSUseNewCodepoint: alpsCodePoint, 7239 }, 7240 resumeConfig: &Config{ 7241 MaxVersion: ver.version, 7242 NextProtos: []string{"proto"}, 7243 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7244 ALPSUseNewCodepoint: alpsCodePoint, 7245 }, 7246 resumeSession: true, 7247 expectations: expectations, 7248 resumeExpectations: resumeExpectations, 7249 flags: flags, 7250 }) 7251 7252 // Test basic server with different ALPS codepoint. 7253 flags = []string{} 7254 expectations = connectionExpectations{ 7255 peerApplicationSettingsOld: []byte("shim1"), 7256 } 7257 resumeExpectations = &connectionExpectations{ 7258 peerApplicationSettingsOld: []byte("shim2"), 7259 } 7260 7261 if alpsCodePoint == ALPSUseCodepointNew { 7262 flags = append(flags, "-alps-use-new-codepoint") 7263 expectations = connectionExpectations{ 7264 peerApplicationSettings: []byte("shim1"), 7265 } 7266 resumeExpectations = &connectionExpectations{ 7267 peerApplicationSettings: []byte("shim2"), 7268 } 7269 } 7270 7271 flags = append(flags, 7272 "-select-alpn", "proto", 7273 "-on-initial-application-settings", "proto,shim1", 7274 "-on-initial-expect-peer-application-settings", "runner1", 7275 "-on-resume-application-settings", "proto,shim2", 7276 "-on-resume-expect-peer-application-settings", "runner2") 7277 7278 // Test that server can negotiate ALPS, including different values 7279 // on resumption. 7280 testCases = append(testCases, testCase{ 7281 protocol: protocol, 7282 testType: serverTest, 7283 name: fmt.Sprintf("ALPS-Basic-Server-%s-%s", alpsCodePoint, suffix), 7284 skipQUICALPNConfig: true, 7285 config: Config{ 7286 MaxVersion: ver.version, 7287 NextProtos: []string{"proto"}, 7288 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7289 ALPSUseNewCodepoint: alpsCodePoint, 7290 }, 7291 resumeConfig: &Config{ 7292 MaxVersion: ver.version, 7293 NextProtos: []string{"proto"}, 7294 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7295 ALPSUseNewCodepoint: alpsCodePoint, 7296 }, 7297 resumeSession: true, 7298 expectations: expectations, 7299 resumeExpectations: resumeExpectations, 7300 flags: flags, 7301 }) 7302 7303 // Try different ALPS codepoint for all the existing tests. 7304 alpsFlags := []string{} 7305 expectations = connectionExpectations{ 7306 peerApplicationSettingsOld: []byte("shim1"), 7307 } 7308 resumeExpectations = &connectionExpectations{ 7309 peerApplicationSettingsOld: []byte("shim2"), 7310 } 7311 if alpsCodePoint == ALPSUseCodepointNew { 7312 alpsFlags = append(alpsFlags, "-alps-use-new-codepoint") 7313 expectations = connectionExpectations{ 7314 peerApplicationSettings: []byte("shim1"), 7315 } 7316 resumeExpectations = &connectionExpectations{ 7317 peerApplicationSettings: []byte("shim2"), 7318 } 7319 } 7320 7321 // Test that the server can defer its ALPS configuration to the ALPN 7322 // selection callback. 7323 testCases = append(testCases, testCase{ 7324 protocol: protocol, 7325 testType: serverTest, 7326 name: fmt.Sprintf("ALPS-Basic-Server-Defer-%s-%s", alpsCodePoint, suffix), 7327 skipQUICALPNConfig: true, 7328 config: Config{ 7329 MaxVersion: ver.version, 7330 NextProtos: []string{"proto"}, 7331 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7332 ALPSUseNewCodepoint: alpsCodePoint, 7333 }, 7334 resumeConfig: &Config{ 7335 MaxVersion: ver.version, 7336 NextProtos: []string{"proto"}, 7337 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7338 ALPSUseNewCodepoint: alpsCodePoint, 7339 }, 7340 resumeSession: true, 7341 expectations: expectations, 7342 resumeExpectations: resumeExpectations, 7343 flags: append([]string{ 7344 "-select-alpn", "proto", 7345 "-defer-alps", 7346 "-on-initial-application-settings", "proto,shim1", 7347 "-on-initial-expect-peer-application-settings", "runner1", 7348 "-on-resume-application-settings", "proto,shim2", 7349 "-on-resume-expect-peer-application-settings", "runner2", 7350 }, alpsFlags...), 7351 }) 7352 7353 expectations = connectionExpectations{ 7354 peerApplicationSettingsOld: []byte{}, 7355 } 7356 if alpsCodePoint == ALPSUseCodepointNew { 7357 expectations = connectionExpectations{ 7358 peerApplicationSettings: []byte{}, 7359 } 7360 } 7361 // Test the client and server correctly handle empty settings. 7362 testCases = append(testCases, testCase{ 7363 protocol: protocol, 7364 testType: clientTest, 7365 name: fmt.Sprintf("ALPS-Empty-Client-%s-%s", alpsCodePoint, suffix), 7366 skipQUICALPNConfig: true, 7367 config: Config{ 7368 MaxVersion: ver.version, 7369 NextProtos: []string{"proto"}, 7370 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7371 ALPSUseNewCodepoint: alpsCodePoint, 7372 }, 7373 resumeSession: true, 7374 expectations: expectations, 7375 flags: append([]string{ 7376 "-advertise-alpn", "\x05proto", 7377 "-expect-alpn", "proto", 7378 "-application-settings", "proto,", 7379 "-expect-peer-application-settings", "", 7380 }, alpsFlags...), 7381 }) 7382 testCases = append(testCases, testCase{ 7383 protocol: protocol, 7384 testType: serverTest, 7385 name: fmt.Sprintf("ALPS-Empty-Server-%s-%s", alpsCodePoint, suffix), 7386 skipQUICALPNConfig: true, 7387 config: Config{ 7388 MaxVersion: ver.version, 7389 NextProtos: []string{"proto"}, 7390 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7391 ALPSUseNewCodepoint: alpsCodePoint, 7392 }, 7393 resumeSession: true, 7394 expectations: expectations, 7395 flags: append([]string{ 7396 "-select-alpn", "proto", 7397 "-application-settings", "proto,", 7398 "-expect-peer-application-settings", "", 7399 }, alpsFlags...), 7400 }) 7401 7402 bugs := ProtocolBugs{ 7403 AlwaysNegotiateApplicationSettingsOld: true, 7404 } 7405 if alpsCodePoint == ALPSUseCodepointNew { 7406 bugs = ProtocolBugs{ 7407 AlwaysNegotiateApplicationSettingsNew: true, 7408 } 7409 } 7410 // Test the client rejects application settings from the server on 7411 // protocols it doesn't have them. 7412 testCases = append(testCases, testCase{ 7413 protocol: protocol, 7414 testType: clientTest, 7415 name: fmt.Sprintf("ALPS-UnsupportedProtocol-Client-%s-%s", alpsCodePoint, suffix), 7416 skipQUICALPNConfig: true, 7417 config: Config{ 7418 MaxVersion: ver.version, 7419 NextProtos: []string{"proto1"}, 7420 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7421 Bugs: bugs, 7422 ALPSUseNewCodepoint: alpsCodePoint, 7423 }, 7424 // The client supports ALPS with "proto2", but not "proto1". 7425 flags: append([]string{ 7426 "-advertise-alpn", "\x06proto1\x06proto2", 7427 "-application-settings", "proto2,shim", 7428 "-expect-alpn", "proto1", 7429 }, alpsFlags...), 7430 // The server sends ALPS with "proto1", which is invalid. 7431 shouldFail: true, 7432 expectedError: ":INVALID_ALPN_PROTOCOL:", 7433 expectedLocalError: "remote error: illegal parameter", 7434 }) 7435 7436 // Test client rejects application settings from the server when 7437 // server sends the wrong ALPS codepoint. 7438 bugs = ProtocolBugs{ 7439 AlwaysNegotiateApplicationSettingsOld: true, 7440 } 7441 if alpsCodePoint == ALPSUseCodepointOld { 7442 bugs = ProtocolBugs{ 7443 AlwaysNegotiateApplicationSettingsNew: true, 7444 } 7445 } 7446 7447 testCases = append(testCases, testCase{ 7448 protocol: protocol, 7449 testType: clientTest, 7450 name: fmt.Sprintf("ALPS-WrongServerCodepoint-Client-%s-%s", alpsCodePoint, suffix), 7451 skipQUICALPNConfig: true, 7452 config: Config{ 7453 MaxVersion: ver.version, 7454 NextProtos: []string{"proto"}, 7455 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7456 Bugs: bugs, 7457 ALPSUseNewCodepoint: alpsCodePoint, 7458 }, 7459 flags: append([]string{ 7460 "-advertise-alpn", "\x05proto", 7461 "-expect-alpn", "proto", 7462 "-application-settings", "proto,", 7463 "-expect-peer-application-settings", "", 7464 }, alpsFlags...), 7465 shouldFail: true, 7466 expectedError: ":UNEXPECTED_EXTENSION:", 7467 expectedLocalError: "remote error: unsupported extension", 7468 }) 7469 7470 // Test server ignore wrong codepoint from client. 7471 clientSends := ALPSUseCodepointNew 7472 if alpsCodePoint == ALPSUseCodepointNew { 7473 clientSends = ALPSUseCodepointOld 7474 } 7475 7476 testCases = append(testCases, testCase{ 7477 protocol: protocol, 7478 testType: serverTest, 7479 name: fmt.Sprintf("ALPS-IgnoreClientWrongCodepoint-Server-%s-%s", alpsCodePoint, suffix), 7480 skipQUICALPNConfig: true, 7481 config: Config{ 7482 MaxVersion: ver.version, 7483 NextProtos: []string{"proto"}, 7484 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7485 ALPSUseNewCodepoint: clientSends, 7486 }, 7487 resumeConfig: &Config{ 7488 MaxVersion: ver.version, 7489 NextProtos: []string{"proto"}, 7490 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7491 ALPSUseNewCodepoint: clientSends, 7492 }, 7493 resumeSession: true, 7494 flags: append([]string{ 7495 "-select-alpn", "proto", 7496 "-on-initial-application-settings", "proto,shim1", 7497 "-on-resume-application-settings", "proto,shim2", 7498 }, alpsFlags...), 7499 }) 7500 7501 // Test the server declines ALPS if it doesn't support it for the 7502 // specified protocol. 7503 testCases = append(testCases, testCase{ 7504 protocol: protocol, 7505 testType: serverTest, 7506 name: fmt.Sprintf("ALPS-UnsupportedProtocol-Server-%s-%s", alpsCodePoint, suffix), 7507 skipQUICALPNConfig: true, 7508 config: Config{ 7509 MaxVersion: ver.version, 7510 NextProtos: []string{"proto1"}, 7511 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7512 ALPSUseNewCodepoint: alpsCodePoint, 7513 }, 7514 // The server supports ALPS with "proto2", but not "proto1". 7515 flags: append([]string{ 7516 "-select-alpn", "proto1", 7517 "-application-settings", "proto2,shim", 7518 }, alpsFlags...), 7519 }) 7520 7521 // Test the client rejects application settings from the server when 7522 // it always negotiate both codepoint. 7523 testCases = append(testCases, testCase{ 7524 protocol: protocol, 7525 testType: clientTest, 7526 name: fmt.Sprintf("ALPS-UnsupportedProtocol-Client-ServerBoth-%s-%s", alpsCodePoint, suffix), 7527 skipQUICALPNConfig: true, 7528 config: Config{ 7529 MaxVersion: ver.version, 7530 NextProtos: []string{"proto1"}, 7531 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7532 Bugs: ProtocolBugs{ 7533 AlwaysNegotiateApplicationSettingsBoth: true, 7534 }, 7535 ALPSUseNewCodepoint: alpsCodePoint, 7536 }, 7537 flags: append([]string{ 7538 "-advertise-alpn", "\x06proto1\x06proto2", 7539 "-application-settings", "proto1,shim", 7540 "-expect-alpn", "proto1", 7541 }, alpsFlags...), 7542 // The server sends ALPS with both application settings, which is invalid. 7543 shouldFail: true, 7544 expectedError: ":UNEXPECTED_EXTENSION:", 7545 expectedLocalError: "remote error: unsupported extension", 7546 }) 7547 7548 expectations = connectionExpectations{ 7549 peerApplicationSettingsOld: []byte("shim"), 7550 } 7551 if alpsCodePoint == ALPSUseCodepointNew { 7552 expectations = connectionExpectations{ 7553 peerApplicationSettings: []byte("shim"), 7554 } 7555 } 7556 7557 // Test that the server rejects a missing application_settings extension. 7558 testCases = append(testCases, testCase{ 7559 protocol: protocol, 7560 testType: serverTest, 7561 name: fmt.Sprintf("ALPS-OmitClientApplicationSettings-%s-%s", alpsCodePoint, suffix), 7562 skipQUICALPNConfig: true, 7563 config: Config{ 7564 MaxVersion: ver.version, 7565 NextProtos: []string{"proto"}, 7566 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7567 Bugs: ProtocolBugs{ 7568 OmitClientApplicationSettings: true, 7569 }, 7570 ALPSUseNewCodepoint: alpsCodePoint, 7571 }, 7572 flags: append([]string{ 7573 "-select-alpn", "proto", 7574 "-application-settings", "proto,shim", 7575 }, alpsFlags...), 7576 // The runner is a client, so it only processes the shim's alert 7577 // after checking connection state. 7578 expectations: expectations, 7579 shouldFail: true, 7580 expectedError: ":MISSING_EXTENSION:", 7581 expectedLocalError: "remote error: missing extension", 7582 }) 7583 7584 // Test that the server rejects a missing EncryptedExtensions message. 7585 testCases = append(testCases, testCase{ 7586 protocol: protocol, 7587 testType: serverTest, 7588 name: fmt.Sprintf("ALPS-OmitClientEncryptedExtensions-%s-%s", alpsCodePoint, suffix), 7589 skipQUICALPNConfig: true, 7590 config: Config{ 7591 MaxVersion: ver.version, 7592 NextProtos: []string{"proto"}, 7593 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7594 Bugs: ProtocolBugs{ 7595 OmitClientEncryptedExtensions: true, 7596 }, 7597 ALPSUseNewCodepoint: alpsCodePoint, 7598 }, 7599 flags: append([]string{ 7600 "-select-alpn", "proto", 7601 "-application-settings", "proto,shim", 7602 }, alpsFlags...), 7603 // The runner is a client, so it only processes the shim's alert 7604 // after checking connection state. 7605 expectations: expectations, 7606 shouldFail: true, 7607 expectedError: ":UNEXPECTED_MESSAGE:", 7608 expectedLocalError: "remote error: unexpected message", 7609 }) 7610 7611 // Test that the server rejects an unexpected EncryptedExtensions message. 7612 testCases = append(testCases, testCase{ 7613 protocol: protocol, 7614 testType: serverTest, 7615 name: fmt.Sprintf("UnexpectedClientEncryptedExtensions-%s-%s", alpsCodePoint, suffix), 7616 config: Config{ 7617 MaxVersion: ver.version, 7618 Bugs: ProtocolBugs{ 7619 AlwaysSendClientEncryptedExtensions: true, 7620 }, 7621 ALPSUseNewCodepoint: alpsCodePoint, 7622 }, 7623 shouldFail: true, 7624 expectedError: ":UNEXPECTED_MESSAGE:", 7625 expectedLocalError: "remote error: unexpected message", 7626 }) 7627 7628 // Test that the server rejects an unexpected extension in an 7629 // expected EncryptedExtensions message. 7630 testCases = append(testCases, testCase{ 7631 protocol: protocol, 7632 testType: serverTest, 7633 name: fmt.Sprintf("ExtraClientEncryptedExtension-%s-%s", alpsCodePoint, suffix), 7634 skipQUICALPNConfig: true, 7635 config: Config{ 7636 MaxVersion: ver.version, 7637 NextProtos: []string{"proto"}, 7638 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7639 Bugs: ProtocolBugs{ 7640 SendExtraClientEncryptedExtension: true, 7641 }, 7642 ALPSUseNewCodepoint: alpsCodePoint, 7643 }, 7644 flags: append([]string{ 7645 "-select-alpn", "proto", 7646 "-application-settings", "proto,shim", 7647 }, alpsFlags...), 7648 // The runner is a client, so it only processes the shim's alert 7649 // after checking connection state. 7650 expectations: expectations, 7651 shouldFail: true, 7652 expectedError: ":UNEXPECTED_EXTENSION:", 7653 expectedLocalError: "remote error: unsupported extension", 7654 }) 7655 7656 // Test that ALPS is carried over on 0-RTT. 7657 for _, empty := range []bool{false, true} { 7658 maybeEmpty := "" 7659 runnerSettings := "runner" 7660 shimSettings := "shim" 7661 if empty { 7662 maybeEmpty = "Empty-" 7663 runnerSettings = "" 7664 shimSettings = "" 7665 } 7666 7667 expectations = connectionExpectations{ 7668 peerApplicationSettingsOld: []byte(shimSettings), 7669 } 7670 if alpsCodePoint == ALPSUseCodepointNew { 7671 expectations = connectionExpectations{ 7672 peerApplicationSettings: []byte(shimSettings), 7673 } 7674 } 7675 testCases = append(testCases, testCase{ 7676 protocol: protocol, 7677 testType: clientTest, 7678 name: fmt.Sprintf("ALPS-EarlyData-Client-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7679 skipQUICALPNConfig: true, 7680 config: Config{ 7681 MaxVersion: ver.version, 7682 NextProtos: []string{"proto"}, 7683 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7684 ALPSUseNewCodepoint: alpsCodePoint, 7685 }, 7686 resumeSession: true, 7687 earlyData: true, 7688 flags: append([]string{ 7689 "-advertise-alpn", "\x05proto", 7690 "-expect-alpn", "proto", 7691 "-application-settings", "proto," + shimSettings, 7692 "-expect-peer-application-settings", runnerSettings, 7693 }, alpsFlags...), 7694 expectations: expectations, 7695 }) 7696 testCases = append(testCases, testCase{ 7697 protocol: protocol, 7698 testType: serverTest, 7699 name: fmt.Sprintf("ALPS-EarlyData-Server-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7700 skipQUICALPNConfig: true, 7701 config: Config{ 7702 MaxVersion: ver.version, 7703 NextProtos: []string{"proto"}, 7704 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7705 ALPSUseNewCodepoint: alpsCodePoint, 7706 }, 7707 resumeSession: true, 7708 earlyData: true, 7709 flags: append([]string{ 7710 "-select-alpn", "proto", 7711 "-application-settings", "proto," + shimSettings, 7712 "-expect-peer-application-settings", runnerSettings, 7713 }, alpsFlags...), 7714 expectations: expectations, 7715 }) 7716 7717 // Sending application settings in 0-RTT handshakes is forbidden. 7718 testCases = append(testCases, testCase{ 7719 protocol: protocol, 7720 testType: clientTest, 7721 name: fmt.Sprintf("ALPS-EarlyData-SendApplicationSettingsWithEarlyData-Client-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7722 skipQUICALPNConfig: true, 7723 config: Config{ 7724 MaxVersion: ver.version, 7725 NextProtos: []string{"proto"}, 7726 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7727 Bugs: ProtocolBugs{ 7728 SendApplicationSettingsWithEarlyData: true, 7729 }, 7730 ALPSUseNewCodepoint: alpsCodePoint, 7731 }, 7732 resumeSession: true, 7733 earlyData: true, 7734 flags: append([]string{ 7735 "-advertise-alpn", "\x05proto", 7736 "-expect-alpn", "proto", 7737 "-application-settings", "proto," + shimSettings, 7738 "-expect-peer-application-settings", runnerSettings, 7739 }, alpsFlags...), 7740 expectations: expectations, 7741 shouldFail: true, 7742 expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:", 7743 expectedLocalError: "remote error: illegal parameter", 7744 }) 7745 testCases = append(testCases, testCase{ 7746 protocol: protocol, 7747 testType: serverTest, 7748 name: fmt.Sprintf("ALPS-EarlyData-SendApplicationSettingsWithEarlyData-Server-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7749 skipQUICALPNConfig: true, 7750 config: Config{ 7751 MaxVersion: ver.version, 7752 NextProtos: []string{"proto"}, 7753 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7754 Bugs: ProtocolBugs{ 7755 SendApplicationSettingsWithEarlyData: true, 7756 }, 7757 ALPSUseNewCodepoint: alpsCodePoint, 7758 }, 7759 resumeSession: true, 7760 earlyData: true, 7761 flags: append([]string{ 7762 "-select-alpn", "proto", 7763 "-application-settings", "proto," + shimSettings, 7764 "-expect-peer-application-settings", runnerSettings, 7765 }, alpsFlags...), 7766 expectations: expectations, 7767 shouldFail: true, 7768 expectedError: ":UNEXPECTED_MESSAGE:", 7769 expectedLocalError: "remote error: unexpected message", 7770 }) 7771 } 7772 7773 // Test that the client and server each decline early data if local 7774 // ALPS preferences has changed for the current connection. 7775 alpsMismatchTests := []struct { 7776 name string 7777 initialSettings, resumeSettings []byte 7778 }{ 7779 {"DifferentValues", []byte("settings1"), []byte("settings2")}, 7780 {"OnOff", []byte("settings"), nil}, 7781 {"OffOn", nil, []byte("settings")}, 7782 // The empty settings value should not be mistaken for ALPS not 7783 // being negotiated. 7784 {"OnEmpty", []byte("settings"), []byte{}}, 7785 {"EmptyOn", []byte{}, []byte("settings")}, 7786 {"EmptyOff", []byte{}, nil}, 7787 {"OffEmpty", nil, []byte{}}, 7788 } 7789 for _, test := range alpsMismatchTests { 7790 flags := []string{"-on-resume-expect-early-data-reason", "alps_mismatch"} 7791 flags = append(flags, alpsFlags...) 7792 if test.initialSettings != nil { 7793 flags = append(flags, "-on-initial-application-settings", "proto,"+string(test.initialSettings)) 7794 flags = append(flags, "-on-initial-expect-peer-application-settings", "runner") 7795 } 7796 if test.resumeSettings != nil { 7797 flags = append(flags, "-on-resume-application-settings", "proto,"+string(test.resumeSettings)) 7798 flags = append(flags, "-on-resume-expect-peer-application-settings", "runner") 7799 } 7800 7801 expectations = connectionExpectations{ 7802 peerApplicationSettingsOld: test.initialSettings, 7803 } 7804 resumeExpectations = &connectionExpectations{ 7805 peerApplicationSettingsOld: test.resumeSettings, 7806 } 7807 if alpsCodePoint == ALPSUseCodepointNew { 7808 expectations = connectionExpectations{ 7809 peerApplicationSettings: test.initialSettings, 7810 } 7811 resumeExpectations = &connectionExpectations{ 7812 peerApplicationSettings: test.resumeSettings, 7813 } 7814 } 7815 // The client should not offer early data if the session is 7816 // inconsistent with the new configuration. Note that if 7817 // the session did not negotiate ALPS (test.initialSettings 7818 // is nil), the client always offers early data. 7819 if test.initialSettings != nil { 7820 testCases = append(testCases, testCase{ 7821 protocol: protocol, 7822 testType: clientTest, 7823 name: fmt.Sprintf("ALPS-EarlyData-Mismatch-%s-Client-%s-%s", test.name, alpsCodePoint, suffix), 7824 skipQUICALPNConfig: true, 7825 config: Config{ 7826 MaxVersion: ver.version, 7827 MaxEarlyDataSize: 16384, 7828 NextProtos: []string{"proto"}, 7829 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7830 ALPSUseNewCodepoint: alpsCodePoint, 7831 }, 7832 resumeSession: true, 7833 flags: append([]string{ 7834 "-enable-early-data", 7835 "-expect-ticket-supports-early-data", 7836 "-expect-no-offer-early-data", 7837 "-advertise-alpn", "\x05proto", 7838 "-expect-alpn", "proto", 7839 }, flags...), 7840 expectations: expectations, 7841 resumeExpectations: resumeExpectations, 7842 }) 7843 } 7844 7845 // The server should reject early data if the session is 7846 // inconsistent with the new selection. 7847 testCases = append(testCases, testCase{ 7848 protocol: protocol, 7849 testType: serverTest, 7850 name: fmt.Sprintf("ALPS-EarlyData-Mismatch-%s-Server-%s-%s", test.name, alpsCodePoint, suffix), 7851 skipQUICALPNConfig: true, 7852 config: Config{ 7853 MaxVersion: ver.version, 7854 NextProtos: []string{"proto"}, 7855 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7856 ALPSUseNewCodepoint: alpsCodePoint, 7857 }, 7858 resumeSession: true, 7859 earlyData: true, 7860 expectEarlyDataRejected: true, 7861 flags: append([]string{ 7862 "-select-alpn", "proto", 7863 }, flags...), 7864 expectations: expectations, 7865 resumeExpectations: resumeExpectations, 7866 }) 7867 } 7868 7869 // Test that 0-RTT continues working when the shim configures 7870 // ALPS but the peer does not. 7871 testCases = append(testCases, testCase{ 7872 protocol: protocol, 7873 testType: clientTest, 7874 name: fmt.Sprintf("ALPS-EarlyData-Client-ServerDecline-%s-%s", alpsCodePoint, suffix), 7875 skipQUICALPNConfig: true, 7876 config: Config{ 7877 MaxVersion: ver.version, 7878 NextProtos: []string{"proto"}, 7879 ALPSUseNewCodepoint: alpsCodePoint, 7880 }, 7881 resumeSession: true, 7882 earlyData: true, 7883 flags: append([]string{ 7884 "-advertise-alpn", "\x05proto", 7885 "-expect-alpn", "proto", 7886 "-application-settings", "proto,shim", 7887 }, alpsFlags...), 7888 }) 7889 testCases = append(testCases, testCase{ 7890 protocol: protocol, 7891 testType: serverTest, 7892 name: fmt.Sprintf("ALPS-EarlyData-Server-ClientNoOffe-%s-%s", alpsCodePoint, suffix), 7893 skipQUICALPNConfig: true, 7894 config: Config{ 7895 MaxVersion: ver.version, 7896 NextProtos: []string{"proto"}, 7897 ALPSUseNewCodepoint: alpsCodePoint, 7898 }, 7899 resumeSession: true, 7900 earlyData: true, 7901 flags: append([]string{ 7902 "-select-alpn", "proto", 7903 "-application-settings", "proto,shim", 7904 }, alpsFlags...), 7905 }) 7906 } 7907 } else { 7908 // Test the client rejects the ALPS extension if the server 7909 // negotiated TLS 1.2 or below. 7910 for _, alpsCodePoint := range []ALPSUseCodepoint{ALPSUseCodepointNew, ALPSUseCodepointOld} { 7911 flags := []string{ 7912 "-advertise-alpn", "\x03foo", 7913 "-expect-alpn", "foo", 7914 "-application-settings", "foo,shim", 7915 } 7916 bugs := ProtocolBugs{ 7917 AlwaysNegotiateApplicationSettingsOld: true, 7918 } 7919 if alpsCodePoint == ALPSUseCodepointNew { 7920 flags = append(flags, "-alps-use-new-codepoint") 7921 bugs = ProtocolBugs{ 7922 AlwaysNegotiateApplicationSettingsNew: true, 7923 } 7924 } 7925 testCases = append(testCases, testCase{ 7926 protocol: protocol, 7927 testType: clientTest, 7928 name: fmt.Sprintf("ALPS-Reject-Client-%s-%s", alpsCodePoint, suffix), 7929 config: Config{ 7930 MaxVersion: ver.version, 7931 NextProtos: []string{"foo"}, 7932 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 7933 Bugs: bugs, 7934 ALPSUseNewCodepoint: alpsCodePoint, 7935 }, 7936 flags: flags, 7937 shouldFail: true, 7938 expectedError: ":UNEXPECTED_EXTENSION:", 7939 expectedLocalError: "remote error: unsupported extension", 7940 }) 7941 7942 flags = []string{ 7943 "-on-resume-advertise-alpn", "\x03foo", 7944 "-on-resume-expect-alpn", "foo", 7945 "-on-resume-application-settings", "foo,shim", 7946 } 7947 bugs = ProtocolBugs{ 7948 AlwaysNegotiateApplicationSettingsOld: true, 7949 } 7950 if alpsCodePoint == ALPSUseCodepointNew { 7951 flags = append(flags, "-alps-use-new-codepoint") 7952 bugs = ProtocolBugs{ 7953 AlwaysNegotiateApplicationSettingsNew: true, 7954 } 7955 } 7956 testCases = append(testCases, testCase{ 7957 protocol: protocol, 7958 testType: clientTest, 7959 name: fmt.Sprintf("ALPS-Reject-Client-Resume-%s-%s", alpsCodePoint, suffix), 7960 config: Config{ 7961 MaxVersion: ver.version, 7962 }, 7963 resumeConfig: &Config{ 7964 MaxVersion: ver.version, 7965 NextProtos: []string{"foo"}, 7966 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 7967 Bugs: bugs, 7968 ALPSUseNewCodepoint: alpsCodePoint, 7969 }, 7970 resumeSession: true, 7971 flags: flags, 7972 shouldFail: true, 7973 expectedError: ":UNEXPECTED_EXTENSION:", 7974 expectedLocalError: "remote error: unsupported extension", 7975 }) 7976 7977 // Test the server declines ALPS if it negotiates TLS 1.2 or below. 7978 flags = []string{ 7979 "-select-alpn", "foo", 7980 "-application-settings", "foo,shim", 7981 } 7982 if alpsCodePoint == ALPSUseCodepointNew { 7983 flags = append(flags, "-alps-use-new-codepoint") 7984 } 7985 testCases = append(testCases, testCase{ 7986 protocol: protocol, 7987 testType: serverTest, 7988 name: fmt.Sprintf("ALPS-Decline-Server-%s-%s", alpsCodePoint, suffix), 7989 config: Config{ 7990 MaxVersion: ver.version, 7991 NextProtos: []string{"foo"}, 7992 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 7993 ALPSUseNewCodepoint: alpsCodePoint, 7994 }, 7995 // Test both TLS 1.2 full and resumption handshakes. 7996 resumeSession: true, 7997 flags: flags, 7998 // If not specified, runner and shim both implicitly expect ALPS 7999 // is not negotiated. 8000 }) 8001 } 8002 } 8003 8004 // Test QUIC transport params 8005 if protocol == quic { 8006 // Client sends params 8007 for _, clientConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8008 for _, serverSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 8009 useCodepointFlag := "0" 8010 if clientConfig == QUICUseCodepointLegacy { 8011 useCodepointFlag = "1" 8012 } 8013 flags := []string{ 8014 "-quic-transport-params", 8015 base64FlagValue([]byte{1, 2}), 8016 "-quic-use-legacy-codepoint", useCodepointFlag, 8017 } 8018 expectations := connectionExpectations{ 8019 quicTransportParams: []byte{1, 2}, 8020 } 8021 shouldFail := false 8022 expectedError := "" 8023 expectedLocalError := "" 8024 if clientConfig == QUICUseCodepointLegacy { 8025 expectations = connectionExpectations{ 8026 quicTransportParamsLegacy: []byte{1, 2}, 8027 } 8028 } 8029 if serverSends != clientConfig { 8030 expectations = connectionExpectations{} 8031 shouldFail = true 8032 if serverSends == QUICUseCodepointNeither { 8033 expectedError = ":MISSING_EXTENSION:" 8034 } else { 8035 expectedLocalError = "remote error: unsupported extension" 8036 } 8037 } else { 8038 flags = append(flags, 8039 "-expect-quic-transport-params", 8040 base64FlagValue([]byte{3, 4})) 8041 } 8042 testCases = append(testCases, testCase{ 8043 testType: clientTest, 8044 protocol: protocol, 8045 name: fmt.Sprintf("QUICTransportParams-Client-Client%s-Server%s-%s", clientConfig, serverSends, suffix), 8046 config: Config{ 8047 MinVersion: ver.version, 8048 MaxVersion: ver.version, 8049 QUICTransportParams: []byte{3, 4}, 8050 QUICTransportParamsUseLegacyCodepoint: serverSends, 8051 }, 8052 flags: flags, 8053 expectations: expectations, 8054 shouldFail: shouldFail, 8055 expectedError: expectedError, 8056 expectedLocalError: expectedLocalError, 8057 skipTransportParamsConfig: true, 8058 }) 8059 } 8060 } 8061 // Server sends params 8062 for _, clientSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 8063 for _, serverConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8064 expectations := connectionExpectations{ 8065 quicTransportParams: []byte{3, 4}, 8066 } 8067 shouldFail := false 8068 expectedError := "" 8069 useCodepointFlag := "0" 8070 if serverConfig == QUICUseCodepointLegacy { 8071 useCodepointFlag = "1" 8072 expectations = connectionExpectations{ 8073 quicTransportParamsLegacy: []byte{3, 4}, 8074 } 8075 } 8076 flags := []string{ 8077 "-quic-transport-params", 8078 base64FlagValue([]byte{3, 4}), 8079 "-quic-use-legacy-codepoint", useCodepointFlag, 8080 } 8081 if clientSends != QUICUseCodepointBoth && clientSends != serverConfig { 8082 expectations = connectionExpectations{} 8083 shouldFail = true 8084 expectedError = ":MISSING_EXTENSION:" 8085 } else { 8086 flags = append(flags, 8087 "-expect-quic-transport-params", 8088 base64FlagValue([]byte{1, 2}), 8089 ) 8090 } 8091 testCases = append(testCases, testCase{ 8092 testType: serverTest, 8093 protocol: protocol, 8094 name: fmt.Sprintf("QUICTransportParams-Server-Client%s-Server%s-%s", clientSends, serverConfig, suffix), 8095 config: Config{ 8096 MinVersion: ver.version, 8097 MaxVersion: ver.version, 8098 QUICTransportParams: []byte{1, 2}, 8099 QUICTransportParamsUseLegacyCodepoint: clientSends, 8100 }, 8101 flags: flags, 8102 expectations: expectations, 8103 shouldFail: shouldFail, 8104 expectedError: expectedError, 8105 skipTransportParamsConfig: true, 8106 }) 8107 } 8108 } 8109 } else { 8110 // Ensure non-QUIC client doesn't send QUIC transport parameters. 8111 for _, clientConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8112 useCodepointFlag := "0" 8113 if clientConfig == QUICUseCodepointLegacy { 8114 useCodepointFlag = "1" 8115 } 8116 testCases = append(testCases, testCase{ 8117 protocol: protocol, 8118 testType: clientTest, 8119 name: fmt.Sprintf("QUICTransportParams-Client-NotSentInNonQUIC-%s-%s", clientConfig, suffix), 8120 config: Config{ 8121 MinVersion: ver.version, 8122 MaxVersion: ver.version, 8123 QUICTransportParamsUseLegacyCodepoint: clientConfig, 8124 }, 8125 flags: []string{ 8126 "-max-version", 8127 strconv.Itoa(int(ver.versionWire)), 8128 "-quic-transport-params", 8129 base64FlagValue([]byte{3, 4}), 8130 "-quic-use-legacy-codepoint", useCodepointFlag, 8131 }, 8132 shouldFail: true, 8133 expectedError: ":QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED:", 8134 skipTransportParamsConfig: true, 8135 }) 8136 } 8137 // Ensure non-QUIC server rejects codepoint 57 but ignores legacy 0xffa5. 8138 for _, clientSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 8139 for _, serverConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8140 shouldFail := false 8141 expectedLocalError := "" 8142 useCodepointFlag := "0" 8143 if serverConfig == QUICUseCodepointLegacy { 8144 useCodepointFlag = "1" 8145 } 8146 if clientSends == QUICUseCodepointStandard || clientSends == QUICUseCodepointBoth { 8147 shouldFail = true 8148 expectedLocalError = "remote error: unsupported extension" 8149 } 8150 testCases = append(testCases, testCase{ 8151 protocol: protocol, 8152 testType: serverTest, 8153 name: fmt.Sprintf("QUICTransportParams-NonQUICServer-Client%s-Server%s-%s", clientSends, serverConfig, suffix), 8154 config: Config{ 8155 MinVersion: ver.version, 8156 MaxVersion: ver.version, 8157 QUICTransportParams: []byte{1, 2}, 8158 QUICTransportParamsUseLegacyCodepoint: clientSends, 8159 }, 8160 flags: []string{ 8161 "-quic-use-legacy-codepoint", useCodepointFlag, 8162 }, 8163 shouldFail: shouldFail, 8164 expectedLocalError: expectedLocalError, 8165 skipTransportParamsConfig: true, 8166 }) 8167 } 8168 } 8169 8170 } 8171 8172 // Test ticket behavior. 8173 8174 // Resume with a corrupt ticket. 8175 testCases = append(testCases, testCase{ 8176 protocol: protocol, 8177 testType: serverTest, 8178 name: "CorruptTicket-" + suffix, 8179 config: Config{ 8180 MaxVersion: ver.version, 8181 Bugs: ProtocolBugs{ 8182 FilterTicket: func(in []byte) ([]byte, error) { 8183 in[len(in)-1] ^= 1 8184 return in, nil 8185 }, 8186 }, 8187 }, 8188 resumeSession: true, 8189 expectResumeRejected: true, 8190 }) 8191 // Test the ticket callback, with and without renewal. 8192 testCases = append(testCases, testCase{ 8193 protocol: protocol, 8194 testType: serverTest, 8195 name: "TicketCallback-" + suffix, 8196 config: Config{ 8197 MaxVersion: ver.version, 8198 }, 8199 resumeSession: true, 8200 flags: []string{"-use-ticket-callback"}, 8201 }) 8202 testCases = append(testCases, testCase{ 8203 protocol: protocol, 8204 testType: serverTest, 8205 name: "TicketCallback-Renew-" + suffix, 8206 config: Config{ 8207 MaxVersion: ver.version, 8208 Bugs: ProtocolBugs{ 8209 ExpectNewTicket: true, 8210 }, 8211 }, 8212 flags: []string{"-use-ticket-callback", "-renew-ticket"}, 8213 resumeSession: true, 8214 }) 8215 8216 // Test that the ticket callback is only called once when everything before 8217 // it in the ClientHello is asynchronous. This corrupts the ticket so 8218 // certificate selection callbacks run. 8219 testCases = append(testCases, testCase{ 8220 protocol: protocol, 8221 testType: serverTest, 8222 name: "TicketCallback-SingleCall-" + suffix, 8223 config: Config{ 8224 MaxVersion: ver.version, 8225 Bugs: ProtocolBugs{ 8226 FilterTicket: func(in []byte) ([]byte, error) { 8227 in[len(in)-1] ^= 1 8228 return in, nil 8229 }, 8230 }, 8231 }, 8232 resumeSession: true, 8233 expectResumeRejected: true, 8234 flags: []string{ 8235 "-use-ticket-callback", 8236 "-async", 8237 }, 8238 }) 8239 8240 // Resume with various lengths of ticket session id. 8241 if ver.version < VersionTLS13 { 8242 testCases = append(testCases, testCase{ 8243 protocol: protocol, 8244 testType: serverTest, 8245 name: "TicketSessionIDLength-0-" + suffix, 8246 config: Config{ 8247 MaxVersion: ver.version, 8248 Bugs: ProtocolBugs{ 8249 EmptyTicketSessionID: true, 8250 }, 8251 }, 8252 resumeSession: true, 8253 }) 8254 testCases = append(testCases, testCase{ 8255 protocol: protocol, 8256 testType: serverTest, 8257 name: "TicketSessionIDLength-16-" + suffix, 8258 config: Config{ 8259 MaxVersion: ver.version, 8260 Bugs: ProtocolBugs{ 8261 TicketSessionIDLength: 16, 8262 }, 8263 }, 8264 resumeSession: true, 8265 }) 8266 testCases = append(testCases, testCase{ 8267 protocol: protocol, 8268 testType: serverTest, 8269 name: "TicketSessionIDLength-32-" + suffix, 8270 config: Config{ 8271 MaxVersion: ver.version, 8272 Bugs: ProtocolBugs{ 8273 TicketSessionIDLength: 32, 8274 }, 8275 }, 8276 resumeSession: true, 8277 }) 8278 testCases = append(testCases, testCase{ 8279 protocol: protocol, 8280 testType: serverTest, 8281 name: "TicketSessionIDLength-33-" + suffix, 8282 config: Config{ 8283 MaxVersion: ver.version, 8284 Bugs: ProtocolBugs{ 8285 TicketSessionIDLength: 33, 8286 }, 8287 }, 8288 resumeSession: true, 8289 shouldFail: true, 8290 // The maximum session ID length is 32. 8291 expectedError: ":DECODE_ERROR:", 8292 }) 8293 } 8294 8295 // Basic DTLS-SRTP tests. Include fake profiles to ensure they 8296 // are ignored. 8297 if protocol == dtls { 8298 testCases = append(testCases, testCase{ 8299 protocol: protocol, 8300 name: "SRTP-Client-" + suffix, 8301 config: Config{ 8302 MaxVersion: ver.version, 8303 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8304 }, 8305 flags: []string{ 8306 "-srtp-profiles", 8307 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8308 }, 8309 expectations: connectionExpectations{ 8310 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8311 }, 8312 }) 8313 testCases = append(testCases, testCase{ 8314 protocol: protocol, 8315 testType: serverTest, 8316 name: "SRTP-Server-" + suffix, 8317 config: Config{ 8318 MaxVersion: ver.version, 8319 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8320 }, 8321 flags: []string{ 8322 "-srtp-profiles", 8323 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8324 }, 8325 expectations: connectionExpectations{ 8326 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8327 }, 8328 }) 8329 // Test that the MKI is ignored. 8330 testCases = append(testCases, testCase{ 8331 protocol: protocol, 8332 testType: serverTest, 8333 name: "SRTP-Server-IgnoreMKI-" + suffix, 8334 config: Config{ 8335 MaxVersion: ver.version, 8336 SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80}, 8337 Bugs: ProtocolBugs{ 8338 SRTPMasterKeyIdentifer: "bogus", 8339 }, 8340 }, 8341 flags: []string{ 8342 "-srtp-profiles", 8343 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8344 }, 8345 expectations: connectionExpectations{ 8346 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8347 }, 8348 }) 8349 // Test that SRTP isn't negotiated on the server if there were 8350 // no matching profiles. 8351 testCases = append(testCases, testCase{ 8352 protocol: protocol, 8353 testType: serverTest, 8354 name: "SRTP-Server-NoMatch-" + suffix, 8355 config: Config{ 8356 MaxVersion: ver.version, 8357 SRTPProtectionProfiles: []uint16{100, 101, 102}, 8358 }, 8359 flags: []string{ 8360 "-srtp-profiles", 8361 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8362 }, 8363 expectations: connectionExpectations{ 8364 srtpProtectionProfile: 0, 8365 }, 8366 }) 8367 // Test that the server returning an invalid SRTP profile is 8368 // flagged as an error by the client. 8369 testCases = append(testCases, testCase{ 8370 protocol: protocol, 8371 name: "SRTP-Client-NoMatch-" + suffix, 8372 config: Config{ 8373 MaxVersion: ver.version, 8374 Bugs: ProtocolBugs{ 8375 SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32, 8376 }, 8377 }, 8378 flags: []string{ 8379 "-srtp-profiles", 8380 "SRTP_AES128_CM_SHA1_80", 8381 }, 8382 shouldFail: true, 8383 expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:", 8384 }) 8385 } else { 8386 // DTLS-SRTP is not defined for other protocols. Configuring it 8387 // on the client and server should ignore the extension. 8388 testCases = append(testCases, testCase{ 8389 protocol: protocol, 8390 name: "SRTP-Client-Ignore-" + suffix, 8391 config: Config{ 8392 MaxVersion: ver.version, 8393 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8394 }, 8395 flags: []string{ 8396 "-srtp-profiles", 8397 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8398 }, 8399 expectations: connectionExpectations{ 8400 srtpProtectionProfile: 0, 8401 }, 8402 }) 8403 testCases = append(testCases, testCase{ 8404 protocol: protocol, 8405 testType: serverTest, 8406 name: "SRTP-Server-Ignore-" + suffix, 8407 config: Config{ 8408 MaxVersion: ver.version, 8409 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8410 }, 8411 flags: []string{ 8412 "-srtp-profiles", 8413 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8414 }, 8415 expectations: connectionExpectations{ 8416 srtpProtectionProfile: 0, 8417 }, 8418 }) 8419 } 8420 8421 // Test SCT list. 8422 testCases = append(testCases, testCase{ 8423 protocol: protocol, 8424 name: "SignedCertificateTimestampList-Client-" + suffix, 8425 testType: clientTest, 8426 config: Config{ 8427 MaxVersion: ver.version, 8428 }, 8429 flags: []string{ 8430 "-enable-signed-cert-timestamps", 8431 "-expect-signed-cert-timestamps", 8432 base64FlagValue(testSCTList), 8433 }, 8434 resumeSession: true, 8435 }) 8436 8437 var differentSCTList []byte 8438 differentSCTList = append(differentSCTList, testSCTList...) 8439 differentSCTList[len(differentSCTList)-1] ^= 1 8440 8441 // The SCT extension did not specify that it must only be sent on resumption as it 8442 // should have, so test that we tolerate but ignore it. 8443 testCases = append(testCases, testCase{ 8444 protocol: protocol, 8445 name: "SendSCTListOnResume-" + suffix, 8446 config: Config{ 8447 MaxVersion: ver.version, 8448 Bugs: ProtocolBugs{ 8449 SendSCTListOnResume: differentSCTList, 8450 }, 8451 }, 8452 flags: []string{ 8453 "-enable-signed-cert-timestamps", 8454 "-expect-signed-cert-timestamps", 8455 base64FlagValue(testSCTList), 8456 }, 8457 resumeSession: true, 8458 }) 8459 8460 testCases = append(testCases, testCase{ 8461 protocol: protocol, 8462 name: "SignedCertificateTimestampList-Server-" + suffix, 8463 testType: serverTest, 8464 config: Config{ 8465 MaxVersion: ver.version, 8466 }, 8467 flags: []string{ 8468 "-signed-cert-timestamps", 8469 base64FlagValue(testSCTList), 8470 }, 8471 expectations: connectionExpectations{ 8472 sctList: testSCTList, 8473 }, 8474 resumeSession: true, 8475 }) 8476 8477 emptySCTListCert := *testCerts[0].cert 8478 emptySCTListCert.SignedCertificateTimestampList = []byte{0, 0} 8479 8480 // Test empty SCT list. 8481 testCases = append(testCases, testCase{ 8482 protocol: protocol, 8483 name: "SignedCertificateTimestampListEmpty-Client-" + suffix, 8484 testType: clientTest, 8485 config: Config{ 8486 MaxVersion: ver.version, 8487 Certificates: []Certificate{emptySCTListCert}, 8488 }, 8489 flags: []string{ 8490 "-enable-signed-cert-timestamps", 8491 }, 8492 shouldFail: true, 8493 expectedError: ":ERROR_PARSING_EXTENSION:", 8494 }) 8495 8496 emptySCTCert := *testCerts[0].cert 8497 emptySCTCert.SignedCertificateTimestampList = []byte{0, 6, 0, 2, 1, 2, 0, 0} 8498 8499 // Test empty SCT in non-empty list. 8500 testCases = append(testCases, testCase{ 8501 protocol: protocol, 8502 name: "SignedCertificateTimestampListEmptySCT-Client-" + suffix, 8503 testType: clientTest, 8504 config: Config{ 8505 MaxVersion: ver.version, 8506 Certificates: []Certificate{emptySCTCert}, 8507 }, 8508 flags: []string{ 8509 "-enable-signed-cert-timestamps", 8510 }, 8511 shouldFail: true, 8512 expectedError: ":ERROR_PARSING_EXTENSION:", 8513 }) 8514 8515 // Test that certificate-related extensions are not sent unsolicited. 8516 testCases = append(testCases, testCase{ 8517 protocol: protocol, 8518 testType: serverTest, 8519 name: "UnsolicitedCertificateExtensions-" + suffix, 8520 config: Config{ 8521 MaxVersion: ver.version, 8522 Bugs: ProtocolBugs{ 8523 NoOCSPStapling: true, 8524 NoSignedCertificateTimestamps: true, 8525 }, 8526 }, 8527 flags: []string{ 8528 "-ocsp-response", 8529 base64FlagValue(testOCSPResponse), 8530 "-signed-cert-timestamps", 8531 base64FlagValue(testSCTList), 8532 }, 8533 }) 8534 8535 // Extension permutation should interact correctly with other extensions, 8536 // HelloVerifyRequest, HelloRetryRequest, and ECH. SSLTest.PermuteExtensions 8537 // in ssl_test.cc tests that the extensions are actually permuted. This 8538 // tests the handshake still works. 8539 // 8540 // This test also tests that all our extensions interact with each other. 8541 for _, ech := range []bool{false, true} { 8542 if ech && ver.version < VersionTLS13 { 8543 continue 8544 } 8545 8546 test := testCase{ 8547 protocol: protocol, 8548 name: "AllExtensions-Client-Permute", 8549 skipQUICALPNConfig: true, 8550 config: Config{ 8551 MinVersion: ver.version, 8552 MaxVersion: ver.version, 8553 NextProtos: []string{"proto"}, 8554 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 8555 Bugs: ProtocolBugs{ 8556 SendServerNameAck: true, 8557 ExpectServerName: "example.com", 8558 ExpectGREASE: true, 8559 }, 8560 }, 8561 resumeSession: true, 8562 flags: []string{ 8563 "-permute-extensions", 8564 "-enable-grease", 8565 "-enable-ocsp-stapling", 8566 "-enable-signed-cert-timestamps", 8567 "-advertise-alpn", "\x05proto", 8568 "-expect-alpn", "proto", 8569 "-host-name", "example.com", 8570 }, 8571 } 8572 8573 if ech { 8574 test.name += "-ECH" 8575 echConfig := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 8576 test.config.ServerECHConfigs = []ServerECHConfig{echConfig} 8577 test.flags = append(test.flags, 8578 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 8579 "-expect-ech-accept", 8580 ) 8581 test.expectations.echAccepted = true 8582 } 8583 8584 if ver.version >= VersionTLS13 { 8585 // Trigger a HelloRetryRequest to test both ClientHellos. Note 8586 // our DTLS tests always enable HelloVerifyRequest. 8587 test.name += "-HelloRetryRequest" 8588 8589 // ALPS is only available on TLS 1.3. 8590 test.config.ApplicationSettings = map[string][]byte{"proto": []byte("runner")} 8591 test.flags = append(test.flags, 8592 "-application-settings", "proto,shim", 8593 "-alps-use-new-codepoint", 8594 "-expect-peer-application-settings", "runner") 8595 test.expectations.peerApplicationSettings = []byte("shim") 8596 } 8597 8598 if protocol == dtls { 8599 test.config.SRTPProtectionProfiles = []uint16{SRTP_AES128_CM_HMAC_SHA1_80} 8600 test.flags = append(test.flags, "-srtp-profiles", "SRTP_AES128_CM_SHA1_80") 8601 test.expectations.srtpProtectionProfile = SRTP_AES128_CM_HMAC_SHA1_80 8602 } 8603 8604 test.name += "-" + suffix 8605 testCases = append(testCases, test) 8606 } 8607 } 8608 } 8609 8610 testCases = append(testCases, testCase{ 8611 testType: clientTest, 8612 name: "ClientHelloPadding", 8613 config: Config{ 8614 Bugs: ProtocolBugs{ 8615 RequireClientHelloSize: 512, 8616 }, 8617 }, 8618 // This hostname just needs to be long enough to push the 8619 // ClientHello into F5's danger zone between 256 and 511 bytes 8620 // long. 8621 flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"}, 8622 }) 8623 8624 // Test that illegal extensions in TLS 1.3 are rejected by the client if 8625 // in ServerHello. 8626 testCases = append(testCases, testCase{ 8627 name: "NPN-Forbidden-TLS13", 8628 config: Config{ 8629 MaxVersion: VersionTLS13, 8630 NextProtos: []string{"foo"}, 8631 Bugs: ProtocolBugs{ 8632 NegotiateNPNAtAllVersions: true, 8633 }, 8634 }, 8635 flags: []string{"-select-next-proto", "foo"}, 8636 shouldFail: true, 8637 expectedError: ":ERROR_PARSING_EXTENSION:", 8638 }) 8639 testCases = append(testCases, testCase{ 8640 name: "EMS-Forbidden-TLS13", 8641 config: Config{ 8642 MaxVersion: VersionTLS13, 8643 Bugs: ProtocolBugs{ 8644 NegotiateEMSAtAllVersions: true, 8645 }, 8646 }, 8647 shouldFail: true, 8648 expectedError: ":ERROR_PARSING_EXTENSION:", 8649 }) 8650 testCases = append(testCases, testCase{ 8651 name: "RenegotiationInfo-Forbidden-TLS13", 8652 config: Config{ 8653 MaxVersion: VersionTLS13, 8654 Bugs: ProtocolBugs{ 8655 NegotiateRenegotiationInfoAtAllVersions: true, 8656 }, 8657 }, 8658 shouldFail: true, 8659 expectedError: ":ERROR_PARSING_EXTENSION:", 8660 }) 8661 testCases = append(testCases, testCase{ 8662 name: "Ticket-Forbidden-TLS13", 8663 config: Config{ 8664 MaxVersion: VersionTLS12, 8665 }, 8666 resumeConfig: &Config{ 8667 MaxVersion: VersionTLS13, 8668 Bugs: ProtocolBugs{ 8669 AdvertiseTicketExtension: true, 8670 }, 8671 }, 8672 resumeSession: true, 8673 shouldFail: true, 8674 expectedError: ":ERROR_PARSING_EXTENSION:", 8675 }) 8676 8677 // Test that illegal extensions in TLS 1.3 are declined by the server if 8678 // offered in ClientHello. The runner's server will fail if this occurs, 8679 // so we exercise the offering path. (EMS and Renegotiation Info are 8680 // implicit in every test.) 8681 testCases = append(testCases, testCase{ 8682 testType: serverTest, 8683 name: "NPN-Declined-TLS13", 8684 config: Config{ 8685 MaxVersion: VersionTLS13, 8686 NextProtos: []string{"bar"}, 8687 }, 8688 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"}, 8689 }) 8690 8691 // OpenSSL sends the status_request extension on resumption in TLS 1.2. Test that this is 8692 // tolerated. 8693 testCases = append(testCases, testCase{ 8694 name: "SendOCSPResponseOnResume-TLS12", 8695 config: Config{ 8696 MaxVersion: VersionTLS12, 8697 Bugs: ProtocolBugs{ 8698 SendOCSPResponseOnResume: []byte("bogus"), 8699 }, 8700 }, 8701 flags: []string{ 8702 "-enable-ocsp-stapling", 8703 "-expect-ocsp-response", 8704 base64FlagValue(testOCSPResponse), 8705 }, 8706 resumeSession: true, 8707 }) 8708 8709 testCases = append(testCases, testCase{ 8710 name: "SendUnsolicitedOCSPOnCertificate-TLS13", 8711 config: Config{ 8712 MaxVersion: VersionTLS13, 8713 Bugs: ProtocolBugs{ 8714 SendExtensionOnCertificate: testOCSPExtension, 8715 }, 8716 }, 8717 shouldFail: true, 8718 expectedError: ":UNEXPECTED_EXTENSION:", 8719 }) 8720 8721 testCases = append(testCases, testCase{ 8722 name: "SendUnsolicitedSCTOnCertificate-TLS13", 8723 config: Config{ 8724 MaxVersion: VersionTLS13, 8725 Bugs: ProtocolBugs{ 8726 SendExtensionOnCertificate: testSCTExtension, 8727 }, 8728 }, 8729 shouldFail: true, 8730 expectedError: ":UNEXPECTED_EXTENSION:", 8731 }) 8732 8733 // Test that extensions on client certificates are never accepted. 8734 testCases = append(testCases, testCase{ 8735 name: "SendExtensionOnClientCertificate-TLS13", 8736 testType: serverTest, 8737 config: Config{ 8738 MaxVersion: VersionTLS13, 8739 Certificates: []Certificate{rsaCertificate}, 8740 Bugs: ProtocolBugs{ 8741 SendExtensionOnCertificate: testOCSPExtension, 8742 }, 8743 }, 8744 flags: []string{ 8745 "-enable-ocsp-stapling", 8746 "-require-any-client-certificate", 8747 }, 8748 shouldFail: true, 8749 expectedError: ":UNEXPECTED_EXTENSION:", 8750 }) 8751 8752 testCases = append(testCases, testCase{ 8753 name: "SendUnknownExtensionOnCertificate-TLS13", 8754 config: Config{ 8755 MaxVersion: VersionTLS13, 8756 Bugs: ProtocolBugs{ 8757 SendExtensionOnCertificate: []byte{0x00, 0x7f, 0, 0}, 8758 }, 8759 }, 8760 shouldFail: true, 8761 expectedError: ":UNEXPECTED_EXTENSION:", 8762 }) 8763 8764 // Test that extensions on intermediates are allowed but ignored. 8765 testCases = append(testCases, testCase{ 8766 name: "IgnoreExtensionsOnIntermediates-TLS13", 8767 config: Config{ 8768 MaxVersion: VersionTLS13, 8769 Certificates: []Certificate{rsaChainCertificate}, 8770 Bugs: ProtocolBugs{ 8771 // Send different values on the intermediate. This tests 8772 // the intermediate's extensions do not override the 8773 // leaf's. 8774 SendOCSPOnIntermediates: testOCSPResponse2, 8775 SendSCTOnIntermediates: testSCTList2, 8776 }, 8777 }, 8778 flags: []string{ 8779 "-enable-ocsp-stapling", 8780 "-expect-ocsp-response", 8781 base64FlagValue(testOCSPResponse), 8782 "-enable-signed-cert-timestamps", 8783 "-expect-signed-cert-timestamps", 8784 base64FlagValue(testSCTList), 8785 }, 8786 resumeSession: true, 8787 }) 8788 8789 // Test that extensions are not sent on intermediates when configured 8790 // only for a leaf. 8791 testCases = append(testCases, testCase{ 8792 testType: serverTest, 8793 name: "SendNoExtensionsOnIntermediate-TLS13", 8794 config: Config{ 8795 MaxVersion: VersionTLS13, 8796 Bugs: ProtocolBugs{ 8797 ExpectNoExtensionsOnIntermediate: true, 8798 }, 8799 }, 8800 flags: []string{ 8801 "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 8802 "-key-file", path.Join(*resourceDir, rsaChainKeyFile), 8803 "-ocsp-response", 8804 base64FlagValue(testOCSPResponse), 8805 "-signed-cert-timestamps", 8806 base64FlagValue(testSCTList), 8807 }, 8808 }) 8809 8810 // Test that extensions are not sent on client certificates. 8811 testCases = append(testCases, testCase{ 8812 name: "SendNoClientCertificateExtensions-TLS13", 8813 config: Config{ 8814 MaxVersion: VersionTLS13, 8815 ClientAuth: RequireAnyClientCert, 8816 }, 8817 flags: []string{ 8818 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 8819 "-key-file", path.Join(*resourceDir, rsaKeyFile), 8820 "-ocsp-response", 8821 base64FlagValue(testOCSPResponse), 8822 "-signed-cert-timestamps", 8823 base64FlagValue(testSCTList), 8824 }, 8825 }) 8826 8827 testCases = append(testCases, testCase{ 8828 name: "SendDuplicateExtensionsOnCerts-TLS13", 8829 config: Config{ 8830 MaxVersion: VersionTLS13, 8831 Bugs: ProtocolBugs{ 8832 SendDuplicateCertExtensions: true, 8833 }, 8834 }, 8835 flags: []string{ 8836 "-enable-ocsp-stapling", 8837 "-enable-signed-cert-timestamps", 8838 }, 8839 resumeSession: true, 8840 shouldFail: true, 8841 expectedError: ":DUPLICATE_EXTENSION:", 8842 }) 8843 8844 testCases = append(testCases, testCase{ 8845 name: "SignedCertificateTimestampListInvalid-Server", 8846 testType: serverTest, 8847 flags: []string{ 8848 "-signed-cert-timestamps", 8849 base64FlagValue([]byte{0, 0}), 8850 }, 8851 shouldFail: true, 8852 expectedError: ":INVALID_SCT_LIST:", 8853 }) 8854} 8855 8856func addResumptionVersionTests() { 8857 for _, sessionVers := range tlsVersions { 8858 for _, resumeVers := range tlsVersions { 8859 protocols := []protocol{tls} 8860 if sessionVers.hasDTLS && resumeVers.hasDTLS { 8861 protocols = append(protocols, dtls) 8862 } 8863 if sessionVers.hasQUIC && resumeVers.hasQUIC { 8864 protocols = append(protocols, quic) 8865 } 8866 for _, protocol := range protocols { 8867 suffix := "-" + sessionVers.name + "-" + resumeVers.name 8868 suffix += "-" + protocol.String() 8869 8870 if sessionVers.version == resumeVers.version { 8871 testCases = append(testCases, testCase{ 8872 protocol: protocol, 8873 name: "Resume-Client" + suffix, 8874 resumeSession: true, 8875 config: Config{ 8876 MaxVersion: sessionVers.version, 8877 Bugs: ProtocolBugs{ 8878 ExpectNoTLS13PSK: sessionVers.version < VersionTLS13, 8879 }, 8880 }, 8881 expectations: connectionExpectations{ 8882 version: sessionVers.version, 8883 }, 8884 resumeExpectations: &connectionExpectations{ 8885 version: resumeVers.version, 8886 }, 8887 }) 8888 } else { 8889 testCases = append(testCases, testCase{ 8890 protocol: protocol, 8891 name: "Resume-Client-Mismatch" + suffix, 8892 resumeSession: true, 8893 config: Config{ 8894 MaxVersion: sessionVers.version, 8895 }, 8896 expectations: connectionExpectations{ 8897 version: sessionVers.version, 8898 }, 8899 resumeConfig: &Config{ 8900 MaxVersion: resumeVers.version, 8901 Bugs: ProtocolBugs{ 8902 AcceptAnySession: true, 8903 }, 8904 }, 8905 resumeExpectations: &connectionExpectations{ 8906 version: resumeVers.version, 8907 }, 8908 shouldFail: true, 8909 expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:", 8910 }) 8911 } 8912 8913 testCases = append(testCases, testCase{ 8914 protocol: protocol, 8915 name: "Resume-Client-NoResume" + suffix, 8916 resumeSession: true, 8917 config: Config{ 8918 MaxVersion: sessionVers.version, 8919 }, 8920 expectations: connectionExpectations{ 8921 version: sessionVers.version, 8922 }, 8923 resumeConfig: &Config{ 8924 MaxVersion: resumeVers.version, 8925 }, 8926 newSessionsOnResume: true, 8927 expectResumeRejected: true, 8928 resumeExpectations: &connectionExpectations{ 8929 version: resumeVers.version, 8930 }, 8931 }) 8932 8933 testCases = append(testCases, testCase{ 8934 protocol: protocol, 8935 testType: serverTest, 8936 name: "Resume-Server" + suffix, 8937 resumeSession: true, 8938 config: Config{ 8939 MaxVersion: sessionVers.version, 8940 }, 8941 expectations: connectionExpectations{ 8942 version: sessionVers.version, 8943 }, 8944 expectResumeRejected: sessionVers != resumeVers, 8945 resumeConfig: &Config{ 8946 MaxVersion: resumeVers.version, 8947 Bugs: ProtocolBugs{ 8948 SendBothTickets: true, 8949 }, 8950 }, 8951 resumeExpectations: &connectionExpectations{ 8952 version: resumeVers.version, 8953 }, 8954 }) 8955 8956 // Repeat the test using session IDs, rather than tickets. 8957 if sessionVers.version < VersionTLS13 && resumeVers.version < VersionTLS13 { 8958 testCases = append(testCases, testCase{ 8959 protocol: protocol, 8960 testType: serverTest, 8961 name: "Resume-Server-NoTickets" + suffix, 8962 resumeSession: true, 8963 config: Config{ 8964 MaxVersion: sessionVers.version, 8965 SessionTicketsDisabled: true, 8966 }, 8967 expectations: connectionExpectations{ 8968 version: sessionVers.version, 8969 }, 8970 expectResumeRejected: sessionVers != resumeVers, 8971 resumeConfig: &Config{ 8972 MaxVersion: resumeVers.version, 8973 SessionTicketsDisabled: true, 8974 }, 8975 resumeExpectations: &connectionExpectations{ 8976 version: resumeVers.version, 8977 }, 8978 }) 8979 } 8980 } 8981 } 8982 } 8983 8984 // Make sure shim ticket mutations are functional. 8985 testCases = append(testCases, testCase{ 8986 testType: serverTest, 8987 name: "ShimTicketRewritable", 8988 resumeSession: true, 8989 config: Config{ 8990 MaxVersion: VersionTLS12, 8991 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 8992 Bugs: ProtocolBugs{ 8993 FilterTicket: func(in []byte) ([]byte, error) { 8994 in, err := SetShimTicketVersion(in, VersionTLS12) 8995 if err != nil { 8996 return nil, err 8997 } 8998 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) 8999 }, 9000 }, 9001 }, 9002 flags: []string{ 9003 "-ticket-key", 9004 base64FlagValue(TestShimTicketKey), 9005 }, 9006 }) 9007 9008 // Resumptions are declined if the version does not match. 9009 testCases = append(testCases, testCase{ 9010 testType: serverTest, 9011 name: "Resume-Server-DeclineCrossVersion", 9012 resumeSession: true, 9013 config: Config{ 9014 MaxVersion: VersionTLS12, 9015 Bugs: ProtocolBugs{ 9016 ExpectNewTicket: true, 9017 FilterTicket: func(in []byte) ([]byte, error) { 9018 return SetShimTicketVersion(in, VersionTLS13) 9019 }, 9020 }, 9021 }, 9022 flags: []string{ 9023 "-ticket-key", 9024 base64FlagValue(TestShimTicketKey), 9025 }, 9026 expectResumeRejected: true, 9027 }) 9028 9029 testCases = append(testCases, testCase{ 9030 testType: serverTest, 9031 name: "Resume-Server-DeclineCrossVersion-TLS13", 9032 resumeSession: true, 9033 config: Config{ 9034 MaxVersion: VersionTLS13, 9035 Bugs: ProtocolBugs{ 9036 FilterTicket: func(in []byte) ([]byte, error) { 9037 return SetShimTicketVersion(in, VersionTLS12) 9038 }, 9039 }, 9040 }, 9041 flags: []string{ 9042 "-ticket-key", 9043 base64FlagValue(TestShimTicketKey), 9044 }, 9045 expectResumeRejected: true, 9046 }) 9047 9048 // Resumptions are declined if the cipher is invalid or disabled. 9049 testCases = append(testCases, testCase{ 9050 testType: serverTest, 9051 name: "Resume-Server-DeclineBadCipher", 9052 resumeSession: true, 9053 config: Config{ 9054 MaxVersion: VersionTLS12, 9055 Bugs: ProtocolBugs{ 9056 ExpectNewTicket: true, 9057 FilterTicket: func(in []byte) ([]byte, error) { 9058 return SetShimTicketCipherSuite(in, TLS_AES_128_GCM_SHA256) 9059 }, 9060 }, 9061 }, 9062 flags: []string{ 9063 "-ticket-key", 9064 base64FlagValue(TestShimTicketKey), 9065 }, 9066 expectResumeRejected: true, 9067 }) 9068 9069 testCases = append(testCases, testCase{ 9070 testType: serverTest, 9071 name: "Resume-Server-DeclineBadCipher-2", 9072 resumeSession: true, 9073 config: Config{ 9074 MaxVersion: VersionTLS12, 9075 Bugs: ProtocolBugs{ 9076 ExpectNewTicket: true, 9077 FilterTicket: func(in []byte) ([]byte, error) { 9078 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) 9079 }, 9080 }, 9081 }, 9082 flags: []string{ 9083 "-cipher", "AES128", 9084 "-ticket-key", 9085 base64FlagValue(TestShimTicketKey), 9086 }, 9087 expectResumeRejected: true, 9088 }) 9089 9090 // Sessions are not resumed if they do not use the preferred cipher. 9091 testCases = append(testCases, testCase{ 9092 testType: serverTest, 9093 name: "Resume-Server-CipherNotPreferred", 9094 resumeSession: true, 9095 config: Config{ 9096 MaxVersion: VersionTLS12, 9097 Bugs: ProtocolBugs{ 9098 ExpectNewTicket: true, 9099 FilterTicket: func(in []byte) ([]byte, error) { 9100 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) 9101 }, 9102 }, 9103 }, 9104 flags: []string{ 9105 "-ticket-key", 9106 base64FlagValue(TestShimTicketKey), 9107 }, 9108 shouldFail: false, 9109 expectResumeRejected: true, 9110 }) 9111 9112 // TLS 1.3 allows sessions to be resumed at a different cipher if their 9113 // PRF hashes match, but BoringSSL will always decline such resumptions. 9114 testCases = append(testCases, testCase{ 9115 testType: serverTest, 9116 name: "Resume-Server-CipherNotPreferred-TLS13", 9117 resumeSession: true, 9118 config: Config{ 9119 MaxVersion: VersionTLS13, 9120 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_GCM_SHA256}, 9121 Bugs: ProtocolBugs{ 9122 FilterTicket: func(in []byte) ([]byte, error) { 9123 // If the client (runner) offers ChaCha20-Poly1305 first, the 9124 // server (shim) always prefers it. Switch it to AES-GCM. 9125 return SetShimTicketCipherSuite(in, TLS_AES_128_GCM_SHA256) 9126 }, 9127 }, 9128 }, 9129 flags: []string{ 9130 "-ticket-key", 9131 base64FlagValue(TestShimTicketKey), 9132 }, 9133 shouldFail: false, 9134 expectResumeRejected: true, 9135 }) 9136 9137 // Sessions may not be resumed if they contain another version's cipher. 9138 testCases = append(testCases, testCase{ 9139 testType: serverTest, 9140 name: "Resume-Server-DeclineBadCipher-TLS13", 9141 resumeSession: true, 9142 config: Config{ 9143 MaxVersion: VersionTLS13, 9144 Bugs: ProtocolBugs{ 9145 FilterTicket: func(in []byte) ([]byte, error) { 9146 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) 9147 }, 9148 }, 9149 }, 9150 flags: []string{ 9151 "-ticket-key", 9152 base64FlagValue(TestShimTicketKey), 9153 }, 9154 expectResumeRejected: true, 9155 }) 9156 9157 // If the client does not offer the cipher from the session, decline to 9158 // resume. Clients are forbidden from doing this, but BoringSSL selects 9159 // the cipher first, so we only decline. 9160 testCases = append(testCases, testCase{ 9161 testType: serverTest, 9162 name: "Resume-Server-UnofferedCipher", 9163 resumeSession: true, 9164 config: Config{ 9165 MaxVersion: VersionTLS12, 9166 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 9167 }, 9168 resumeConfig: &Config{ 9169 MaxVersion: VersionTLS12, 9170 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 9171 Bugs: ProtocolBugs{ 9172 SendCipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9173 }, 9174 }, 9175 expectResumeRejected: true, 9176 }) 9177 9178 // In TLS 1.3, clients may advertise a cipher list which does not 9179 // include the selected cipher. Test that we tolerate this. Servers may 9180 // resume at another cipher if the PRF matches and are not doing 0-RTT, but 9181 // BoringSSL will always decline. 9182 testCases = append(testCases, testCase{ 9183 testType: serverTest, 9184 name: "Resume-Server-UnofferedCipher-TLS13", 9185 resumeSession: true, 9186 config: Config{ 9187 MaxVersion: VersionTLS13, 9188 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 9189 }, 9190 resumeConfig: &Config{ 9191 MaxVersion: VersionTLS13, 9192 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 9193 Bugs: ProtocolBugs{ 9194 SendCipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9195 }, 9196 }, 9197 expectResumeRejected: true, 9198 }) 9199 9200 // Sessions may not be resumed at a different cipher. 9201 testCases = append(testCases, testCase{ 9202 name: "Resume-Client-CipherMismatch", 9203 resumeSession: true, 9204 config: Config{ 9205 MaxVersion: VersionTLS12, 9206 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 9207 }, 9208 resumeConfig: &Config{ 9209 MaxVersion: VersionTLS12, 9210 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 9211 Bugs: ProtocolBugs{ 9212 SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA, 9213 }, 9214 }, 9215 shouldFail: true, 9216 expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:", 9217 }) 9218 9219 // Session resumption in TLS 1.3 may change the cipher suite if the PRF 9220 // matches. 9221 testCases = append(testCases, testCase{ 9222 name: "Resume-Client-CipherMismatch-TLS13", 9223 resumeSession: true, 9224 config: Config{ 9225 MaxVersion: VersionTLS13, 9226 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9227 }, 9228 resumeConfig: &Config{ 9229 MaxVersion: VersionTLS13, 9230 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 9231 }, 9232 }) 9233 9234 // Session resumption in TLS 1.3 is forbidden if the PRF does not match. 9235 testCases = append(testCases, testCase{ 9236 name: "Resume-Client-PRFMismatch-TLS13", 9237 resumeSession: true, 9238 config: Config{ 9239 MaxVersion: VersionTLS13, 9240 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9241 }, 9242 resumeConfig: &Config{ 9243 MaxVersion: VersionTLS13, 9244 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9245 Bugs: ProtocolBugs{ 9246 SendCipherSuite: TLS_AES_256_GCM_SHA384, 9247 }, 9248 }, 9249 shouldFail: true, 9250 expectedError: ":OLD_SESSION_PRF_HASH_MISMATCH:", 9251 }) 9252 9253 for _, secondBinder := range []bool{false, true} { 9254 var suffix string 9255 var defaultCurves []CurveID 9256 if secondBinder { 9257 suffix = "-SecondBinder" 9258 // Force a HelloRetryRequest by predicting an empty curve list. 9259 defaultCurves = []CurveID{} 9260 } 9261 9262 testCases = append(testCases, testCase{ 9263 testType: serverTest, 9264 name: "Resume-Server-BinderWrongLength" + suffix, 9265 resumeSession: true, 9266 config: Config{ 9267 MaxVersion: VersionTLS13, 9268 DefaultCurves: defaultCurves, 9269 Bugs: ProtocolBugs{ 9270 SendShortPSKBinder: true, 9271 OnlyCorruptSecondPSKBinder: secondBinder, 9272 }, 9273 }, 9274 shouldFail: true, 9275 expectedLocalError: "remote error: error decrypting message", 9276 expectedError: ":DIGEST_CHECK_FAILED:", 9277 }) 9278 9279 testCases = append(testCases, testCase{ 9280 testType: serverTest, 9281 name: "Resume-Server-NoPSKBinder" + suffix, 9282 resumeSession: true, 9283 config: Config{ 9284 MaxVersion: VersionTLS13, 9285 DefaultCurves: defaultCurves, 9286 Bugs: ProtocolBugs{ 9287 SendNoPSKBinder: true, 9288 OnlyCorruptSecondPSKBinder: secondBinder, 9289 }, 9290 }, 9291 shouldFail: true, 9292 expectedLocalError: "remote error: error decoding message", 9293 expectedError: ":DECODE_ERROR:", 9294 }) 9295 9296 testCases = append(testCases, testCase{ 9297 testType: serverTest, 9298 name: "Resume-Server-ExtraPSKBinder" + suffix, 9299 resumeSession: true, 9300 config: Config{ 9301 MaxVersion: VersionTLS13, 9302 DefaultCurves: defaultCurves, 9303 Bugs: ProtocolBugs{ 9304 SendExtraPSKBinder: true, 9305 OnlyCorruptSecondPSKBinder: secondBinder, 9306 }, 9307 }, 9308 shouldFail: true, 9309 expectedLocalError: "remote error: illegal parameter", 9310 expectedError: ":PSK_IDENTITY_BINDER_COUNT_MISMATCH:", 9311 }) 9312 9313 testCases = append(testCases, testCase{ 9314 testType: serverTest, 9315 name: "Resume-Server-ExtraIdentityNoBinder" + suffix, 9316 resumeSession: true, 9317 config: Config{ 9318 MaxVersion: VersionTLS13, 9319 DefaultCurves: defaultCurves, 9320 Bugs: ProtocolBugs{ 9321 ExtraPSKIdentity: true, 9322 OnlyCorruptSecondPSKBinder: secondBinder, 9323 }, 9324 }, 9325 shouldFail: true, 9326 expectedLocalError: "remote error: illegal parameter", 9327 expectedError: ":PSK_IDENTITY_BINDER_COUNT_MISMATCH:", 9328 }) 9329 9330 testCases = append(testCases, testCase{ 9331 testType: serverTest, 9332 name: "Resume-Server-InvalidPSKBinder" + suffix, 9333 resumeSession: true, 9334 config: Config{ 9335 MaxVersion: VersionTLS13, 9336 DefaultCurves: defaultCurves, 9337 Bugs: ProtocolBugs{ 9338 SendInvalidPSKBinder: true, 9339 OnlyCorruptSecondPSKBinder: secondBinder, 9340 }, 9341 }, 9342 shouldFail: true, 9343 expectedLocalError: "remote error: error decrypting message", 9344 expectedError: ":DIGEST_CHECK_FAILED:", 9345 }) 9346 9347 testCases = append(testCases, testCase{ 9348 testType: serverTest, 9349 name: "Resume-Server-PSKBinderFirstExtension" + suffix, 9350 resumeSession: true, 9351 config: Config{ 9352 MaxVersion: VersionTLS13, 9353 DefaultCurves: defaultCurves, 9354 Bugs: ProtocolBugs{ 9355 PSKBinderFirst: true, 9356 OnlyCorruptSecondPSKBinder: secondBinder, 9357 }, 9358 }, 9359 shouldFail: true, 9360 expectedLocalError: "remote error: illegal parameter", 9361 expectedError: ":PRE_SHARED_KEY_MUST_BE_LAST:", 9362 }) 9363 } 9364 9365 testCases = append(testCases, testCase{ 9366 testType: serverTest, 9367 name: "Resume-Server-OmitPSKsOnSecondClientHello", 9368 resumeSession: true, 9369 config: Config{ 9370 MaxVersion: VersionTLS13, 9371 DefaultCurves: []CurveID{}, 9372 Bugs: ProtocolBugs{ 9373 OmitPSKsOnSecondClientHello: true, 9374 }, 9375 }, 9376 shouldFail: true, 9377 expectedLocalError: "remote error: illegal parameter", 9378 expectedError: ":INCONSISTENT_CLIENT_HELLO:", 9379 }) 9380} 9381 9382func addRenegotiationTests() { 9383 // Servers cannot renegotiate. 9384 testCases = append(testCases, testCase{ 9385 testType: serverTest, 9386 name: "Renegotiate-Server-Forbidden", 9387 config: Config{ 9388 MaxVersion: VersionTLS12, 9389 }, 9390 renegotiate: 1, 9391 shouldFail: true, 9392 expectedError: ":NO_RENEGOTIATION:", 9393 expectedLocalError: "remote error: no renegotiation", 9394 }) 9395 // The server shouldn't echo the renegotiation extension unless 9396 // requested by the client. 9397 testCases = append(testCases, testCase{ 9398 testType: serverTest, 9399 name: "Renegotiate-Server-NoExt", 9400 config: Config{ 9401 MaxVersion: VersionTLS12, 9402 Bugs: ProtocolBugs{ 9403 NoRenegotiationInfo: true, 9404 RequireRenegotiationInfo: true, 9405 }, 9406 }, 9407 shouldFail: true, 9408 expectedLocalError: "renegotiation extension missing", 9409 }) 9410 // The renegotiation SCSV should be sufficient for the server to echo 9411 // the extension. 9412 testCases = append(testCases, testCase{ 9413 testType: serverTest, 9414 name: "Renegotiate-Server-NoExt-SCSV", 9415 config: Config{ 9416 MaxVersion: VersionTLS12, 9417 Bugs: ProtocolBugs{ 9418 NoRenegotiationInfo: true, 9419 SendRenegotiationSCSV: true, 9420 RequireRenegotiationInfo: true, 9421 }, 9422 }, 9423 }) 9424 testCases = append(testCases, testCase{ 9425 name: "Renegotiate-Client", 9426 config: Config{ 9427 MaxVersion: VersionTLS12, 9428 Bugs: ProtocolBugs{ 9429 FailIfResumeOnRenego: true, 9430 }, 9431 }, 9432 renegotiate: 1, 9433 // Test renegotiation after both an initial and resumption 9434 // handshake. 9435 resumeSession: true, 9436 flags: []string{ 9437 "-renegotiate-freely", 9438 "-expect-total-renegotiations", "1", 9439 "-expect-secure-renegotiation", 9440 }, 9441 }) 9442 testCases = append(testCases, testCase{ 9443 name: "Renegotiate-Client-TLS12", 9444 config: Config{ 9445 MaxVersion: VersionTLS12, 9446 Bugs: ProtocolBugs{ 9447 FailIfResumeOnRenego: true, 9448 }, 9449 }, 9450 renegotiate: 1, 9451 // Test renegotiation after both an initial and resumption 9452 // handshake. 9453 resumeSession: true, 9454 flags: []string{ 9455 "-renegotiate-freely", 9456 "-expect-total-renegotiations", "1", 9457 "-expect-secure-renegotiation", 9458 }, 9459 }) 9460 testCases = append(testCases, testCase{ 9461 name: "Renegotiate-Client-EmptyExt", 9462 renegotiate: 1, 9463 config: Config{ 9464 MaxVersion: VersionTLS12, 9465 Bugs: ProtocolBugs{ 9466 EmptyRenegotiationInfo: true, 9467 }, 9468 }, 9469 flags: []string{"-renegotiate-freely"}, 9470 shouldFail: true, 9471 expectedError: ":RENEGOTIATION_MISMATCH:", 9472 expectedLocalError: "handshake failure", 9473 }) 9474 testCases = append(testCases, testCase{ 9475 name: "Renegotiate-Client-BadExt", 9476 renegotiate: 1, 9477 config: Config{ 9478 MaxVersion: VersionTLS12, 9479 Bugs: ProtocolBugs{ 9480 BadRenegotiationInfo: true, 9481 }, 9482 }, 9483 flags: []string{"-renegotiate-freely"}, 9484 shouldFail: true, 9485 expectedError: ":RENEGOTIATION_MISMATCH:", 9486 expectedLocalError: "handshake failure", 9487 }) 9488 testCases = append(testCases, testCase{ 9489 name: "Renegotiate-Client-BadExt2", 9490 renegotiate: 1, 9491 config: Config{ 9492 MaxVersion: VersionTLS12, 9493 Bugs: ProtocolBugs{ 9494 BadRenegotiationInfoEnd: true, 9495 }, 9496 }, 9497 flags: []string{"-renegotiate-freely"}, 9498 shouldFail: true, 9499 expectedError: ":RENEGOTIATION_MISMATCH:", 9500 expectedLocalError: "handshake failure", 9501 }) 9502 testCases = append(testCases, testCase{ 9503 name: "Renegotiate-Client-Downgrade", 9504 renegotiate: 1, 9505 config: Config{ 9506 MaxVersion: VersionTLS12, 9507 Bugs: ProtocolBugs{ 9508 NoRenegotiationInfoAfterInitial: true, 9509 }, 9510 }, 9511 flags: []string{"-renegotiate-freely"}, 9512 shouldFail: true, 9513 expectedError: ":RENEGOTIATION_MISMATCH:", 9514 expectedLocalError: "handshake failure", 9515 }) 9516 testCases = append(testCases, testCase{ 9517 name: "Renegotiate-Client-Upgrade", 9518 renegotiate: 1, 9519 config: Config{ 9520 MaxVersion: VersionTLS12, 9521 Bugs: ProtocolBugs{ 9522 NoRenegotiationInfoInInitial: true, 9523 }, 9524 }, 9525 flags: []string{"-renegotiate-freely"}, 9526 shouldFail: true, 9527 expectedError: ":RENEGOTIATION_MISMATCH:", 9528 expectedLocalError: "handshake failure", 9529 }) 9530 testCases = append(testCases, testCase{ 9531 name: "Renegotiate-Client-NoExt-Allowed", 9532 renegotiate: 1, 9533 config: Config{ 9534 MaxVersion: VersionTLS12, 9535 Bugs: ProtocolBugs{ 9536 NoRenegotiationInfo: true, 9537 }, 9538 }, 9539 flags: []string{ 9540 "-renegotiate-freely", 9541 "-expect-total-renegotiations", "1", 9542 "-expect-no-secure-renegotiation", 9543 }, 9544 }) 9545 9546 // Test that the server may switch ciphers on renegotiation without 9547 // problems. 9548 testCases = append(testCases, testCase{ 9549 name: "Renegotiate-Client-SwitchCiphers", 9550 renegotiate: 1, 9551 config: Config{ 9552 MaxVersion: VersionTLS12, 9553 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 9554 }, 9555 renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9556 flags: []string{ 9557 "-renegotiate-freely", 9558 "-expect-total-renegotiations", "1", 9559 }, 9560 }) 9561 testCases = append(testCases, testCase{ 9562 name: "Renegotiate-Client-SwitchCiphers2", 9563 renegotiate: 1, 9564 config: Config{ 9565 MaxVersion: VersionTLS12, 9566 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9567 }, 9568 renegotiateCiphers: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 9569 flags: []string{ 9570 "-renegotiate-freely", 9571 "-expect-total-renegotiations", "1", 9572 }, 9573 }) 9574 9575 // Test that the server may not switch versions on renegotiation. 9576 testCases = append(testCases, testCase{ 9577 name: "Renegotiate-Client-SwitchVersion", 9578 config: Config{ 9579 MaxVersion: VersionTLS12, 9580 // Pick a cipher which exists at both versions. 9581 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 9582 Bugs: ProtocolBugs{ 9583 NegotiateVersionOnRenego: VersionTLS11, 9584 // Avoid failing early at the record layer. 9585 SendRecordVersion: VersionTLS12, 9586 }, 9587 }, 9588 renegotiate: 1, 9589 flags: []string{ 9590 "-renegotiate-freely", 9591 "-expect-total-renegotiations", "1", 9592 }, 9593 shouldFail: true, 9594 expectedError: ":WRONG_SSL_VERSION:", 9595 }) 9596 9597 testCases = append(testCases, testCase{ 9598 name: "Renegotiate-SameClientVersion", 9599 renegotiate: 1, 9600 config: Config{ 9601 MaxVersion: VersionTLS10, 9602 Bugs: ProtocolBugs{ 9603 RequireSameRenegoClientVersion: true, 9604 }, 9605 }, 9606 flags: []string{ 9607 "-renegotiate-freely", 9608 "-expect-total-renegotiations", "1", 9609 }, 9610 }) 9611 testCases = append(testCases, testCase{ 9612 name: "Renegotiate-FalseStart", 9613 renegotiate: 1, 9614 config: Config{ 9615 MaxVersion: VersionTLS12, 9616 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9617 NextProtos: []string{"foo"}, 9618 }, 9619 flags: []string{ 9620 "-false-start", 9621 "-select-next-proto", "foo", 9622 "-renegotiate-freely", 9623 "-expect-total-renegotiations", "1", 9624 }, 9625 shimWritesFirst: true, 9626 }) 9627 9628 // Client-side renegotiation controls. 9629 testCases = append(testCases, testCase{ 9630 name: "Renegotiate-Client-Forbidden-1", 9631 config: Config{ 9632 MaxVersion: VersionTLS12, 9633 }, 9634 renegotiate: 1, 9635 shouldFail: true, 9636 expectedError: ":NO_RENEGOTIATION:", 9637 expectedLocalError: "remote error: no renegotiation", 9638 }) 9639 testCases = append(testCases, testCase{ 9640 name: "Renegotiate-Client-Once-1", 9641 config: Config{ 9642 MaxVersion: VersionTLS12, 9643 }, 9644 renegotiate: 1, 9645 flags: []string{ 9646 "-renegotiate-once", 9647 "-expect-total-renegotiations", "1", 9648 }, 9649 }) 9650 testCases = append(testCases, testCase{ 9651 name: "Renegotiate-Client-Freely-1", 9652 config: Config{ 9653 MaxVersion: VersionTLS12, 9654 }, 9655 renegotiate: 1, 9656 flags: []string{ 9657 "-renegotiate-freely", 9658 "-expect-total-renegotiations", "1", 9659 }, 9660 }) 9661 testCases = append(testCases, testCase{ 9662 name: "Renegotiate-Client-Once-2", 9663 config: Config{ 9664 MaxVersion: VersionTLS12, 9665 }, 9666 renegotiate: 2, 9667 flags: []string{"-renegotiate-once"}, 9668 shouldFail: true, 9669 expectedError: ":NO_RENEGOTIATION:", 9670 expectedLocalError: "remote error: no renegotiation", 9671 }) 9672 testCases = append(testCases, testCase{ 9673 name: "Renegotiate-Client-Freely-2", 9674 config: Config{ 9675 MaxVersion: VersionTLS12, 9676 }, 9677 renegotiate: 2, 9678 flags: []string{ 9679 "-renegotiate-freely", 9680 "-expect-total-renegotiations", "2", 9681 }, 9682 }) 9683 testCases = append(testCases, testCase{ 9684 name: "Renegotiate-Client-NoIgnore", 9685 config: Config{ 9686 MaxVersion: VersionTLS12, 9687 Bugs: ProtocolBugs{ 9688 SendHelloRequestBeforeEveryAppDataRecord: true, 9689 }, 9690 }, 9691 shouldFail: true, 9692 expectedError: ":NO_RENEGOTIATION:", 9693 }) 9694 testCases = append(testCases, testCase{ 9695 name: "Renegotiate-Client-Ignore", 9696 config: Config{ 9697 MaxVersion: VersionTLS12, 9698 Bugs: ProtocolBugs{ 9699 SendHelloRequestBeforeEveryAppDataRecord: true, 9700 }, 9701 }, 9702 flags: []string{ 9703 "-renegotiate-ignore", 9704 "-expect-total-renegotiations", "0", 9705 }, 9706 }) 9707 9708 // Renegotiation may be enabled and then disabled immediately after the 9709 // handshake. 9710 testCases = append(testCases, testCase{ 9711 name: "Renegotiate-ForbidAfterHandshake", 9712 config: Config{ 9713 MaxVersion: VersionTLS12, 9714 }, 9715 renegotiate: 1, 9716 flags: []string{"-forbid-renegotiation-after-handshake"}, 9717 shouldFail: true, 9718 expectedError: ":NO_RENEGOTIATION:", 9719 expectedLocalError: "remote error: no renegotiation", 9720 }) 9721 9722 // Renegotiation is not allowed when there is an unfinished write. 9723 testCases = append(testCases, testCase{ 9724 name: "Renegotiate-Client-UnfinishedWrite", 9725 config: Config{ 9726 MaxVersion: VersionTLS12, 9727 }, 9728 renegotiate: 1, 9729 readWithUnfinishedWrite: true, 9730 flags: []string{ 9731 "-async", 9732 "-renegotiate-freely", 9733 }, 9734 shouldFail: true, 9735 expectedError: ":NO_RENEGOTIATION:", 9736 // We do not successfully send the no_renegotiation alert in 9737 // this case. https://crbug.com/boringssl/130 9738 }) 9739 9740 // We reject stray HelloRequests during the handshake in TLS 1.2. 9741 testCases = append(testCases, testCase{ 9742 name: "StrayHelloRequest", 9743 config: Config{ 9744 MaxVersion: VersionTLS12, 9745 Bugs: ProtocolBugs{ 9746 SendHelloRequestBeforeEveryHandshakeMessage: true, 9747 }, 9748 }, 9749 shouldFail: true, 9750 expectedError: ":UNEXPECTED_MESSAGE:", 9751 }) 9752 testCases = append(testCases, testCase{ 9753 name: "StrayHelloRequest-Packed", 9754 config: Config{ 9755 MaxVersion: VersionTLS12, 9756 Bugs: ProtocolBugs{ 9757 PackHandshakeFlight: true, 9758 SendHelloRequestBeforeEveryHandshakeMessage: true, 9759 }, 9760 }, 9761 shouldFail: true, 9762 expectedError: ":UNEXPECTED_MESSAGE:", 9763 }) 9764 9765 // Test that HelloRequest is rejected if it comes in the same record as the 9766 // server Finished. 9767 testCases = append(testCases, testCase{ 9768 name: "Renegotiate-Client-Packed", 9769 config: Config{ 9770 MaxVersion: VersionTLS12, 9771 Bugs: ProtocolBugs{ 9772 PackHandshakeFlight: true, 9773 PackHelloRequestWithFinished: true, 9774 }, 9775 }, 9776 renegotiate: 1, 9777 flags: []string{"-renegotiate-freely"}, 9778 shouldFail: true, 9779 expectedError: ":EXCESS_HANDSHAKE_DATA:", 9780 expectedLocalError: "remote error: unexpected message", 9781 }) 9782 9783 // Renegotiation is forbidden in TLS 1.3. 9784 testCases = append(testCases, testCase{ 9785 name: "Renegotiate-Client-TLS13", 9786 config: Config{ 9787 MaxVersion: VersionTLS13, 9788 Bugs: ProtocolBugs{ 9789 SendHelloRequestBeforeEveryAppDataRecord: true, 9790 }, 9791 }, 9792 flags: []string{ 9793 "-renegotiate-freely", 9794 }, 9795 shouldFail: true, 9796 expectedError: ":UNEXPECTED_MESSAGE:", 9797 }) 9798 9799 // Stray HelloRequests during the handshake are forbidden in TLS 1.3. 9800 testCases = append(testCases, testCase{ 9801 name: "StrayHelloRequest-TLS13", 9802 config: Config{ 9803 MaxVersion: VersionTLS13, 9804 Bugs: ProtocolBugs{ 9805 SendHelloRequestBeforeEveryHandshakeMessage: true, 9806 }, 9807 }, 9808 shouldFail: true, 9809 expectedError: ":UNEXPECTED_MESSAGE:", 9810 }) 9811 9812 // The renegotiation_info extension is not sent in TLS 1.3, but TLS 1.3 9813 // always reads as supporting it, regardless of whether it was 9814 // negotiated. 9815 testCases = append(testCases, testCase{ 9816 name: "AlwaysReportRenegotiationInfo-TLS13", 9817 config: Config{ 9818 MaxVersion: VersionTLS13, 9819 Bugs: ProtocolBugs{ 9820 NoRenegotiationInfo: true, 9821 }, 9822 }, 9823 flags: []string{ 9824 "-expect-secure-renegotiation", 9825 }, 9826 }) 9827 9828 // Certificates may not change on renegotiation. 9829 testCases = append(testCases, testCase{ 9830 name: "Renegotiation-CertificateChange", 9831 config: Config{ 9832 MaxVersion: VersionTLS12, 9833 Certificates: []Certificate{rsaCertificate}, 9834 Bugs: ProtocolBugs{ 9835 RenegotiationCertificate: &rsaChainCertificate, 9836 }, 9837 }, 9838 renegotiate: 1, 9839 flags: []string{"-renegotiate-freely"}, 9840 shouldFail: true, 9841 expectedError: ":SERVER_CERT_CHANGED:", 9842 }) 9843 testCases = append(testCases, testCase{ 9844 name: "Renegotiation-CertificateChange-2", 9845 config: Config{ 9846 MaxVersion: VersionTLS12, 9847 Certificates: []Certificate{rsaCertificate}, 9848 Bugs: ProtocolBugs{ 9849 RenegotiationCertificate: &rsa1024Certificate, 9850 }, 9851 }, 9852 renegotiate: 1, 9853 flags: []string{"-renegotiate-freely"}, 9854 shouldFail: true, 9855 expectedError: ":SERVER_CERT_CHANGED:", 9856 }) 9857 9858 // We do not negotiate ALPN after the initial handshake. This is 9859 // error-prone and only risks bugs in consumers. 9860 testCases = append(testCases, testCase{ 9861 testType: clientTest, 9862 name: "Renegotiation-ForbidALPN", 9863 config: Config{ 9864 MaxVersion: VersionTLS12, 9865 Bugs: ProtocolBugs{ 9866 // Forcibly negotiate ALPN on both initial and 9867 // renegotiation handshakes. The test stack will 9868 // internally check the client does not offer 9869 // it. 9870 SendALPN: "foo", 9871 }, 9872 }, 9873 flags: []string{ 9874 "-advertise-alpn", "\x03foo\x03bar\x03baz", 9875 "-expect-alpn", "foo", 9876 "-renegotiate-freely", 9877 }, 9878 renegotiate: 1, 9879 shouldFail: true, 9880 expectedError: ":UNEXPECTED_EXTENSION:", 9881 }) 9882 9883 // The server may send different stapled OCSP responses or SCT lists on 9884 // renegotiation, but BoringSSL ignores this and reports the old values. 9885 // Also test that non-fatal verify results are preserved. 9886 testCases = append(testCases, testCase{ 9887 testType: clientTest, 9888 name: "Renegotiation-ChangeAuthProperties", 9889 config: Config{ 9890 MaxVersion: VersionTLS12, 9891 Bugs: ProtocolBugs{ 9892 SendOCSPResponseOnRenegotiation: testOCSPResponse2, 9893 SendSCTListOnRenegotiation: testSCTList2, 9894 }, 9895 }, 9896 renegotiate: 1, 9897 flags: []string{ 9898 "-renegotiate-freely", 9899 "-expect-total-renegotiations", "1", 9900 "-enable-ocsp-stapling", 9901 "-expect-ocsp-response", 9902 base64FlagValue(testOCSPResponse), 9903 "-enable-signed-cert-timestamps", 9904 "-expect-signed-cert-timestamps", 9905 base64FlagValue(testSCTList), 9906 "-verify-fail", 9907 "-expect-verify-result", 9908 }, 9909 }) 9910} 9911 9912func addDTLSReplayTests() { 9913 // Test that sequence number replays are detected. 9914 testCases = append(testCases, testCase{ 9915 protocol: dtls, 9916 name: "DTLS-Replay", 9917 messageCount: 200, 9918 replayWrites: true, 9919 }) 9920 9921 // Test the incoming sequence number skipping by values larger 9922 // than the retransmit window. 9923 testCases = append(testCases, testCase{ 9924 protocol: dtls, 9925 name: "DTLS-Replay-LargeGaps", 9926 config: Config{ 9927 Bugs: ProtocolBugs{ 9928 SequenceNumberMapping: func(in uint64) uint64 { 9929 return in * 127 9930 }, 9931 }, 9932 }, 9933 messageCount: 200, 9934 replayWrites: true, 9935 }) 9936 9937 // Test the incoming sequence number changing non-monotonically. 9938 testCases = append(testCases, testCase{ 9939 protocol: dtls, 9940 name: "DTLS-Replay-NonMonotonic", 9941 config: Config{ 9942 Bugs: ProtocolBugs{ 9943 SequenceNumberMapping: func(in uint64) uint64 { 9944 return in ^ 31 9945 }, 9946 }, 9947 }, 9948 messageCount: 200, 9949 replayWrites: true, 9950 }) 9951} 9952 9953var testSignatureAlgorithms = []struct { 9954 name string 9955 id signatureAlgorithm 9956 cert testCert 9957 // If non-zero, the curve that must be supported in TLS 1.2 for cert to be 9958 // accepted. 9959 curve CurveID 9960}{ 9961 {"RSA_PKCS1_SHA1", signatureRSAPKCS1WithSHA1, testCertRSA, 0}, 9962 {"RSA_PKCS1_SHA256", signatureRSAPKCS1WithSHA256, testCertRSA, 0}, 9963 {"RSA_PKCS1_SHA384", signatureRSAPKCS1WithSHA384, testCertRSA, 0}, 9964 {"RSA_PKCS1_SHA512", signatureRSAPKCS1WithSHA512, testCertRSA, 0}, 9965 {"ECDSA_SHA1", signatureECDSAWithSHA1, testCertECDSAP256, CurveP256}, 9966 // The “P256” in the following line is not a mistake. In TLS 1.2 the 9967 // hash function doesn't have to match the curve and so the same 9968 // signature algorithm works with P-224. 9969 {"ECDSA_P224_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP224, CurveP224}, 9970 {"ECDSA_P256_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP256, CurveP256}, 9971 {"ECDSA_P384_SHA384", signatureECDSAWithP384AndSHA384, testCertECDSAP384, CurveP384}, 9972 {"ECDSA_P521_SHA512", signatureECDSAWithP521AndSHA512, testCertECDSAP521, CurveP521}, 9973 {"RSA_PSS_SHA256", signatureRSAPSSWithSHA256, testCertRSA, 0}, 9974 {"RSA_PSS_SHA384", signatureRSAPSSWithSHA384, testCertRSA, 0}, 9975 {"RSA_PSS_SHA512", signatureRSAPSSWithSHA512, testCertRSA, 0}, 9976 {"Ed25519", signatureEd25519, testCertEd25519, 0}, 9977 // Tests for key types prior to TLS 1.2. 9978 {"RSA", 0, testCertRSA, 0}, 9979 {"ECDSA", 0, testCertECDSAP256, CurveP256}, 9980} 9981 9982const fakeSigAlg1 signatureAlgorithm = 0x2a01 9983const fakeSigAlg2 signatureAlgorithm = 0xff01 9984 9985func addSignatureAlgorithmTests() { 9986 // Not all ciphers involve a signature. Advertise a list which gives all 9987 // versions a signing cipher. 9988 signingCiphers := []uint16{ 9989 TLS_AES_256_GCM_SHA384, 9990 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 9991 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 9992 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 9993 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 9994 } 9995 9996 var allAlgorithms []signatureAlgorithm 9997 for _, alg := range testSignatureAlgorithms { 9998 if alg.id != 0 { 9999 allAlgorithms = append(allAlgorithms, alg.id) 10000 } 10001 } 10002 10003 // Make sure each signature algorithm works. Include some fake values in 10004 // the list and ensure they're ignored. 10005 for _, alg := range testSignatureAlgorithms { 10006 for _, ver := range tlsVersions { 10007 if (ver.version < VersionTLS12) != (alg.id == 0) { 10008 continue 10009 } 10010 10011 var shouldFail, rejectByDefault bool 10012 // ecdsa_sha1 does not exist in TLS 1.3. 10013 if ver.version >= VersionTLS13 && alg.id == signatureECDSAWithSHA1 { 10014 shouldFail = true 10015 } 10016 // RSA-PKCS1 does not exist in TLS 1.3. 10017 if ver.version >= VersionTLS13 && hasComponent(alg.name, "PKCS1") { 10018 shouldFail = true 10019 } 10020 // SHA-224 has been removed from TLS 1.3 and, in 1.3, 10021 // the curve has to match the hash size. 10022 if ver.version >= VersionTLS13 && alg.cert == testCertECDSAP224 { 10023 shouldFail = true 10024 } 10025 10026 // By default, BoringSSL does not enable ecdsa_sha1, ecdsa_secp521_sha512, and ed25519. 10027 if alg.id == signatureECDSAWithSHA1 || alg.id == signatureECDSAWithP521AndSHA512 || alg.id == signatureEd25519 { 10028 rejectByDefault = true 10029 } 10030 10031 var curveFlags []string 10032 if alg.curve != 0 && ver.version <= VersionTLS12 { 10033 // In TLS 1.2, the ECDH curve list also constrains ECDSA keys. Ensure the 10034 // corresponding curve is enabled on the shim. Also include X25519 to 10035 // ensure the shim and runner have something in common for ECDH. 10036 curveFlags = flagInts("-curves", []int{int(CurveX25519), int(alg.curve)}) 10037 } 10038 10039 var signError, signLocalError, verifyError, verifyLocalError, defaultError, defaultLocalError string 10040 if shouldFail { 10041 signError = ":NO_COMMON_SIGNATURE_ALGORITHMS:" 10042 signLocalError = "remote error: handshake failure" 10043 verifyError = ":WRONG_SIGNATURE_TYPE:" 10044 verifyLocalError = "remote error" 10045 rejectByDefault = true 10046 } 10047 if rejectByDefault { 10048 defaultError = ":WRONG_SIGNATURE_TYPE:" 10049 defaultLocalError = "remote error" 10050 } 10051 10052 suffix := "-" + alg.name + "-" + ver.name 10053 10054 for _, testType := range []testType{clientTest, serverTest} { 10055 prefix := "Client-" 10056 if testType == serverTest { 10057 prefix = "Server-" 10058 } 10059 10060 // Test the shim using the algorithm for signing. 10061 signTest := testCase{ 10062 testType: testType, 10063 name: prefix + "Sign" + suffix, 10064 config: Config{ 10065 MaxVersion: ver.version, 10066 VerifySignatureAlgorithms: []signatureAlgorithm{ 10067 fakeSigAlg1, 10068 alg.id, 10069 fakeSigAlg2, 10070 }, 10071 }, 10072 flags: append( 10073 []string{ 10074 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)), 10075 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)), 10076 }, 10077 curveFlags..., 10078 ), 10079 shouldFail: shouldFail, 10080 expectedError: signError, 10081 expectedLocalError: signLocalError, 10082 expectations: connectionExpectations{ 10083 peerSignatureAlgorithm: alg.id, 10084 }, 10085 } 10086 10087 // Test that the shim will select the algorithm when configured to only 10088 // support it. 10089 negotiateTest := testCase{ 10090 testType: testType, 10091 name: prefix + "Sign-Negotiate" + suffix, 10092 config: Config{ 10093 MaxVersion: ver.version, 10094 VerifySignatureAlgorithms: allAlgorithms, 10095 }, 10096 flags: append( 10097 []string{ 10098 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)), 10099 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)), 10100 }, 10101 curveFlags..., 10102 ), 10103 expectations: connectionExpectations{ 10104 peerSignatureAlgorithm: alg.id, 10105 }, 10106 } 10107 if alg.id != 0 { 10108 negotiateTest.flags = append(negotiateTest.flags, "-signing-prefs", strconv.Itoa(int(alg.id))) 10109 } 10110 10111 if testType == serverTest { 10112 // TLS 1.2 servers only sign on some cipher suites. 10113 signTest.config.CipherSuites = signingCiphers 10114 negotiateTest.config.CipherSuites = signingCiphers 10115 } else { 10116 // TLS 1.2 clients only sign when the server requests certificates. 10117 signTest.config.ClientAuth = RequireAnyClientCert 10118 negotiateTest.config.ClientAuth = RequireAnyClientCert 10119 } 10120 testCases = append(testCases, signTest) 10121 if ver.version >= VersionTLS12 && !shouldFail { 10122 testCases = append(testCases, negotiateTest) 10123 } 10124 10125 // Test the shim using the algorithm for verifying. 10126 verifyTest := testCase{ 10127 testType: testType, 10128 name: prefix + "Verify" + suffix, 10129 config: Config{ 10130 MaxVersion: ver.version, 10131 Certificates: []Certificate{getRunnerCertificate(alg.cert)}, 10132 SignSignatureAlgorithms: []signatureAlgorithm{ 10133 alg.id, 10134 }, 10135 Bugs: ProtocolBugs{ 10136 SkipECDSACurveCheck: shouldFail, 10137 IgnoreSignatureVersionChecks: shouldFail, 10138 // Some signature algorithms may not be advertised. 10139 IgnorePeerSignatureAlgorithmPreferences: shouldFail, 10140 }, 10141 }, 10142 flags: curveFlags, 10143 // Resume the session to assert the peer signature 10144 // algorithm is reported on both handshakes. 10145 resumeSession: !shouldFail, 10146 shouldFail: shouldFail, 10147 expectedError: verifyError, 10148 expectedLocalError: verifyLocalError, 10149 } 10150 if alg.id != 0 { 10151 verifyTest.flags = append(verifyTest.flags, "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))) 10152 // The algorithm may be disabled by default, so explicitly enable it. 10153 verifyTest.flags = append(verifyTest.flags, "-verify-prefs", strconv.Itoa(int(alg.id))) 10154 } 10155 10156 // Test whether the shim expects the algorithm enabled by default. 10157 defaultTest := testCase{ 10158 testType: testType, 10159 name: prefix + "VerifyDefault" + suffix, 10160 config: Config{ 10161 MaxVersion: ver.version, 10162 Certificates: []Certificate{getRunnerCertificate(alg.cert)}, 10163 SignSignatureAlgorithms: []signatureAlgorithm{ 10164 alg.id, 10165 }, 10166 Bugs: ProtocolBugs{ 10167 SkipECDSACurveCheck: rejectByDefault, 10168 IgnoreSignatureVersionChecks: rejectByDefault, 10169 // Some signature algorithms may not be advertised. 10170 IgnorePeerSignatureAlgorithmPreferences: rejectByDefault, 10171 }, 10172 }, 10173 flags: append( 10174 []string{"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))}, 10175 curveFlags..., 10176 ), 10177 // Resume the session to assert the peer signature 10178 // algorithm is reported on both handshakes. 10179 resumeSession: !rejectByDefault, 10180 shouldFail: rejectByDefault, 10181 expectedError: defaultError, 10182 expectedLocalError: defaultLocalError, 10183 } 10184 10185 // Test whether the shim handles invalid signatures for this algorithm. 10186 invalidTest := testCase{ 10187 testType: testType, 10188 name: prefix + "InvalidSignature" + suffix, 10189 config: Config{ 10190 MaxVersion: ver.version, 10191 Certificates: []Certificate{getRunnerCertificate(alg.cert)}, 10192 SignSignatureAlgorithms: []signatureAlgorithm{ 10193 alg.id, 10194 }, 10195 Bugs: ProtocolBugs{ 10196 InvalidSignature: true, 10197 }, 10198 }, 10199 flags: curveFlags, 10200 shouldFail: true, 10201 expectedError: ":BAD_SIGNATURE:", 10202 } 10203 if alg.id != 0 { 10204 // The algorithm may be disabled by default, so explicitly enable it. 10205 invalidTest.flags = append(invalidTest.flags, "-verify-prefs", strconv.Itoa(int(alg.id))) 10206 } 10207 10208 if testType == serverTest { 10209 // TLS 1.2 servers only verify when they request client certificates. 10210 verifyTest.flags = append(verifyTest.flags, "-require-any-client-certificate") 10211 defaultTest.flags = append(defaultTest.flags, "-require-any-client-certificate") 10212 invalidTest.flags = append(invalidTest.flags, "-require-any-client-certificate") 10213 } else { 10214 // TLS 1.2 clients only verify on some cipher suites. 10215 verifyTest.config.CipherSuites = signingCiphers 10216 defaultTest.config.CipherSuites = signingCiphers 10217 invalidTest.config.CipherSuites = signingCiphers 10218 } 10219 testCases = append(testCases, verifyTest, defaultTest) 10220 if !shouldFail { 10221 testCases = append(testCases, invalidTest) 10222 } 10223 } 10224 } 10225 } 10226 10227 // Test the peer's verify preferences are available. 10228 for _, ver := range tlsVersions { 10229 if ver.version < VersionTLS12 { 10230 continue 10231 } 10232 testCases = append(testCases, testCase{ 10233 name: "ClientAuth-PeerVerifyPrefs-" + ver.name, 10234 config: Config{ 10235 MaxVersion: ver.version, 10236 ClientAuth: RequireAnyClientCert, 10237 VerifySignatureAlgorithms: []signatureAlgorithm{ 10238 signatureRSAPSSWithSHA256, 10239 signatureEd25519, 10240 signatureECDSAWithP256AndSHA256, 10241 }, 10242 }, 10243 flags: []string{ 10244 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10245 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10246 "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 10247 "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), 10248 "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 10249 }, 10250 }) 10251 10252 testCases = append(testCases, testCase{ 10253 testType: serverTest, 10254 name: "ServerAuth-PeerVerifyPrefs-" + ver.name, 10255 config: Config{ 10256 MaxVersion: ver.version, 10257 VerifySignatureAlgorithms: []signatureAlgorithm{ 10258 signatureRSAPSSWithSHA256, 10259 signatureEd25519, 10260 signatureECDSAWithP256AndSHA256, 10261 }, 10262 }, 10263 flags: []string{ 10264 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10265 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10266 "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 10267 "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), 10268 "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 10269 }, 10270 }) 10271 10272 } 10273 10274 // Test that algorithm selection takes the key type into account. 10275 testCases = append(testCases, testCase{ 10276 name: "ClientAuth-SignatureType", 10277 config: Config{ 10278 ClientAuth: RequireAnyClientCert, 10279 MaxVersion: VersionTLS12, 10280 VerifySignatureAlgorithms: []signatureAlgorithm{ 10281 signatureECDSAWithP521AndSHA512, 10282 signatureRSAPKCS1WithSHA384, 10283 signatureECDSAWithSHA1, 10284 }, 10285 }, 10286 flags: []string{ 10287 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10288 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10289 }, 10290 expectations: connectionExpectations{ 10291 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, 10292 }, 10293 }) 10294 10295 testCases = append(testCases, testCase{ 10296 name: "ClientAuth-SignatureType-TLS13", 10297 config: Config{ 10298 ClientAuth: RequireAnyClientCert, 10299 MaxVersion: VersionTLS13, 10300 VerifySignatureAlgorithms: []signatureAlgorithm{ 10301 signatureECDSAWithP521AndSHA512, 10302 signatureRSAPKCS1WithSHA384, 10303 signatureRSAPSSWithSHA384, 10304 signatureECDSAWithSHA1, 10305 }, 10306 }, 10307 flags: []string{ 10308 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10309 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10310 }, 10311 expectations: connectionExpectations{ 10312 peerSignatureAlgorithm: signatureRSAPSSWithSHA384, 10313 }, 10314 }) 10315 10316 testCases = append(testCases, testCase{ 10317 testType: serverTest, 10318 name: "ServerAuth-SignatureType", 10319 config: Config{ 10320 MaxVersion: VersionTLS12, 10321 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10322 VerifySignatureAlgorithms: []signatureAlgorithm{ 10323 signatureECDSAWithP521AndSHA512, 10324 signatureRSAPKCS1WithSHA384, 10325 signatureECDSAWithSHA1, 10326 }, 10327 }, 10328 expectations: connectionExpectations{ 10329 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, 10330 }, 10331 }) 10332 10333 testCases = append(testCases, testCase{ 10334 testType: serverTest, 10335 name: "ServerAuth-SignatureType-TLS13", 10336 config: Config{ 10337 MaxVersion: VersionTLS13, 10338 VerifySignatureAlgorithms: []signatureAlgorithm{ 10339 signatureECDSAWithP521AndSHA512, 10340 signatureRSAPKCS1WithSHA384, 10341 signatureRSAPSSWithSHA384, 10342 signatureECDSAWithSHA1, 10343 }, 10344 }, 10345 expectations: connectionExpectations{ 10346 peerSignatureAlgorithm: signatureRSAPSSWithSHA384, 10347 }, 10348 }) 10349 10350 // Test that signature verification takes the key type into account. 10351 testCases = append(testCases, testCase{ 10352 testType: serverTest, 10353 name: "Verify-ClientAuth-SignatureType", 10354 config: Config{ 10355 MaxVersion: VersionTLS12, 10356 Certificates: []Certificate{rsaCertificate}, 10357 SignSignatureAlgorithms: []signatureAlgorithm{ 10358 signatureRSAPKCS1WithSHA256, 10359 }, 10360 Bugs: ProtocolBugs{ 10361 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10362 }, 10363 }, 10364 flags: []string{ 10365 "-require-any-client-certificate", 10366 }, 10367 shouldFail: true, 10368 expectedError: ":WRONG_SIGNATURE_TYPE:", 10369 }) 10370 10371 testCases = append(testCases, testCase{ 10372 testType: serverTest, 10373 name: "Verify-ClientAuth-SignatureType-TLS13", 10374 config: Config{ 10375 MaxVersion: VersionTLS13, 10376 Certificates: []Certificate{rsaCertificate}, 10377 SignSignatureAlgorithms: []signatureAlgorithm{ 10378 signatureRSAPSSWithSHA256, 10379 }, 10380 Bugs: ProtocolBugs{ 10381 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10382 }, 10383 }, 10384 flags: []string{ 10385 "-require-any-client-certificate", 10386 }, 10387 shouldFail: true, 10388 expectedError: ":WRONG_SIGNATURE_TYPE:", 10389 }) 10390 10391 testCases = append(testCases, testCase{ 10392 name: "Verify-ServerAuth-SignatureType", 10393 config: Config{ 10394 MaxVersion: VersionTLS12, 10395 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10396 SignSignatureAlgorithms: []signatureAlgorithm{ 10397 signatureRSAPKCS1WithSHA256, 10398 }, 10399 Bugs: ProtocolBugs{ 10400 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10401 }, 10402 }, 10403 shouldFail: true, 10404 expectedError: ":WRONG_SIGNATURE_TYPE:", 10405 }) 10406 10407 testCases = append(testCases, testCase{ 10408 name: "Verify-ServerAuth-SignatureType-TLS13", 10409 config: Config{ 10410 MaxVersion: VersionTLS13, 10411 SignSignatureAlgorithms: []signatureAlgorithm{ 10412 signatureRSAPSSWithSHA256, 10413 }, 10414 Bugs: ProtocolBugs{ 10415 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10416 }, 10417 }, 10418 shouldFail: true, 10419 expectedError: ":WRONG_SIGNATURE_TYPE:", 10420 }) 10421 10422 // Test that, if the ClientHello list is missing, the server falls back 10423 // to SHA-1 in TLS 1.2, but not TLS 1.3. 10424 testCases = append(testCases, testCase{ 10425 testType: serverTest, 10426 name: "ServerAuth-SHA1-Fallback-RSA", 10427 config: Config{ 10428 MaxVersion: VersionTLS12, 10429 VerifySignatureAlgorithms: []signatureAlgorithm{ 10430 signatureRSAPKCS1WithSHA1, 10431 }, 10432 Bugs: ProtocolBugs{ 10433 NoSignatureAlgorithms: true, 10434 }, 10435 }, 10436 flags: []string{ 10437 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10438 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10439 }, 10440 }) 10441 10442 testCases = append(testCases, testCase{ 10443 testType: serverTest, 10444 name: "ServerAuth-SHA1-Fallback-ECDSA", 10445 config: Config{ 10446 MaxVersion: VersionTLS12, 10447 VerifySignatureAlgorithms: []signatureAlgorithm{ 10448 signatureECDSAWithSHA1, 10449 }, 10450 Bugs: ProtocolBugs{ 10451 NoSignatureAlgorithms: true, 10452 }, 10453 }, 10454 flags: []string{ 10455 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 10456 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 10457 }, 10458 }) 10459 10460 testCases = append(testCases, testCase{ 10461 testType: serverTest, 10462 name: "ServerAuth-NoFallback-TLS13", 10463 config: Config{ 10464 MaxVersion: VersionTLS13, 10465 VerifySignatureAlgorithms: []signatureAlgorithm{ 10466 signatureRSAPKCS1WithSHA1, 10467 }, 10468 Bugs: ProtocolBugs{ 10469 NoSignatureAlgorithms: true, 10470 DisableDelegatedCredentials: true, 10471 }, 10472 }, 10473 shouldFail: true, 10474 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10475 }) 10476 10477 // The CertificateRequest list, however, may never be omitted. It is a 10478 // syntax error for it to be empty. 10479 testCases = append(testCases, testCase{ 10480 name: "ClientAuth-NoFallback-RSA", 10481 config: Config{ 10482 MaxVersion: VersionTLS12, 10483 ClientAuth: RequireAnyClientCert, 10484 VerifySignatureAlgorithms: []signatureAlgorithm{ 10485 signatureRSAPKCS1WithSHA1, 10486 }, 10487 Bugs: ProtocolBugs{ 10488 NoSignatureAlgorithms: true, 10489 }, 10490 }, 10491 flags: []string{ 10492 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10493 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10494 }, 10495 shouldFail: true, 10496 expectedError: ":DECODE_ERROR:", 10497 expectedLocalError: "remote error: error decoding message", 10498 }) 10499 10500 testCases = append(testCases, testCase{ 10501 name: "ClientAuth-NoFallback-ECDSA", 10502 config: Config{ 10503 MaxVersion: VersionTLS12, 10504 ClientAuth: RequireAnyClientCert, 10505 VerifySignatureAlgorithms: []signatureAlgorithm{ 10506 signatureECDSAWithSHA1, 10507 }, 10508 Bugs: ProtocolBugs{ 10509 NoSignatureAlgorithms: true, 10510 }, 10511 }, 10512 flags: []string{ 10513 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 10514 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 10515 }, 10516 shouldFail: true, 10517 expectedError: ":DECODE_ERROR:", 10518 expectedLocalError: "remote error: error decoding message", 10519 }) 10520 10521 testCases = append(testCases, testCase{ 10522 name: "ClientAuth-NoFallback-TLS13", 10523 config: Config{ 10524 MaxVersion: VersionTLS13, 10525 ClientAuth: RequireAnyClientCert, 10526 VerifySignatureAlgorithms: []signatureAlgorithm{ 10527 signatureRSAPKCS1WithSHA1, 10528 }, 10529 Bugs: ProtocolBugs{ 10530 NoSignatureAlgorithms: true, 10531 }, 10532 }, 10533 flags: []string{ 10534 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10535 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10536 }, 10537 shouldFail: true, 10538 expectedError: ":DECODE_ERROR:", 10539 expectedLocalError: "remote error: error decoding message", 10540 }) 10541 10542 // Test that signature preferences are enforced. BoringSSL does not 10543 // implement MD5 signatures. 10544 testCases = append(testCases, testCase{ 10545 testType: serverTest, 10546 name: "ClientAuth-Enforced", 10547 config: Config{ 10548 MaxVersion: VersionTLS12, 10549 Certificates: []Certificate{rsaCertificate}, 10550 SignSignatureAlgorithms: []signatureAlgorithm{ 10551 signatureRSAPKCS1WithMD5, 10552 }, 10553 Bugs: ProtocolBugs{ 10554 IgnorePeerSignatureAlgorithmPreferences: true, 10555 }, 10556 }, 10557 flags: []string{"-require-any-client-certificate"}, 10558 shouldFail: true, 10559 expectedError: ":WRONG_SIGNATURE_TYPE:", 10560 }) 10561 10562 testCases = append(testCases, testCase{ 10563 name: "ServerAuth-Enforced", 10564 config: Config{ 10565 MaxVersion: VersionTLS12, 10566 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10567 SignSignatureAlgorithms: []signatureAlgorithm{ 10568 signatureRSAPKCS1WithMD5, 10569 }, 10570 Bugs: ProtocolBugs{ 10571 IgnorePeerSignatureAlgorithmPreferences: true, 10572 }, 10573 }, 10574 shouldFail: true, 10575 expectedError: ":WRONG_SIGNATURE_TYPE:", 10576 }) 10577 testCases = append(testCases, testCase{ 10578 testType: serverTest, 10579 name: "ClientAuth-Enforced-TLS13", 10580 config: Config{ 10581 MaxVersion: VersionTLS13, 10582 Certificates: []Certificate{rsaCertificate}, 10583 SignSignatureAlgorithms: []signatureAlgorithm{ 10584 signatureRSAPKCS1WithMD5, 10585 }, 10586 Bugs: ProtocolBugs{ 10587 IgnorePeerSignatureAlgorithmPreferences: true, 10588 IgnoreSignatureVersionChecks: true, 10589 }, 10590 }, 10591 flags: []string{"-require-any-client-certificate"}, 10592 shouldFail: true, 10593 expectedError: ":WRONG_SIGNATURE_TYPE:", 10594 }) 10595 10596 testCases = append(testCases, testCase{ 10597 name: "ServerAuth-Enforced-TLS13", 10598 config: Config{ 10599 MaxVersion: VersionTLS13, 10600 SignSignatureAlgorithms: []signatureAlgorithm{ 10601 signatureRSAPKCS1WithMD5, 10602 }, 10603 Bugs: ProtocolBugs{ 10604 IgnorePeerSignatureAlgorithmPreferences: true, 10605 IgnoreSignatureVersionChecks: true, 10606 }, 10607 }, 10608 shouldFail: true, 10609 expectedError: ":WRONG_SIGNATURE_TYPE:", 10610 }) 10611 10612 // Test that the negotiated signature algorithm respects the client and 10613 // server preferences. 10614 testCases = append(testCases, testCase{ 10615 name: "NoCommonAlgorithms", 10616 config: Config{ 10617 MaxVersion: VersionTLS12, 10618 ClientAuth: RequireAnyClientCert, 10619 VerifySignatureAlgorithms: []signatureAlgorithm{ 10620 signatureRSAPKCS1WithSHA512, 10621 signatureRSAPKCS1WithSHA1, 10622 }, 10623 }, 10624 flags: []string{ 10625 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10626 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10627 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 10628 }, 10629 shouldFail: true, 10630 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10631 }) 10632 testCases = append(testCases, testCase{ 10633 name: "NoCommonAlgorithms-TLS13", 10634 config: Config{ 10635 MaxVersion: VersionTLS13, 10636 ClientAuth: RequireAnyClientCert, 10637 VerifySignatureAlgorithms: []signatureAlgorithm{ 10638 signatureRSAPSSWithSHA512, 10639 signatureRSAPSSWithSHA384, 10640 }, 10641 }, 10642 flags: []string{ 10643 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10644 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10645 "-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 10646 }, 10647 shouldFail: true, 10648 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10649 }) 10650 testCases = append(testCases, testCase{ 10651 name: "Agree-Digest-SHA256", 10652 config: Config{ 10653 MaxVersion: VersionTLS12, 10654 ClientAuth: RequireAnyClientCert, 10655 VerifySignatureAlgorithms: []signatureAlgorithm{ 10656 signatureRSAPKCS1WithSHA1, 10657 signatureRSAPKCS1WithSHA256, 10658 }, 10659 }, 10660 flags: []string{ 10661 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10662 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10663 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 10664 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA1)), 10665 }, 10666 expectations: connectionExpectations{ 10667 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10668 }, 10669 }) 10670 testCases = append(testCases, testCase{ 10671 name: "Agree-Digest-SHA1", 10672 config: Config{ 10673 MaxVersion: VersionTLS12, 10674 ClientAuth: RequireAnyClientCert, 10675 VerifySignatureAlgorithms: []signatureAlgorithm{ 10676 signatureRSAPKCS1WithSHA1, 10677 }, 10678 }, 10679 flags: []string{ 10680 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10681 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10682 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA512)), 10683 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 10684 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA1)), 10685 }, 10686 expectations: connectionExpectations{ 10687 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA1, 10688 }, 10689 }) 10690 testCases = append(testCases, testCase{ 10691 name: "Agree-Digest-Default", 10692 config: Config{ 10693 MaxVersion: VersionTLS12, 10694 ClientAuth: RequireAnyClientCert, 10695 VerifySignatureAlgorithms: []signatureAlgorithm{ 10696 signatureRSAPKCS1WithSHA256, 10697 signatureECDSAWithP256AndSHA256, 10698 signatureRSAPKCS1WithSHA1, 10699 signatureECDSAWithSHA1, 10700 }, 10701 }, 10702 flags: []string{ 10703 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10704 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10705 }, 10706 expectations: connectionExpectations{ 10707 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10708 }, 10709 }) 10710 10711 // Test that the signing preference list may include extra algorithms 10712 // without negotiation problems. 10713 testCases = append(testCases, testCase{ 10714 testType: serverTest, 10715 name: "FilterExtraAlgorithms", 10716 config: Config{ 10717 MaxVersion: VersionTLS12, 10718 VerifySignatureAlgorithms: []signatureAlgorithm{ 10719 signatureRSAPKCS1WithSHA256, 10720 }, 10721 }, 10722 flags: []string{ 10723 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10724 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10725 "-signing-prefs", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 10726 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 10727 }, 10728 expectations: connectionExpectations{ 10729 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10730 }, 10731 }) 10732 10733 // In TLS 1.2 and below, ECDSA uses the curve list rather than the 10734 // signature algorithms. 10735 testCases = append(testCases, testCase{ 10736 name: "CheckLeafCurve", 10737 config: Config{ 10738 MaxVersion: VersionTLS12, 10739 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 10740 Certificates: []Certificate{ecdsaP256Certificate}, 10741 }, 10742 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 10743 shouldFail: true, 10744 expectedError: ":BAD_ECC_CERT:", 10745 }) 10746 10747 // In TLS 1.3, ECDSA does not use the ECDHE curve list. 10748 testCases = append(testCases, testCase{ 10749 name: "CheckLeafCurve-TLS13", 10750 config: Config{ 10751 MaxVersion: VersionTLS13, 10752 Certificates: []Certificate{ecdsaP256Certificate}, 10753 }, 10754 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 10755 }) 10756 10757 // In TLS 1.2, the ECDSA curve is not in the signature algorithm. 10758 testCases = append(testCases, testCase{ 10759 name: "ECDSACurveMismatch-Verify-TLS12", 10760 config: Config{ 10761 MaxVersion: VersionTLS12, 10762 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 10763 Certificates: []Certificate{ecdsaP256Certificate}, 10764 SignSignatureAlgorithms: []signatureAlgorithm{ 10765 signatureECDSAWithP384AndSHA384, 10766 }, 10767 }, 10768 }) 10769 10770 // In TLS 1.3, the ECDSA curve comes from the signature algorithm. 10771 testCases = append(testCases, testCase{ 10772 name: "ECDSACurveMismatch-Verify-TLS13", 10773 config: Config{ 10774 MaxVersion: VersionTLS13, 10775 Certificates: []Certificate{ecdsaP256Certificate}, 10776 SignSignatureAlgorithms: []signatureAlgorithm{ 10777 signatureECDSAWithP384AndSHA384, 10778 }, 10779 Bugs: ProtocolBugs{ 10780 SkipECDSACurveCheck: true, 10781 }, 10782 }, 10783 shouldFail: true, 10784 expectedError: ":WRONG_SIGNATURE_TYPE:", 10785 }) 10786 10787 // Signature algorithm selection in TLS 1.3 should take the curve into 10788 // account. 10789 testCases = append(testCases, testCase{ 10790 testType: serverTest, 10791 name: "ECDSACurveMismatch-Sign-TLS13", 10792 config: Config{ 10793 MaxVersion: VersionTLS13, 10794 VerifySignatureAlgorithms: []signatureAlgorithm{ 10795 signatureECDSAWithP384AndSHA384, 10796 signatureECDSAWithP256AndSHA256, 10797 }, 10798 }, 10799 flags: []string{ 10800 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 10801 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 10802 }, 10803 expectations: connectionExpectations{ 10804 peerSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10805 }, 10806 }) 10807 10808 // RSASSA-PSS with SHA-512 is too large for 1024-bit RSA. Test that the 10809 // server does not attempt to sign in that case. 10810 testCases = append(testCases, testCase{ 10811 testType: serverTest, 10812 name: "RSA-PSS-Large", 10813 config: Config{ 10814 MaxVersion: VersionTLS13, 10815 VerifySignatureAlgorithms: []signatureAlgorithm{ 10816 signatureRSAPSSWithSHA512, 10817 }, 10818 }, 10819 flags: []string{ 10820 "-cert-file", path.Join(*resourceDir, rsa1024CertificateFile), 10821 "-key-file", path.Join(*resourceDir, rsa1024KeyFile), 10822 }, 10823 shouldFail: true, 10824 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10825 }) 10826 10827 // Test that RSA-PSS is enabled by default for TLS 1.2. 10828 testCases = append(testCases, testCase{ 10829 testType: clientTest, 10830 name: "RSA-PSS-Default-Verify", 10831 config: Config{ 10832 MaxVersion: VersionTLS12, 10833 SignSignatureAlgorithms: []signatureAlgorithm{ 10834 signatureRSAPSSWithSHA256, 10835 }, 10836 }, 10837 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 10838 }) 10839 10840 testCases = append(testCases, testCase{ 10841 testType: serverTest, 10842 name: "RSA-PSS-Default-Sign", 10843 config: Config{ 10844 MaxVersion: VersionTLS12, 10845 VerifySignatureAlgorithms: []signatureAlgorithm{ 10846 signatureRSAPSSWithSHA256, 10847 }, 10848 }, 10849 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 10850 }) 10851 10852 // TLS 1.1 and below has no way to advertise support for or negotiate 10853 // Ed25519's signature algorithm. 10854 testCases = append(testCases, testCase{ 10855 testType: clientTest, 10856 name: "NoEd25519-TLS11-ServerAuth-Verify", 10857 config: Config{ 10858 MaxVersion: VersionTLS11, 10859 Certificates: []Certificate{ed25519Certificate}, 10860 Bugs: ProtocolBugs{ 10861 // Sign with Ed25519 even though it is TLS 1.1. 10862 SigningAlgorithmForLegacyVersions: signatureEd25519, 10863 }, 10864 }, 10865 flags: []string{"-verify-prefs", strconv.Itoa(int(signatureEd25519))}, 10866 shouldFail: true, 10867 expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:", 10868 }) 10869 testCases = append(testCases, testCase{ 10870 testType: serverTest, 10871 name: "NoEd25519-TLS11-ServerAuth-Sign", 10872 config: Config{ 10873 MaxVersion: VersionTLS11, 10874 }, 10875 flags: []string{ 10876 "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), 10877 "-key-file", path.Join(*resourceDir, ed25519KeyFile), 10878 }, 10879 shouldFail: true, 10880 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10881 }) 10882 testCases = append(testCases, testCase{ 10883 testType: serverTest, 10884 name: "NoEd25519-TLS11-ClientAuth-Verify", 10885 config: Config{ 10886 MaxVersion: VersionTLS11, 10887 Certificates: []Certificate{ed25519Certificate}, 10888 Bugs: ProtocolBugs{ 10889 // Sign with Ed25519 even though it is TLS 1.1. 10890 SigningAlgorithmForLegacyVersions: signatureEd25519, 10891 }, 10892 }, 10893 flags: []string{ 10894 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 10895 "-require-any-client-certificate", 10896 }, 10897 shouldFail: true, 10898 expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:", 10899 }) 10900 testCases = append(testCases, testCase{ 10901 testType: clientTest, 10902 name: "NoEd25519-TLS11-ClientAuth-Sign", 10903 config: Config{ 10904 MaxVersion: VersionTLS11, 10905 ClientAuth: RequireAnyClientCert, 10906 }, 10907 flags: []string{ 10908 "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), 10909 "-key-file", path.Join(*resourceDir, ed25519KeyFile), 10910 }, 10911 shouldFail: true, 10912 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10913 }) 10914 10915 // Test Ed25519 is not advertised by default. 10916 testCases = append(testCases, testCase{ 10917 testType: clientTest, 10918 name: "Ed25519DefaultDisable-NoAdvertise", 10919 config: Config{ 10920 Certificates: []Certificate{ed25519Certificate}, 10921 }, 10922 shouldFail: true, 10923 expectedLocalError: "tls: no common signature algorithms", 10924 }) 10925 10926 // Test Ed25519, when disabled, is not accepted if the peer ignores our 10927 // preferences. 10928 testCases = append(testCases, testCase{ 10929 testType: clientTest, 10930 name: "Ed25519DefaultDisable-NoAccept", 10931 config: Config{ 10932 Certificates: []Certificate{ed25519Certificate}, 10933 Bugs: ProtocolBugs{ 10934 IgnorePeerSignatureAlgorithmPreferences: true, 10935 }, 10936 }, 10937 shouldFail: true, 10938 expectedLocalError: "remote error: illegal parameter", 10939 expectedError: ":WRONG_SIGNATURE_TYPE:", 10940 }) 10941 10942 // Test that configuring verify preferences changes what the client 10943 // advertises. 10944 testCases = append(testCases, testCase{ 10945 name: "VerifyPreferences-Advertised", 10946 config: Config{ 10947 Certificates: []Certificate{rsaCertificate}, 10948 SignSignatureAlgorithms: []signatureAlgorithm{ 10949 signatureRSAPSSWithSHA256, 10950 signatureRSAPSSWithSHA384, 10951 signatureRSAPSSWithSHA512, 10952 }, 10953 }, 10954 flags: []string{ 10955 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10956 "-expect-peer-signature-algorithm", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10957 }, 10958 }) 10959 10960 // Test that the client advertises a set which the runner can find 10961 // nothing in common with. 10962 testCases = append(testCases, testCase{ 10963 name: "VerifyPreferences-NoCommonAlgorithms", 10964 config: Config{ 10965 Certificates: []Certificate{rsaCertificate}, 10966 SignSignatureAlgorithms: []signatureAlgorithm{ 10967 signatureRSAPSSWithSHA256, 10968 signatureRSAPSSWithSHA512, 10969 }, 10970 }, 10971 flags: []string{ 10972 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10973 }, 10974 shouldFail: true, 10975 expectedLocalError: "tls: no common signature algorithms", 10976 }) 10977 10978 // Test that the client enforces its preferences when configured. 10979 testCases = append(testCases, testCase{ 10980 name: "VerifyPreferences-Enforced", 10981 config: Config{ 10982 Certificates: []Certificate{rsaCertificate}, 10983 SignSignatureAlgorithms: []signatureAlgorithm{ 10984 signatureRSAPSSWithSHA256, 10985 signatureRSAPSSWithSHA512, 10986 }, 10987 Bugs: ProtocolBugs{ 10988 IgnorePeerSignatureAlgorithmPreferences: true, 10989 }, 10990 }, 10991 flags: []string{ 10992 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10993 }, 10994 shouldFail: true, 10995 expectedLocalError: "remote error: illegal parameter", 10996 expectedError: ":WRONG_SIGNATURE_TYPE:", 10997 }) 10998 10999 // Test that explicitly configuring Ed25519 is as good as changing the 11000 // boolean toggle. 11001 testCases = append(testCases, testCase{ 11002 name: "VerifyPreferences-Ed25519", 11003 config: Config{ 11004 Certificates: []Certificate{ed25519Certificate}, 11005 }, 11006 flags: []string{ 11007 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 11008 }, 11009 }) 11010 11011 for _, testType := range []testType{clientTest, serverTest} { 11012 for _, ver := range tlsVersions { 11013 if ver.version < VersionTLS12 { 11014 continue 11015 } 11016 11017 prefix := "Client-" + ver.name + "-" 11018 if testType == serverTest { 11019 prefix = "Server-" + ver.name + "-" 11020 } 11021 11022 // Test that the shim will not sign MD5/SHA1 with RSA at TLS 1.2, 11023 // even if specified in signing preferences. 11024 testCases = append(testCases, testCase{ 11025 testType: testType, 11026 name: prefix + "NoSign-RSA_PKCS1_MD5_SHA1", 11027 config: Config{ 11028 MaxVersion: ver.version, 11029 CipherSuites: signingCiphers, 11030 ClientAuth: RequireAnyClientCert, 11031 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPKCS1WithMD5AndSHA1}, 11032 }, 11033 flags: []string{ 11034 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 11035 "-key-file", path.Join(*resourceDir, rsaKeyFile), 11036 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithMD5AndSHA1)), 11037 // Include a valid algorithm as well, to avoid an empty list 11038 // if filtered out. 11039 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 11040 }, 11041 shouldFail: true, 11042 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 11043 }) 11044 11045 // Test that the shim will not accept MD5/SHA1 with RSA at TLS 1.2, 11046 // even if specified in verify preferences. 11047 testCases = append(testCases, testCase{ 11048 testType: testType, 11049 name: prefix + "NoVerify-RSA_PKCS1_MD5_SHA1", 11050 config: Config{ 11051 MaxVersion: ver.version, 11052 Certificates: []Certificate{rsaCertificate}, 11053 Bugs: ProtocolBugs{ 11054 IgnorePeerSignatureAlgorithmPreferences: true, 11055 AlwaysSignAsLegacyVersion: true, 11056 SendSignatureAlgorithm: signatureRSAPKCS1WithMD5AndSHA1, 11057 }, 11058 }, 11059 flags: []string{ 11060 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 11061 "-key-file", path.Join(*resourceDir, rsaKeyFile), 11062 "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithMD5AndSHA1)), 11063 // Include a valid algorithm as well, to avoid an empty list 11064 // if filtered out. 11065 "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 11066 "-require-any-client-certificate", 11067 }, 11068 shouldFail: true, 11069 expectedError: ":WRONG_SIGNATURE_TYPE:", 11070 }) 11071 } 11072 } 11073} 11074 11075// timeouts is the retransmit schedule for BoringSSL. It doubles and 11076// caps at 60 seconds. On the 13th timeout, it gives up. 11077var timeouts = []time.Duration{ 11078 1 * time.Second, 11079 2 * time.Second, 11080 4 * time.Second, 11081 8 * time.Second, 11082 16 * time.Second, 11083 32 * time.Second, 11084 60 * time.Second, 11085 60 * time.Second, 11086 60 * time.Second, 11087 60 * time.Second, 11088 60 * time.Second, 11089 60 * time.Second, 11090 60 * time.Second, 11091} 11092 11093// shortTimeouts is an alternate set of timeouts which would occur if the 11094// initial timeout duration was set to 250ms. 11095var shortTimeouts = []time.Duration{ 11096 250 * time.Millisecond, 11097 500 * time.Millisecond, 11098 1 * time.Second, 11099 2 * time.Second, 11100 4 * time.Second, 11101 8 * time.Second, 11102 16 * time.Second, 11103 32 * time.Second, 11104 60 * time.Second, 11105 60 * time.Second, 11106 60 * time.Second, 11107 60 * time.Second, 11108 60 * time.Second, 11109} 11110 11111func addDTLSRetransmitTests() { 11112 // These tests work by coordinating some behavior on both the shim and 11113 // the runner. 11114 // 11115 // TimeoutSchedule configures the runner to send a series of timeout 11116 // opcodes to the shim (see packetAdaptor) immediately before reading 11117 // each peer handshake flight N. The timeout opcode both simulates a 11118 // timeout in the shim and acts as a synchronization point to help the 11119 // runner bracket each handshake flight. 11120 // 11121 // We assume the shim does not read from the channel eagerly. It must 11122 // first wait until it has sent flight N and is ready to receive 11123 // handshake flight N+1. At this point, it will process the timeout 11124 // opcode. It must then immediately respond with a timeout ACK and act 11125 // as if the shim was idle for the specified amount of time. 11126 // 11127 // The runner then drops all packets received before the ACK and 11128 // continues waiting for flight N. This ordering results in one attempt 11129 // at sending flight N to be dropped. For the test to complete, the 11130 // shim must send flight N again, testing that the shim implements DTLS 11131 // retransmit on a timeout. 11132 11133 // TODO(davidben): Add DTLS 1.3 versions of these tests. There will 11134 // likely be more epochs to cross and the final message's retransmit may 11135 // be more complex. 11136 11137 // Test that this is indeed the timeout schedule. Stress all 11138 // four patterns of handshake. 11139 for i := 1; i < len(timeouts); i++ { 11140 number := strconv.Itoa(i) 11141 testCases = append(testCases, testCase{ 11142 protocol: dtls, 11143 name: "DTLS-Retransmit-Client-" + number, 11144 config: Config{ 11145 MaxVersion: VersionTLS12, 11146 Bugs: ProtocolBugs{ 11147 TimeoutSchedule: timeouts[:i], 11148 }, 11149 }, 11150 resumeSession: true, 11151 flags: []string{"-async"}, 11152 }) 11153 testCases = append(testCases, testCase{ 11154 protocol: dtls, 11155 testType: serverTest, 11156 name: "DTLS-Retransmit-Server-" + number, 11157 config: Config{ 11158 MaxVersion: VersionTLS12, 11159 Bugs: ProtocolBugs{ 11160 TimeoutSchedule: timeouts[:i], 11161 }, 11162 }, 11163 resumeSession: true, 11164 flags: []string{"-async"}, 11165 }) 11166 } 11167 11168 // Test that exceeding the timeout schedule hits a read 11169 // timeout. 11170 testCases = append(testCases, testCase{ 11171 protocol: dtls, 11172 name: "DTLS-Retransmit-Timeout", 11173 config: Config{ 11174 MaxVersion: VersionTLS12, 11175 Bugs: ProtocolBugs{ 11176 TimeoutSchedule: timeouts, 11177 }, 11178 }, 11179 resumeSession: true, 11180 flags: []string{"-async"}, 11181 shouldFail: true, 11182 expectedError: ":READ_TIMEOUT_EXPIRED:", 11183 }) 11184 11185 // Test that timeout handling has a fudge factor, due to API 11186 // problems. 11187 testCases = append(testCases, testCase{ 11188 protocol: dtls, 11189 name: "DTLS-Retransmit-Fudge", 11190 config: Config{ 11191 MaxVersion: VersionTLS12, 11192 Bugs: ProtocolBugs{ 11193 TimeoutSchedule: []time.Duration{ 11194 timeouts[0] - 10*time.Millisecond, 11195 }, 11196 }, 11197 }, 11198 resumeSession: true, 11199 flags: []string{"-async"}, 11200 }) 11201 11202 // Test that the final Finished retransmitting isn't 11203 // duplicated if the peer badly fragments everything. 11204 testCases = append(testCases, testCase{ 11205 testType: serverTest, 11206 protocol: dtls, 11207 name: "DTLS-Retransmit-Fragmented", 11208 config: Config{ 11209 MaxVersion: VersionTLS12, 11210 Bugs: ProtocolBugs{ 11211 TimeoutSchedule: []time.Duration{timeouts[0]}, 11212 MaxHandshakeRecordLength: 2, 11213 }, 11214 }, 11215 flags: []string{"-async"}, 11216 }) 11217 11218 // Test the timeout schedule when a shorter initial timeout duration is set. 11219 testCases = append(testCases, testCase{ 11220 protocol: dtls, 11221 name: "DTLS-Retransmit-Short-Client", 11222 config: Config{ 11223 MaxVersion: VersionTLS12, 11224 Bugs: ProtocolBugs{ 11225 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1], 11226 }, 11227 }, 11228 resumeSession: true, 11229 flags: []string{ 11230 "-async", 11231 "-initial-timeout-duration-ms", "250", 11232 }, 11233 }) 11234 testCases = append(testCases, testCase{ 11235 protocol: dtls, 11236 testType: serverTest, 11237 name: "DTLS-Retransmit-Short-Server", 11238 config: Config{ 11239 MaxVersion: VersionTLS12, 11240 Bugs: ProtocolBugs{ 11241 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1], 11242 }, 11243 }, 11244 resumeSession: true, 11245 flags: []string{ 11246 "-async", 11247 "-initial-timeout-duration-ms", "250", 11248 }, 11249 }) 11250 11251 // If the shim sends the last Finished (server full or client resume 11252 // handshakes), it must retransmit that Finished when it sees a 11253 // post-handshake penultimate Finished from the runner. The above tests 11254 // cover this. Conversely, if the shim sends the penultimate Finished 11255 // (client full or server resume), test that it does not retransmit. 11256 testCases = append(testCases, testCase{ 11257 protocol: dtls, 11258 testType: clientTest, 11259 name: "DTLS-StrayRetransmitFinished-ClientFull", 11260 config: Config{ 11261 MaxVersion: VersionTLS12, 11262 Bugs: ProtocolBugs{ 11263 RetransmitFinished: true, 11264 }, 11265 }, 11266 }) 11267 testCases = append(testCases, testCase{ 11268 protocol: dtls, 11269 testType: serverTest, 11270 name: "DTLS-StrayRetransmitFinished-ServerResume", 11271 config: Config{ 11272 MaxVersion: VersionTLS12, 11273 }, 11274 resumeConfig: &Config{ 11275 MaxVersion: VersionTLS12, 11276 Bugs: ProtocolBugs{ 11277 RetransmitFinished: true, 11278 }, 11279 }, 11280 resumeSession: true, 11281 }) 11282} 11283 11284func addExportKeyingMaterialTests() { 11285 for _, vers := range tlsVersions { 11286 testCases = append(testCases, testCase{ 11287 name: "ExportKeyingMaterial-" + vers.name, 11288 config: Config{ 11289 MaxVersion: vers.version, 11290 }, 11291 // Test the exporter in both initial and resumption 11292 // handshakes. 11293 resumeSession: true, 11294 exportKeyingMaterial: 1024, 11295 exportLabel: "label", 11296 exportContext: "context", 11297 useExportContext: true, 11298 }) 11299 testCases = append(testCases, testCase{ 11300 name: "ExportKeyingMaterial-NoContext-" + vers.name, 11301 config: Config{ 11302 MaxVersion: vers.version, 11303 }, 11304 exportKeyingMaterial: 1024, 11305 }) 11306 testCases = append(testCases, testCase{ 11307 name: "ExportKeyingMaterial-EmptyContext-" + vers.name, 11308 config: Config{ 11309 MaxVersion: vers.version, 11310 }, 11311 exportKeyingMaterial: 1024, 11312 useExportContext: true, 11313 }) 11314 testCases = append(testCases, testCase{ 11315 name: "ExportKeyingMaterial-Small-" + vers.name, 11316 config: Config{ 11317 MaxVersion: vers.version, 11318 }, 11319 exportKeyingMaterial: 1, 11320 exportLabel: "label", 11321 exportContext: "context", 11322 useExportContext: true, 11323 }) 11324 11325 if vers.version >= VersionTLS13 { 11326 // Test the exporters do not work while the client is 11327 // sending 0-RTT data. 11328 testCases = append(testCases, testCase{ 11329 name: "NoEarlyKeyingMaterial-Client-InEarlyData-" + vers.name, 11330 config: Config{ 11331 MaxVersion: vers.version, 11332 }, 11333 resumeSession: true, 11334 earlyData: true, 11335 flags: []string{ 11336 "-on-resume-export-keying-material", "1024", 11337 "-on-resume-export-label", "label", 11338 "-on-resume-export-context", "context", 11339 }, 11340 shouldFail: true, 11341 expectedError: ":HANDSHAKE_NOT_COMPLETE:", 11342 }) 11343 11344 // Test the normal exporter on the server in half-RTT. 11345 testCases = append(testCases, testCase{ 11346 testType: serverTest, 11347 name: "ExportKeyingMaterial-Server-HalfRTT-" + vers.name, 11348 config: Config{ 11349 MaxVersion: vers.version, 11350 Bugs: ProtocolBugs{ 11351 // The shim writes exported data immediately after 11352 // the handshake returns, so disable the built-in 11353 // early data test. 11354 SendEarlyData: [][]byte{}, 11355 ExpectHalfRTTData: [][]byte{}, 11356 }, 11357 }, 11358 resumeSession: true, 11359 earlyData: true, 11360 exportKeyingMaterial: 1024, 11361 exportLabel: "label", 11362 exportContext: "context", 11363 useExportContext: true, 11364 }) 11365 } 11366 } 11367 11368 // Exporters work during a False Start. 11369 testCases = append(testCases, testCase{ 11370 name: "ExportKeyingMaterial-FalseStart", 11371 config: Config{ 11372 MaxVersion: VersionTLS12, 11373 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11374 NextProtos: []string{"foo"}, 11375 Bugs: ProtocolBugs{ 11376 ExpectFalseStart: true, 11377 }, 11378 }, 11379 flags: []string{ 11380 "-false-start", 11381 "-advertise-alpn", "\x03foo", 11382 "-expect-alpn", "foo", 11383 }, 11384 shimWritesFirst: true, 11385 exportKeyingMaterial: 1024, 11386 exportLabel: "label", 11387 exportContext: "context", 11388 useExportContext: true, 11389 }) 11390 11391 // Exporters do not work in the middle of a renegotiation. Test this by 11392 // triggering the exporter after every SSL_read call and configuring the 11393 // shim to run asynchronously. 11394 testCases = append(testCases, testCase{ 11395 name: "ExportKeyingMaterial-Renegotiate", 11396 config: Config{ 11397 MaxVersion: VersionTLS12, 11398 }, 11399 renegotiate: 1, 11400 flags: []string{ 11401 "-async", 11402 "-use-exporter-between-reads", 11403 "-renegotiate-freely", 11404 "-expect-total-renegotiations", "1", 11405 }, 11406 shouldFail: true, 11407 expectedError: "failed to export keying material", 11408 }) 11409} 11410 11411func addExportTrafficSecretsTests() { 11412 for _, cipherSuite := range []testCipherSuite{ 11413 // Test a SHA-256 and SHA-384 based cipher suite. 11414 {"AEAD-AES128-GCM-SHA256", TLS_AES_128_GCM_SHA256}, 11415 {"AEAD-AES256-GCM-SHA384", TLS_AES_256_GCM_SHA384}, 11416 } { 11417 11418 testCases = append(testCases, testCase{ 11419 name: "ExportTrafficSecrets-" + cipherSuite.name, 11420 config: Config{ 11421 MinVersion: VersionTLS13, 11422 CipherSuites: []uint16{cipherSuite.id}, 11423 }, 11424 exportTrafficSecrets: true, 11425 }) 11426 } 11427} 11428 11429func addTLSUniqueTests() { 11430 for _, isClient := range []bool{false, true} { 11431 for _, isResumption := range []bool{false, true} { 11432 for _, hasEMS := range []bool{false, true} { 11433 var suffix string 11434 if isResumption { 11435 suffix = "Resume-" 11436 } else { 11437 suffix = "Full-" 11438 } 11439 11440 if hasEMS { 11441 suffix += "EMS-" 11442 } else { 11443 suffix += "NoEMS-" 11444 } 11445 11446 if isClient { 11447 suffix += "Client" 11448 } else { 11449 suffix += "Server" 11450 } 11451 11452 test := testCase{ 11453 name: "TLSUnique-" + suffix, 11454 testTLSUnique: true, 11455 config: Config{ 11456 MaxVersion: VersionTLS12, 11457 Bugs: ProtocolBugs{ 11458 NoExtendedMasterSecret: !hasEMS, 11459 }, 11460 }, 11461 } 11462 11463 if isResumption { 11464 test.resumeSession = true 11465 test.resumeConfig = &Config{ 11466 MaxVersion: VersionTLS12, 11467 Bugs: ProtocolBugs{ 11468 NoExtendedMasterSecret: !hasEMS, 11469 }, 11470 } 11471 } 11472 11473 if isResumption && !hasEMS { 11474 test.shouldFail = true 11475 test.expectedError = "failed to get tls-unique" 11476 } 11477 11478 testCases = append(testCases, test) 11479 } 11480 } 11481 } 11482} 11483 11484func addCustomExtensionTests() { 11485 // Test an unknown extension from the server. 11486 testCases = append(testCases, testCase{ 11487 testType: clientTest, 11488 name: "UnknownExtension-Client", 11489 config: Config{ 11490 MaxVersion: VersionTLS12, 11491 Bugs: ProtocolBugs{ 11492 CustomExtension: "custom extension", 11493 }, 11494 }, 11495 shouldFail: true, 11496 expectedError: ":UNEXPECTED_EXTENSION:", 11497 expectedLocalError: "remote error: unsupported extension", 11498 }) 11499 testCases = append(testCases, testCase{ 11500 testType: clientTest, 11501 name: "UnknownExtension-Client-TLS13", 11502 config: Config{ 11503 MaxVersion: VersionTLS13, 11504 Bugs: ProtocolBugs{ 11505 CustomExtension: "custom extension", 11506 }, 11507 }, 11508 shouldFail: true, 11509 expectedError: ":UNEXPECTED_EXTENSION:", 11510 expectedLocalError: "remote error: unsupported extension", 11511 }) 11512 testCases = append(testCases, testCase{ 11513 testType: clientTest, 11514 name: "UnknownUnencryptedExtension-Client-TLS13", 11515 config: Config{ 11516 MaxVersion: VersionTLS13, 11517 Bugs: ProtocolBugs{ 11518 CustomUnencryptedExtension: "custom extension", 11519 }, 11520 }, 11521 shouldFail: true, 11522 expectedError: ":UNEXPECTED_EXTENSION:", 11523 // The shim must send an alert, but alerts at this point do not 11524 // get successfully decrypted by the runner. 11525 expectedLocalError: "local error: bad record MAC", 11526 }) 11527 testCases = append(testCases, testCase{ 11528 testType: clientTest, 11529 name: "UnexpectedUnencryptedExtension-Client-TLS13", 11530 config: Config{ 11531 MaxVersion: VersionTLS13, 11532 Bugs: ProtocolBugs{ 11533 SendUnencryptedALPN: "foo", 11534 }, 11535 }, 11536 flags: []string{ 11537 "-advertise-alpn", "\x03foo\x03bar", 11538 }, 11539 shouldFail: true, 11540 expectedError: ":UNEXPECTED_EXTENSION:", 11541 // The shim must send an alert, but alerts at this point do not 11542 // get successfully decrypted by the runner. 11543 expectedLocalError: "local error: bad record MAC", 11544 }) 11545 11546 // Test a known but unoffered extension from the server. 11547 testCases = append(testCases, testCase{ 11548 testType: clientTest, 11549 name: "UnofferedExtension-Client", 11550 config: Config{ 11551 MaxVersion: VersionTLS12, 11552 Bugs: ProtocolBugs{ 11553 SendALPN: "alpn", 11554 }, 11555 }, 11556 shouldFail: true, 11557 expectedError: ":UNEXPECTED_EXTENSION:", 11558 expectedLocalError: "remote error: unsupported extension", 11559 }) 11560 testCases = append(testCases, testCase{ 11561 testType: clientTest, 11562 name: "UnofferedExtension-Client-TLS13", 11563 config: Config{ 11564 MaxVersion: VersionTLS13, 11565 Bugs: ProtocolBugs{ 11566 SendALPN: "alpn", 11567 }, 11568 }, 11569 shouldFail: true, 11570 expectedError: ":UNEXPECTED_EXTENSION:", 11571 expectedLocalError: "remote error: unsupported extension", 11572 }) 11573} 11574 11575func addRSAClientKeyExchangeTests() { 11576 for bad := RSABadValue(1); bad < NumRSABadValues; bad++ { 11577 testCases = append(testCases, testCase{ 11578 testType: serverTest, 11579 name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad), 11580 config: Config{ 11581 // Ensure the ClientHello version and final 11582 // version are different, to detect if the 11583 // server uses the wrong one. 11584 MaxVersion: VersionTLS11, 11585 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 11586 Bugs: ProtocolBugs{ 11587 BadRSAClientKeyExchange: bad, 11588 }, 11589 }, 11590 shouldFail: true, 11591 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 11592 }) 11593 } 11594 11595 // The server must compare whatever was in ClientHello.version for the 11596 // RSA premaster. 11597 testCases = append(testCases, testCase{ 11598 testType: serverTest, 11599 name: "SendClientVersion-RSA", 11600 config: Config{ 11601 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 11602 Bugs: ProtocolBugs{ 11603 SendClientVersion: 0x1234, 11604 }, 11605 }, 11606 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 11607 }) 11608} 11609 11610var testCurves = []struct { 11611 name string 11612 id CurveID 11613}{ 11614 {"P-224", CurveP224}, 11615 {"P-256", CurveP256}, 11616 {"P-384", CurveP384}, 11617 {"P-521", CurveP521}, 11618 {"X25519", CurveX25519}, 11619 {"Kyber", CurveX25519Kyber768}, 11620} 11621 11622const bogusCurve = 0x1234 11623 11624func isPqGroup(r CurveID) bool { 11625 return r == CurveX25519Kyber768 11626} 11627 11628func addCurveTests() { 11629 for _, curve := range testCurves { 11630 for _, ver := range tlsVersions { 11631 if isPqGroup(curve.id) && ver.version < VersionTLS13 { 11632 continue 11633 } 11634 11635 suffix := curve.name + "-" + ver.name 11636 11637 testCases = append(testCases, testCase{ 11638 name: "CurveTest-Client-" + suffix, 11639 config: Config{ 11640 MaxVersion: ver.version, 11641 CipherSuites: []uint16{ 11642 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11643 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11644 TLS_AES_256_GCM_SHA384, 11645 }, 11646 CurvePreferences: []CurveID{curve.id}, 11647 }, 11648 flags: append( 11649 []string{"-expect-curve-id", strconv.Itoa(int(curve.id))}, 11650 flagInts("-curves", shimConfig.AllCurves)..., 11651 ), 11652 expectations: connectionExpectations{ 11653 curveID: curve.id, 11654 }, 11655 }) 11656 testCases = append(testCases, testCase{ 11657 testType: serverTest, 11658 name: "CurveTest-Server-" + suffix, 11659 config: Config{ 11660 MaxVersion: ver.version, 11661 CipherSuites: []uint16{ 11662 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11663 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11664 TLS_AES_256_GCM_SHA384, 11665 }, 11666 CurvePreferences: []CurveID{curve.id}, 11667 }, 11668 flags: append( 11669 []string{"-expect-curve-id", strconv.Itoa(int(curve.id))}, 11670 flagInts("-curves", shimConfig.AllCurves)..., 11671 ), 11672 expectations: connectionExpectations{ 11673 curveID: curve.id, 11674 }, 11675 }) 11676 11677 if curve.id != CurveX25519 && !isPqGroup(curve.id) { 11678 testCases = append(testCases, testCase{ 11679 name: "CurveTest-Client-Compressed-" + suffix, 11680 config: Config{ 11681 MaxVersion: ver.version, 11682 CipherSuites: []uint16{ 11683 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11684 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11685 TLS_AES_256_GCM_SHA384, 11686 }, 11687 CurvePreferences: []CurveID{curve.id}, 11688 Bugs: ProtocolBugs{ 11689 SendCompressedCoordinates: true, 11690 }, 11691 }, 11692 flags: flagInts("-curves", shimConfig.AllCurves), 11693 shouldFail: true, 11694 expectedError: ":BAD_ECPOINT:", 11695 }) 11696 testCases = append(testCases, testCase{ 11697 testType: serverTest, 11698 name: "CurveTest-Server-Compressed-" + suffix, 11699 config: Config{ 11700 MaxVersion: ver.version, 11701 CipherSuites: []uint16{ 11702 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11703 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11704 TLS_AES_256_GCM_SHA384, 11705 }, 11706 CurvePreferences: []CurveID{curve.id}, 11707 Bugs: ProtocolBugs{ 11708 SendCompressedCoordinates: true, 11709 }, 11710 }, 11711 flags: flagInts("-curves", shimConfig.AllCurves), 11712 shouldFail: true, 11713 expectedError: ":BAD_ECPOINT:", 11714 }) 11715 } 11716 } 11717 } 11718 11719 // The server must be tolerant to bogus curves. 11720 testCases = append(testCases, testCase{ 11721 testType: serverTest, 11722 name: "UnknownCurve", 11723 config: Config{ 11724 MaxVersion: VersionTLS12, 11725 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11726 CurvePreferences: []CurveID{bogusCurve, CurveP256}, 11727 }, 11728 }) 11729 11730 // The server must be tolerant to bogus curves. 11731 testCases = append(testCases, testCase{ 11732 testType: serverTest, 11733 name: "UnknownCurve-TLS13", 11734 config: Config{ 11735 MaxVersion: VersionTLS13, 11736 CurvePreferences: []CurveID{bogusCurve, CurveP256}, 11737 }, 11738 }) 11739 11740 // The server must not consider ECDHE ciphers when there are no 11741 // supported curves. 11742 testCases = append(testCases, testCase{ 11743 testType: serverTest, 11744 name: "NoSupportedCurves", 11745 config: Config{ 11746 MaxVersion: VersionTLS12, 11747 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11748 Bugs: ProtocolBugs{ 11749 NoSupportedCurves: true, 11750 }, 11751 }, 11752 shouldFail: true, 11753 expectedError: ":NO_SHARED_CIPHER:", 11754 }) 11755 testCases = append(testCases, testCase{ 11756 testType: serverTest, 11757 name: "NoSupportedCurves-TLS13", 11758 config: Config{ 11759 MaxVersion: VersionTLS13, 11760 Bugs: ProtocolBugs{ 11761 NoSupportedCurves: true, 11762 }, 11763 }, 11764 shouldFail: true, 11765 expectedError: ":NO_SHARED_GROUP:", 11766 }) 11767 11768 // The server must fall back to another cipher when there are no 11769 // supported curves. 11770 testCases = append(testCases, testCase{ 11771 testType: serverTest, 11772 name: "NoCommonCurves", 11773 config: Config{ 11774 MaxVersion: VersionTLS12, 11775 CipherSuites: []uint16{ 11776 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11777 TLS_RSA_WITH_AES_128_GCM_SHA256, 11778 }, 11779 CurvePreferences: []CurveID{CurveP224}, 11780 }, 11781 expectations: connectionExpectations{ 11782 cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, 11783 }, 11784 }) 11785 11786 // The client must reject bogus curves and disabled curves. 11787 testCases = append(testCases, testCase{ 11788 name: "BadECDHECurve", 11789 config: Config{ 11790 MaxVersion: VersionTLS12, 11791 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11792 Bugs: ProtocolBugs{ 11793 SendCurve: bogusCurve, 11794 }, 11795 }, 11796 shouldFail: true, 11797 expectedError: ":WRONG_CURVE:", 11798 }) 11799 testCases = append(testCases, testCase{ 11800 name: "BadECDHECurve-TLS13", 11801 config: Config{ 11802 MaxVersion: VersionTLS13, 11803 Bugs: ProtocolBugs{ 11804 SendCurve: bogusCurve, 11805 }, 11806 }, 11807 shouldFail: true, 11808 expectedError: ":WRONG_CURVE:", 11809 }) 11810 11811 testCases = append(testCases, testCase{ 11812 name: "UnsupportedCurve", 11813 config: Config{ 11814 MaxVersion: VersionTLS12, 11815 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11816 CurvePreferences: []CurveID{CurveP256}, 11817 Bugs: ProtocolBugs{ 11818 IgnorePeerCurvePreferences: true, 11819 }, 11820 }, 11821 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 11822 shouldFail: true, 11823 expectedError: ":WRONG_CURVE:", 11824 }) 11825 11826 testCases = append(testCases, testCase{ 11827 // TODO(davidben): Add a TLS 1.3 version where 11828 // HelloRetryRequest requests an unsupported curve. 11829 name: "UnsupportedCurve-ServerHello-TLS13", 11830 config: Config{ 11831 MaxVersion: VersionTLS13, 11832 CurvePreferences: []CurveID{CurveP384}, 11833 Bugs: ProtocolBugs{ 11834 SendCurve: CurveP256, 11835 }, 11836 }, 11837 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 11838 shouldFail: true, 11839 expectedError: ":WRONG_CURVE:", 11840 }) 11841 11842 // Test invalid curve points. 11843 testCases = append(testCases, testCase{ 11844 name: "InvalidECDHPoint-Client", 11845 config: Config{ 11846 MaxVersion: VersionTLS12, 11847 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11848 CurvePreferences: []CurveID{CurveP256}, 11849 Bugs: ProtocolBugs{ 11850 InvalidECDHPoint: true, 11851 }, 11852 }, 11853 shouldFail: true, 11854 expectedError: ":BAD_ECPOINT:", 11855 }) 11856 testCases = append(testCases, testCase{ 11857 name: "InvalidECDHPoint-Client-TLS13", 11858 config: Config{ 11859 MaxVersion: VersionTLS13, 11860 CurvePreferences: []CurveID{CurveP256}, 11861 Bugs: ProtocolBugs{ 11862 InvalidECDHPoint: true, 11863 }, 11864 }, 11865 shouldFail: true, 11866 expectedError: ":BAD_ECPOINT:", 11867 }) 11868 testCases = append(testCases, testCase{ 11869 testType: serverTest, 11870 name: "InvalidECDHPoint-Server", 11871 config: Config{ 11872 MaxVersion: VersionTLS12, 11873 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11874 CurvePreferences: []CurveID{CurveP256}, 11875 Bugs: ProtocolBugs{ 11876 InvalidECDHPoint: true, 11877 }, 11878 }, 11879 shouldFail: true, 11880 expectedError: ":BAD_ECPOINT:", 11881 }) 11882 testCases = append(testCases, testCase{ 11883 testType: serverTest, 11884 name: "InvalidECDHPoint-Server-TLS13", 11885 config: Config{ 11886 MaxVersion: VersionTLS13, 11887 CurvePreferences: []CurveID{CurveP256}, 11888 Bugs: ProtocolBugs{ 11889 InvalidECDHPoint: true, 11890 }, 11891 }, 11892 shouldFail: true, 11893 expectedError: ":BAD_ECPOINT:", 11894 }) 11895 11896 // The previous curve ID should be reported on TLS 1.2 resumption. 11897 testCases = append(testCases, testCase{ 11898 name: "CurveID-Resume-Client", 11899 config: Config{ 11900 MaxVersion: VersionTLS12, 11901 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11902 CurvePreferences: []CurveID{CurveX25519}, 11903 }, 11904 flags: []string{"-expect-curve-id", strconv.Itoa(int(CurveX25519))}, 11905 resumeSession: true, 11906 }) 11907 testCases = append(testCases, testCase{ 11908 testType: serverTest, 11909 name: "CurveID-Resume-Server", 11910 config: Config{ 11911 MaxVersion: VersionTLS12, 11912 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11913 CurvePreferences: []CurveID{CurveX25519}, 11914 }, 11915 flags: []string{"-expect-curve-id", strconv.Itoa(int(CurveX25519))}, 11916 resumeSession: true, 11917 }) 11918 11919 // TLS 1.3 allows resuming at a differet curve. If this happens, the new 11920 // one should be reported. 11921 testCases = append(testCases, testCase{ 11922 name: "CurveID-Resume-Client-TLS13", 11923 config: Config{ 11924 MaxVersion: VersionTLS13, 11925 CurvePreferences: []CurveID{CurveX25519}, 11926 }, 11927 resumeConfig: &Config{ 11928 MaxVersion: VersionTLS13, 11929 CurvePreferences: []CurveID{CurveP256}, 11930 }, 11931 flags: []string{ 11932 "-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)), 11933 "-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)), 11934 }, 11935 resumeSession: true, 11936 }) 11937 testCases = append(testCases, testCase{ 11938 testType: serverTest, 11939 name: "CurveID-Resume-Server-TLS13", 11940 config: Config{ 11941 MaxVersion: VersionTLS13, 11942 CurvePreferences: []CurveID{CurveX25519}, 11943 }, 11944 resumeConfig: &Config{ 11945 MaxVersion: VersionTLS13, 11946 CurvePreferences: []CurveID{CurveP256}, 11947 }, 11948 flags: []string{ 11949 "-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)), 11950 "-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)), 11951 }, 11952 resumeSession: true, 11953 }) 11954 11955 // Server-sent point formats are legal in TLS 1.2, but not in TLS 1.3. 11956 testCases = append(testCases, testCase{ 11957 name: "PointFormat-ServerHello-TLS12", 11958 config: Config{ 11959 MaxVersion: VersionTLS12, 11960 Bugs: ProtocolBugs{ 11961 SendSupportedPointFormats: []byte{pointFormatUncompressed}, 11962 }, 11963 }, 11964 }) 11965 testCases = append(testCases, testCase{ 11966 name: "PointFormat-EncryptedExtensions-TLS13", 11967 config: Config{ 11968 MaxVersion: VersionTLS13, 11969 Bugs: ProtocolBugs{ 11970 SendSupportedPointFormats: []byte{pointFormatUncompressed}, 11971 }, 11972 }, 11973 shouldFail: true, 11974 expectedError: ":ERROR_PARSING_EXTENSION:", 11975 }) 11976 11977 // Server-sent supported groups/curves are legal in TLS 1.3. They are 11978 // illegal in TLS 1.2, but some servers send them anyway, so we must 11979 // tolerate them. 11980 testCases = append(testCases, testCase{ 11981 name: "SupportedCurves-ServerHello-TLS12", 11982 config: Config{ 11983 MaxVersion: VersionTLS12, 11984 Bugs: ProtocolBugs{ 11985 SendServerSupportedCurves: true, 11986 }, 11987 }, 11988 }) 11989 testCases = append(testCases, testCase{ 11990 name: "SupportedCurves-EncryptedExtensions-TLS13", 11991 config: Config{ 11992 MaxVersion: VersionTLS13, 11993 Bugs: ProtocolBugs{ 11994 SendServerSupportedCurves: true, 11995 }, 11996 }, 11997 }) 11998 11999 // Test that we tolerate unknown point formats, as long as 12000 // pointFormatUncompressed is present. Limit ciphers to ECDHE ciphers to 12001 // check they are still functional. 12002 testCases = append(testCases, testCase{ 12003 name: "PointFormat-Client-Tolerance", 12004 config: Config{ 12005 MaxVersion: VersionTLS12, 12006 Bugs: ProtocolBugs{ 12007 SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime}, 12008 }, 12009 }, 12010 }) 12011 testCases = append(testCases, testCase{ 12012 testType: serverTest, 12013 name: "PointFormat-Server-Tolerance", 12014 config: Config{ 12015 MaxVersion: VersionTLS12, 12016 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 12017 Bugs: ProtocolBugs{ 12018 SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime}, 12019 }, 12020 }, 12021 }) 12022 12023 // Test TLS 1.2 does not require the point format extension to be 12024 // present. 12025 testCases = append(testCases, testCase{ 12026 name: "PointFormat-Client-Missing", 12027 config: Config{ 12028 MaxVersion: VersionTLS12, 12029 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 12030 Bugs: ProtocolBugs{ 12031 SendSupportedPointFormats: []byte{}, 12032 }, 12033 }, 12034 }) 12035 testCases = append(testCases, testCase{ 12036 testType: serverTest, 12037 name: "PointFormat-Server-Missing", 12038 config: Config{ 12039 MaxVersion: VersionTLS12, 12040 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 12041 Bugs: ProtocolBugs{ 12042 SendSupportedPointFormats: []byte{}, 12043 }, 12044 }, 12045 }) 12046 12047 // If the point format extension is present, uncompressed points must be 12048 // offered. BoringSSL requires this whether or not ECDHE is used. 12049 testCases = append(testCases, testCase{ 12050 name: "PointFormat-Client-MissingUncompressed", 12051 config: Config{ 12052 MaxVersion: VersionTLS12, 12053 Bugs: ProtocolBugs{ 12054 SendSupportedPointFormats: []byte{pointFormatCompressedPrime}, 12055 }, 12056 }, 12057 shouldFail: true, 12058 expectedError: ":ERROR_PARSING_EXTENSION:", 12059 }) 12060 testCases = append(testCases, testCase{ 12061 testType: serverTest, 12062 name: "PointFormat-Server-MissingUncompressed", 12063 config: Config{ 12064 MaxVersion: VersionTLS12, 12065 Bugs: ProtocolBugs{ 12066 SendSupportedPointFormats: []byte{pointFormatCompressedPrime}, 12067 }, 12068 }, 12069 shouldFail: true, 12070 expectedError: ":ERROR_PARSING_EXTENSION:", 12071 }) 12072 12073 // Implementations should mask off the high order bit in X25519. 12074 testCases = append(testCases, testCase{ 12075 name: "SetX25519HighBit", 12076 config: Config{ 12077 CipherSuites: []uint16{ 12078 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 12079 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 12080 TLS_AES_128_GCM_SHA256, 12081 }, 12082 CurvePreferences: []CurveID{CurveX25519}, 12083 Bugs: ProtocolBugs{ 12084 SetX25519HighBit: true, 12085 }, 12086 }, 12087 }) 12088 12089 // Kyber should not be offered by a TLS < 1.3 client. 12090 testCases = append(testCases, testCase{ 12091 name: "KyberNotInTLS12", 12092 config: Config{ 12093 Bugs: ProtocolBugs{ 12094 FailIfKyberOffered: true, 12095 }, 12096 }, 12097 flags: []string{ 12098 "-max-version", strconv.Itoa(VersionTLS12), 12099 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12100 "-curves", strconv.Itoa(int(CurveX25519)), 12101 }, 12102 }) 12103 12104 // Kyber should not crash a TLS < 1.3 client if the server mistakenly 12105 // selects it. 12106 testCases = append(testCases, testCase{ 12107 name: "KyberNotAcceptedByTLS12Client", 12108 config: Config{ 12109 Bugs: ProtocolBugs{ 12110 SendCurve: CurveX25519Kyber768, 12111 }, 12112 }, 12113 flags: []string{ 12114 "-max-version", strconv.Itoa(VersionTLS12), 12115 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12116 "-curves", strconv.Itoa(int(CurveX25519)), 12117 }, 12118 shouldFail: true, 12119 expectedError: ":WRONG_CURVE:", 12120 }) 12121 12122 // Kyber should not be offered by default as a client. 12123 testCases = append(testCases, testCase{ 12124 name: "KyberNotEnabledByDefaultInClients", 12125 config: Config{ 12126 MinVersion: VersionTLS13, 12127 Bugs: ProtocolBugs{ 12128 FailIfKyberOffered: true, 12129 }, 12130 }, 12131 }) 12132 12133 // If Kyber is offered, both X25519 and Kyber should have a key-share. 12134 testCases = append(testCases, testCase{ 12135 name: "NotJustKyberKeyShare", 12136 config: Config{ 12137 MinVersion: VersionTLS13, 12138 Bugs: ProtocolBugs{ 12139 ExpectedKeyShares: []CurveID{CurveX25519Kyber768, CurveX25519}, 12140 }, 12141 }, 12142 flags: []string{ 12143 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12144 "-curves", strconv.Itoa(int(CurveX25519)), 12145 // Cannot expect Kyber until we have a Go implementation of it. 12146 // "-expect-curve-id", strconv.Itoa(int(CurveX25519Kyber768)), 12147 }, 12148 }) 12149 12150 // ... and the other way around 12151 testCases = append(testCases, testCase{ 12152 name: "KyberKeyShareIncludedSecond", 12153 config: Config{ 12154 MinVersion: VersionTLS13, 12155 Bugs: ProtocolBugs{ 12156 ExpectedKeyShares: []CurveID{CurveX25519, CurveX25519Kyber768}, 12157 }, 12158 }, 12159 flags: []string{ 12160 "-curves", strconv.Itoa(int(CurveX25519)), 12161 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12162 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 12163 }, 12164 }) 12165 12166 // ... and even if there's another curve in the middle because it's the 12167 // first classical and first post-quantum "curves" that get key shares 12168 // included. 12169 testCases = append(testCases, testCase{ 12170 name: "KyberKeyShareIncludedThird", 12171 config: Config{ 12172 MinVersion: VersionTLS13, 12173 Bugs: ProtocolBugs{ 12174 ExpectedKeyShares: []CurveID{CurveX25519, CurveX25519Kyber768}, 12175 }, 12176 }, 12177 flags: []string{ 12178 "-curves", strconv.Itoa(int(CurveX25519)), 12179 "-curves", strconv.Itoa(int(CurveP256)), 12180 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12181 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 12182 }, 12183 }) 12184 12185 // If Kyber is the only configured curve, the key share is sent. 12186 testCases = append(testCases, testCase{ 12187 name: "JustConfiguringKyberWorks", 12188 config: Config{ 12189 MinVersion: VersionTLS13, 12190 Bugs: ProtocolBugs{ 12191 ExpectedKeyShares: []CurveID{CurveX25519Kyber768}, 12192 }, 12193 }, 12194 flags: []string{ 12195 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12196 "-expect-curve-id", strconv.Itoa(int(CurveX25519Kyber768)), 12197 }, 12198 }) 12199 12200 // As a server, Kyber is not yet supported by default. 12201 testCases = append(testCases, testCase{ 12202 testType: serverTest, 12203 name: "KyberNotEnabledByDefaultForAServer", 12204 config: Config{ 12205 MinVersion: VersionTLS13, 12206 CurvePreferences: []CurveID{CurveX25519Kyber768, CurveX25519}, 12207 DefaultCurves: []CurveID{CurveX25519Kyber768}, 12208 }, 12209 flags: []string{ 12210 "-server-preference", 12211 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 12212 }, 12213 }) 12214} 12215 12216func addTLS13RecordTests() { 12217 testCases = append(testCases, testCase{ 12218 name: "TLS13-RecordPadding", 12219 config: Config{ 12220 MaxVersion: VersionTLS13, 12221 MinVersion: VersionTLS13, 12222 Bugs: ProtocolBugs{ 12223 RecordPadding: 10, 12224 }, 12225 }, 12226 }) 12227 12228 testCases = append(testCases, testCase{ 12229 name: "TLS13-EmptyRecords", 12230 config: Config{ 12231 MaxVersion: VersionTLS13, 12232 MinVersion: VersionTLS13, 12233 Bugs: ProtocolBugs{ 12234 OmitRecordContents: true, 12235 }, 12236 }, 12237 shouldFail: true, 12238 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 12239 }) 12240 12241 testCases = append(testCases, testCase{ 12242 name: "TLS13-OnlyPadding", 12243 config: Config{ 12244 MaxVersion: VersionTLS13, 12245 MinVersion: VersionTLS13, 12246 Bugs: ProtocolBugs{ 12247 OmitRecordContents: true, 12248 RecordPadding: 10, 12249 }, 12250 }, 12251 shouldFail: true, 12252 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 12253 }) 12254 12255 testCases = append(testCases, testCase{ 12256 name: "TLS13-WrongOuterRecord", 12257 config: Config{ 12258 MaxVersion: VersionTLS13, 12259 MinVersion: VersionTLS13, 12260 Bugs: ProtocolBugs{ 12261 OuterRecordType: recordTypeHandshake, 12262 }, 12263 }, 12264 shouldFail: true, 12265 expectedError: ":INVALID_OUTER_RECORD_TYPE:", 12266 }) 12267} 12268 12269func addSessionTicketTests() { 12270 testCases = append(testCases, testCase{ 12271 // In TLS 1.2 and below, empty NewSessionTicket messages 12272 // mean the server changed its mind on sending a ticket. 12273 name: "SendEmptySessionTicket", 12274 config: Config{ 12275 MaxVersion: VersionTLS12, 12276 Bugs: ProtocolBugs{ 12277 SendEmptySessionTicket: true, 12278 }, 12279 }, 12280 flags: []string{"-expect-no-session"}, 12281 }) 12282 12283 // Test that the server ignores unknown PSK modes. 12284 testCases = append(testCases, testCase{ 12285 testType: serverTest, 12286 name: "TLS13-SendUnknownModeSessionTicket-Server", 12287 config: Config{ 12288 MaxVersion: VersionTLS13, 12289 Bugs: ProtocolBugs{ 12290 SendPSKKeyExchangeModes: []byte{0x1a, pskDHEKEMode, 0x2a}, 12291 }, 12292 }, 12293 resumeSession: true, 12294 expectations: connectionExpectations{ 12295 version: VersionTLS13, 12296 }, 12297 }) 12298 12299 // Test that the server does not send session tickets with no matching key exchange mode. 12300 testCases = append(testCases, testCase{ 12301 testType: serverTest, 12302 name: "TLS13-ExpectNoSessionTicketOnBadKEMode-Server", 12303 config: Config{ 12304 MaxVersion: VersionTLS13, 12305 Bugs: ProtocolBugs{ 12306 SendPSKKeyExchangeModes: []byte{0x1a}, 12307 ExpectNoNewSessionTicket: true, 12308 }, 12309 }, 12310 }) 12311 12312 // Test that the server does not accept a session with no matching key exchange mode. 12313 testCases = append(testCases, testCase{ 12314 testType: serverTest, 12315 name: "TLS13-SendBadKEModeSessionTicket-Server", 12316 config: Config{ 12317 MaxVersion: VersionTLS13, 12318 }, 12319 resumeConfig: &Config{ 12320 MaxVersion: VersionTLS13, 12321 Bugs: ProtocolBugs{ 12322 SendPSKKeyExchangeModes: []byte{0x1a}, 12323 }, 12324 }, 12325 resumeSession: true, 12326 expectResumeRejected: true, 12327 }) 12328 12329 // Test that the server rejects ClientHellos with pre_shared_key but without 12330 // psk_key_exchange_modes. 12331 testCases = append(testCases, testCase{ 12332 testType: serverTest, 12333 name: "TLS13-SendNoKEMModesWithPSK-Server", 12334 config: Config{ 12335 MaxVersion: VersionTLS13, 12336 }, 12337 resumeConfig: &Config{ 12338 MaxVersion: VersionTLS13, 12339 Bugs: ProtocolBugs{ 12340 SendPSKKeyExchangeModes: []byte{}, 12341 }, 12342 }, 12343 resumeSession: true, 12344 shouldFail: true, 12345 expectedLocalError: "remote error: missing extension", 12346 expectedError: ":MISSING_EXTENSION:", 12347 }) 12348 12349 // Test that the client ticket age is sent correctly. 12350 testCases = append(testCases, testCase{ 12351 testType: clientTest, 12352 name: "TLS13-TestValidTicketAge-Client", 12353 config: Config{ 12354 MaxVersion: VersionTLS13, 12355 Bugs: ProtocolBugs{ 12356 ExpectTicketAge: 10 * time.Second, 12357 }, 12358 }, 12359 resumeSession: true, 12360 flags: []string{ 12361 "-resumption-delay", "10", 12362 }, 12363 }) 12364 12365 // Test that the client ticket age is enforced. 12366 testCases = append(testCases, testCase{ 12367 testType: clientTest, 12368 name: "TLS13-TestBadTicketAge-Client", 12369 config: Config{ 12370 MaxVersion: VersionTLS13, 12371 Bugs: ProtocolBugs{ 12372 ExpectTicketAge: 1000 * time.Second, 12373 }, 12374 }, 12375 resumeSession: true, 12376 shouldFail: true, 12377 expectedLocalError: "tls: invalid ticket age", 12378 }) 12379 12380 // Test that the server's ticket age skew reporting works. 12381 testCases = append(testCases, testCase{ 12382 testType: serverTest, 12383 name: "TLS13-TicketAgeSkew-Forward", 12384 config: Config{ 12385 MaxVersion: VersionTLS13, 12386 Bugs: ProtocolBugs{ 12387 SendTicketAge: 15 * time.Second, 12388 }, 12389 }, 12390 resumeSession: true, 12391 resumeRenewedSession: true, 12392 flags: []string{ 12393 "-resumption-delay", "10", 12394 "-expect-ticket-age-skew", "5", 12395 }, 12396 }) 12397 testCases = append(testCases, testCase{ 12398 testType: serverTest, 12399 name: "TLS13-TicketAgeSkew-Backward", 12400 config: Config{ 12401 MaxVersion: VersionTLS13, 12402 Bugs: ProtocolBugs{ 12403 SendTicketAge: 5 * time.Second, 12404 }, 12405 }, 12406 resumeSession: true, 12407 resumeRenewedSession: true, 12408 flags: []string{ 12409 "-resumption-delay", "10", 12410 "-expect-ticket-age-skew", "-5", 12411 }, 12412 }) 12413 12414 // Test that ticket age skew up to 60 seconds in either direction is accepted. 12415 testCases = append(testCases, testCase{ 12416 testType: serverTest, 12417 name: "TLS13-TicketAgeSkew-Forward-60-Accept", 12418 config: Config{ 12419 MaxVersion: VersionTLS13, 12420 Bugs: ProtocolBugs{ 12421 SendTicketAge: 70 * time.Second, 12422 }, 12423 }, 12424 resumeSession: true, 12425 earlyData: true, 12426 flags: []string{ 12427 "-resumption-delay", "10", 12428 "-expect-ticket-age-skew", "60", 12429 }, 12430 }) 12431 testCases = append(testCases, testCase{ 12432 testType: serverTest, 12433 name: "TLS13-TicketAgeSkew-Backward-60-Accept", 12434 config: Config{ 12435 MaxVersion: VersionTLS13, 12436 Bugs: ProtocolBugs{ 12437 SendTicketAge: 10 * time.Second, 12438 }, 12439 }, 12440 resumeSession: true, 12441 earlyData: true, 12442 flags: []string{ 12443 "-resumption-delay", "70", 12444 "-expect-ticket-age-skew", "-60", 12445 }, 12446 }) 12447 12448 // Test that ticket age skew beyond 60 seconds in either direction is rejected. 12449 testCases = append(testCases, testCase{ 12450 testType: serverTest, 12451 name: "TLS13-TicketAgeSkew-Forward-61-Reject", 12452 config: Config{ 12453 MaxVersion: VersionTLS13, 12454 Bugs: ProtocolBugs{ 12455 SendTicketAge: 71 * time.Second, 12456 }, 12457 }, 12458 resumeSession: true, 12459 earlyData: true, 12460 expectEarlyDataRejected: true, 12461 flags: []string{ 12462 "-resumption-delay", "10", 12463 "-expect-ticket-age-skew", "61", 12464 "-on-resume-expect-early-data-reason", "ticket_age_skew", 12465 }, 12466 }) 12467 testCases = append(testCases, testCase{ 12468 testType: serverTest, 12469 name: "TLS13-TicketAgeSkew-Backward-61-Reject", 12470 config: Config{ 12471 MaxVersion: VersionTLS13, 12472 Bugs: ProtocolBugs{ 12473 SendTicketAge: 10 * time.Second, 12474 }, 12475 }, 12476 resumeSession: true, 12477 earlyData: true, 12478 expectEarlyDataRejected: true, 12479 flags: []string{ 12480 "-resumption-delay", "71", 12481 "-expect-ticket-age-skew", "-61", 12482 "-on-resume-expect-early-data-reason", "ticket_age_skew", 12483 }, 12484 }) 12485 12486 testCases = append(testCases, testCase{ 12487 testType: clientTest, 12488 name: "TLS13-SendTicketEarlyDataSupport", 12489 config: Config{ 12490 MaxVersion: VersionTLS13, 12491 MaxEarlyDataSize: 16384, 12492 }, 12493 flags: []string{ 12494 "-enable-early-data", 12495 "-expect-ticket-supports-early-data", 12496 }, 12497 }) 12498 12499 // Test that 0-RTT tickets are still recorded as such when early data is disabled overall. 12500 testCases = append(testCases, testCase{ 12501 testType: clientTest, 12502 name: "TLS13-SendTicketEarlyDataSupport-Disabled", 12503 config: Config{ 12504 MaxVersion: VersionTLS13, 12505 MaxEarlyDataSize: 16384, 12506 }, 12507 flags: []string{ 12508 "-expect-ticket-supports-early-data", 12509 }, 12510 }) 12511 12512 testCases = append(testCases, testCase{ 12513 testType: clientTest, 12514 name: "TLS13-DuplicateTicketEarlyDataSupport", 12515 config: Config{ 12516 MaxVersion: VersionTLS13, 12517 MaxEarlyDataSize: 16384, 12518 Bugs: ProtocolBugs{ 12519 DuplicateTicketEarlyData: true, 12520 }, 12521 }, 12522 shouldFail: true, 12523 expectedError: ":DUPLICATE_EXTENSION:", 12524 expectedLocalError: "remote error: illegal parameter", 12525 }) 12526 12527 testCases = append(testCases, testCase{ 12528 testType: serverTest, 12529 name: "TLS13-ExpectTicketEarlyDataSupport", 12530 config: Config{ 12531 MaxVersion: VersionTLS13, 12532 Bugs: ProtocolBugs{ 12533 ExpectTicketEarlyData: true, 12534 }, 12535 }, 12536 flags: []string{ 12537 "-enable-early-data", 12538 }, 12539 }) 12540 12541 // Test that, in TLS 1.3, the server-offered NewSessionTicket lifetime 12542 // is honored. 12543 testCases = append(testCases, testCase{ 12544 testType: clientTest, 12545 name: "TLS13-HonorServerSessionTicketLifetime", 12546 config: Config{ 12547 MaxVersion: VersionTLS13, 12548 Bugs: ProtocolBugs{ 12549 SendTicketLifetime: 20 * time.Second, 12550 }, 12551 }, 12552 flags: []string{ 12553 "-resumption-delay", "19", 12554 }, 12555 resumeSession: true, 12556 }) 12557 testCases = append(testCases, testCase{ 12558 testType: clientTest, 12559 name: "TLS13-HonorServerSessionTicketLifetime-2", 12560 config: Config{ 12561 MaxVersion: VersionTLS13, 12562 Bugs: ProtocolBugs{ 12563 SendTicketLifetime: 20 * time.Second, 12564 // The client should not offer the expired session. 12565 ExpectNoTLS13PSK: true, 12566 }, 12567 }, 12568 flags: []string{ 12569 "-resumption-delay", "21", 12570 }, 12571 resumeSession: true, 12572 expectResumeRejected: true, 12573 }) 12574 12575 for _, ver := range tlsVersions { 12576 // Prior to TLS 1.3, disabling session tickets enables session IDs. 12577 useStatefulResumption := ver.version < VersionTLS13 12578 12579 // SSL_OP_NO_TICKET implies the server must not mint any tickets. 12580 testCases = append(testCases, testCase{ 12581 testType: serverTest, 12582 name: ver.name + "-NoTicket-NoMint", 12583 config: Config{ 12584 MinVersion: ver.version, 12585 MaxVersion: ver.version, 12586 Bugs: ProtocolBugs{ 12587 ExpectNoNewSessionTicket: true, 12588 RequireSessionIDs: useStatefulResumption, 12589 }, 12590 }, 12591 resumeSession: useStatefulResumption, 12592 flags: []string{"-no-ticket"}, 12593 }) 12594 12595 // SSL_OP_NO_TICKET implies the server must not accept any tickets. 12596 testCases = append(testCases, testCase{ 12597 testType: serverTest, 12598 name: ver.name + "-NoTicket-NoAccept", 12599 config: Config{ 12600 MinVersion: ver.version, 12601 MaxVersion: ver.version, 12602 }, 12603 resumeSession: true, 12604 expectResumeRejected: true, 12605 // Set SSL_OP_NO_TICKET on the second connection, after the first 12606 // has established tickets. 12607 flags: []string{"-on-resume-no-ticket"}, 12608 }) 12609 } 12610} 12611 12612func addChangeCipherSpecTests() { 12613 // Test missing ChangeCipherSpecs. 12614 testCases = append(testCases, testCase{ 12615 name: "SkipChangeCipherSpec-Client", 12616 config: Config{ 12617 MaxVersion: VersionTLS12, 12618 Bugs: ProtocolBugs{ 12619 SkipChangeCipherSpec: true, 12620 }, 12621 }, 12622 shouldFail: true, 12623 expectedError: ":UNEXPECTED_RECORD:", 12624 }) 12625 testCases = append(testCases, testCase{ 12626 testType: serverTest, 12627 name: "SkipChangeCipherSpec-Server", 12628 config: Config{ 12629 MaxVersion: VersionTLS12, 12630 Bugs: ProtocolBugs{ 12631 SkipChangeCipherSpec: true, 12632 }, 12633 }, 12634 shouldFail: true, 12635 expectedError: ":UNEXPECTED_RECORD:", 12636 }) 12637 testCases = append(testCases, testCase{ 12638 testType: serverTest, 12639 name: "SkipChangeCipherSpec-Server-NPN", 12640 config: Config{ 12641 MaxVersion: VersionTLS12, 12642 NextProtos: []string{"bar"}, 12643 Bugs: ProtocolBugs{ 12644 SkipChangeCipherSpec: true, 12645 }, 12646 }, 12647 flags: []string{ 12648 "-advertise-npn", "\x03foo\x03bar\x03baz", 12649 }, 12650 shouldFail: true, 12651 expectedError: ":UNEXPECTED_RECORD:", 12652 }) 12653 12654 // Test synchronization between the handshake and ChangeCipherSpec. 12655 // Partial post-CCS handshake messages before ChangeCipherSpec should be 12656 // rejected. Test both with and without handshake packing to handle both 12657 // when the partial post-CCS message is in its own record and when it is 12658 // attached to the pre-CCS message. 12659 for _, packed := range []bool{false, true} { 12660 var suffix string 12661 if packed { 12662 suffix = "-Packed" 12663 } 12664 12665 testCases = append(testCases, testCase{ 12666 name: "FragmentAcrossChangeCipherSpec-Client" + suffix, 12667 config: Config{ 12668 MaxVersion: VersionTLS12, 12669 Bugs: ProtocolBugs{ 12670 FragmentAcrossChangeCipherSpec: true, 12671 PackHandshakeFlight: packed, 12672 }, 12673 }, 12674 shouldFail: true, 12675 expectedError: ":UNEXPECTED_RECORD:", 12676 }) 12677 testCases = append(testCases, testCase{ 12678 name: "FragmentAcrossChangeCipherSpec-Client-Resume" + suffix, 12679 config: Config{ 12680 MaxVersion: VersionTLS12, 12681 }, 12682 resumeSession: true, 12683 resumeConfig: &Config{ 12684 MaxVersion: VersionTLS12, 12685 Bugs: ProtocolBugs{ 12686 FragmentAcrossChangeCipherSpec: true, 12687 PackHandshakeFlight: packed, 12688 }, 12689 }, 12690 shouldFail: true, 12691 expectedError: ":UNEXPECTED_RECORD:", 12692 }) 12693 testCases = append(testCases, testCase{ 12694 testType: serverTest, 12695 name: "FragmentAcrossChangeCipherSpec-Server" + suffix, 12696 config: Config{ 12697 MaxVersion: VersionTLS12, 12698 Bugs: ProtocolBugs{ 12699 FragmentAcrossChangeCipherSpec: true, 12700 PackHandshakeFlight: packed, 12701 }, 12702 }, 12703 shouldFail: true, 12704 expectedError: ":UNEXPECTED_RECORD:", 12705 }) 12706 testCases = append(testCases, testCase{ 12707 testType: serverTest, 12708 name: "FragmentAcrossChangeCipherSpec-Server-Resume" + suffix, 12709 config: Config{ 12710 MaxVersion: VersionTLS12, 12711 }, 12712 resumeSession: true, 12713 resumeConfig: &Config{ 12714 MaxVersion: VersionTLS12, 12715 Bugs: ProtocolBugs{ 12716 FragmentAcrossChangeCipherSpec: true, 12717 PackHandshakeFlight: packed, 12718 }, 12719 }, 12720 shouldFail: true, 12721 expectedError: ":UNEXPECTED_RECORD:", 12722 }) 12723 testCases = append(testCases, testCase{ 12724 testType: serverTest, 12725 name: "FragmentAcrossChangeCipherSpec-Server-NPN" + suffix, 12726 config: Config{ 12727 MaxVersion: VersionTLS12, 12728 NextProtos: []string{"bar"}, 12729 Bugs: ProtocolBugs{ 12730 FragmentAcrossChangeCipherSpec: true, 12731 PackHandshakeFlight: packed, 12732 }, 12733 }, 12734 flags: []string{ 12735 "-advertise-npn", "\x03foo\x03bar\x03baz", 12736 }, 12737 shouldFail: true, 12738 expectedError: ":UNEXPECTED_RECORD:", 12739 }) 12740 } 12741 12742 // In TLS 1.2 resumptions, the client sends ClientHello in the first flight 12743 // and ChangeCipherSpec + Finished in the second flight. Test the server's 12744 // behavior when the Finished message is fragmented across not only 12745 // ChangeCipherSpec but also the flight boundary. 12746 testCases = append(testCases, testCase{ 12747 testType: serverTest, 12748 name: "PartialClientFinishedWithClientHello-TLS12-Resume", 12749 config: Config{ 12750 MaxVersion: VersionTLS12, 12751 }, 12752 resumeConfig: &Config{ 12753 MaxVersion: VersionTLS12, 12754 Bugs: ProtocolBugs{ 12755 PartialClientFinishedWithClientHello: true, 12756 }, 12757 }, 12758 resumeSession: true, 12759 shouldFail: true, 12760 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12761 expectedLocalError: "remote error: unexpected message", 12762 }) 12763 12764 // In TLS 1.2 full handshakes without tickets, the server's first flight ends 12765 // with ServerHelloDone and the second flight is ChangeCipherSpec + Finished. 12766 // Test the client's behavior when the Finished message is fragmented across 12767 // not only ChangeCipherSpec but also the flight boundary. 12768 testCases = append(testCases, testCase{ 12769 testType: clientTest, 12770 name: "PartialFinishedWithServerHelloDone", 12771 config: Config{ 12772 MaxVersion: VersionTLS12, 12773 SessionTicketsDisabled: true, 12774 Bugs: ProtocolBugs{ 12775 PartialFinishedWithServerHelloDone: true, 12776 }, 12777 }, 12778 shouldFail: true, 12779 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12780 expectedLocalError: "remote error: unexpected message", 12781 }) 12782 12783 // Test that, in DTLS, ChangeCipherSpec is not allowed when there are 12784 // messages in the handshake queue. Do this by testing the server 12785 // reading the client Finished, reversing the flight so Finished comes 12786 // first. 12787 testCases = append(testCases, testCase{ 12788 protocol: dtls, 12789 testType: serverTest, 12790 name: "SendUnencryptedFinished-DTLS", 12791 config: Config{ 12792 MaxVersion: VersionTLS12, 12793 Bugs: ProtocolBugs{ 12794 SendUnencryptedFinished: true, 12795 ReverseHandshakeFragments: true, 12796 }, 12797 }, 12798 shouldFail: true, 12799 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12800 }) 12801 12802 // Test synchronization between encryption changes and the handshake in 12803 // TLS 1.3, where ChangeCipherSpec is implicit. 12804 testCases = append(testCases, testCase{ 12805 name: "PartialEncryptedExtensionsWithServerHello", 12806 config: Config{ 12807 MaxVersion: VersionTLS13, 12808 Bugs: ProtocolBugs{ 12809 PartialEncryptedExtensionsWithServerHello: true, 12810 }, 12811 }, 12812 shouldFail: true, 12813 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12814 }) 12815 testCases = append(testCases, testCase{ 12816 testType: serverTest, 12817 name: "PartialClientFinishedWithClientHello", 12818 config: Config{ 12819 MaxVersion: VersionTLS13, 12820 Bugs: ProtocolBugs{ 12821 PartialClientFinishedWithClientHello: true, 12822 }, 12823 }, 12824 shouldFail: true, 12825 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12826 }) 12827 testCases = append(testCases, testCase{ 12828 testType: serverTest, 12829 name: "PartialClientFinishedWithSecondClientHello", 12830 config: Config{ 12831 MaxVersion: VersionTLS13, 12832 // Trigger a curve-based HelloRetryRequest. 12833 DefaultCurves: []CurveID{}, 12834 Bugs: ProtocolBugs{ 12835 PartialClientFinishedWithSecondClientHello: true, 12836 }, 12837 }, 12838 shouldFail: true, 12839 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12840 }) 12841 testCases = append(testCases, testCase{ 12842 testType: serverTest, 12843 name: "PartialEndOfEarlyDataWithClientHello", 12844 config: Config{ 12845 MaxVersion: VersionTLS13, 12846 }, 12847 resumeConfig: &Config{ 12848 MaxVersion: VersionTLS13, 12849 Bugs: ProtocolBugs{ 12850 PartialEndOfEarlyDataWithClientHello: true, 12851 }, 12852 }, 12853 resumeSession: true, 12854 earlyData: true, 12855 shouldFail: true, 12856 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12857 }) 12858 12859 // Test that early ChangeCipherSpecs are handled correctly. 12860 testCases = append(testCases, testCase{ 12861 testType: serverTest, 12862 name: "EarlyChangeCipherSpec-server-1", 12863 config: Config{ 12864 MaxVersion: VersionTLS12, 12865 Bugs: ProtocolBugs{ 12866 EarlyChangeCipherSpec: 1, 12867 }, 12868 }, 12869 shouldFail: true, 12870 expectedError: ":UNEXPECTED_RECORD:", 12871 }) 12872 testCases = append(testCases, testCase{ 12873 testType: serverTest, 12874 name: "EarlyChangeCipherSpec-server-2", 12875 config: Config{ 12876 MaxVersion: VersionTLS12, 12877 Bugs: ProtocolBugs{ 12878 EarlyChangeCipherSpec: 2, 12879 }, 12880 }, 12881 shouldFail: true, 12882 expectedError: ":UNEXPECTED_RECORD:", 12883 }) 12884 testCases = append(testCases, testCase{ 12885 protocol: dtls, 12886 name: "StrayChangeCipherSpec", 12887 config: Config{ 12888 // TODO(davidben): Once DTLS 1.3 exists, test 12889 // that stray ChangeCipherSpec messages are 12890 // rejected. 12891 MaxVersion: VersionTLS12, 12892 Bugs: ProtocolBugs{ 12893 StrayChangeCipherSpec: true, 12894 }, 12895 }, 12896 }) 12897 12898 // Test that reordered ChangeCipherSpecs are tolerated. 12899 testCases = append(testCases, testCase{ 12900 protocol: dtls, 12901 name: "ReorderChangeCipherSpec-DTLS-Client", 12902 config: Config{ 12903 MaxVersion: VersionTLS12, 12904 Bugs: ProtocolBugs{ 12905 ReorderChangeCipherSpec: true, 12906 }, 12907 }, 12908 resumeSession: true, 12909 }) 12910 testCases = append(testCases, testCase{ 12911 testType: serverTest, 12912 protocol: dtls, 12913 name: "ReorderChangeCipherSpec-DTLS-Server", 12914 config: Config{ 12915 MaxVersion: VersionTLS12, 12916 Bugs: ProtocolBugs{ 12917 ReorderChangeCipherSpec: true, 12918 }, 12919 }, 12920 resumeSession: true, 12921 }) 12922 12923 // Test that the contents of ChangeCipherSpec are checked. 12924 testCases = append(testCases, testCase{ 12925 name: "BadChangeCipherSpec-1", 12926 config: Config{ 12927 MaxVersion: VersionTLS12, 12928 Bugs: ProtocolBugs{ 12929 BadChangeCipherSpec: []byte{2}, 12930 }, 12931 }, 12932 shouldFail: true, 12933 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12934 }) 12935 testCases = append(testCases, testCase{ 12936 name: "BadChangeCipherSpec-2", 12937 config: Config{ 12938 MaxVersion: VersionTLS12, 12939 Bugs: ProtocolBugs{ 12940 BadChangeCipherSpec: []byte{1, 1}, 12941 }, 12942 }, 12943 shouldFail: true, 12944 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12945 }) 12946 testCases = append(testCases, testCase{ 12947 protocol: dtls, 12948 name: "BadChangeCipherSpec-DTLS-1", 12949 config: Config{ 12950 MaxVersion: VersionTLS12, 12951 Bugs: ProtocolBugs{ 12952 BadChangeCipherSpec: []byte{2}, 12953 }, 12954 }, 12955 shouldFail: true, 12956 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12957 }) 12958 testCases = append(testCases, testCase{ 12959 protocol: dtls, 12960 name: "BadChangeCipherSpec-DTLS-2", 12961 config: Config{ 12962 MaxVersion: VersionTLS12, 12963 Bugs: ProtocolBugs{ 12964 BadChangeCipherSpec: []byte{1, 1}, 12965 }, 12966 }, 12967 shouldFail: true, 12968 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12969 }) 12970} 12971 12972// addEndOfFlightTests adds tests where the runner adds extra data in the final 12973// record of each handshake flight. Depending on the implementation strategy, 12974// this data may be carried over to the next flight (assuming no key change) or 12975// may be rejected. To avoid differences with split handshakes and generally 12976// reject misbehavior, BoringSSL treats this as an error. When possible, these 12977// tests pull the extra data from the subsequent flight to distinguish the data 12978// being carried over from a general syntax error. 12979// 12980// These tests are similar to tests in |addChangeCipherSpecTests| that send 12981// extra data at key changes. Not all key changes are at the end of a flight and 12982// not all flights end at a key change. 12983func addEndOfFlightTests() { 12984 // TLS 1.3 client handshakes. 12985 // 12986 // Data following the second TLS 1.3 ClientHello is covered by 12987 // PartialClientFinishedWithClientHello, 12988 // PartialClientFinishedWithSecondClientHello, and 12989 // PartialEndOfEarlyDataWithClientHello in |addChangeCipherSpecTests|. 12990 testCases = append(testCases, testCase{ 12991 testType: serverTest, 12992 name: "PartialSecondClientHelloAfterFirst", 12993 config: Config{ 12994 MaxVersion: VersionTLS13, 12995 // Trigger a curve-based HelloRetryRequest. 12996 DefaultCurves: []CurveID{}, 12997 Bugs: ProtocolBugs{ 12998 PartialSecondClientHelloAfterFirst: true, 12999 }, 13000 }, 13001 shouldFail: true, 13002 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13003 expectedLocalError: "remote error: unexpected message", 13004 }) 13005 13006 // TLS 1.3 server handshakes. 13007 testCases = append(testCases, testCase{ 13008 testType: clientTest, 13009 name: "PartialServerHelloWithHelloRetryRequest", 13010 config: Config{ 13011 MaxVersion: VersionTLS13, 13012 // P-384 requires HelloRetryRequest in BoringSSL. 13013 CurvePreferences: []CurveID{CurveP384}, 13014 Bugs: ProtocolBugs{ 13015 PartialServerHelloWithHelloRetryRequest: true, 13016 }, 13017 }, 13018 shouldFail: true, 13019 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13020 expectedLocalError: "remote error: unexpected message", 13021 }) 13022 13023 // TLS 1.2 client handshakes. 13024 testCases = append(testCases, testCase{ 13025 testType: serverTest, 13026 name: "PartialClientKeyExchangeWithClientHello", 13027 config: Config{ 13028 MaxVersion: VersionTLS12, 13029 Bugs: ProtocolBugs{ 13030 PartialClientKeyExchangeWithClientHello: true, 13031 }, 13032 }, 13033 shouldFail: true, 13034 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13035 expectedLocalError: "remote error: unexpected message", 13036 }) 13037 13038 // TLS 1.2 server handshakes. 13039 testCases = append(testCases, testCase{ 13040 testType: clientTest, 13041 name: "PartialNewSessionTicketWithServerHelloDone", 13042 config: Config{ 13043 MaxVersion: VersionTLS12, 13044 Bugs: ProtocolBugs{ 13045 PartialNewSessionTicketWithServerHelloDone: true, 13046 }, 13047 }, 13048 shouldFail: true, 13049 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13050 expectedLocalError: "remote error: unexpected message", 13051 }) 13052 13053 for _, vers := range tlsVersions { 13054 for _, testType := range []testType{clientTest, serverTest} { 13055 suffix := "-Client" 13056 if testType == serverTest { 13057 suffix = "-Server" 13058 } 13059 suffix += "-" + vers.name 13060 13061 testCases = append(testCases, testCase{ 13062 testType: testType, 13063 name: "TrailingDataWithFinished" + suffix, 13064 config: Config{ 13065 MaxVersion: vers.version, 13066 Bugs: ProtocolBugs{ 13067 TrailingDataWithFinished: true, 13068 }, 13069 }, 13070 shouldFail: true, 13071 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13072 expectedLocalError: "remote error: unexpected message", 13073 }) 13074 testCases = append(testCases, testCase{ 13075 testType: testType, 13076 name: "TrailingDataWithFinished-Resume" + suffix, 13077 config: Config{ 13078 MaxVersion: vers.version, 13079 }, 13080 resumeConfig: &Config{ 13081 MaxVersion: vers.version, 13082 Bugs: ProtocolBugs{ 13083 TrailingDataWithFinished: true, 13084 }, 13085 }, 13086 resumeSession: true, 13087 shouldFail: true, 13088 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13089 expectedLocalError: "remote error: unexpected message", 13090 }) 13091 } 13092 } 13093} 13094 13095type perMessageTest struct { 13096 messageType uint8 13097 test testCase 13098} 13099 13100// makePerMessageTests returns a series of test templates which cover each 13101// message in the TLS handshake. These may be used with bugs like 13102// WrongMessageType to fully test a per-message bug. 13103func makePerMessageTests() []perMessageTest { 13104 var ret []perMessageTest 13105 // The following tests are limited to TLS 1.2, so QUIC is not tested. 13106 for _, protocol := range []protocol{tls, dtls} { 13107 suffix := "-" + protocol.String() 13108 13109 ret = append(ret, perMessageTest{ 13110 messageType: typeClientHello, 13111 test: testCase{ 13112 protocol: protocol, 13113 testType: serverTest, 13114 name: "ClientHello" + suffix, 13115 config: Config{ 13116 MaxVersion: VersionTLS12, 13117 }, 13118 }, 13119 }) 13120 13121 if protocol == dtls { 13122 ret = append(ret, perMessageTest{ 13123 messageType: typeHelloVerifyRequest, 13124 test: testCase{ 13125 protocol: protocol, 13126 name: "HelloVerifyRequest" + suffix, 13127 config: Config{ 13128 MaxVersion: VersionTLS12, 13129 }, 13130 }, 13131 }) 13132 } 13133 13134 ret = append(ret, perMessageTest{ 13135 messageType: typeServerHello, 13136 test: testCase{ 13137 protocol: protocol, 13138 name: "ServerHello" + suffix, 13139 config: Config{ 13140 MaxVersion: VersionTLS12, 13141 }, 13142 }, 13143 }) 13144 13145 ret = append(ret, perMessageTest{ 13146 messageType: typeCertificate, 13147 test: testCase{ 13148 protocol: protocol, 13149 name: "ServerCertificate" + suffix, 13150 config: Config{ 13151 MaxVersion: VersionTLS12, 13152 }, 13153 }, 13154 }) 13155 13156 ret = append(ret, perMessageTest{ 13157 messageType: typeCertificateStatus, 13158 test: testCase{ 13159 protocol: protocol, 13160 name: "CertificateStatus" + suffix, 13161 config: Config{ 13162 MaxVersion: VersionTLS12, 13163 }, 13164 flags: []string{"-enable-ocsp-stapling"}, 13165 }, 13166 }) 13167 13168 ret = append(ret, perMessageTest{ 13169 messageType: typeServerKeyExchange, 13170 test: testCase{ 13171 protocol: protocol, 13172 name: "ServerKeyExchange" + suffix, 13173 config: Config{ 13174 MaxVersion: VersionTLS12, 13175 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 13176 }, 13177 }, 13178 }) 13179 13180 ret = append(ret, perMessageTest{ 13181 messageType: typeCertificateRequest, 13182 test: testCase{ 13183 protocol: protocol, 13184 name: "CertificateRequest" + suffix, 13185 config: Config{ 13186 MaxVersion: VersionTLS12, 13187 ClientAuth: RequireAnyClientCert, 13188 }, 13189 }, 13190 }) 13191 13192 ret = append(ret, perMessageTest{ 13193 messageType: typeServerHelloDone, 13194 test: testCase{ 13195 protocol: protocol, 13196 name: "ServerHelloDone" + suffix, 13197 config: Config{ 13198 MaxVersion: VersionTLS12, 13199 }, 13200 }, 13201 }) 13202 13203 ret = append(ret, perMessageTest{ 13204 messageType: typeCertificate, 13205 test: testCase{ 13206 testType: serverTest, 13207 protocol: protocol, 13208 name: "ClientCertificate" + suffix, 13209 config: Config{ 13210 Certificates: []Certificate{rsaCertificate}, 13211 MaxVersion: VersionTLS12, 13212 }, 13213 flags: []string{"-require-any-client-certificate"}, 13214 }, 13215 }) 13216 13217 ret = append(ret, perMessageTest{ 13218 messageType: typeCertificateVerify, 13219 test: testCase{ 13220 testType: serverTest, 13221 protocol: protocol, 13222 name: "CertificateVerify" + suffix, 13223 config: Config{ 13224 Certificates: []Certificate{rsaCertificate}, 13225 MaxVersion: VersionTLS12, 13226 }, 13227 flags: []string{"-require-any-client-certificate"}, 13228 }, 13229 }) 13230 13231 ret = append(ret, perMessageTest{ 13232 messageType: typeClientKeyExchange, 13233 test: testCase{ 13234 testType: serverTest, 13235 protocol: protocol, 13236 name: "ClientKeyExchange" + suffix, 13237 config: Config{ 13238 MaxVersion: VersionTLS12, 13239 }, 13240 }, 13241 }) 13242 13243 if protocol != dtls { 13244 ret = append(ret, perMessageTest{ 13245 messageType: typeNextProtocol, 13246 test: testCase{ 13247 testType: serverTest, 13248 protocol: protocol, 13249 name: "NextProtocol" + suffix, 13250 config: Config{ 13251 MaxVersion: VersionTLS12, 13252 NextProtos: []string{"bar"}, 13253 }, 13254 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"}, 13255 }, 13256 }) 13257 13258 ret = append(ret, perMessageTest{ 13259 messageType: typeChannelID, 13260 test: testCase{ 13261 testType: serverTest, 13262 protocol: protocol, 13263 name: "ChannelID" + suffix, 13264 config: Config{ 13265 MaxVersion: VersionTLS12, 13266 ChannelID: channelIDKey, 13267 }, 13268 flags: []string{ 13269 "-expect-channel-id", 13270 base64FlagValue(channelIDBytes), 13271 }, 13272 }, 13273 }) 13274 } 13275 13276 ret = append(ret, perMessageTest{ 13277 messageType: typeFinished, 13278 test: testCase{ 13279 testType: serverTest, 13280 protocol: protocol, 13281 name: "ClientFinished" + suffix, 13282 config: Config{ 13283 MaxVersion: VersionTLS12, 13284 }, 13285 }, 13286 }) 13287 13288 ret = append(ret, perMessageTest{ 13289 messageType: typeNewSessionTicket, 13290 test: testCase{ 13291 protocol: protocol, 13292 name: "NewSessionTicket" + suffix, 13293 config: Config{ 13294 MaxVersion: VersionTLS12, 13295 }, 13296 }, 13297 }) 13298 13299 ret = append(ret, perMessageTest{ 13300 messageType: typeFinished, 13301 test: testCase{ 13302 protocol: protocol, 13303 name: "ServerFinished" + suffix, 13304 config: Config{ 13305 MaxVersion: VersionTLS12, 13306 }, 13307 }, 13308 }) 13309 13310 } 13311 13312 for _, protocol := range []protocol{tls, quic} { 13313 suffix := "-" + protocol.String() 13314 ret = append(ret, perMessageTest{ 13315 messageType: typeClientHello, 13316 test: testCase{ 13317 testType: serverTest, 13318 protocol: protocol, 13319 name: "TLS13-ClientHello" + suffix, 13320 config: Config{ 13321 MaxVersion: VersionTLS13, 13322 }, 13323 }, 13324 }) 13325 13326 ret = append(ret, perMessageTest{ 13327 messageType: typeServerHello, 13328 test: testCase{ 13329 name: "TLS13-ServerHello" + suffix, 13330 protocol: protocol, 13331 config: Config{ 13332 MaxVersion: VersionTLS13, 13333 }, 13334 }, 13335 }) 13336 13337 ret = append(ret, perMessageTest{ 13338 messageType: typeEncryptedExtensions, 13339 test: testCase{ 13340 name: "TLS13-EncryptedExtensions" + suffix, 13341 protocol: protocol, 13342 config: Config{ 13343 MaxVersion: VersionTLS13, 13344 }, 13345 }, 13346 }) 13347 13348 ret = append(ret, perMessageTest{ 13349 messageType: typeCertificateRequest, 13350 test: testCase{ 13351 name: "TLS13-CertificateRequest" + suffix, 13352 protocol: protocol, 13353 config: Config{ 13354 MaxVersion: VersionTLS13, 13355 ClientAuth: RequireAnyClientCert, 13356 }, 13357 }, 13358 }) 13359 13360 ret = append(ret, perMessageTest{ 13361 messageType: typeCertificate, 13362 test: testCase{ 13363 name: "TLS13-ServerCertificate" + suffix, 13364 protocol: protocol, 13365 config: Config{ 13366 MaxVersion: VersionTLS13, 13367 }, 13368 }, 13369 }) 13370 13371 ret = append(ret, perMessageTest{ 13372 messageType: typeCertificateVerify, 13373 test: testCase{ 13374 name: "TLS13-ServerCertificateVerify" + suffix, 13375 protocol: protocol, 13376 config: Config{ 13377 MaxVersion: VersionTLS13, 13378 }, 13379 }, 13380 }) 13381 13382 ret = append(ret, perMessageTest{ 13383 messageType: typeFinished, 13384 test: testCase{ 13385 name: "TLS13-ServerFinished" + suffix, 13386 protocol: protocol, 13387 config: Config{ 13388 MaxVersion: VersionTLS13, 13389 }, 13390 }, 13391 }) 13392 13393 ret = append(ret, perMessageTest{ 13394 messageType: typeCertificate, 13395 test: testCase{ 13396 testType: serverTest, 13397 protocol: protocol, 13398 name: "TLS13-ClientCertificate" + suffix, 13399 config: Config{ 13400 Certificates: []Certificate{rsaCertificate}, 13401 MaxVersion: VersionTLS13, 13402 }, 13403 flags: []string{"-require-any-client-certificate"}, 13404 }, 13405 }) 13406 13407 ret = append(ret, perMessageTest{ 13408 messageType: typeCertificateVerify, 13409 test: testCase{ 13410 testType: serverTest, 13411 protocol: protocol, 13412 name: "TLS13-ClientCertificateVerify" + suffix, 13413 config: Config{ 13414 Certificates: []Certificate{rsaCertificate}, 13415 MaxVersion: VersionTLS13, 13416 }, 13417 flags: []string{"-require-any-client-certificate"}, 13418 }, 13419 }) 13420 13421 ret = append(ret, perMessageTest{ 13422 messageType: typeFinished, 13423 test: testCase{ 13424 testType: serverTest, 13425 protocol: protocol, 13426 name: "TLS13-ClientFinished" + suffix, 13427 config: Config{ 13428 MaxVersion: VersionTLS13, 13429 }, 13430 }, 13431 }) 13432 13433 // Only TLS uses EndOfEarlyData. 13434 if protocol == tls { 13435 ret = append(ret, perMessageTest{ 13436 messageType: typeEndOfEarlyData, 13437 test: testCase{ 13438 testType: serverTest, 13439 protocol: protocol, 13440 name: "TLS13-EndOfEarlyData" + suffix, 13441 config: Config{ 13442 MaxVersion: VersionTLS13, 13443 }, 13444 resumeSession: true, 13445 earlyData: true, 13446 }, 13447 }) 13448 } 13449 } 13450 13451 return ret 13452} 13453 13454func addWrongMessageTypeTests() { 13455 for _, t := range makePerMessageTests() { 13456 t.test.name = "WrongMessageType-" + t.test.name 13457 if t.test.resumeConfig != nil { 13458 t.test.resumeConfig.Bugs.SendWrongMessageType = t.messageType 13459 } else { 13460 t.test.config.Bugs.SendWrongMessageType = t.messageType 13461 } 13462 t.test.shouldFail = true 13463 t.test.expectedError = ":UNEXPECTED_MESSAGE:" 13464 t.test.expectedLocalError = "remote error: unexpected message" 13465 13466 if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello { 13467 // In TLS 1.3, if the server believes it has sent ServerHello, 13468 // but the client cannot process it, the client will send an 13469 // unencrypted alert while the server expects encryption. In TLS, 13470 // this is a decryption failure. In QUIC, the encryption levels 13471 // do not match. 13472 if t.test.protocol == quic { 13473 t.test.expectedLocalError = "received record at initial encryption level, but expected handshake" 13474 } else { 13475 t.test.expectedLocalError = "local error: bad record MAC" 13476 } 13477 } 13478 13479 testCases = append(testCases, t.test) 13480 } 13481} 13482 13483func addTrailingMessageDataTests() { 13484 for _, t := range makePerMessageTests() { 13485 t.test.name = "TrailingMessageData-" + t.test.name 13486 if t.test.resumeConfig != nil { 13487 t.test.resumeConfig.Bugs.SendTrailingMessageData = t.messageType 13488 } else { 13489 t.test.config.Bugs.SendTrailingMessageData = t.messageType 13490 } 13491 t.test.shouldFail = true 13492 t.test.expectedError = ":DECODE_ERROR:" 13493 t.test.expectedLocalError = "remote error: error decoding message" 13494 13495 if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello { 13496 // In TLS 1.3, if the server believes it has sent ServerHello, 13497 // but the client cannot process it, the client will send an 13498 // unencrypted alert while the server expects encryption. In TLS, 13499 // this is a decryption failure. In QUIC, the encryption levels 13500 // do not match. 13501 if t.test.protocol == quic { 13502 t.test.expectedLocalError = "received record at initial encryption level, but expected handshake" 13503 } else { 13504 t.test.expectedLocalError = "local error: bad record MAC" 13505 } 13506 } 13507 13508 if t.messageType == typeFinished { 13509 // Bad Finished messages read as the verify data having 13510 // the wrong length. 13511 t.test.expectedError = ":DIGEST_CHECK_FAILED:" 13512 t.test.expectedLocalError = "remote error: error decrypting message" 13513 } 13514 13515 testCases = append(testCases, t.test) 13516 } 13517} 13518 13519func addTLS13HandshakeTests() { 13520 testCases = append(testCases, testCase{ 13521 testType: clientTest, 13522 name: "NegotiatePSKResumption-TLS13", 13523 config: Config{ 13524 MaxVersion: VersionTLS13, 13525 Bugs: ProtocolBugs{ 13526 NegotiatePSKResumption: true, 13527 }, 13528 }, 13529 resumeSession: true, 13530 shouldFail: true, 13531 expectedError: ":MISSING_KEY_SHARE:", 13532 }) 13533 13534 testCases = append(testCases, testCase{ 13535 testType: clientTest, 13536 name: "MissingKeyShare-Client-TLS13", 13537 config: Config{ 13538 MaxVersion: VersionTLS13, 13539 Bugs: ProtocolBugs{ 13540 MissingKeyShare: true, 13541 }, 13542 }, 13543 shouldFail: true, 13544 expectedError: ":MISSING_KEY_SHARE:", 13545 }) 13546 13547 testCases = append(testCases, testCase{ 13548 testType: serverTest, 13549 name: "MissingKeyShare-Server-TLS13", 13550 config: Config{ 13551 MaxVersion: VersionTLS13, 13552 Bugs: ProtocolBugs{ 13553 MissingKeyShare: true, 13554 }, 13555 }, 13556 shouldFail: true, 13557 expectedError: ":MISSING_KEY_SHARE:", 13558 }) 13559 13560 testCases = append(testCases, testCase{ 13561 testType: serverTest, 13562 name: "DuplicateKeyShares-TLS13", 13563 config: Config{ 13564 MaxVersion: VersionTLS13, 13565 Bugs: ProtocolBugs{ 13566 DuplicateKeyShares: true, 13567 }, 13568 }, 13569 shouldFail: true, 13570 expectedError: ":DUPLICATE_KEY_SHARE:", 13571 }) 13572 13573 testCases = append(testCases, testCase{ 13574 testType: serverTest, 13575 name: "SkipEarlyData-TLS13", 13576 config: Config{ 13577 MaxVersion: VersionTLS13, 13578 Bugs: ProtocolBugs{ 13579 SendFakeEarlyDataLength: 4, 13580 }, 13581 }, 13582 }) 13583 13584 // Test that enabling TLS 1.3 does not interfere with TLS 1.2 session ID 13585 // resumption. 13586 testCases = append(testCases, testCase{ 13587 testType: clientTest, 13588 name: "ResumeTLS12SessionID-TLS13", 13589 config: Config{ 13590 MaxVersion: VersionTLS12, 13591 SessionTicketsDisabled: true, 13592 }, 13593 flags: []string{"-max-version", strconv.Itoa(VersionTLS13)}, 13594 resumeSession: true, 13595 }) 13596 13597 // Test that the client correctly handles a TLS 1.3 ServerHello which echoes 13598 // a TLS 1.2 session ID. 13599 testCases = append(testCases, testCase{ 13600 testType: clientTest, 13601 name: "TLS12SessionID-TLS13", 13602 config: Config{ 13603 MaxVersion: VersionTLS12, 13604 SessionTicketsDisabled: true, 13605 }, 13606 resumeConfig: &Config{ 13607 MaxVersion: VersionTLS13, 13608 }, 13609 resumeSession: true, 13610 expectResumeRejected: true, 13611 }) 13612 13613 // Test that the server correctly echoes back session IDs of 13614 // various lengths. The first test additionally asserts that 13615 // BoringSSL always sends the ChangeCipherSpec messages for 13616 // compatibility mode, rather than negotiating it based on the 13617 // ClientHello. 13618 testCases = append(testCases, testCase{ 13619 testType: serverTest, 13620 name: "EmptySessionID-TLS13", 13621 config: Config{ 13622 MaxVersion: VersionTLS13, 13623 Bugs: ProtocolBugs{ 13624 SendClientHelloSessionID: []byte{}, 13625 }, 13626 }, 13627 }) 13628 13629 testCases = append(testCases, testCase{ 13630 testType: serverTest, 13631 name: "Server-ShortSessionID-TLS13", 13632 config: Config{ 13633 MaxVersion: VersionTLS13, 13634 Bugs: ProtocolBugs{ 13635 SendClientHelloSessionID: make([]byte, 16), 13636 }, 13637 }, 13638 }) 13639 13640 testCases = append(testCases, testCase{ 13641 testType: serverTest, 13642 name: "Server-FullSessionID-TLS13", 13643 config: Config{ 13644 MaxVersion: VersionTLS13, 13645 Bugs: ProtocolBugs{ 13646 SendClientHelloSessionID: make([]byte, 32), 13647 }, 13648 }, 13649 }) 13650 13651 // The server should reject ClientHellos whose session IDs are too long. 13652 testCases = append(testCases, testCase{ 13653 testType: serverTest, 13654 name: "Server-TooLongSessionID-TLS13", 13655 config: Config{ 13656 MaxVersion: VersionTLS13, 13657 Bugs: ProtocolBugs{ 13658 SendClientHelloSessionID: make([]byte, 33), 13659 }, 13660 }, 13661 shouldFail: true, 13662 expectedError: ":DECODE_ERROR:", 13663 expectedLocalError: "remote error: error decoding message", 13664 }) 13665 testCases = append(testCases, testCase{ 13666 testType: serverTest, 13667 name: "Server-TooLongSessionID-TLS12", 13668 config: Config{ 13669 MaxVersion: VersionTLS12, 13670 Bugs: ProtocolBugs{ 13671 SendClientHelloSessionID: make([]byte, 33), 13672 }, 13673 }, 13674 shouldFail: true, 13675 expectedError: ":DECODE_ERROR:", 13676 expectedLocalError: "remote error: error decoding message", 13677 }) 13678 13679 // Test that the client correctly accepts or rejects short session IDs from 13680 // the server. Our tests use 32 bytes by default, so the boundary condition 13681 // is already covered. 13682 testCases = append(testCases, testCase{ 13683 name: "Client-ShortSessionID", 13684 config: Config{ 13685 MaxVersion: VersionTLS12, 13686 SessionTicketsDisabled: true, 13687 Bugs: ProtocolBugs{ 13688 NewSessionIDLength: 1, 13689 }, 13690 }, 13691 resumeSession: true, 13692 }) 13693 testCases = append(testCases, testCase{ 13694 name: "Client-TooLongSessionID", 13695 config: Config{ 13696 MaxVersion: VersionTLS12, 13697 SessionTicketsDisabled: true, 13698 Bugs: ProtocolBugs{ 13699 NewSessionIDLength: 33, 13700 }, 13701 }, 13702 shouldFail: true, 13703 expectedError: ":DECODE_ERROR:", 13704 expectedLocalError: "remote error: error decoding message", 13705 }) 13706 13707 // Test that the client sends a fake session ID in TLS 1.3. We cover both 13708 // normal and resumption handshakes to capture interactions with the 13709 // session resumption path. 13710 testCases = append(testCases, testCase{ 13711 testType: clientTest, 13712 name: "TLS13SessionID-TLS13", 13713 config: Config{ 13714 MaxVersion: VersionTLS13, 13715 Bugs: ProtocolBugs{ 13716 ExpectClientHelloSessionID: true, 13717 }, 13718 }, 13719 resumeSession: true, 13720 }) 13721 13722 // Test that the client omits the fake session ID when the max version is TLS 1.2 and below. 13723 testCases = append(testCases, testCase{ 13724 testType: clientTest, 13725 name: "TLS12NoSessionID-TLS13", 13726 config: Config{ 13727 MaxVersion: VersionTLS13, 13728 Bugs: ProtocolBugs{ 13729 ExpectNoSessionID: true, 13730 }, 13731 }, 13732 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 13733 }) 13734 13735 testCases = append(testCases, testCase{ 13736 testType: clientTest, 13737 name: "EarlyData-Client-TLS13", 13738 config: Config{ 13739 MaxVersion: VersionTLS13, 13740 MinVersion: VersionTLS13, 13741 }, 13742 resumeSession: true, 13743 earlyData: true, 13744 flags: []string{ 13745 "-on-initial-expect-early-data-reason", "no_session_offered", 13746 "-on-resume-expect-early-data-reason", "accept", 13747 }, 13748 }) 13749 13750 testCases = append(testCases, testCase{ 13751 testType: clientTest, 13752 name: "EarlyData-Reject-Client-TLS13", 13753 config: Config{ 13754 MaxVersion: VersionTLS13, 13755 }, 13756 resumeConfig: &Config{ 13757 MaxVersion: VersionTLS13, 13758 Bugs: ProtocolBugs{ 13759 AlwaysRejectEarlyData: true, 13760 }, 13761 }, 13762 resumeSession: true, 13763 earlyData: true, 13764 expectEarlyDataRejected: true, 13765 flags: []string{ 13766 "-on-retry-expect-early-data-reason", "peer_declined", 13767 }, 13768 }) 13769 13770 testCases = append(testCases, testCase{ 13771 testType: serverTest, 13772 name: "EarlyData-Server-TLS13", 13773 config: Config{ 13774 MaxVersion: VersionTLS13, 13775 MinVersion: VersionTLS13, 13776 }, 13777 messageCount: 2, 13778 resumeSession: true, 13779 earlyData: true, 13780 flags: []string{ 13781 "-on-initial-expect-early-data-reason", "no_session_offered", 13782 "-on-resume-expect-early-data-reason", "accept", 13783 }, 13784 }) 13785 13786 // The above tests the most recent ticket. Additionally test that 0-RTT 13787 // works on the first ticket issued by the server. 13788 testCases = append(testCases, testCase{ 13789 testType: serverTest, 13790 name: "EarlyData-FirstTicket-Server-TLS13", 13791 config: Config{ 13792 MaxVersion: VersionTLS13, 13793 MinVersion: VersionTLS13, 13794 Bugs: ProtocolBugs{ 13795 UseFirstSessionTicket: true, 13796 }, 13797 }, 13798 messageCount: 2, 13799 resumeSession: true, 13800 earlyData: true, 13801 flags: []string{ 13802 "-on-resume-expect-early-data-reason", "accept", 13803 }, 13804 }) 13805 13806 testCases = append(testCases, testCase{ 13807 testType: serverTest, 13808 name: "SkipEarlyData-OmitEarlyDataExtension-TLS13", 13809 config: Config{ 13810 MaxVersion: VersionTLS13, 13811 Bugs: ProtocolBugs{ 13812 SendFakeEarlyDataLength: 4, 13813 OmitEarlyDataExtension: true, 13814 }, 13815 }, 13816 shouldFail: true, 13817 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 13818 }) 13819 13820 testCases = append(testCases, testCase{ 13821 testType: serverTest, 13822 name: "SkipEarlyData-OmitEarlyDataExtension-HelloRetryRequest-TLS13", 13823 config: Config{ 13824 MaxVersion: VersionTLS13, 13825 // Require a HelloRetryRequest for every curve. 13826 DefaultCurves: []CurveID{}, 13827 Bugs: ProtocolBugs{ 13828 SendFakeEarlyDataLength: 4, 13829 OmitEarlyDataExtension: true, 13830 }, 13831 }, 13832 shouldFail: true, 13833 expectedError: ":UNEXPECTED_RECORD:", 13834 expectedLocalError: "remote error: unexpected message", 13835 }) 13836 13837 testCases = append(testCases, testCase{ 13838 testType: serverTest, 13839 name: "SkipEarlyData-TooMuchData-TLS13", 13840 config: Config{ 13841 MaxVersion: VersionTLS13, 13842 Bugs: ProtocolBugs{ 13843 SendFakeEarlyDataLength: 16384 + 1, 13844 }, 13845 }, 13846 shouldFail: true, 13847 expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:", 13848 }) 13849 13850 testCases = append(testCases, testCase{ 13851 testType: serverTest, 13852 name: "SkipEarlyData-Interleaved-TLS13", 13853 config: Config{ 13854 MaxVersion: VersionTLS13, 13855 Bugs: ProtocolBugs{ 13856 SendFakeEarlyDataLength: 4, 13857 InterleaveEarlyData: true, 13858 }, 13859 }, 13860 shouldFail: true, 13861 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 13862 }) 13863 13864 testCases = append(testCases, testCase{ 13865 testType: serverTest, 13866 name: "SkipEarlyData-EarlyDataInTLS12-TLS13", 13867 config: Config{ 13868 MaxVersion: VersionTLS13, 13869 Bugs: ProtocolBugs{ 13870 SendFakeEarlyDataLength: 4, 13871 }, 13872 }, 13873 shouldFail: true, 13874 expectedError: ":UNEXPECTED_RECORD:", 13875 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 13876 }) 13877 13878 testCases = append(testCases, testCase{ 13879 testType: serverTest, 13880 name: "SkipEarlyData-HRR-TLS13", 13881 config: Config{ 13882 MaxVersion: VersionTLS13, 13883 Bugs: ProtocolBugs{ 13884 SendFakeEarlyDataLength: 4, 13885 }, 13886 DefaultCurves: []CurveID{}, 13887 }, 13888 // Though the session is not resumed and we send HelloRetryRequest, 13889 // early data being disabled takes priority as the reject reason. 13890 flags: []string{"-expect-early-data-reason", "disabled"}, 13891 }) 13892 13893 testCases = append(testCases, testCase{ 13894 testType: serverTest, 13895 name: "SkipEarlyData-HRR-Interleaved-TLS13", 13896 config: Config{ 13897 MaxVersion: VersionTLS13, 13898 Bugs: ProtocolBugs{ 13899 SendFakeEarlyDataLength: 4, 13900 InterleaveEarlyData: true, 13901 }, 13902 DefaultCurves: []CurveID{}, 13903 }, 13904 shouldFail: true, 13905 expectedError: ":UNEXPECTED_RECORD:", 13906 }) 13907 13908 testCases = append(testCases, testCase{ 13909 testType: serverTest, 13910 name: "SkipEarlyData-HRR-TooMuchData-TLS13", 13911 config: Config{ 13912 MaxVersion: VersionTLS13, 13913 Bugs: ProtocolBugs{ 13914 SendFakeEarlyDataLength: 16384 + 1, 13915 }, 13916 DefaultCurves: []CurveID{}, 13917 }, 13918 shouldFail: true, 13919 expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:", 13920 }) 13921 13922 // Test that skipping early data looking for cleartext correctly 13923 // processes an alert record. 13924 testCases = append(testCases, testCase{ 13925 testType: serverTest, 13926 name: "SkipEarlyData-HRR-FatalAlert-TLS13", 13927 config: Config{ 13928 MaxVersion: VersionTLS13, 13929 Bugs: ProtocolBugs{ 13930 SendEarlyAlert: true, 13931 SendFakeEarlyDataLength: 4, 13932 }, 13933 DefaultCurves: []CurveID{}, 13934 }, 13935 shouldFail: true, 13936 expectedError: ":SSLV3_ALERT_HANDSHAKE_FAILURE:", 13937 }) 13938 13939 testCases = append(testCases, testCase{ 13940 testType: serverTest, 13941 name: "SkipEarlyData-SecondClientHelloEarlyData-TLS13", 13942 config: Config{ 13943 MaxVersion: VersionTLS13, 13944 Bugs: ProtocolBugs{ 13945 SendEarlyDataOnSecondClientHello: true, 13946 }, 13947 DefaultCurves: []CurveID{}, 13948 }, 13949 shouldFail: true, 13950 expectedLocalError: "remote error: bad record MAC", 13951 }) 13952 13953 testCases = append(testCases, testCase{ 13954 testType: clientTest, 13955 name: "EmptyEncryptedExtensions-TLS13", 13956 config: Config{ 13957 MaxVersion: VersionTLS13, 13958 Bugs: ProtocolBugs{ 13959 EmptyEncryptedExtensions: true, 13960 }, 13961 }, 13962 shouldFail: true, 13963 expectedLocalError: "remote error: error decoding message", 13964 }) 13965 13966 testCases = append(testCases, testCase{ 13967 testType: clientTest, 13968 name: "EncryptedExtensionsWithKeyShare-TLS13", 13969 config: Config{ 13970 MaxVersion: VersionTLS13, 13971 Bugs: ProtocolBugs{ 13972 EncryptedExtensionsWithKeyShare: true, 13973 }, 13974 }, 13975 shouldFail: true, 13976 expectedLocalError: "remote error: unsupported extension", 13977 }) 13978 13979 testCases = append(testCases, testCase{ 13980 testType: serverTest, 13981 name: "SendHelloRetryRequest-TLS13", 13982 config: Config{ 13983 MaxVersion: VersionTLS13, 13984 // Require a HelloRetryRequest for every curve. 13985 DefaultCurves: []CurveID{}, 13986 CurvePreferences: []CurveID{CurveX25519}, 13987 }, 13988 expectations: connectionExpectations{ 13989 curveID: CurveX25519, 13990 }, 13991 flags: []string{"-expect-hrr"}, 13992 }) 13993 13994 testCases = append(testCases, testCase{ 13995 testType: serverTest, 13996 name: "SendHelloRetryRequest-2-TLS13", 13997 config: Config{ 13998 MaxVersion: VersionTLS13, 13999 DefaultCurves: []CurveID{CurveP384}, 14000 CurvePreferences: []CurveID{CurveX25519, CurveP384}, 14001 }, 14002 // Although the ClientHello did not predict our preferred curve, 14003 // we always select it whether it is predicted or not. 14004 expectations: connectionExpectations{ 14005 curveID: CurveX25519, 14006 }, 14007 flags: []string{"-expect-hrr"}, 14008 }) 14009 14010 testCases = append(testCases, testCase{ 14011 name: "UnknownCurve-HelloRetryRequest-TLS13", 14012 config: Config{ 14013 MaxVersion: VersionTLS13, 14014 // P-384 requires HelloRetryRequest in BoringSSL. 14015 CurvePreferences: []CurveID{CurveP384}, 14016 Bugs: ProtocolBugs{ 14017 SendHelloRetryRequestCurve: bogusCurve, 14018 }, 14019 }, 14020 shouldFail: true, 14021 expectedError: ":WRONG_CURVE:", 14022 }) 14023 14024 testCases = append(testCases, testCase{ 14025 name: "HelloRetryRequest-CipherChange-TLS13", 14026 config: Config{ 14027 MaxVersion: VersionTLS13, 14028 // P-384 requires HelloRetryRequest in BoringSSL. 14029 CurvePreferences: []CurveID{CurveP384}, 14030 Bugs: ProtocolBugs{ 14031 SendCipherSuite: TLS_AES_128_GCM_SHA256, 14032 SendHelloRetryRequestCipherSuite: TLS_CHACHA20_POLY1305_SHA256, 14033 }, 14034 }, 14035 shouldFail: true, 14036 expectedError: ":WRONG_CIPHER_RETURNED:", 14037 }) 14038 14039 // Test that the client does not offer a PSK in the second ClientHello if the 14040 // HelloRetryRequest is incompatible with it. 14041 testCases = append(testCases, testCase{ 14042 testType: clientTest, 14043 name: "HelloRetryRequest-NonResumableCipher-TLS13", 14044 config: Config{ 14045 MaxVersion: VersionTLS13, 14046 CipherSuites: []uint16{ 14047 TLS_AES_128_GCM_SHA256, 14048 }, 14049 }, 14050 resumeConfig: &Config{ 14051 MaxVersion: VersionTLS13, 14052 // P-384 requires HelloRetryRequest in BoringSSL. 14053 CurvePreferences: []CurveID{CurveP384}, 14054 Bugs: ProtocolBugs{ 14055 ExpectNoTLS13PSKAfterHRR: true, 14056 }, 14057 CipherSuites: []uint16{ 14058 TLS_AES_256_GCM_SHA384, 14059 }, 14060 }, 14061 resumeSession: true, 14062 expectResumeRejected: true, 14063 }) 14064 14065 testCases = append(testCases, testCase{ 14066 name: "DisabledCurve-HelloRetryRequest-TLS13", 14067 config: Config{ 14068 MaxVersion: VersionTLS13, 14069 CurvePreferences: []CurveID{CurveP256}, 14070 Bugs: ProtocolBugs{ 14071 IgnorePeerCurvePreferences: true, 14072 }, 14073 }, 14074 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 14075 shouldFail: true, 14076 expectedError: ":WRONG_CURVE:", 14077 }) 14078 14079 testCases = append(testCases, testCase{ 14080 name: "UnnecessaryHelloRetryRequest-TLS13", 14081 config: Config{ 14082 MaxVersion: VersionTLS13, 14083 CurvePreferences: []CurveID{CurveX25519}, 14084 Bugs: ProtocolBugs{ 14085 SendHelloRetryRequestCurve: CurveX25519, 14086 }, 14087 }, 14088 shouldFail: true, 14089 expectedError: ":WRONG_CURVE:", 14090 }) 14091 14092 testCases = append(testCases, testCase{ 14093 name: "SecondHelloRetryRequest-TLS13", 14094 config: Config{ 14095 MaxVersion: VersionTLS13, 14096 // P-384 requires HelloRetryRequest in BoringSSL. 14097 CurvePreferences: []CurveID{CurveP384}, 14098 Bugs: ProtocolBugs{ 14099 SecondHelloRetryRequest: true, 14100 }, 14101 }, 14102 shouldFail: true, 14103 expectedError: ":UNEXPECTED_MESSAGE:", 14104 }) 14105 14106 testCases = append(testCases, testCase{ 14107 name: "HelloRetryRequest-Empty-TLS13", 14108 config: Config{ 14109 MaxVersion: VersionTLS13, 14110 Bugs: ProtocolBugs{ 14111 AlwaysSendHelloRetryRequest: true, 14112 }, 14113 }, 14114 shouldFail: true, 14115 expectedError: ":EMPTY_HELLO_RETRY_REQUEST:", 14116 expectedLocalError: "remote error: illegal parameter", 14117 }) 14118 14119 testCases = append(testCases, testCase{ 14120 name: "HelloRetryRequest-DuplicateCurve-TLS13", 14121 config: Config{ 14122 MaxVersion: VersionTLS13, 14123 // P-384 requires a HelloRetryRequest against BoringSSL's default 14124 // configuration. Assert this ExpectMissingKeyShare. 14125 CurvePreferences: []CurveID{CurveP384}, 14126 Bugs: ProtocolBugs{ 14127 ExpectMissingKeyShare: true, 14128 DuplicateHelloRetryRequestExtensions: true, 14129 }, 14130 }, 14131 shouldFail: true, 14132 expectedError: ":DUPLICATE_EXTENSION:", 14133 expectedLocalError: "remote error: illegal parameter", 14134 }) 14135 14136 testCases = append(testCases, testCase{ 14137 name: "HelloRetryRequest-Cookie-TLS13", 14138 config: Config{ 14139 MaxVersion: VersionTLS13, 14140 Bugs: ProtocolBugs{ 14141 SendHelloRetryRequestCookie: []byte("cookie"), 14142 }, 14143 }, 14144 }) 14145 14146 testCases = append(testCases, testCase{ 14147 name: "HelloRetryRequest-DuplicateCookie-TLS13", 14148 config: Config{ 14149 MaxVersion: VersionTLS13, 14150 Bugs: ProtocolBugs{ 14151 SendHelloRetryRequestCookie: []byte("cookie"), 14152 DuplicateHelloRetryRequestExtensions: true, 14153 }, 14154 }, 14155 shouldFail: true, 14156 expectedError: ":DUPLICATE_EXTENSION:", 14157 expectedLocalError: "remote error: illegal parameter", 14158 }) 14159 14160 testCases = append(testCases, testCase{ 14161 name: "HelloRetryRequest-EmptyCookie-TLS13", 14162 config: Config{ 14163 MaxVersion: VersionTLS13, 14164 Bugs: ProtocolBugs{ 14165 SendHelloRetryRequestCookie: []byte{}, 14166 }, 14167 }, 14168 shouldFail: true, 14169 expectedError: ":DECODE_ERROR:", 14170 }) 14171 14172 testCases = append(testCases, testCase{ 14173 name: "HelloRetryRequest-Cookie-Curve-TLS13", 14174 config: Config{ 14175 MaxVersion: VersionTLS13, 14176 // P-384 requires HelloRetryRequest in BoringSSL. 14177 CurvePreferences: []CurveID{CurveP384}, 14178 Bugs: ProtocolBugs{ 14179 SendHelloRetryRequestCookie: []byte("cookie"), 14180 ExpectMissingKeyShare: true, 14181 }, 14182 }, 14183 }) 14184 14185 testCases = append(testCases, testCase{ 14186 name: "HelloRetryRequest-Unknown-TLS13", 14187 config: Config{ 14188 MaxVersion: VersionTLS13, 14189 Bugs: ProtocolBugs{ 14190 CustomHelloRetryRequestExtension: "extension", 14191 }, 14192 }, 14193 shouldFail: true, 14194 expectedError: ":UNEXPECTED_EXTENSION:", 14195 expectedLocalError: "remote error: unsupported extension", 14196 }) 14197 14198 testCases = append(testCases, testCase{ 14199 testType: serverTest, 14200 name: "SecondClientHelloMissingKeyShare-TLS13", 14201 config: Config{ 14202 MaxVersion: VersionTLS13, 14203 DefaultCurves: []CurveID{}, 14204 Bugs: ProtocolBugs{ 14205 SecondClientHelloMissingKeyShare: true, 14206 }, 14207 }, 14208 shouldFail: true, 14209 expectedError: ":MISSING_KEY_SHARE:", 14210 }) 14211 14212 testCases = append(testCases, testCase{ 14213 testType: serverTest, 14214 name: "SecondClientHelloWrongCurve-TLS13", 14215 config: Config{ 14216 MaxVersion: VersionTLS13, 14217 DefaultCurves: []CurveID{}, 14218 Bugs: ProtocolBugs{ 14219 MisinterpretHelloRetryRequestCurve: CurveP521, 14220 }, 14221 }, 14222 shouldFail: true, 14223 expectedError: ":WRONG_CURVE:", 14224 }) 14225 14226 testCases = append(testCases, testCase{ 14227 name: "HelloRetryRequestVersionMismatch-TLS13", 14228 config: Config{ 14229 MaxVersion: VersionTLS13, 14230 // P-384 requires HelloRetryRequest in BoringSSL. 14231 CurvePreferences: []CurveID{CurveP384}, 14232 Bugs: ProtocolBugs{ 14233 SendServerHelloVersion: 0x0305, 14234 }, 14235 }, 14236 shouldFail: true, 14237 expectedError: ":DECODE_ERROR:", 14238 }) 14239 14240 testCases = append(testCases, testCase{ 14241 name: "HelloRetryRequestCurveMismatch-TLS13", 14242 config: Config{ 14243 MaxVersion: VersionTLS13, 14244 // P-384 requires HelloRetryRequest in BoringSSL. 14245 CurvePreferences: []CurveID{CurveP384}, 14246 Bugs: ProtocolBugs{ 14247 // Send P-384 (correct) in the HelloRetryRequest. 14248 SendHelloRetryRequestCurve: CurveP384, 14249 // But send P-256 in the ServerHello. 14250 SendCurve: CurveP256, 14251 }, 14252 }, 14253 shouldFail: true, 14254 expectedError: ":WRONG_CURVE:", 14255 }) 14256 14257 // Test the server selecting a curve that requires a HelloRetryRequest 14258 // without sending it. 14259 testCases = append(testCases, testCase{ 14260 name: "SkipHelloRetryRequest-TLS13", 14261 config: Config{ 14262 MaxVersion: VersionTLS13, 14263 // P-384 requires HelloRetryRequest in BoringSSL. 14264 CurvePreferences: []CurveID{CurveP384}, 14265 Bugs: ProtocolBugs{ 14266 SkipHelloRetryRequest: true, 14267 }, 14268 }, 14269 shouldFail: true, 14270 expectedError: ":WRONG_CURVE:", 14271 }) 14272 14273 testCases = append(testCases, testCase{ 14274 name: "SecondServerHelloNoVersion-TLS13", 14275 config: Config{ 14276 MaxVersion: VersionTLS13, 14277 // P-384 requires HelloRetryRequest in BoringSSL. 14278 CurvePreferences: []CurveID{CurveP384}, 14279 Bugs: ProtocolBugs{ 14280 OmitServerSupportedVersionExtension: true, 14281 }, 14282 }, 14283 shouldFail: true, 14284 expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:", 14285 }) 14286 testCases = append(testCases, testCase{ 14287 name: "SecondServerHelloWrongVersion-TLS13", 14288 config: Config{ 14289 MaxVersion: VersionTLS13, 14290 // P-384 requires HelloRetryRequest in BoringSSL. 14291 CurvePreferences: []CurveID{CurveP384}, 14292 Bugs: ProtocolBugs{ 14293 SendServerSupportedVersionExtension: 0x1234, 14294 }, 14295 }, 14296 shouldFail: true, 14297 expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:", 14298 }) 14299 14300 testCases = append(testCases, testCase{ 14301 name: "RequestContextInHandshake-TLS13", 14302 config: Config{ 14303 MaxVersion: VersionTLS13, 14304 MinVersion: VersionTLS13, 14305 ClientAuth: RequireAnyClientCert, 14306 Bugs: ProtocolBugs{ 14307 SendRequestContext: []byte("request context"), 14308 }, 14309 }, 14310 flags: []string{ 14311 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14312 "-key-file", path.Join(*resourceDir, rsaKeyFile), 14313 }, 14314 shouldFail: true, 14315 expectedError: ":DECODE_ERROR:", 14316 }) 14317 14318 testCases = append(testCases, testCase{ 14319 name: "UnknownExtensionInCertificateRequest-TLS13", 14320 config: Config{ 14321 MaxVersion: VersionTLS13, 14322 MinVersion: VersionTLS13, 14323 ClientAuth: RequireAnyClientCert, 14324 Bugs: ProtocolBugs{ 14325 SendCustomCertificateRequest: 0x1212, 14326 }, 14327 }, 14328 flags: []string{ 14329 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14330 "-key-file", path.Join(*resourceDir, rsaKeyFile), 14331 }, 14332 }) 14333 14334 testCases = append(testCases, testCase{ 14335 name: "MissingSignatureAlgorithmsInCertificateRequest-TLS13", 14336 config: Config{ 14337 MaxVersion: VersionTLS13, 14338 MinVersion: VersionTLS13, 14339 ClientAuth: RequireAnyClientCert, 14340 Bugs: ProtocolBugs{ 14341 OmitCertificateRequestAlgorithms: true, 14342 }, 14343 }, 14344 flags: []string{ 14345 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14346 "-key-file", path.Join(*resourceDir, rsaKeyFile), 14347 }, 14348 shouldFail: true, 14349 expectedError: ":DECODE_ERROR:", 14350 }) 14351 14352 testCases = append(testCases, testCase{ 14353 testType: serverTest, 14354 name: "TrailingKeyShareData-TLS13", 14355 config: Config{ 14356 MaxVersion: VersionTLS13, 14357 Bugs: ProtocolBugs{ 14358 TrailingKeyShareData: true, 14359 }, 14360 }, 14361 shouldFail: true, 14362 expectedError: ":DECODE_ERROR:", 14363 }) 14364 14365 testCases = append(testCases, testCase{ 14366 name: "AlwaysSelectPSKIdentity-TLS13", 14367 config: Config{ 14368 MaxVersion: VersionTLS13, 14369 Bugs: ProtocolBugs{ 14370 AlwaysSelectPSKIdentity: true, 14371 }, 14372 }, 14373 shouldFail: true, 14374 expectedError: ":UNEXPECTED_EXTENSION:", 14375 }) 14376 14377 testCases = append(testCases, testCase{ 14378 name: "InvalidPSKIdentity-TLS13", 14379 config: Config{ 14380 MaxVersion: VersionTLS13, 14381 Bugs: ProtocolBugs{ 14382 SelectPSKIdentityOnResume: 1, 14383 }, 14384 }, 14385 resumeSession: true, 14386 shouldFail: true, 14387 expectedError: ":PSK_IDENTITY_NOT_FOUND:", 14388 }) 14389 14390 testCases = append(testCases, testCase{ 14391 testType: serverTest, 14392 name: "ExtraPSKIdentity-TLS13", 14393 config: Config{ 14394 MaxVersion: VersionTLS13, 14395 Bugs: ProtocolBugs{ 14396 ExtraPSKIdentity: true, 14397 SendExtraPSKBinder: true, 14398 }, 14399 }, 14400 resumeSession: true, 14401 }) 14402 14403 // Test that unknown NewSessionTicket extensions are tolerated. 14404 testCases = append(testCases, testCase{ 14405 name: "CustomTicketExtension-TLS13", 14406 config: Config{ 14407 MaxVersion: VersionTLS13, 14408 Bugs: ProtocolBugs{ 14409 CustomTicketExtension: "1234", 14410 }, 14411 }, 14412 }) 14413 14414 // Test the client handles 0-RTT being rejected by a full handshake 14415 // and correctly reports a certificate change. 14416 testCases = append(testCases, testCase{ 14417 testType: clientTest, 14418 name: "EarlyData-RejectTicket-Client-TLS13", 14419 config: Config{ 14420 MaxVersion: VersionTLS13, 14421 Certificates: []Certificate{rsaCertificate}, 14422 }, 14423 resumeConfig: &Config{ 14424 MaxVersion: VersionTLS13, 14425 Certificates: []Certificate{ecdsaP256Certificate}, 14426 SessionTicketsDisabled: true, 14427 }, 14428 resumeSession: true, 14429 expectResumeRejected: true, 14430 earlyData: true, 14431 expectEarlyDataRejected: true, 14432 flags: []string{ 14433 "-on-retry-expect-early-data-reason", "session_not_resumed", 14434 // Test the peer certificate is reported correctly in each of the 14435 // three logical connections. 14436 "-on-initial-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14437 "-on-resume-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14438 "-on-retry-expect-peer-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 14439 // Session tickets are disabled, so the runner will not send a ticket. 14440 "-on-retry-expect-no-session", 14441 }, 14442 }) 14443 14444 // Test the server rejects 0-RTT if it does not recognize the ticket. 14445 testCases = append(testCases, testCase{ 14446 testType: serverTest, 14447 name: "EarlyData-RejectTicket-Server-TLS13", 14448 config: Config{ 14449 MaxVersion: VersionTLS13, 14450 MinVersion: VersionTLS13, 14451 Bugs: ProtocolBugs{ 14452 // Corrupt the ticket. 14453 FilterTicket: func(in []byte) ([]byte, error) { 14454 in[len(in)-1] ^= 1 14455 return in, nil 14456 }, 14457 }, 14458 }, 14459 messageCount: 2, 14460 resumeSession: true, 14461 expectResumeRejected: true, 14462 earlyData: true, 14463 expectEarlyDataRejected: true, 14464 flags: []string{ 14465 "-on-resume-expect-early-data-reason", "session_not_resumed", 14466 }, 14467 }) 14468 14469 // Test the client handles 0-RTT being rejected via a HelloRetryRequest. 14470 testCases = append(testCases, testCase{ 14471 testType: clientTest, 14472 name: "EarlyData-HRR-Client-TLS13", 14473 config: Config{ 14474 MaxVersion: VersionTLS13, 14475 }, 14476 resumeConfig: &Config{ 14477 MaxVersion: VersionTLS13, 14478 Bugs: ProtocolBugs{ 14479 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14480 }, 14481 }, 14482 resumeSession: true, 14483 earlyData: true, 14484 expectEarlyDataRejected: true, 14485 flags: []string{ 14486 "-on-retry-expect-early-data-reason", "hello_retry_request", 14487 }, 14488 }) 14489 14490 // Test the server rejects 0-RTT if it needs to send a HelloRetryRequest. 14491 testCases = append(testCases, testCase{ 14492 testType: serverTest, 14493 name: "EarlyData-HRR-Server-TLS13", 14494 config: Config{ 14495 MaxVersion: VersionTLS13, 14496 MinVersion: VersionTLS13, 14497 // Require a HelloRetryRequest for every curve. 14498 DefaultCurves: []CurveID{}, 14499 }, 14500 messageCount: 2, 14501 resumeSession: true, 14502 earlyData: true, 14503 expectEarlyDataRejected: true, 14504 flags: []string{ 14505 "-on-resume-expect-early-data-reason", "hello_retry_request", 14506 }, 14507 }) 14508 14509 // Test the client handles a 0-RTT reject from both ticket rejection and 14510 // HelloRetryRequest. 14511 testCases = append(testCases, testCase{ 14512 testType: clientTest, 14513 name: "EarlyData-HRR-RejectTicket-Client-TLS13", 14514 config: Config{ 14515 MaxVersion: VersionTLS13, 14516 Certificates: []Certificate{rsaCertificate}, 14517 }, 14518 resumeConfig: &Config{ 14519 MaxVersion: VersionTLS13, 14520 Certificates: []Certificate{ecdsaP256Certificate}, 14521 SessionTicketsDisabled: true, 14522 Bugs: ProtocolBugs{ 14523 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14524 }, 14525 }, 14526 resumeSession: true, 14527 expectResumeRejected: true, 14528 earlyData: true, 14529 expectEarlyDataRejected: true, 14530 flags: []string{ 14531 // The client sees HelloRetryRequest before the resumption result, 14532 // though neither value is inherently preferable. 14533 "-on-retry-expect-early-data-reason", "hello_retry_request", 14534 // Test the peer certificate is reported correctly in each of the 14535 // three logical connections. 14536 "-on-initial-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14537 "-on-resume-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14538 "-on-retry-expect-peer-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 14539 // Session tickets are disabled, so the runner will not send a ticket. 14540 "-on-retry-expect-no-session", 14541 }, 14542 }) 14543 14544 // Test the server rejects 0-RTT if it needs to send a HelloRetryRequest. 14545 testCases = append(testCases, testCase{ 14546 testType: serverTest, 14547 name: "EarlyData-HRR-RejectTicket-Server-TLS13", 14548 config: Config{ 14549 MaxVersion: VersionTLS13, 14550 MinVersion: VersionTLS13, 14551 // Require a HelloRetryRequest for every curve. 14552 DefaultCurves: []CurveID{}, 14553 Bugs: ProtocolBugs{ 14554 // Corrupt the ticket. 14555 FilterTicket: func(in []byte) ([]byte, error) { 14556 in[len(in)-1] ^= 1 14557 return in, nil 14558 }, 14559 }, 14560 }, 14561 messageCount: 2, 14562 resumeSession: true, 14563 expectResumeRejected: true, 14564 earlyData: true, 14565 expectEarlyDataRejected: true, 14566 flags: []string{ 14567 // The server sees the missed resumption before HelloRetryRequest, 14568 // though neither value is inherently preferable. 14569 "-on-resume-expect-early-data-reason", "session_not_resumed", 14570 }, 14571 }) 14572 14573 // The client must check the server does not send the early_data 14574 // extension while rejecting the session. 14575 testCases = append(testCases, testCase{ 14576 testType: clientTest, 14577 name: "EarlyDataWithoutResume-Client-TLS13", 14578 config: Config{ 14579 MaxVersion: VersionTLS13, 14580 MaxEarlyDataSize: 16384, 14581 }, 14582 resumeConfig: &Config{ 14583 MaxVersion: VersionTLS13, 14584 SessionTicketsDisabled: true, 14585 Bugs: ProtocolBugs{ 14586 SendEarlyDataExtension: true, 14587 }, 14588 }, 14589 resumeSession: true, 14590 earlyData: true, 14591 shouldFail: true, 14592 expectedError: ":UNEXPECTED_EXTENSION:", 14593 }) 14594 14595 // The client must fail with a dedicated error code if the server 14596 // responds with TLS 1.2 when offering 0-RTT. 14597 testCases = append(testCases, testCase{ 14598 testType: clientTest, 14599 name: "EarlyDataVersionDowngrade-Client-TLS13", 14600 config: Config{ 14601 MaxVersion: VersionTLS13, 14602 }, 14603 resumeConfig: &Config{ 14604 MaxVersion: VersionTLS12, 14605 }, 14606 resumeSession: true, 14607 earlyData: true, 14608 shouldFail: true, 14609 expectedError: ":WRONG_VERSION_ON_EARLY_DATA:", 14610 }) 14611 14612 // Test that the client rejects an (unsolicited) early_data extension if 14613 // the server sent an HRR. 14614 testCases = append(testCases, testCase{ 14615 testType: clientTest, 14616 name: "ServerAcceptsEarlyDataOnHRR-Client-TLS13", 14617 config: Config{ 14618 MaxVersion: VersionTLS13, 14619 }, 14620 resumeConfig: &Config{ 14621 MaxVersion: VersionTLS13, 14622 Bugs: ProtocolBugs{ 14623 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14624 SendEarlyDataExtension: true, 14625 }, 14626 }, 14627 resumeSession: true, 14628 earlyData: true, 14629 // The client will first process an early data reject from the HRR. 14630 expectEarlyDataRejected: true, 14631 shouldFail: true, 14632 expectedError: ":UNEXPECTED_EXTENSION:", 14633 }) 14634 14635 testCases = append(testCases, testCase{ 14636 testType: clientTest, 14637 name: "SkipChangeCipherSpec-Client-TLS13", 14638 config: Config{ 14639 MaxVersion: VersionTLS13, 14640 Bugs: ProtocolBugs{ 14641 SkipChangeCipherSpec: true, 14642 }, 14643 }, 14644 }) 14645 14646 testCases = append(testCases, testCase{ 14647 testType: serverTest, 14648 name: "SkipChangeCipherSpec-Server-TLS13", 14649 config: Config{ 14650 MaxVersion: VersionTLS13, 14651 Bugs: ProtocolBugs{ 14652 SkipChangeCipherSpec: true, 14653 }, 14654 }, 14655 }) 14656 14657 testCases = append(testCases, testCase{ 14658 testType: clientTest, 14659 name: "TooManyChangeCipherSpec-Client-TLS13", 14660 config: Config{ 14661 MaxVersion: VersionTLS13, 14662 Bugs: ProtocolBugs{ 14663 SendExtraChangeCipherSpec: 33, 14664 }, 14665 }, 14666 shouldFail: true, 14667 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 14668 }) 14669 14670 testCases = append(testCases, testCase{ 14671 testType: serverTest, 14672 name: "TooManyChangeCipherSpec-Server-TLS13", 14673 config: Config{ 14674 MaxVersion: VersionTLS13, 14675 Bugs: ProtocolBugs{ 14676 SendExtraChangeCipherSpec: 33, 14677 }, 14678 }, 14679 shouldFail: true, 14680 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 14681 }) 14682 14683 testCases = append(testCases, testCase{ 14684 name: "SendPostHandshakeChangeCipherSpec-TLS13", 14685 config: Config{ 14686 MaxVersion: VersionTLS13, 14687 Bugs: ProtocolBugs{ 14688 SendPostHandshakeChangeCipherSpec: true, 14689 }, 14690 }, 14691 shouldFail: true, 14692 expectedError: ":UNEXPECTED_RECORD:", 14693 expectedLocalError: "remote error: unexpected message", 14694 }) 14695 14696 fooString := "foo" 14697 barString := "bar" 14698 14699 // Test that the client reports the correct ALPN after a 0-RTT reject 14700 // that changed it. 14701 testCases = append(testCases, testCase{ 14702 testType: clientTest, 14703 name: "EarlyData-ALPNMismatch-Client-TLS13", 14704 config: Config{ 14705 MaxVersion: VersionTLS13, 14706 Bugs: ProtocolBugs{ 14707 ALPNProtocol: &fooString, 14708 }, 14709 }, 14710 resumeConfig: &Config{ 14711 MaxVersion: VersionTLS13, 14712 Bugs: ProtocolBugs{ 14713 ALPNProtocol: &barString, 14714 }, 14715 }, 14716 resumeSession: true, 14717 earlyData: true, 14718 expectEarlyDataRejected: true, 14719 flags: []string{ 14720 "-advertise-alpn", "\x03foo\x03bar", 14721 // The client does not learn ALPN was the cause. 14722 "-on-retry-expect-early-data-reason", "peer_declined", 14723 // In the 0-RTT state, we surface the predicted ALPN. After 14724 // processing the reject, we surface the real one. 14725 "-on-initial-expect-alpn", "foo", 14726 "-on-resume-expect-alpn", "foo", 14727 "-on-retry-expect-alpn", "bar", 14728 }, 14729 }) 14730 14731 // Test that the client reports the correct ALPN after a 0-RTT reject if 14732 // ALPN was omitted from the first connection. 14733 testCases = append(testCases, testCase{ 14734 testType: clientTest, 14735 name: "EarlyData-ALPNOmitted1-Client-TLS13", 14736 config: Config{ 14737 MaxVersion: VersionTLS13, 14738 }, 14739 resumeConfig: &Config{ 14740 MaxVersion: VersionTLS13, 14741 NextProtos: []string{"foo"}, 14742 }, 14743 resumeSession: true, 14744 earlyData: true, 14745 expectEarlyDataRejected: true, 14746 flags: []string{ 14747 "-advertise-alpn", "\x03foo\x03bar", 14748 // The client does not learn ALPN was the cause. 14749 "-on-retry-expect-early-data-reason", "peer_declined", 14750 // In the 0-RTT state, we surface the predicted ALPN. After 14751 // processing the reject, we surface the real one. 14752 "-on-initial-expect-alpn", "", 14753 "-on-resume-expect-alpn", "", 14754 "-on-retry-expect-alpn", "foo", 14755 }, 14756 }) 14757 14758 // Test that the client reports the correct ALPN after a 0-RTT reject if 14759 // ALPN was omitted from the second connection. 14760 testCases = append(testCases, testCase{ 14761 testType: clientTest, 14762 name: "EarlyData-ALPNOmitted2-Client-TLS13", 14763 config: Config{ 14764 MaxVersion: VersionTLS13, 14765 NextProtos: []string{"foo"}, 14766 }, 14767 resumeConfig: &Config{ 14768 MaxVersion: VersionTLS13, 14769 }, 14770 resumeSession: true, 14771 earlyData: true, 14772 expectEarlyDataRejected: true, 14773 flags: []string{ 14774 "-advertise-alpn", "\x03foo\x03bar", 14775 // The client does not learn ALPN was the cause. 14776 "-on-retry-expect-early-data-reason", "peer_declined", 14777 // In the 0-RTT state, we surface the predicted ALPN. After 14778 // processing the reject, we surface the real one. 14779 "-on-initial-expect-alpn", "foo", 14780 "-on-resume-expect-alpn", "foo", 14781 "-on-retry-expect-alpn", "", 14782 }, 14783 }) 14784 14785 // Test that the client enforces ALPN match on 0-RTT accept. 14786 testCases = append(testCases, testCase{ 14787 testType: clientTest, 14788 name: "EarlyData-BadALPNMismatch-Client-TLS13", 14789 config: Config{ 14790 MaxVersion: VersionTLS13, 14791 Bugs: ProtocolBugs{ 14792 ALPNProtocol: &fooString, 14793 }, 14794 }, 14795 resumeConfig: &Config{ 14796 MaxVersion: VersionTLS13, 14797 Bugs: ProtocolBugs{ 14798 AlwaysAcceptEarlyData: true, 14799 ALPNProtocol: &barString, 14800 }, 14801 }, 14802 resumeSession: true, 14803 earlyData: true, 14804 flags: []string{ 14805 "-advertise-alpn", "\x03foo\x03bar", 14806 "-on-initial-expect-alpn", "foo", 14807 "-on-resume-expect-alpn", "foo", 14808 "-on-retry-expect-alpn", "bar", 14809 }, 14810 shouldFail: true, 14811 expectedError: ":ALPN_MISMATCH_ON_EARLY_DATA:", 14812 expectedLocalError: "remote error: illegal parameter", 14813 }) 14814 14815 // Test that the client does not offer early data if it is incompatible 14816 // with ALPN preferences. 14817 testCases = append(testCases, testCase{ 14818 testType: clientTest, 14819 name: "EarlyData-ALPNPreferenceChanged-TLS13", 14820 config: Config{ 14821 MaxVersion: VersionTLS13, 14822 MaxEarlyDataSize: 16384, 14823 NextProtos: []string{"foo", "bar"}, 14824 }, 14825 resumeSession: true, 14826 flags: []string{ 14827 "-enable-early-data", 14828 "-expect-ticket-supports-early-data", 14829 "-expect-no-offer-early-data", 14830 // Offer different ALPN values in the initial and resumption. 14831 "-on-initial-advertise-alpn", "\x03foo", 14832 "-on-initial-expect-alpn", "foo", 14833 "-on-resume-advertise-alpn", "\x03bar", 14834 "-on-resume-expect-alpn", "bar", 14835 // The ALPN mismatch comes from the client, so it reports it as the 14836 // reason. 14837 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14838 }, 14839 }) 14840 14841 // Test that the client does not offer 0-RTT to servers which never 14842 // advertise it. 14843 testCases = append(testCases, testCase{ 14844 testType: clientTest, 14845 name: "EarlyData-NonZeroRTTSession-Client-TLS13", 14846 config: Config{ 14847 MaxVersion: VersionTLS13, 14848 }, 14849 resumeSession: true, 14850 flags: []string{ 14851 "-enable-early-data", 14852 "-on-resume-expect-no-offer-early-data", 14853 // The client declines to offer 0-RTT because of the session. 14854 "-on-resume-expect-early-data-reason", "unsupported_for_session", 14855 }, 14856 }) 14857 14858 // Test that the server correctly rejects 0-RTT when the previous 14859 // session did not allow early data on resumption. 14860 testCases = append(testCases, testCase{ 14861 testType: serverTest, 14862 name: "EarlyData-NonZeroRTTSession-Server-TLS13", 14863 config: Config{ 14864 MaxVersion: VersionTLS13, 14865 }, 14866 resumeConfig: &Config{ 14867 MaxVersion: VersionTLS13, 14868 Bugs: ProtocolBugs{ 14869 SendEarlyData: [][]byte{{1, 2, 3, 4}}, 14870 ExpectEarlyDataAccepted: false, 14871 }, 14872 }, 14873 resumeSession: true, 14874 // This test configures early data manually instead of the earlyData 14875 // option, to customize the -enable-early-data flag. 14876 flags: []string{ 14877 "-on-resume-enable-early-data", 14878 "-expect-reject-early-data", 14879 // The server rejects 0-RTT because of the session. 14880 "-on-resume-expect-early-data-reason", "unsupported_for_session", 14881 }, 14882 }) 14883 14884 // Test that we reject early data where ALPN is omitted from the first 14885 // connection, but negotiated in the second. 14886 testCases = append(testCases, testCase{ 14887 testType: serverTest, 14888 name: "EarlyData-ALPNOmitted1-Server-TLS13", 14889 config: Config{ 14890 MaxVersion: VersionTLS13, 14891 NextProtos: []string{}, 14892 }, 14893 resumeConfig: &Config{ 14894 MaxVersion: VersionTLS13, 14895 NextProtos: []string{"foo"}, 14896 }, 14897 resumeSession: true, 14898 earlyData: true, 14899 expectEarlyDataRejected: true, 14900 flags: []string{ 14901 "-on-initial-select-alpn", "", 14902 "-on-resume-select-alpn", "foo", 14903 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14904 }, 14905 }) 14906 14907 // Test that we reject early data where ALPN is omitted from the second 14908 // connection, but negotiated in the first. 14909 testCases = append(testCases, testCase{ 14910 testType: serverTest, 14911 name: "EarlyData-ALPNOmitted2-Server-TLS13", 14912 config: Config{ 14913 MaxVersion: VersionTLS13, 14914 NextProtos: []string{"foo"}, 14915 }, 14916 resumeConfig: &Config{ 14917 MaxVersion: VersionTLS13, 14918 NextProtos: []string{}, 14919 }, 14920 resumeSession: true, 14921 earlyData: true, 14922 expectEarlyDataRejected: true, 14923 flags: []string{ 14924 "-on-initial-select-alpn", "foo", 14925 "-on-resume-select-alpn", "", 14926 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14927 }, 14928 }) 14929 14930 // Test that we reject early data with mismatched ALPN. 14931 testCases = append(testCases, testCase{ 14932 testType: serverTest, 14933 name: "EarlyData-ALPNMismatch-Server-TLS13", 14934 config: Config{ 14935 MaxVersion: VersionTLS13, 14936 NextProtos: []string{"foo"}, 14937 }, 14938 resumeConfig: &Config{ 14939 MaxVersion: VersionTLS13, 14940 NextProtos: []string{"bar"}, 14941 }, 14942 resumeSession: true, 14943 earlyData: true, 14944 expectEarlyDataRejected: true, 14945 flags: []string{ 14946 "-on-initial-select-alpn", "foo", 14947 "-on-resume-select-alpn", "bar", 14948 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14949 }, 14950 }) 14951 14952 // Test that the client offering 0-RTT and Channel ID forbids the server 14953 // from accepting both. 14954 testCases = append(testCases, testCase{ 14955 testType: clientTest, 14956 name: "EarlyDataChannelID-AcceptBoth-Client-TLS13", 14957 config: Config{ 14958 MaxVersion: VersionTLS13, 14959 RequestChannelID: true, 14960 }, 14961 resumeSession: true, 14962 earlyData: true, 14963 expectations: connectionExpectations{ 14964 channelID: true, 14965 }, 14966 shouldFail: true, 14967 expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:", 14968 expectedLocalError: "remote error: illegal parameter", 14969 flags: []string{ 14970 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 14971 }, 14972 }) 14973 14974 // Test that the client offering Channel ID and 0-RTT allows the server 14975 // to decline 0-RTT. 14976 testCases = append(testCases, testCase{ 14977 testType: clientTest, 14978 name: "EarlyDataChannelID-AcceptChannelID-Client-TLS13", 14979 config: Config{ 14980 MaxVersion: VersionTLS13, 14981 RequestChannelID: true, 14982 Bugs: ProtocolBugs{ 14983 AlwaysRejectEarlyData: true, 14984 }, 14985 }, 14986 resumeSession: true, 14987 earlyData: true, 14988 expectEarlyDataRejected: true, 14989 expectations: connectionExpectations{ 14990 channelID: true, 14991 }, 14992 flags: []string{ 14993 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 14994 // The client never learns the reason was Channel ID. 14995 "-on-retry-expect-early-data-reason", "peer_declined", 14996 }, 14997 }) 14998 14999 // Test that the client offering Channel ID and 0-RTT allows the server 15000 // to decline Channel ID. 15001 testCases = append(testCases, testCase{ 15002 testType: clientTest, 15003 name: "EarlyDataChannelID-AcceptEarlyData-Client-TLS13", 15004 config: Config{ 15005 MaxVersion: VersionTLS13, 15006 }, 15007 resumeSession: true, 15008 earlyData: true, 15009 flags: []string{ 15010 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 15011 }, 15012 }) 15013 15014 // Test that the server supporting Channel ID and 0-RTT declines 0-RTT 15015 // if it would negotiate Channel ID. 15016 testCases = append(testCases, testCase{ 15017 testType: serverTest, 15018 name: "EarlyDataChannelID-OfferBoth-Server-TLS13", 15019 config: Config{ 15020 MaxVersion: VersionTLS13, 15021 ChannelID: channelIDKey, 15022 }, 15023 resumeSession: true, 15024 earlyData: true, 15025 expectEarlyDataRejected: true, 15026 expectations: connectionExpectations{ 15027 channelID: true, 15028 }, 15029 flags: []string{ 15030 "-expect-channel-id", 15031 base64FlagValue(channelIDBytes), 15032 "-on-resume-expect-early-data-reason", "channel_id", 15033 }, 15034 }) 15035 15036 // Test that the server supporting Channel ID and 0-RTT accepts 0-RTT 15037 // if not offered Channel ID. 15038 testCases = append(testCases, testCase{ 15039 testType: serverTest, 15040 name: "EarlyDataChannelID-OfferEarlyData-Server-TLS13", 15041 config: Config{ 15042 MaxVersion: VersionTLS13, 15043 }, 15044 resumeSession: true, 15045 earlyData: true, 15046 expectations: connectionExpectations{ 15047 channelID: false, 15048 }, 15049 flags: []string{ 15050 "-enable-channel-id", 15051 "-on-resume-expect-early-data-reason", "accept", 15052 }, 15053 }) 15054 15055 // Test that the server errors on 0-RTT streams without end_of_early_data. 15056 // The subsequent records should fail to decrypt. 15057 testCases = append(testCases, testCase{ 15058 testType: serverTest, 15059 name: "EarlyData-SkipEndOfEarlyData-TLS13", 15060 config: Config{ 15061 MaxVersion: VersionTLS13, 15062 Bugs: ProtocolBugs{ 15063 SkipEndOfEarlyData: true, 15064 }, 15065 }, 15066 resumeSession: true, 15067 earlyData: true, 15068 shouldFail: true, 15069 expectedLocalError: "remote error: bad record MAC", 15070 expectedError: ":BAD_DECRYPT:", 15071 }) 15072 15073 // Test that the server errors on 0-RTT streams with a stray handshake 15074 // message in them. 15075 testCases = append(testCases, testCase{ 15076 testType: serverTest, 15077 name: "EarlyData-UnexpectedHandshake-Server-TLS13", 15078 config: Config{ 15079 MaxVersion: VersionTLS13, 15080 }, 15081 resumeConfig: &Config{ 15082 MaxVersion: VersionTLS13, 15083 Bugs: ProtocolBugs{ 15084 SendStrayEarlyHandshake: true, 15085 }, 15086 }, 15087 resumeSession: true, 15088 earlyData: true, 15089 shouldFail: true, 15090 expectedError: ":UNEXPECTED_MESSAGE:", 15091 expectedLocalError: "remote error: unexpected message", 15092 }) 15093 15094 // Test that the client reports TLS 1.3 as the version while sending 15095 // early data. 15096 testCases = append(testCases, testCase{ 15097 testType: clientTest, 15098 name: "EarlyData-Client-VersionAPI-TLS13", 15099 config: Config{ 15100 MaxVersion: VersionTLS13, 15101 }, 15102 resumeSession: true, 15103 earlyData: true, 15104 flags: []string{ 15105 "-expect-version", strconv.Itoa(VersionTLS13), 15106 }, 15107 }) 15108 15109 // Test that client and server both notice handshake errors after data 15110 // has started flowing. 15111 testCases = append(testCases, testCase{ 15112 testType: clientTest, 15113 name: "EarlyData-Client-BadFinished-TLS13", 15114 config: Config{ 15115 MaxVersion: VersionTLS13, 15116 }, 15117 resumeConfig: &Config{ 15118 MaxVersion: VersionTLS13, 15119 Bugs: ProtocolBugs{ 15120 BadFinished: true, 15121 }, 15122 }, 15123 resumeSession: true, 15124 earlyData: true, 15125 shouldFail: true, 15126 expectedError: ":DIGEST_CHECK_FAILED:", 15127 expectedLocalError: "remote error: error decrypting message", 15128 }) 15129 testCases = append(testCases, testCase{ 15130 testType: serverTest, 15131 name: "EarlyData-Server-BadFinished-TLS13", 15132 config: Config{ 15133 MaxVersion: VersionTLS13, 15134 }, 15135 resumeConfig: &Config{ 15136 MaxVersion: VersionTLS13, 15137 Bugs: ProtocolBugs{ 15138 BadFinished: true, 15139 }, 15140 }, 15141 resumeSession: true, 15142 earlyData: true, 15143 shouldFail: true, 15144 expectedError: ":DIGEST_CHECK_FAILED:", 15145 expectedLocalError: "remote error: error decrypting message", 15146 }) 15147 15148 testCases = append(testCases, testCase{ 15149 testType: serverTest, 15150 name: "Server-NonEmptyEndOfEarlyData-TLS13", 15151 config: Config{ 15152 MaxVersion: VersionTLS13, 15153 }, 15154 resumeConfig: &Config{ 15155 MaxVersion: VersionTLS13, 15156 Bugs: ProtocolBugs{ 15157 NonEmptyEndOfEarlyData: true, 15158 }, 15159 }, 15160 resumeSession: true, 15161 earlyData: true, 15162 shouldFail: true, 15163 expectedError: ":DECODE_ERROR:", 15164 }) 15165 15166 testCases = append(testCases, testCase{ 15167 testType: serverTest, 15168 name: "ServerSkipCertificateVerify-TLS13", 15169 config: Config{ 15170 MinVersion: VersionTLS13, 15171 MaxVersion: VersionTLS13, 15172 Certificates: []Certificate{rsaChainCertificate}, 15173 Bugs: ProtocolBugs{ 15174 SkipCertificateVerify: true, 15175 }, 15176 }, 15177 expectations: connectionExpectations{ 15178 peerCertificate: &rsaChainCertificate, 15179 }, 15180 flags: []string{ 15181 "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 15182 "-key-file", path.Join(*resourceDir, rsaChainKeyFile), 15183 "-require-any-client-certificate", 15184 }, 15185 shouldFail: true, 15186 expectedError: ":UNEXPECTED_MESSAGE:", 15187 expectedLocalError: "remote error: unexpected message", 15188 }) 15189 testCases = append(testCases, testCase{ 15190 testType: clientTest, 15191 name: "ClientSkipCertificateVerify-TLS13", 15192 config: Config{ 15193 MinVersion: VersionTLS13, 15194 MaxVersion: VersionTLS13, 15195 Certificates: []Certificate{rsaChainCertificate}, 15196 Bugs: ProtocolBugs{ 15197 SkipCertificateVerify: true, 15198 }, 15199 }, 15200 expectations: connectionExpectations{ 15201 peerCertificate: &rsaChainCertificate, 15202 }, 15203 flags: []string{ 15204 "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 15205 "-key-file", path.Join(*resourceDir, rsaChainKeyFile), 15206 }, 15207 shouldFail: true, 15208 expectedError: ":UNEXPECTED_MESSAGE:", 15209 expectedLocalError: "remote error: unexpected message", 15210 }) 15211 15212 // If the client or server has 0-RTT enabled but disabled TLS 1.3, it should 15213 // report a reason of protocol_version. 15214 testCases = append(testCases, testCase{ 15215 testType: clientTest, 15216 name: "EarlyDataEnabled-Client-MaxTLS12", 15217 expectations: connectionExpectations{ 15218 version: VersionTLS12, 15219 }, 15220 flags: []string{ 15221 "-enable-early-data", 15222 "-max-version", strconv.Itoa(VersionTLS12), 15223 "-expect-early-data-reason", "protocol_version", 15224 }, 15225 }) 15226 testCases = append(testCases, testCase{ 15227 testType: serverTest, 15228 name: "EarlyDataEnabled-Server-MaxTLS12", 15229 expectations: connectionExpectations{ 15230 version: VersionTLS12, 15231 }, 15232 flags: []string{ 15233 "-enable-early-data", 15234 "-max-version", strconv.Itoa(VersionTLS12), 15235 "-expect-early-data-reason", "protocol_version", 15236 }, 15237 }) 15238 15239 // The server additionally reports protocol_version if it enabled TLS 1.3, 15240 // but the peer negotiated TLS 1.2. (The corresponding situation does not 15241 // exist on the client because negotiating TLS 1.2 with a 0-RTT ClientHello 15242 // is a fatal error.) 15243 testCases = append(testCases, testCase{ 15244 testType: serverTest, 15245 name: "EarlyDataEnabled-Server-NegotiateTLS12", 15246 config: Config{ 15247 MaxVersion: VersionTLS12, 15248 }, 15249 expectations: connectionExpectations{ 15250 version: VersionTLS12, 15251 }, 15252 flags: []string{ 15253 "-enable-early-data", 15254 "-expect-early-data-reason", "protocol_version", 15255 }, 15256 }) 15257 15258 // On 0-RTT reject, the server may end up negotiating a cipher suite with a 15259 // different PRF hash. Test that the client handles this correctly. 15260 testCases = append(testCases, testCase{ 15261 testType: clientTest, 15262 name: "EarlyData-Reject0RTT-DifferentPRF-Client", 15263 config: Config{ 15264 MaxVersion: VersionTLS13, 15265 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 15266 }, 15267 resumeConfig: &Config{ 15268 MaxVersion: VersionTLS13, 15269 CipherSuites: []uint16{TLS_AES_256_GCM_SHA384}, 15270 }, 15271 resumeSession: true, 15272 expectResumeRejected: true, 15273 earlyData: true, 15274 expectEarlyDataRejected: true, 15275 flags: []string{ 15276 "-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15277 // The client initially reports the old cipher suite while sending 15278 // early data. After processing the 0-RTT reject, it reports the 15279 // true cipher suite. 15280 "-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15281 "-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)), 15282 }, 15283 }) 15284 testCases = append(testCases, testCase{ 15285 testType: clientTest, 15286 name: "EarlyData-Reject0RTT-DifferentPRF-HRR-Client", 15287 config: Config{ 15288 MaxVersion: VersionTLS13, 15289 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 15290 }, 15291 resumeConfig: &Config{ 15292 MaxVersion: VersionTLS13, 15293 CipherSuites: []uint16{TLS_AES_256_GCM_SHA384}, 15294 // P-384 requires a HelloRetryRequest against BoringSSL's default 15295 // configuration. Assert this with ExpectMissingKeyShare. 15296 CurvePreferences: []CurveID{CurveP384}, 15297 Bugs: ProtocolBugs{ 15298 ExpectMissingKeyShare: true, 15299 }, 15300 }, 15301 resumeSession: true, 15302 expectResumeRejected: true, 15303 earlyData: true, 15304 expectEarlyDataRejected: true, 15305 flags: []string{ 15306 "-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15307 // The client initially reports the old cipher suite while sending 15308 // early data. After processing the 0-RTT reject, it reports the 15309 // true cipher suite. 15310 "-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15311 "-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)), 15312 }, 15313 }) 15314 15315 // Test that the client enforces cipher suite match on 0-RTT accept. 15316 testCases = append(testCases, testCase{ 15317 testType: clientTest, 15318 name: "EarlyData-CipherMismatch-Client-TLS13", 15319 config: Config{ 15320 MaxVersion: VersionTLS13, 15321 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 15322 }, 15323 resumeConfig: &Config{ 15324 MaxVersion: VersionTLS13, 15325 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 15326 Bugs: ProtocolBugs{ 15327 AlwaysAcceptEarlyData: true, 15328 }, 15329 }, 15330 resumeSession: true, 15331 earlyData: true, 15332 shouldFail: true, 15333 expectedError: ":CIPHER_MISMATCH_ON_EARLY_DATA:", 15334 expectedLocalError: "remote error: illegal parameter", 15335 }) 15336 15337 // Test that the client can write early data when it has received a partial 15338 // ServerHello..Finished flight. See https://crbug.com/1208784. Note the 15339 // EncryptedExtensions test assumes EncryptedExtensions and Finished are in 15340 // separate records, i.e. that PackHandshakeFlight is disabled. 15341 testCases = append(testCases, testCase{ 15342 testType: clientTest, 15343 name: "EarlyData-WriteAfterServerHello", 15344 config: Config{ 15345 MinVersion: VersionTLS13, 15346 MaxVersion: VersionTLS13, 15347 Bugs: ProtocolBugs{ 15348 // Write the server response before expecting early data. 15349 ExpectEarlyData: [][]byte{}, 15350 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 15351 }, 15352 }, 15353 resumeSession: true, 15354 earlyData: true, 15355 flags: []string{ 15356 "-async", 15357 "-on-resume-early-write-after-message", 15358 strconv.Itoa(int(typeServerHello)), 15359 }, 15360 }) 15361 testCases = append(testCases, testCase{ 15362 testType: clientTest, 15363 name: "EarlyData-WriteAfterEncryptedExtensions", 15364 config: Config{ 15365 MinVersion: VersionTLS13, 15366 MaxVersion: VersionTLS13, 15367 Bugs: ProtocolBugs{ 15368 // Write the server response before expecting early data. 15369 ExpectEarlyData: [][]byte{}, 15370 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 15371 }, 15372 }, 15373 resumeSession: true, 15374 earlyData: true, 15375 flags: []string{ 15376 "-async", 15377 "-on-resume-early-write-after-message", 15378 strconv.Itoa(int(typeEncryptedExtensions)), 15379 }, 15380 }) 15381} 15382 15383func addTLS13CipherPreferenceTests() { 15384 // Test that client preference is honored if the shim has AES hardware 15385 // and ChaCha20-Poly1305 is preferred otherwise. 15386 testCases = append(testCases, testCase{ 15387 testType: serverTest, 15388 name: "TLS13-CipherPreference-Server-ChaCha20-AES", 15389 config: Config{ 15390 MaxVersion: VersionTLS13, 15391 CipherSuites: []uint16{ 15392 TLS_CHACHA20_POLY1305_SHA256, 15393 TLS_AES_128_GCM_SHA256, 15394 }, 15395 CurvePreferences: []CurveID{CurveX25519}, 15396 }, 15397 flags: []string{ 15398 "-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15399 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15400 }, 15401 }) 15402 15403 testCases = append(testCases, testCase{ 15404 testType: serverTest, 15405 name: "TLS13-CipherPreference-Server-AES-ChaCha20", 15406 config: Config{ 15407 MaxVersion: VersionTLS13, 15408 CipherSuites: []uint16{ 15409 TLS_AES_128_GCM_SHA256, 15410 TLS_CHACHA20_POLY1305_SHA256, 15411 }, 15412 CurvePreferences: []CurveID{CurveX25519}, 15413 }, 15414 flags: []string{ 15415 "-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15416 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15417 }, 15418 }) 15419 15420 // Test that the client orders ChaCha20-Poly1305 and AES-GCM based on 15421 // whether it has AES hardware. 15422 testCases = append(testCases, testCase{ 15423 name: "TLS13-CipherPreference-Client", 15424 config: Config{ 15425 MaxVersion: VersionTLS13, 15426 // Use the client cipher order. (This is the default but 15427 // is listed to be explicit.) 15428 PreferServerCipherSuites: false, 15429 }, 15430 flags: []string{ 15431 "-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15432 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15433 }, 15434 }) 15435} 15436 15437func addPeekTests() { 15438 // Test SSL_peek works, including on empty records. 15439 testCases = append(testCases, testCase{ 15440 name: "Peek-Basic", 15441 sendEmptyRecords: 1, 15442 flags: []string{"-peek-then-read"}, 15443 }) 15444 15445 // Test SSL_peek can drive the initial handshake. 15446 testCases = append(testCases, testCase{ 15447 name: "Peek-ImplicitHandshake", 15448 flags: []string{ 15449 "-peek-then-read", 15450 "-implicit-handshake", 15451 }, 15452 }) 15453 15454 // Test SSL_peek can discover and drive a renegotiation. 15455 testCases = append(testCases, testCase{ 15456 name: "Peek-Renegotiate", 15457 config: Config{ 15458 MaxVersion: VersionTLS12, 15459 }, 15460 renegotiate: 1, 15461 flags: []string{ 15462 "-peek-then-read", 15463 "-renegotiate-freely", 15464 "-expect-total-renegotiations", "1", 15465 }, 15466 }) 15467 15468 // Test SSL_peek can discover a close_notify. 15469 testCases = append(testCases, testCase{ 15470 name: "Peek-Shutdown", 15471 config: Config{ 15472 Bugs: ProtocolBugs{ 15473 ExpectCloseNotify: true, 15474 }, 15475 }, 15476 flags: []string{ 15477 "-peek-then-read", 15478 "-check-close-notify", 15479 }, 15480 }) 15481 15482 // Test SSL_peek can discover an alert. 15483 testCases = append(testCases, testCase{ 15484 name: "Peek-Alert", 15485 config: Config{ 15486 Bugs: ProtocolBugs{ 15487 SendSpuriousAlert: alertRecordOverflow, 15488 }, 15489 }, 15490 flags: []string{"-peek-then-read"}, 15491 shouldFail: true, 15492 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 15493 }) 15494 15495 // Test SSL_peek can handle KeyUpdate. 15496 testCases = append(testCases, testCase{ 15497 name: "Peek-KeyUpdate", 15498 config: Config{ 15499 MaxVersion: VersionTLS13, 15500 }, 15501 sendKeyUpdates: 1, 15502 keyUpdateRequest: keyUpdateNotRequested, 15503 flags: []string{"-peek-then-read"}, 15504 }) 15505} 15506 15507func addRecordVersionTests() { 15508 for _, ver := range tlsVersions { 15509 // Test that the record version is enforced. 15510 testCases = append(testCases, testCase{ 15511 name: "CheckRecordVersion-" + ver.name, 15512 config: Config{ 15513 MinVersion: ver.version, 15514 MaxVersion: ver.version, 15515 Bugs: ProtocolBugs{ 15516 SendRecordVersion: 0x03ff, 15517 }, 15518 }, 15519 shouldFail: true, 15520 expectedError: ":WRONG_VERSION_NUMBER:", 15521 }) 15522 15523 // Test that the ClientHello may use any record version, for 15524 // compatibility reasons. 15525 testCases = append(testCases, testCase{ 15526 testType: serverTest, 15527 name: "LooseInitialRecordVersion-" + ver.name, 15528 config: Config{ 15529 MinVersion: ver.version, 15530 MaxVersion: ver.version, 15531 Bugs: ProtocolBugs{ 15532 SendInitialRecordVersion: 0x03ff, 15533 }, 15534 }, 15535 }) 15536 15537 // Test that garbage ClientHello record versions are rejected. 15538 testCases = append(testCases, testCase{ 15539 testType: serverTest, 15540 name: "GarbageInitialRecordVersion-" + ver.name, 15541 config: Config{ 15542 MinVersion: ver.version, 15543 MaxVersion: ver.version, 15544 Bugs: ProtocolBugs{ 15545 SendInitialRecordVersion: 0xffff, 15546 }, 15547 }, 15548 shouldFail: true, 15549 expectedError: ":WRONG_VERSION_NUMBER:", 15550 }) 15551 } 15552} 15553 15554func addCertificateTests() { 15555 for _, ver := range tlsVersions { 15556 // Test that a certificate chain with intermediate may be sent 15557 // and received as both client and server. 15558 testCases = append(testCases, testCase{ 15559 testType: clientTest, 15560 name: "SendReceiveIntermediate-Client-" + ver.name, 15561 config: Config{ 15562 MinVersion: ver.version, 15563 MaxVersion: ver.version, 15564 Certificates: []Certificate{rsaChainCertificate}, 15565 ClientAuth: RequireAnyClientCert, 15566 }, 15567 expectations: connectionExpectations{ 15568 peerCertificate: &rsaChainCertificate, 15569 }, 15570 flags: []string{ 15571 "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 15572 "-key-file", path.Join(*resourceDir, rsaChainKeyFile), 15573 "-expect-peer-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 15574 }, 15575 }) 15576 15577 testCases = append(testCases, testCase{ 15578 testType: serverTest, 15579 name: "SendReceiveIntermediate-Server-" + ver.name, 15580 config: Config{ 15581 MinVersion: ver.version, 15582 MaxVersion: ver.version, 15583 Certificates: []Certificate{rsaChainCertificate}, 15584 }, 15585 expectations: connectionExpectations{ 15586 peerCertificate: &rsaChainCertificate, 15587 }, 15588 flags: []string{ 15589 "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 15590 "-key-file", path.Join(*resourceDir, rsaChainKeyFile), 15591 "-require-any-client-certificate", 15592 "-expect-peer-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 15593 }, 15594 }) 15595 15596 // Test that garbage leaf certificates are properly rejected. 15597 testCases = append(testCases, testCase{ 15598 testType: clientTest, 15599 name: "GarbageCertificate-Client-" + ver.name, 15600 config: Config{ 15601 MinVersion: ver.version, 15602 MaxVersion: ver.version, 15603 Certificates: []Certificate{garbageCertificate}, 15604 }, 15605 shouldFail: true, 15606 expectedError: ":CANNOT_PARSE_LEAF_CERT:", 15607 expectedLocalError: "remote error: error decoding message", 15608 }) 15609 15610 testCases = append(testCases, testCase{ 15611 testType: serverTest, 15612 name: "GarbageCertificate-Server-" + ver.name, 15613 config: Config{ 15614 MinVersion: ver.version, 15615 MaxVersion: ver.version, 15616 Certificates: []Certificate{garbageCertificate}, 15617 }, 15618 flags: []string{"-require-any-client-certificate"}, 15619 shouldFail: true, 15620 expectedError: ":CANNOT_PARSE_LEAF_CERT:", 15621 expectedLocalError: "remote error: error decoding message", 15622 }) 15623 } 15624} 15625 15626func addRetainOnlySHA256ClientCertTests() { 15627 for _, ver := range tlsVersions { 15628 // Test that enabling 15629 // SSL_CTX_set_retain_only_sha256_of_client_certs without 15630 // actually requesting a client certificate is a no-op. 15631 testCases = append(testCases, testCase{ 15632 testType: serverTest, 15633 name: "RetainOnlySHA256-NoCert-" + ver.name, 15634 config: Config{ 15635 MinVersion: ver.version, 15636 MaxVersion: ver.version, 15637 }, 15638 flags: []string{ 15639 "-on-initial-retain-only-sha256-client-cert", 15640 "-on-resume-retain-only-sha256-client-cert", 15641 }, 15642 resumeSession: true, 15643 }) 15644 15645 // Test that when retaining only a SHA-256 certificate is 15646 // enabled, the hash appears as expected. 15647 testCases = append(testCases, testCase{ 15648 testType: serverTest, 15649 name: "RetainOnlySHA256-Cert-" + ver.name, 15650 config: Config{ 15651 MinVersion: ver.version, 15652 MaxVersion: ver.version, 15653 Certificates: []Certificate{rsaCertificate}, 15654 }, 15655 flags: []string{ 15656 "-verify-peer", 15657 "-on-initial-retain-only-sha256-client-cert", 15658 "-on-resume-retain-only-sha256-client-cert", 15659 "-on-initial-expect-sha256-client-cert", 15660 "-on-resume-expect-sha256-client-cert", 15661 }, 15662 resumeSession: true, 15663 }) 15664 15665 // Test that when the config changes from on to off, a 15666 // resumption is rejected because the server now wants the full 15667 // certificate chain. 15668 testCases = append(testCases, testCase{ 15669 testType: serverTest, 15670 name: "RetainOnlySHA256-OnOff-" + ver.name, 15671 config: Config{ 15672 MinVersion: ver.version, 15673 MaxVersion: ver.version, 15674 Certificates: []Certificate{rsaCertificate}, 15675 }, 15676 flags: []string{ 15677 "-verify-peer", 15678 "-on-initial-retain-only-sha256-client-cert", 15679 "-on-initial-expect-sha256-client-cert", 15680 }, 15681 resumeSession: true, 15682 expectResumeRejected: true, 15683 }) 15684 15685 // Test that when the config changes from off to on, a 15686 // resumption is rejected because the server now wants just the 15687 // hash. 15688 testCases = append(testCases, testCase{ 15689 testType: serverTest, 15690 name: "RetainOnlySHA256-OffOn-" + ver.name, 15691 config: Config{ 15692 MinVersion: ver.version, 15693 MaxVersion: ver.version, 15694 Certificates: []Certificate{rsaCertificate}, 15695 }, 15696 flags: []string{ 15697 "-verify-peer", 15698 "-on-resume-retain-only-sha256-client-cert", 15699 "-on-resume-expect-sha256-client-cert", 15700 }, 15701 resumeSession: true, 15702 expectResumeRejected: true, 15703 }) 15704 } 15705} 15706 15707func addECDSAKeyUsageTests() { 15708 p256 := elliptic.P256() 15709 priv, err := ecdsa.GenerateKey(p256, rand.Reader) 15710 if err != nil { 15711 panic(err) 15712 } 15713 15714 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 15715 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 15716 if err != nil { 15717 panic(err) 15718 } 15719 15720 template := x509.Certificate{ 15721 SerialNumber: serialNumber, 15722 Subject: pkix.Name{ 15723 Organization: []string{"Acme Co"}, 15724 }, 15725 NotBefore: time.Now(), 15726 NotAfter: time.Now(), 15727 15728 // An ECC certificate with only the keyAgreement key usgae may 15729 // be used with ECDH, but not ECDSA. 15730 KeyUsage: x509.KeyUsageKeyAgreement, 15731 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 15732 BasicConstraintsValid: true, 15733 } 15734 15735 derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) 15736 if err != nil { 15737 panic(err) 15738 } 15739 15740 cert := Certificate{ 15741 Certificate: [][]byte{derBytes}, 15742 PrivateKey: priv, 15743 } 15744 15745 for _, ver := range tlsVersions { 15746 if ver.version < VersionTLS12 { 15747 continue 15748 } 15749 15750 testCases = append(testCases, testCase{ 15751 testType: clientTest, 15752 name: "ECDSAKeyUsage-Client-" + ver.name, 15753 config: Config{ 15754 MinVersion: ver.version, 15755 MaxVersion: ver.version, 15756 Certificates: []Certificate{cert}, 15757 }, 15758 shouldFail: true, 15759 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15760 }) 15761 15762 testCases = append(testCases, testCase{ 15763 testType: serverTest, 15764 name: "ECDSAKeyUsage-Server-" + ver.name, 15765 config: Config{ 15766 MinVersion: ver.version, 15767 MaxVersion: ver.version, 15768 Certificates: []Certificate{cert}, 15769 }, 15770 flags: []string{"-require-any-client-certificate"}, 15771 shouldFail: true, 15772 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15773 }) 15774 } 15775} 15776 15777func addRSAKeyUsageTests() { 15778 priv := rsaCertificate.PrivateKey.(*rsa.PrivateKey) 15779 15780 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 15781 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 15782 if err != nil { 15783 panic(err) 15784 } 15785 15786 dsTemplate := x509.Certificate{ 15787 SerialNumber: serialNumber, 15788 Subject: pkix.Name{ 15789 Organization: []string{"Acme Co"}, 15790 }, 15791 NotBefore: time.Now(), 15792 NotAfter: time.Now(), 15793 15794 KeyUsage: x509.KeyUsageDigitalSignature, 15795 BasicConstraintsValid: true, 15796 } 15797 15798 encTemplate := x509.Certificate{ 15799 SerialNumber: serialNumber, 15800 Subject: pkix.Name{ 15801 Organization: []string{"Acme Co"}, 15802 }, 15803 NotBefore: time.Now(), 15804 NotAfter: time.Now(), 15805 15806 KeyUsage: x509.KeyUsageKeyEncipherment, 15807 BasicConstraintsValid: true, 15808 } 15809 15810 dsDerBytes, err := x509.CreateCertificate(rand.Reader, &dsTemplate, &dsTemplate, &priv.PublicKey, priv) 15811 if err != nil { 15812 panic(err) 15813 } 15814 15815 encDerBytes, err := x509.CreateCertificate(rand.Reader, &encTemplate, &encTemplate, &priv.PublicKey, priv) 15816 if err != nil { 15817 panic(err) 15818 } 15819 15820 dsCert := Certificate{ 15821 Certificate: [][]byte{dsDerBytes}, 15822 PrivateKey: priv, 15823 } 15824 15825 encCert := Certificate{ 15826 Certificate: [][]byte{encDerBytes}, 15827 PrivateKey: priv, 15828 } 15829 15830 dsSuites := []uint16{ 15831 TLS_AES_128_GCM_SHA256, 15832 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 15833 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 15834 } 15835 encSuites := []uint16{ 15836 TLS_RSA_WITH_AES_128_GCM_SHA256, 15837 TLS_RSA_WITH_AES_128_CBC_SHA, 15838 } 15839 15840 for _, ver := range tlsVersions { 15841 testCases = append(testCases, testCase{ 15842 testType: clientTest, 15843 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-" + ver.name, 15844 config: Config{ 15845 MinVersion: ver.version, 15846 MaxVersion: ver.version, 15847 Certificates: []Certificate{encCert}, 15848 CipherSuites: dsSuites, 15849 }, 15850 shouldFail: true, 15851 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15852 }) 15853 15854 testCases = append(testCases, testCase{ 15855 testType: clientTest, 15856 name: "RSAKeyUsage-Client-WantSignature-GotSignature-" + ver.name, 15857 config: Config{ 15858 MinVersion: ver.version, 15859 MaxVersion: ver.version, 15860 Certificates: []Certificate{dsCert}, 15861 CipherSuites: dsSuites, 15862 }, 15863 }) 15864 15865 // TLS 1.3 removes the encipherment suites. 15866 if ver.version < VersionTLS13 { 15867 testCases = append(testCases, testCase{ 15868 testType: clientTest, 15869 name: "RSAKeyUsage-Client-WantEncipherment-GotEncipherment" + ver.name, 15870 config: Config{ 15871 MinVersion: ver.version, 15872 MaxVersion: ver.version, 15873 Certificates: []Certificate{encCert}, 15874 CipherSuites: encSuites, 15875 }, 15876 }) 15877 15878 testCases = append(testCases, testCase{ 15879 testType: clientTest, 15880 name: "RSAKeyUsage-Client-WantEncipherment-GotSignature-" + ver.name, 15881 config: Config{ 15882 MinVersion: ver.version, 15883 MaxVersion: ver.version, 15884 Certificates: []Certificate{dsCert}, 15885 CipherSuites: encSuites, 15886 }, 15887 shouldFail: true, 15888 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15889 }) 15890 15891 // In 1.2 and below, we should not enforce without the enforce-rsa-key-usage flag. 15892 testCases = append(testCases, testCase{ 15893 testType: clientTest, 15894 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-Unenforced-" + ver.name, 15895 config: Config{ 15896 MinVersion: ver.version, 15897 MaxVersion: ver.version, 15898 Certificates: []Certificate{dsCert}, 15899 CipherSuites: encSuites, 15900 }, 15901 flags: []string{"-expect-key-usage-invalid", "-ignore-rsa-key-usage"}, 15902 }) 15903 15904 testCases = append(testCases, testCase{ 15905 testType: clientTest, 15906 name: "RSAKeyUsage-Client-WantEncipherment-GotSignature-Unenforced-" + ver.name, 15907 config: Config{ 15908 MinVersion: ver.version, 15909 MaxVersion: ver.version, 15910 Certificates: []Certificate{encCert}, 15911 CipherSuites: dsSuites, 15912 }, 15913 flags: []string{"-expect-key-usage-invalid", "-ignore-rsa-key-usage"}, 15914 }) 15915 } 15916 15917 if ver.version >= VersionTLS13 { 15918 // In 1.3 and above, we enforce keyUsage even when disabled. 15919 testCases = append(testCases, testCase{ 15920 testType: clientTest, 15921 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-AlwaysEnforced-" + ver.name, 15922 config: Config{ 15923 MinVersion: ver.version, 15924 MaxVersion: ver.version, 15925 Certificates: []Certificate{encCert}, 15926 CipherSuites: dsSuites, 15927 }, 15928 flags: []string{"-ignore-rsa-key-usage"}, 15929 shouldFail: true, 15930 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15931 }) 15932 } 15933 15934 // The server only uses signatures and always enforces it. 15935 testCases = append(testCases, testCase{ 15936 testType: serverTest, 15937 name: "RSAKeyUsage-Server-WantSignature-GotEncipherment-" + ver.name, 15938 config: Config{ 15939 MinVersion: ver.version, 15940 MaxVersion: ver.version, 15941 Certificates: []Certificate{encCert}, 15942 }, 15943 shouldFail: true, 15944 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15945 flags: []string{"-require-any-client-certificate"}, 15946 }) 15947 15948 testCases = append(testCases, testCase{ 15949 testType: serverTest, 15950 name: "RSAKeyUsage-Server-WantSignature-GotSignature-" + ver.name, 15951 config: Config{ 15952 MinVersion: ver.version, 15953 MaxVersion: ver.version, 15954 Certificates: []Certificate{dsCert}, 15955 }, 15956 flags: []string{"-require-any-client-certificate"}, 15957 }) 15958 15959 } 15960} 15961 15962func addExtraHandshakeTests() { 15963 // An extra SSL_do_handshake is normally a no-op. These tests use -async 15964 // to ensure there is no transport I/O. 15965 testCases = append(testCases, testCase{ 15966 testType: clientTest, 15967 name: "ExtraHandshake-Client-TLS12", 15968 config: Config{ 15969 MinVersion: VersionTLS12, 15970 MaxVersion: VersionTLS12, 15971 }, 15972 flags: []string{ 15973 "-async", 15974 "-no-op-extra-handshake", 15975 }, 15976 }) 15977 testCases = append(testCases, testCase{ 15978 testType: serverTest, 15979 name: "ExtraHandshake-Server-TLS12", 15980 config: Config{ 15981 MinVersion: VersionTLS12, 15982 MaxVersion: VersionTLS12, 15983 }, 15984 flags: []string{ 15985 "-async", 15986 "-no-op-extra-handshake", 15987 }, 15988 }) 15989 testCases = append(testCases, testCase{ 15990 testType: clientTest, 15991 name: "ExtraHandshake-Client-TLS13", 15992 config: Config{ 15993 MinVersion: VersionTLS13, 15994 MaxVersion: VersionTLS13, 15995 }, 15996 flags: []string{ 15997 "-async", 15998 "-no-op-extra-handshake", 15999 }, 16000 }) 16001 testCases = append(testCases, testCase{ 16002 testType: serverTest, 16003 name: "ExtraHandshake-Server-TLS13", 16004 config: Config{ 16005 MinVersion: VersionTLS13, 16006 MaxVersion: VersionTLS13, 16007 }, 16008 flags: []string{ 16009 "-async", 16010 "-no-op-extra-handshake", 16011 }, 16012 }) 16013 16014 // An extra SSL_do_handshake is a no-op in server 0-RTT. 16015 testCases = append(testCases, testCase{ 16016 testType: serverTest, 16017 name: "ExtraHandshake-Server-EarlyData-TLS13", 16018 config: Config{ 16019 MaxVersion: VersionTLS13, 16020 MinVersion: VersionTLS13, 16021 }, 16022 messageCount: 2, 16023 resumeSession: true, 16024 earlyData: true, 16025 flags: []string{ 16026 "-async", 16027 "-no-op-extra-handshake", 16028 }, 16029 }) 16030 16031 // An extra SSL_do_handshake drives the handshake to completion in False 16032 // Start. We test this by handshaking twice and asserting the False 16033 // Start does not appear to happen. See AlertBeforeFalseStartTest for 16034 // how the test works. 16035 testCases = append(testCases, testCase{ 16036 testType: clientTest, 16037 name: "ExtraHandshake-FalseStart", 16038 config: Config{ 16039 MaxVersion: VersionTLS12, 16040 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 16041 NextProtos: []string{"foo"}, 16042 Bugs: ProtocolBugs{ 16043 ExpectFalseStart: true, 16044 AlertBeforeFalseStartTest: alertAccessDenied, 16045 }, 16046 }, 16047 flags: []string{ 16048 "-handshake-twice", 16049 "-false-start", 16050 "-advertise-alpn", "\x03foo", 16051 "-expect-alpn", "foo", 16052 }, 16053 shimWritesFirst: true, 16054 shouldFail: true, 16055 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 16056 expectedLocalError: "tls: peer did not false start: EOF", 16057 }) 16058} 16059 16060// Test that omitted and empty extensions blocks are tolerated. 16061func addOmitExtensionsTests() { 16062 // Check the ExpectOmitExtensions setting works. 16063 testCases = append(testCases, testCase{ 16064 testType: serverTest, 16065 name: "ExpectOmitExtensions", 16066 config: Config{ 16067 MinVersion: VersionTLS12, 16068 MaxVersion: VersionTLS12, 16069 Bugs: ProtocolBugs{ 16070 ExpectOmitExtensions: true, 16071 }, 16072 }, 16073 shouldFail: true, 16074 expectedLocalError: "tls: ServerHello did not omit extensions", 16075 }) 16076 16077 for _, ver := range tlsVersions { 16078 if ver.version > VersionTLS12 { 16079 continue 16080 } 16081 16082 testCases = append(testCases, testCase{ 16083 testType: serverTest, 16084 name: "OmitExtensions-ClientHello-" + ver.name, 16085 config: Config{ 16086 MinVersion: ver.version, 16087 MaxVersion: ver.version, 16088 SessionTicketsDisabled: true, 16089 Bugs: ProtocolBugs{ 16090 OmitExtensions: true, 16091 // With no client extensions, the ServerHello must not have 16092 // extensions. It should then omit the extensions field. 16093 ExpectOmitExtensions: true, 16094 }, 16095 }, 16096 }) 16097 16098 testCases = append(testCases, testCase{ 16099 testType: serverTest, 16100 name: "EmptyExtensions-ClientHello-" + ver.name, 16101 config: Config{ 16102 MinVersion: ver.version, 16103 MaxVersion: ver.version, 16104 SessionTicketsDisabled: true, 16105 Bugs: ProtocolBugs{ 16106 EmptyExtensions: true, 16107 // With no client extensions, the ServerHello must not have 16108 // extensions. It should then omit the extensions field. 16109 ExpectOmitExtensions: true, 16110 }, 16111 }, 16112 }) 16113 16114 testCases = append(testCases, testCase{ 16115 testType: clientTest, 16116 name: "OmitExtensions-ServerHello-" + ver.name, 16117 config: Config{ 16118 MinVersion: ver.version, 16119 MaxVersion: ver.version, 16120 SessionTicketsDisabled: true, 16121 Bugs: ProtocolBugs{ 16122 OmitExtensions: true, 16123 // Disable all ServerHello extensions so 16124 // OmitExtensions works. 16125 NoExtendedMasterSecret: true, 16126 NoRenegotiationInfo: true, 16127 NoOCSPStapling: true, 16128 NoSignedCertificateTimestamps: true, 16129 }, 16130 }, 16131 }) 16132 16133 testCases = append(testCases, testCase{ 16134 testType: clientTest, 16135 name: "EmptyExtensions-ServerHello-" + ver.name, 16136 config: Config{ 16137 MinVersion: ver.version, 16138 MaxVersion: ver.version, 16139 SessionTicketsDisabled: true, 16140 Bugs: ProtocolBugs{ 16141 EmptyExtensions: true, 16142 // Disable all ServerHello extensions so 16143 // EmptyExtensions works. 16144 NoExtendedMasterSecret: true, 16145 NoRenegotiationInfo: true, 16146 NoOCSPStapling: true, 16147 NoSignedCertificateTimestamps: true, 16148 }, 16149 }, 16150 }) 16151 } 16152} 16153 16154const ( 16155 shrinkingCompressionAlgID = 0xff01 16156 expandingCompressionAlgID = 0xff02 16157 randomCompressionAlgID = 0xff03 16158) 16159 16160var ( 16161 // shrinkingPrefix is the first two bytes of a Certificate message. 16162 shrinkingPrefix = []byte{0, 0} 16163 // expandingPrefix is just some arbitrary byte string. This has to match the 16164 // value in the shim. 16165 expandingPrefix = []byte{1, 2, 3, 4} 16166) 16167 16168var shrinkingCompression = CertCompressionAlg{ 16169 Compress: func(uncompressed []byte) []byte { 16170 if !bytes.HasPrefix(uncompressed, shrinkingPrefix) { 16171 panic(fmt.Sprintf("cannot compress certificate message %x", uncompressed)) 16172 } 16173 return uncompressed[len(shrinkingPrefix):] 16174 }, 16175 Decompress: func(out []byte, compressed []byte) bool { 16176 if len(out) != len(shrinkingPrefix)+len(compressed) { 16177 return false 16178 } 16179 16180 copy(out, shrinkingPrefix) 16181 copy(out[len(shrinkingPrefix):], compressed) 16182 return true 16183 }, 16184} 16185 16186var expandingCompression = CertCompressionAlg{ 16187 Compress: func(uncompressed []byte) []byte { 16188 ret := make([]byte, 0, len(expandingPrefix)+len(uncompressed)) 16189 ret = append(ret, expandingPrefix...) 16190 return append(ret, uncompressed...) 16191 }, 16192 Decompress: func(out []byte, compressed []byte) bool { 16193 if !bytes.HasPrefix(compressed, expandingPrefix) { 16194 return false 16195 } 16196 copy(out, compressed[len(expandingPrefix):]) 16197 return true 16198 }, 16199} 16200 16201var randomCompression = CertCompressionAlg{ 16202 Compress: func(uncompressed []byte) []byte { 16203 ret := make([]byte, 1+len(uncompressed)) 16204 if _, err := rand.Read(ret[:1]); err != nil { 16205 panic(err) 16206 } 16207 copy(ret[1:], uncompressed) 16208 return ret 16209 }, 16210 Decompress: func(out []byte, compressed []byte) bool { 16211 if len(compressed) != 1+len(out) { 16212 return false 16213 } 16214 copy(out, compressed[1:]) 16215 return true 16216 }, 16217} 16218 16219func addCertCompressionTests() { 16220 for _, ver := range tlsVersions { 16221 if ver.version < VersionTLS12 { 16222 continue 16223 } 16224 16225 // Duplicate compression algorithms is an error, even if nothing is 16226 // configured. 16227 testCases = append(testCases, testCase{ 16228 testType: serverTest, 16229 name: "DuplicateCertCompressionExt-" + ver.name, 16230 config: Config{ 16231 MinVersion: ver.version, 16232 MaxVersion: ver.version, 16233 Bugs: ProtocolBugs{ 16234 DuplicateCompressedCertAlgs: true, 16235 }, 16236 }, 16237 shouldFail: true, 16238 expectedError: ":ERROR_PARSING_EXTENSION:", 16239 }) 16240 16241 // With compression algorithms configured, an duplicate values should still 16242 // be an error. 16243 testCases = append(testCases, testCase{ 16244 testType: serverTest, 16245 name: "DuplicateCertCompressionExt2-" + ver.name, 16246 flags: []string{"-install-cert-compression-algs"}, 16247 config: Config{ 16248 MinVersion: ver.version, 16249 MaxVersion: ver.version, 16250 Bugs: ProtocolBugs{ 16251 DuplicateCompressedCertAlgs: true, 16252 }, 16253 }, 16254 shouldFail: true, 16255 expectedError: ":ERROR_PARSING_EXTENSION:", 16256 }) 16257 16258 if ver.version < VersionTLS13 { 16259 testCases = append(testCases, testCase{ 16260 testType: serverTest, 16261 name: "CertCompressionIgnoredBefore13-" + ver.name, 16262 flags: []string{"-install-cert-compression-algs"}, 16263 config: Config{ 16264 MinVersion: ver.version, 16265 MaxVersion: ver.version, 16266 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16267 expandingCompressionAlgID: expandingCompression, 16268 }, 16269 }, 16270 }) 16271 16272 continue 16273 } 16274 16275 testCases = append(testCases, testCase{ 16276 testType: serverTest, 16277 name: "CertCompressionExpands-" + ver.name, 16278 flags: []string{"-install-cert-compression-algs"}, 16279 config: Config{ 16280 MinVersion: ver.version, 16281 MaxVersion: ver.version, 16282 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16283 expandingCompressionAlgID: expandingCompression, 16284 }, 16285 Bugs: ProtocolBugs{ 16286 ExpectedCompressedCert: expandingCompressionAlgID, 16287 }, 16288 }, 16289 }) 16290 16291 testCases = append(testCases, testCase{ 16292 testType: serverTest, 16293 name: "CertCompressionShrinks-" + ver.name, 16294 flags: []string{"-install-cert-compression-algs"}, 16295 config: Config{ 16296 MinVersion: ver.version, 16297 MaxVersion: ver.version, 16298 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16299 shrinkingCompressionAlgID: shrinkingCompression, 16300 }, 16301 Bugs: ProtocolBugs{ 16302 ExpectedCompressedCert: shrinkingCompressionAlgID, 16303 }, 16304 }, 16305 }) 16306 16307 // Test that the shim behaves consistently if the compression function 16308 // is non-deterministic. This is intended to model version differences 16309 // between the shim and handshaker with handshake hints, but it is also 16310 // useful in confirming we only call the callbacks once. 16311 testCases = append(testCases, testCase{ 16312 testType: serverTest, 16313 name: "CertCompressionRandom-" + ver.name, 16314 flags: []string{"-install-cert-compression-algs"}, 16315 config: Config{ 16316 MinVersion: ver.version, 16317 MaxVersion: ver.version, 16318 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16319 randomCompressionAlgID: randomCompression, 16320 }, 16321 Bugs: ProtocolBugs{ 16322 ExpectedCompressedCert: randomCompressionAlgID, 16323 }, 16324 }, 16325 }) 16326 16327 // With both algorithms configured, the server should pick its most 16328 // preferable. (Which is expandingCompressionAlgID.) 16329 testCases = append(testCases, testCase{ 16330 testType: serverTest, 16331 name: "CertCompressionPriority-" + ver.name, 16332 flags: []string{"-install-cert-compression-algs"}, 16333 config: Config{ 16334 MinVersion: ver.version, 16335 MaxVersion: ver.version, 16336 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16337 shrinkingCompressionAlgID: shrinkingCompression, 16338 expandingCompressionAlgID: expandingCompression, 16339 }, 16340 Bugs: ProtocolBugs{ 16341 ExpectedCompressedCert: expandingCompressionAlgID, 16342 }, 16343 }, 16344 }) 16345 16346 // With no common algorithms configured, the server should decline 16347 // compression. 16348 testCases = append(testCases, testCase{ 16349 testType: serverTest, 16350 name: "CertCompressionNoCommonAlgs-" + ver.name, 16351 flags: []string{"-install-one-cert-compression-alg", strconv.Itoa(shrinkingCompressionAlgID)}, 16352 config: Config{ 16353 MinVersion: ver.version, 16354 MaxVersion: ver.version, 16355 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16356 expandingCompressionAlgID: expandingCompression, 16357 }, 16358 Bugs: ProtocolBugs{ 16359 ExpectUncompressedCert: true, 16360 }, 16361 }, 16362 }) 16363 16364 testCases = append(testCases, testCase{ 16365 testType: clientTest, 16366 name: "CertCompressionExpandsClient-" + ver.name, 16367 flags: []string{"-install-cert-compression-algs"}, 16368 config: Config{ 16369 MinVersion: ver.version, 16370 MaxVersion: ver.version, 16371 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16372 expandingCompressionAlgID: expandingCompression, 16373 }, 16374 Bugs: ProtocolBugs{ 16375 ExpectedCompressedCert: expandingCompressionAlgID, 16376 }, 16377 }, 16378 }) 16379 16380 testCases = append(testCases, testCase{ 16381 testType: clientTest, 16382 name: "CertCompressionShrinksClient-" + ver.name, 16383 flags: []string{"-install-cert-compression-algs"}, 16384 config: Config{ 16385 MinVersion: ver.version, 16386 MaxVersion: ver.version, 16387 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16388 shrinkingCompressionAlgID: shrinkingCompression, 16389 }, 16390 Bugs: ProtocolBugs{ 16391 ExpectedCompressedCert: shrinkingCompressionAlgID, 16392 }, 16393 }, 16394 }) 16395 16396 testCases = append(testCases, testCase{ 16397 testType: clientTest, 16398 name: "CertCompressionBadAlgIDClient-" + ver.name, 16399 flags: []string{"-install-cert-compression-algs"}, 16400 config: Config{ 16401 MinVersion: ver.version, 16402 MaxVersion: ver.version, 16403 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16404 shrinkingCompressionAlgID: shrinkingCompression, 16405 }, 16406 Bugs: ProtocolBugs{ 16407 ExpectedCompressedCert: shrinkingCompressionAlgID, 16408 SendCertCompressionAlgID: 1234, 16409 }, 16410 }, 16411 shouldFail: true, 16412 expectedError: ":UNKNOWN_CERT_COMPRESSION_ALG:", 16413 }) 16414 16415 testCases = append(testCases, testCase{ 16416 testType: clientTest, 16417 name: "CertCompressionTooSmallClient-" + ver.name, 16418 flags: []string{"-install-cert-compression-algs"}, 16419 config: Config{ 16420 MinVersion: ver.version, 16421 MaxVersion: ver.version, 16422 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16423 shrinkingCompressionAlgID: shrinkingCompression, 16424 }, 16425 Bugs: ProtocolBugs{ 16426 ExpectedCompressedCert: shrinkingCompressionAlgID, 16427 SendCertUncompressedLength: 12, 16428 }, 16429 }, 16430 shouldFail: true, 16431 expectedError: ":CERT_DECOMPRESSION_FAILED:", 16432 }) 16433 16434 testCases = append(testCases, testCase{ 16435 testType: clientTest, 16436 name: "CertCompressionTooLargeClient-" + ver.name, 16437 flags: []string{"-install-cert-compression-algs"}, 16438 config: Config{ 16439 MinVersion: ver.version, 16440 MaxVersion: ver.version, 16441 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16442 shrinkingCompressionAlgID: shrinkingCompression, 16443 }, 16444 Bugs: ProtocolBugs{ 16445 ExpectedCompressedCert: shrinkingCompressionAlgID, 16446 SendCertUncompressedLength: 1 << 20, 16447 }, 16448 }, 16449 shouldFail: true, 16450 expectedError: ":UNCOMPRESSED_CERT_TOO_LARGE:", 16451 }) 16452 } 16453} 16454 16455func addJDK11WorkaroundTests() { 16456 // Test the client treats the JDK 11 downgrade random like the usual one. 16457 testCases = append(testCases, testCase{ 16458 testType: clientTest, 16459 name: "Client-RejectJDK11DowngradeRandom", 16460 config: Config{ 16461 MaxVersion: VersionTLS12, 16462 Bugs: ProtocolBugs{ 16463 SendJDK11DowngradeRandom: true, 16464 }, 16465 }, 16466 shouldFail: true, 16467 expectedError: ":TLS13_DOWNGRADE:", 16468 expectedLocalError: "remote error: illegal parameter", 16469 }) 16470 testCases = append(testCases, testCase{ 16471 testType: clientTest, 16472 name: "Client-AcceptJDK11DowngradeRandom", 16473 config: Config{ 16474 MaxVersion: VersionTLS12, 16475 Bugs: ProtocolBugs{ 16476 SendJDK11DowngradeRandom: true, 16477 }, 16478 }, 16479 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 16480 }) 16481 16482 var clientHelloTests = []struct { 16483 clientHello []byte 16484 isJDK11 bool 16485 }{ 16486 { 16487 // A default JDK 11 ClientHello. 16488 decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"), 16489 true, 16490 }, 16491 { 16492 // The above with supported_versions and 16493 // psk_key_exchange_modes in the wrong order. 16494 decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002d00020101002b00090803040303030203010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"), 16495 false, 16496 }, 16497 { 16498 // The above with a padding extension added at the end. 16499 decodeHexOrPanic("010001b4030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000111000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b50015000700000000000000"), 16500 false, 16501 }, 16502 { 16503 // A JDK 11 ClientHello offering a TLS 1.3 PSK. 16504 decodeHexOrPanic("0100024c0303a8d71b20f060545a398226e807d21371a7a02b7ca2f96f476c2dea7e5860c5a400005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010001c9000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104aaec585ea9e121b24710a23560571322b2cf8ab8cd14e5762ef0486d8a6d0ecd721d8f2abda2eb8ed5ab7195505660450f49bba94bbf0c3f0070a531d9a1be4f002900cb00a600a0e6f7586d9a2bf64a54c1adf55a2f76657047e8e88e26629e2e7b9d630941e06fd87792770f6834e159a70b252157a9b4b082183f24629c8ff5049088b07ce37c49de8cf752a2ed7a545aff63bdc7a1b18e1bc201f23f159ee75d4987a04e00f840824f764691ab83a20e3032646e793065874cdb46138a52f50ed71406f399f96f9309eba4e5b1966148c22a63dc4aa1364269dd41dd5cc0e848d07af0095622c52cfcfc00212009cc315259e2328d65ad17a3de7c182c7874140a9356fecdd4614657806cd659"), 16505 true, 16506 }, 16507 { 16508 // A JDK 11 ClientHello offering a TLS 1.2 session. 16509 decodeHexOrPanic("010001a903038cdec49f4836d064a75046c93f22d0b9c2cf4900917332e6f0e1f41d692d3146201a3e99047492285ec65ab4e0eeee59f8f9d1eb7687398887bcd7b81353e93923005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d0002010100330047004500170041041c83c42fcd8fc06265b9f6e4f076f7e7ee17ace915c587845c0e1bc8cd177f904befeb611b682cae4702509a5f5d0c7162a282b8152d843169b91136e7c6f3e7"), 16510 true, 16511 }, 16512 { 16513 // A JDK 11 ClientHello with EMS disabled. 16514 decodeHexOrPanic("010001a50303323a857c324a9ef57d6e2544d129073830385cb1dc75ea79f6a2ec8ae09d2e7320f85fdd081678874c67ebab235e6d6a81d947f690bc0af9be4d39854ed67d9ef9005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000102000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200110009000702000400000000002b0009080304030303020301002d0002010100330047004500170041049c904c4850b495d75522f955d79e9cabea065c90279d6037a101a4c4ee712afc93ad0df5d12d287d53e458c7075d9a3ce3969c939bb62222bda779cecf54a603"), 16515 true, 16516 }, 16517 { 16518 // A JDK 11 ClientHello with OCSP stapling disabled. 16519 decodeHexOrPanic("0100019303038a50481dc85ee4f6581670821c50f2b3d34ac3251dc6e9b751bfd2521ab47ab02069a963c5486034c37ae0577ddb4c2db28cab592380ef8e4599d1305148712112005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010000f0000000080006000003736e69000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200170000002b0009080304030303020301002d00020101003300470045001700410438a97824f842c549e3c339322d8b2dbaa85d10bd7bca9c969376cb0c60b1e929eb4d13db38dcb0082ad8c637b24f55466a9acbb0b63634c1f431ec8342cf720d"), 16520 true, 16521 }, 16522 { 16523 // A JDK 11 ClientHello configured with a smaller set of 16524 // ciphers. 16525 decodeHexOrPanic("0100015603036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16526 true, 16527 }, 16528 { 16529 // The above with TLS_CHACHA20_POLY1305_SHA256 added, 16530 // which JDK 11 does not support. 16531 decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f48118000813011303c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16532 false, 16533 }, 16534 { 16535 // The above with X25519 added, which JDK 11 does not 16536 // support. 16537 decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000109000000080006000003736e69000500050100000000000a00220020001d0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16538 false, 16539 }, 16540 { 16541 // A JDK 11 ClientHello with ALPN protocols configured. 16542 decodeHexOrPanic("010001bb0303c0e0ea707b00c5311eb09cabd58626692cebfaefaef7265637e4550811dae16220da86d6eea04e214e873675223f08a6926bcf79f16d866280bdbab85e9e09c3ff005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000118000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020010000e000c02683208687474702f312e310011000900070200040000000000170000002b0009080304030303020301002d00020101003300470045001700410416def07c1d66ddde5fc9dcc328c8e77022d321c590c0d30cb41d515b38dca34540819a216c6c053bd47b9068f4f6b960f03647de4e36e8b7ffeea78f7252e3d9"), 16543 true, 16544 }, 16545 } 16546 for i, t := range clientHelloTests { 16547 expectedVersion := uint16(VersionTLS13) 16548 if t.isJDK11 { 16549 expectedVersion = VersionTLS12 16550 } 16551 16552 // In each of these tests, we set DefaultCurves to P-256 to 16553 // match the test inputs. SendClientHelloWithFixes requires the 16554 // key_shares extension to match in type. 16555 16556 // With the workaround enabled, we should negotiate TLS 1.2 on 16557 // JDK 11 ClientHellos. 16558 testCases = append(testCases, testCase{ 16559 testType: serverTest, 16560 name: fmt.Sprintf("Server-JDK11-%d", i), 16561 config: Config{ 16562 MaxVersion: VersionTLS13, 16563 DefaultCurves: []CurveID{CurveP256}, 16564 Bugs: ProtocolBugs{ 16565 SendClientHelloWithFixes: t.clientHello, 16566 ExpectJDK11DowngradeRandom: t.isJDK11, 16567 }, 16568 }, 16569 expectations: connectionExpectations{ 16570 version: expectedVersion, 16571 }, 16572 flags: []string{"-jdk11-workaround"}, 16573 }) 16574 16575 // With the workaround disabled, we always negotiate TLS 1.3. 16576 testCases = append(testCases, testCase{ 16577 testType: serverTest, 16578 name: fmt.Sprintf("Server-JDK11-NoWorkaround-%d", i), 16579 config: Config{ 16580 MaxVersion: VersionTLS13, 16581 DefaultCurves: []CurveID{CurveP256}, 16582 Bugs: ProtocolBugs{ 16583 SendClientHelloWithFixes: t.clientHello, 16584 ExpectJDK11DowngradeRandom: false, 16585 }, 16586 }, 16587 expectations: connectionExpectations{ 16588 version: VersionTLS13, 16589 }, 16590 }) 16591 16592 // If the server does not support TLS 1.3, the workaround should 16593 // be a no-op. In particular, it should not send the downgrade 16594 // signal. 16595 testCases = append(testCases, testCase{ 16596 testType: serverTest, 16597 name: fmt.Sprintf("Server-JDK11-TLS12-%d", i), 16598 config: Config{ 16599 MaxVersion: VersionTLS13, 16600 DefaultCurves: []CurveID{CurveP256}, 16601 Bugs: ProtocolBugs{ 16602 SendClientHelloWithFixes: t.clientHello, 16603 ExpectJDK11DowngradeRandom: false, 16604 }, 16605 }, 16606 expectations: connectionExpectations{ 16607 version: VersionTLS12, 16608 }, 16609 flags: []string{ 16610 "-jdk11-workaround", 16611 "-max-version", strconv.Itoa(VersionTLS12), 16612 }, 16613 }) 16614 } 16615} 16616 16617func addDelegatedCredentialTests() { 16618 certPath := path.Join(*resourceDir, rsaCertificateFile) 16619 pemBytes, err := os.ReadFile(certPath) 16620 if err != nil { 16621 panic(err) 16622 } 16623 16624 block, _ := pem.Decode(pemBytes) 16625 if block == nil { 16626 panic(fmt.Sprintf("no PEM block found in %q", certPath)) 16627 } 16628 parentDER := block.Bytes 16629 16630 rsaPriv, _, err := loadRSAPrivateKey(rsaKeyFile) 16631 if err != nil { 16632 panic(err) 16633 } 16634 16635 ecdsaDC, ecdsaPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{ 16636 algo: signatureRSAPSSWithSHA256, 16637 }, parentDER, rsaPriv) 16638 if err != nil { 16639 panic(err) 16640 } 16641 ecdsaFlagValue := fmt.Sprintf("%x,%x", ecdsaDC, ecdsaPKCS8) 16642 16643 testCases = append(testCases, testCase{ 16644 testType: serverTest, 16645 name: "DelegatedCredentials-NoClientSupport", 16646 config: Config{ 16647 MinVersion: VersionTLS13, 16648 MaxVersion: VersionTLS13, 16649 Bugs: ProtocolBugs{ 16650 DisableDelegatedCredentials: true, 16651 }, 16652 }, 16653 flags: []string{ 16654 "-delegated-credential", ecdsaFlagValue, 16655 }, 16656 }) 16657 16658 testCases = append(testCases, testCase{ 16659 testType: serverTest, 16660 name: "DelegatedCredentials-Basic", 16661 config: Config{ 16662 MinVersion: VersionTLS13, 16663 MaxVersion: VersionTLS13, 16664 Bugs: ProtocolBugs{ 16665 ExpectDelegatedCredentials: true, 16666 }, 16667 }, 16668 flags: []string{ 16669 "-delegated-credential", ecdsaFlagValue, 16670 "-expect-delegated-credential-used", 16671 }, 16672 }) 16673 16674 testCases = append(testCases, testCase{ 16675 testType: serverTest, 16676 name: "DelegatedCredentials-SigAlgoMissing", 16677 config: Config{ 16678 MinVersion: VersionTLS13, 16679 MaxVersion: VersionTLS13, 16680 Bugs: ProtocolBugs{ 16681 FailIfDelegatedCredentials: true, 16682 }, 16683 // If the client doesn't support the delegated credential signature 16684 // algorithm then the handshake should complete without using delegated 16685 // credentials. 16686 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 16687 }, 16688 flags: []string{ 16689 "-delegated-credential", ecdsaFlagValue, 16690 }, 16691 }) 16692 16693 // This flag value has mismatched public and private keys which should cause a 16694 // configuration error in the shim. 16695 _, badTLSVersionPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{ 16696 algo: signatureRSAPSSWithSHA256, 16697 tlsVersion: 0x1234, 16698 }, parentDER, rsaPriv) 16699 if err != nil { 16700 panic(err) 16701 } 16702 mismatchFlagValue := fmt.Sprintf("%x,%x", ecdsaDC, badTLSVersionPKCS8) 16703 testCases = append(testCases, testCase{ 16704 testType: serverTest, 16705 name: "DelegatedCredentials-KeyMismatch", 16706 config: Config{ 16707 MinVersion: VersionTLS13, 16708 MaxVersion: VersionTLS13, 16709 Bugs: ProtocolBugs{ 16710 FailIfDelegatedCredentials: true, 16711 }, 16712 }, 16713 flags: []string{ 16714 "-delegated-credential", mismatchFlagValue, 16715 }, 16716 shouldFail: true, 16717 expectedError: ":KEY_VALUES_MISMATCH:", 16718 }) 16719} 16720 16721type echCipher struct { 16722 name string 16723 cipher HPKECipherSuite 16724} 16725 16726var echCiphers = []echCipher{ 16727 { 16728 name: "HKDF-SHA256-AES-128-GCM", 16729 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.AES128GCM}, 16730 }, 16731 { 16732 name: "HKDF-SHA256-AES-256-GCM", 16733 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.AES256GCM}, 16734 }, { 16735 name: "HKDF-SHA256-ChaCha20-Poly1305", 16736 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.ChaCha20Poly1305}, 16737 }, 16738} 16739 16740// generateServerECHConfig constructs a ServerECHConfig with a fresh X25519 16741// keypair and using |template| as a template for the ECHConfig. If fields are 16742// omitted, defaults are used. 16743func generateServerECHConfig(template *ECHConfig) ServerECHConfig { 16744 publicKey, secretKey, err := hpke.GenerateKeyPairX25519() 16745 if err != nil { 16746 panic(err) 16747 } 16748 templateCopy := *template 16749 if templateCopy.KEM == 0 { 16750 templateCopy.KEM = hpke.X25519WithHKDFSHA256 16751 } 16752 if len(templateCopy.PublicKey) == 0 { 16753 templateCopy.PublicKey = publicKey 16754 } 16755 if len(templateCopy.CipherSuites) == 0 { 16756 templateCopy.CipherSuites = make([]HPKECipherSuite, len(echCiphers)) 16757 for i, cipher := range echCiphers { 16758 templateCopy.CipherSuites[i] = cipher.cipher 16759 } 16760 } 16761 if len(templateCopy.PublicName) == 0 { 16762 templateCopy.PublicName = "public.example" 16763 } 16764 if templateCopy.MaxNameLen == 0 { 16765 templateCopy.MaxNameLen = 64 16766 } 16767 return ServerECHConfig{ECHConfig: CreateECHConfig(&templateCopy), Key: secretKey} 16768} 16769 16770func addEncryptedClientHelloTests() { 16771 // echConfig's ConfigID should match the one used in ssl/test/fuzzer.h. 16772 echConfig := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 16773 echConfig1 := generateServerECHConfig(&ECHConfig{ConfigID: 43}) 16774 echConfig2 := generateServerECHConfig(&ECHConfig{ConfigID: 44}) 16775 echConfig3 := generateServerECHConfig(&ECHConfig{ConfigID: 45}) 16776 echConfigRepeatID := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 16777 16778 for _, protocol := range []protocol{tls, quic} { 16779 prefix := protocol.String() + "-" 16780 16781 // There are two ClientHellos, so many of our tests have 16782 // HelloRetryRequest variations. 16783 for _, hrr := range []bool{false, true} { 16784 var suffix string 16785 var defaultCurves []CurveID 16786 if hrr { 16787 suffix = "-HelloRetryRequest" 16788 // Require a HelloRetryRequest for every curve. 16789 defaultCurves = []CurveID{} 16790 } 16791 16792 // Test the server can accept ECH. 16793 testCases = append(testCases, testCase{ 16794 testType: serverTest, 16795 protocol: protocol, 16796 name: prefix + "ECH-Server" + suffix, 16797 config: Config{ 16798 ServerName: "secret.example", 16799 ClientECHConfig: echConfig.ECHConfig, 16800 DefaultCurves: defaultCurves, 16801 }, 16802 resumeSession: true, 16803 flags: []string{ 16804 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16805 "-ech-server-key", base64FlagValue(echConfig.Key), 16806 "-ech-is-retry-config", "1", 16807 "-expect-server-name", "secret.example", 16808 "-expect-ech-accept", 16809 }, 16810 expectations: connectionExpectations{ 16811 echAccepted: true, 16812 }, 16813 }) 16814 16815 // Test the server can accept ECH with a minimal ClientHelloOuter. 16816 // This confirms that the server does not unexpectedly pick up 16817 // fields from the wrong ClientHello. 16818 testCases = append(testCases, testCase{ 16819 testType: serverTest, 16820 protocol: protocol, 16821 name: prefix + "ECH-Server-MinimalClientHelloOuter" + suffix, 16822 config: Config{ 16823 ServerName: "secret.example", 16824 ClientECHConfig: echConfig.ECHConfig, 16825 DefaultCurves: defaultCurves, 16826 Bugs: ProtocolBugs{ 16827 MinimalClientHelloOuter: true, 16828 }, 16829 }, 16830 resumeSession: true, 16831 flags: []string{ 16832 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16833 "-ech-server-key", base64FlagValue(echConfig.Key), 16834 "-ech-is-retry-config", "1", 16835 "-expect-server-name", "secret.example", 16836 "-expect-ech-accept", 16837 }, 16838 expectations: connectionExpectations{ 16839 echAccepted: true, 16840 }, 16841 }) 16842 16843 // Test that the server can decline ECH. In particular, it must send 16844 // retry configs. 16845 testCases = append(testCases, testCase{ 16846 testType: serverTest, 16847 protocol: protocol, 16848 name: prefix + "ECH-Server-Decline" + suffix, 16849 config: Config{ 16850 ServerName: "secret.example", 16851 DefaultCurves: defaultCurves, 16852 // The client uses an ECHConfig that the server does not understand 16853 // so we can observe which retry configs the server sends back. 16854 ClientECHConfig: echConfig.ECHConfig, 16855 Bugs: ProtocolBugs{ 16856 OfferSessionInClientHelloOuter: true, 16857 ExpectECHRetryConfigs: CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw), 16858 }, 16859 }, 16860 resumeSession: true, 16861 flags: []string{ 16862 // Configure three ECHConfigs on the shim, only two of which 16863 // should be sent in retry configs. 16864 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 16865 "-ech-server-key", base64FlagValue(echConfig1.Key), 16866 "-ech-is-retry-config", "0", 16867 "-ech-server-config", base64FlagValue(echConfig2.ECHConfig.Raw), 16868 "-ech-server-key", base64FlagValue(echConfig2.Key), 16869 "-ech-is-retry-config", "1", 16870 "-ech-server-config", base64FlagValue(echConfig3.ECHConfig.Raw), 16871 "-ech-server-key", base64FlagValue(echConfig3.Key), 16872 "-ech-is-retry-config", "1", 16873 "-expect-server-name", "public.example", 16874 }, 16875 }) 16876 16877 // Test that the server considers a ClientHelloInner indicating TLS 16878 // 1.2 to be a fatal error. 16879 testCases = append(testCases, testCase{ 16880 testType: serverTest, 16881 protocol: protocol, 16882 name: prefix + "ECH-Server-TLS12InInner" + suffix, 16883 config: Config{ 16884 ServerName: "secret.example", 16885 DefaultCurves: defaultCurves, 16886 ClientECHConfig: echConfig.ECHConfig, 16887 Bugs: ProtocolBugs{ 16888 AllowTLS12InClientHelloInner: true, 16889 }, 16890 }, 16891 flags: []string{ 16892 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16893 "-ech-server-key", base64FlagValue(echConfig.Key), 16894 "-ech-is-retry-config", "1"}, 16895 shouldFail: true, 16896 expectedLocalError: "remote error: illegal parameter", 16897 expectedError: ":INVALID_CLIENT_HELLO_INNER:", 16898 }) 16899 16900 // When inner ECH extension is absent from the ClientHelloInner, the 16901 // server should fail the connection. 16902 testCases = append(testCases, testCase{ 16903 testType: serverTest, 16904 protocol: protocol, 16905 name: prefix + "ECH-Server-MissingECHInner" + suffix, 16906 config: Config{ 16907 ServerName: "secret.example", 16908 DefaultCurves: defaultCurves, 16909 ClientECHConfig: echConfig.ECHConfig, 16910 Bugs: ProtocolBugs{ 16911 OmitECHInner: !hrr, 16912 OmitSecondECHInner: hrr, 16913 }, 16914 }, 16915 flags: []string{ 16916 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16917 "-ech-server-key", base64FlagValue(echConfig.Key), 16918 "-ech-is-retry-config", "1", 16919 }, 16920 shouldFail: true, 16921 expectedLocalError: "remote error: illegal parameter", 16922 expectedError: ":INVALID_CLIENT_HELLO_INNER:", 16923 }) 16924 16925 // Test that the server can decode ech_outer_extensions. 16926 testCases = append(testCases, testCase{ 16927 testType: serverTest, 16928 protocol: protocol, 16929 name: prefix + "ECH-Server-OuterExtensions" + suffix, 16930 config: Config{ 16931 ServerName: "secret.example", 16932 DefaultCurves: defaultCurves, 16933 ClientECHConfig: echConfig.ECHConfig, 16934 ECHOuterExtensions: []uint16{ 16935 extensionKeyShare, 16936 extensionSupportedCurves, 16937 // Include a custom extension, to test that unrecognized 16938 // extensions are also decoded. 16939 extensionCustom, 16940 }, 16941 Bugs: ProtocolBugs{ 16942 CustomExtension: "test", 16943 OnlyCompressSecondClientHelloInner: hrr, 16944 }, 16945 }, 16946 flags: []string{ 16947 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16948 "-ech-server-key", base64FlagValue(echConfig.Key), 16949 "-ech-is-retry-config", "1", 16950 "-expect-server-name", "secret.example", 16951 "-expect-ech-accept", 16952 }, 16953 expectations: connectionExpectations{ 16954 echAccepted: true, 16955 }, 16956 }) 16957 16958 // Test that the server allows referenced ClientHelloOuter 16959 // extensions to be interleaved with other extensions. Only the 16960 // relative order must match. 16961 testCases = append(testCases, testCase{ 16962 testType: serverTest, 16963 protocol: protocol, 16964 name: prefix + "ECH-Server-OuterExtensions-Interleaved" + suffix, 16965 config: Config{ 16966 ServerName: "secret.example", 16967 DefaultCurves: defaultCurves, 16968 ClientECHConfig: echConfig.ECHConfig, 16969 ECHOuterExtensions: []uint16{ 16970 extensionKeyShare, 16971 extensionSupportedCurves, 16972 extensionCustom, 16973 }, 16974 Bugs: ProtocolBugs{ 16975 CustomExtension: "test", 16976 OnlyCompressSecondClientHelloInner: hrr, 16977 ECHOuterExtensionOrder: []uint16{ 16978 extensionServerName, 16979 extensionKeyShare, 16980 extensionSupportedVersions, 16981 extensionPSKKeyExchangeModes, 16982 extensionSupportedCurves, 16983 extensionSignatureAlgorithms, 16984 extensionCustom, 16985 }, 16986 }, 16987 }, 16988 flags: []string{ 16989 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16990 "-ech-server-key", base64FlagValue(echConfig.Key), 16991 "-ech-is-retry-config", "1", 16992 "-expect-server-name", "secret.example", 16993 "-expect-ech-accept", 16994 }, 16995 expectations: connectionExpectations{ 16996 echAccepted: true, 16997 }, 16998 }) 16999 17000 // Test that the server rejects references to extensions in the 17001 // wrong order. 17002 testCases = append(testCases, testCase{ 17003 testType: serverTest, 17004 protocol: protocol, 17005 name: prefix + "ECH-Server-OuterExtensions-WrongOrder" + suffix, 17006 config: Config{ 17007 ServerName: "secret.example", 17008 DefaultCurves: defaultCurves, 17009 ClientECHConfig: echConfig.ECHConfig, 17010 ECHOuterExtensions: []uint16{ 17011 extensionKeyShare, 17012 extensionSupportedCurves, 17013 }, 17014 Bugs: ProtocolBugs{ 17015 CustomExtension: "test", 17016 OnlyCompressSecondClientHelloInner: hrr, 17017 ECHOuterExtensionOrder: []uint16{ 17018 extensionSupportedCurves, 17019 extensionKeyShare, 17020 }, 17021 }, 17022 }, 17023 flags: []string{ 17024 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17025 "-ech-server-key", base64FlagValue(echConfig.Key), 17026 "-ech-is-retry-config", "1", 17027 "-expect-server-name", "secret.example", 17028 }, 17029 shouldFail: true, 17030 expectedLocalError: "remote error: illegal parameter", 17031 expectedError: ":INVALID_OUTER_EXTENSION:", 17032 }) 17033 17034 // Test that the server rejects duplicated values in ech_outer_extensions. 17035 // Besides causing the server to reconstruct an invalid ClientHelloInner 17036 // with duplicated extensions, this behavior would be vulnerable to DoS 17037 // attacks. 17038 testCases = append(testCases, testCase{ 17039 testType: serverTest, 17040 protocol: protocol, 17041 name: prefix + "ECH-Server-OuterExtensions-Duplicate" + suffix, 17042 config: Config{ 17043 ServerName: "secret.example", 17044 DefaultCurves: defaultCurves, 17045 ClientECHConfig: echConfig.ECHConfig, 17046 ECHOuterExtensions: []uint16{ 17047 extensionSupportedCurves, 17048 extensionSupportedCurves, 17049 }, 17050 Bugs: ProtocolBugs{ 17051 OnlyCompressSecondClientHelloInner: hrr, 17052 // Don't duplicate the extension in ClientHelloOuter. 17053 ECHOuterExtensionOrder: []uint16{ 17054 extensionSupportedCurves, 17055 }, 17056 }, 17057 }, 17058 flags: []string{ 17059 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17060 "-ech-server-key", base64FlagValue(echConfig.Key), 17061 "-ech-is-retry-config", "1", 17062 }, 17063 shouldFail: true, 17064 expectedLocalError: "remote error: illegal parameter", 17065 expectedError: ":INVALID_OUTER_EXTENSION:", 17066 }) 17067 17068 // Test that the server rejects references to missing extensions in 17069 // ech_outer_extensions. 17070 testCases = append(testCases, testCase{ 17071 testType: serverTest, 17072 protocol: protocol, 17073 name: prefix + "ECH-Server-OuterExtensions-Missing" + suffix, 17074 config: Config{ 17075 ServerName: "secret.example", 17076 DefaultCurves: defaultCurves, 17077 ClientECHConfig: echConfig.ECHConfig, 17078 ECHOuterExtensions: []uint16{ 17079 extensionCustom, 17080 }, 17081 Bugs: ProtocolBugs{ 17082 OnlyCompressSecondClientHelloInner: hrr, 17083 }, 17084 }, 17085 flags: []string{ 17086 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17087 "-ech-server-key", base64FlagValue(echConfig.Key), 17088 "-ech-is-retry-config", "1", 17089 "-expect-server-name", "secret.example", 17090 "-expect-ech-accept", 17091 }, 17092 shouldFail: true, 17093 expectedLocalError: "remote error: illegal parameter", 17094 expectedError: ":INVALID_OUTER_EXTENSION:", 17095 }) 17096 17097 // Test that the server rejects a references to the ECH extension in 17098 // ech_outer_extensions. The ECH extension is not authenticated in the 17099 // AAD and would result in an invalid ClientHelloInner. 17100 testCases = append(testCases, testCase{ 17101 testType: serverTest, 17102 protocol: protocol, 17103 name: prefix + "ECH-Server-OuterExtensions-SelfReference" + suffix, 17104 config: Config{ 17105 ServerName: "secret.example", 17106 DefaultCurves: defaultCurves, 17107 ClientECHConfig: echConfig.ECHConfig, 17108 ECHOuterExtensions: []uint16{ 17109 extensionEncryptedClientHello, 17110 }, 17111 Bugs: ProtocolBugs{ 17112 OnlyCompressSecondClientHelloInner: hrr, 17113 }, 17114 }, 17115 flags: []string{ 17116 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17117 "-ech-server-key", base64FlagValue(echConfig.Key), 17118 "-ech-is-retry-config", "1", 17119 }, 17120 shouldFail: true, 17121 expectedLocalError: "remote error: illegal parameter", 17122 expectedError: ":INVALID_OUTER_EXTENSION:", 17123 }) 17124 17125 // Test the message callback is correctly reported with ECH. 17126 clientAndServerHello := "read hs 1\nread clienthelloinner\nwrite hs 2\n" 17127 expectMsgCallback := clientAndServerHello + "write ccs\n" 17128 if hrr { 17129 expectMsgCallback += clientAndServerHello 17130 } 17131 // EncryptedExtensions onwards. 17132 expectMsgCallback += `write hs 8 17133write hs 11 17134write hs 15 17135write hs 20 17136read hs 20 17137write hs 4 17138write hs 4 17139` 17140 testCases = append(testCases, testCase{ 17141 testType: serverTest, 17142 protocol: protocol, 17143 name: prefix + "ECH-Server-MessageCallback" + suffix, 17144 config: Config{ 17145 ServerName: "secret.example", 17146 ClientECHConfig: echConfig.ECHConfig, 17147 DefaultCurves: defaultCurves, 17148 Bugs: ProtocolBugs{ 17149 NoCloseNotify: true, // Align QUIC and TCP traces. 17150 }, 17151 }, 17152 flags: []string{ 17153 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17154 "-ech-server-key", base64FlagValue(echConfig.Key), 17155 "-ech-is-retry-config", "1", 17156 "-expect-ech-accept", 17157 "-expect-msg-callback", expectMsgCallback, 17158 }, 17159 expectations: connectionExpectations{ 17160 echAccepted: true, 17161 }, 17162 }) 17163 } 17164 17165 // Test that ECH, which runs before an async early callback, interacts 17166 // correctly in the state machine. 17167 testCases = append(testCases, testCase{ 17168 testType: serverTest, 17169 protocol: protocol, 17170 name: prefix + "ECH-Server-AsyncEarlyCallback", 17171 config: Config{ 17172 ServerName: "secret.example", 17173 ClientECHConfig: echConfig.ECHConfig, 17174 }, 17175 flags: []string{ 17176 "-async", 17177 "-use-early-callback", 17178 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17179 "-ech-server-key", base64FlagValue(echConfig.Key), 17180 "-ech-is-retry-config", "1", 17181 "-expect-server-name", "secret.example", 17182 "-expect-ech-accept", 17183 }, 17184 expectations: connectionExpectations{ 17185 echAccepted: true, 17186 }, 17187 }) 17188 17189 // Test ECH-enabled server with two ECHConfigs can decrypt client's ECH when 17190 // it uses the second ECHConfig. 17191 testCases = append(testCases, testCase{ 17192 testType: serverTest, 17193 protocol: protocol, 17194 name: prefix + "ECH-Server-SecondECHConfig", 17195 config: Config{ 17196 ServerName: "secret.example", 17197 ClientECHConfig: echConfig1.ECHConfig, 17198 }, 17199 flags: []string{ 17200 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17201 "-ech-server-key", base64FlagValue(echConfig.Key), 17202 "-ech-is-retry-config", "1", 17203 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 17204 "-ech-server-key", base64FlagValue(echConfig1.Key), 17205 "-ech-is-retry-config", "1", 17206 "-expect-server-name", "secret.example", 17207 "-expect-ech-accept", 17208 }, 17209 expectations: connectionExpectations{ 17210 echAccepted: true, 17211 }, 17212 }) 17213 17214 // Test ECH-enabled server with two ECHConfigs that have the same config 17215 // ID can decrypt client's ECH when it uses the second ECHConfig. 17216 testCases = append(testCases, testCase{ 17217 testType: serverTest, 17218 protocol: protocol, 17219 name: prefix + "ECH-Server-RepeatedConfigID", 17220 config: Config{ 17221 ServerName: "secret.example", 17222 ClientECHConfig: echConfigRepeatID.ECHConfig, 17223 }, 17224 flags: []string{ 17225 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17226 "-ech-server-key", base64FlagValue(echConfig.Key), 17227 "-ech-is-retry-config", "1", 17228 "-ech-server-config", base64FlagValue(echConfigRepeatID.ECHConfig.Raw), 17229 "-ech-server-key", base64FlagValue(echConfigRepeatID.Key), 17230 "-ech-is-retry-config", "1", 17231 "-expect-server-name", "secret.example", 17232 "-expect-ech-accept", 17233 }, 17234 expectations: connectionExpectations{ 17235 echAccepted: true, 17236 }, 17237 }) 17238 17239 // Test all supported ECH cipher suites. 17240 for i, cipher := range echCiphers { 17241 otherCipher := echCiphers[(i+1)%len(echCiphers)] 17242 17243 // Test the ECH server can handle the specified cipher. 17244 testCases = append(testCases, testCase{ 17245 testType: serverTest, 17246 protocol: protocol, 17247 name: prefix + "ECH-Server-Cipher-" + cipher.name, 17248 config: Config{ 17249 ServerName: "secret.example", 17250 ClientECHConfig: echConfig.ECHConfig, 17251 ECHCipherSuites: []HPKECipherSuite{cipher.cipher}, 17252 }, 17253 flags: []string{ 17254 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17255 "-ech-server-key", base64FlagValue(echConfig.Key), 17256 "-ech-is-retry-config", "1", 17257 "-expect-server-name", "secret.example", 17258 "-expect-ech-accept", 17259 }, 17260 expectations: connectionExpectations{ 17261 echAccepted: true, 17262 }, 17263 }) 17264 17265 // Test that client can offer the specified cipher and skip over 17266 // unrecognized ones. 17267 cipherConfig := generateServerECHConfig(&ECHConfig{ 17268 ConfigID: 42, 17269 CipherSuites: []HPKECipherSuite{ 17270 {KDF: 0x1111, AEAD: 0x2222}, 17271 {KDF: cipher.cipher.KDF, AEAD: 0x2222}, 17272 {KDF: 0x1111, AEAD: cipher.cipher.AEAD}, 17273 cipher.cipher, 17274 }, 17275 }) 17276 testCases = append(testCases, testCase{ 17277 testType: clientTest, 17278 protocol: protocol, 17279 name: prefix + "ECH-Client-Cipher-" + cipher.name, 17280 config: Config{ 17281 ServerECHConfigs: []ServerECHConfig{cipherConfig}, 17282 }, 17283 flags: []string{ 17284 "-ech-config-list", base64FlagValue(CreateECHConfigList(cipherConfig.ECHConfig.Raw)), 17285 "-host-name", "secret.example", 17286 "-expect-ech-accept", 17287 }, 17288 expectations: connectionExpectations{ 17289 echAccepted: true, 17290 }, 17291 }) 17292 17293 // Test that the ECH server rejects the specified cipher if not 17294 // listed in its ECHConfig. 17295 otherCipherConfig := generateServerECHConfig(&ECHConfig{ 17296 ConfigID: 42, 17297 CipherSuites: []HPKECipherSuite{otherCipher.cipher}, 17298 }) 17299 testCases = append(testCases, testCase{ 17300 testType: serverTest, 17301 protocol: protocol, 17302 name: prefix + "ECH-Server-DisabledCipher-" + cipher.name, 17303 config: Config{ 17304 ServerName: "secret.example", 17305 ClientECHConfig: echConfig.ECHConfig, 17306 ECHCipherSuites: []HPKECipherSuite{cipher.cipher}, 17307 Bugs: ProtocolBugs{ 17308 ExpectECHRetryConfigs: CreateECHConfigList(otherCipherConfig.ECHConfig.Raw), 17309 }, 17310 }, 17311 flags: []string{ 17312 "-ech-server-config", base64FlagValue(otherCipherConfig.ECHConfig.Raw), 17313 "-ech-server-key", base64FlagValue(otherCipherConfig.Key), 17314 "-ech-is-retry-config", "1", 17315 "-expect-server-name", "public.example", 17316 }, 17317 }) 17318 } 17319 17320 // Test that the ECH server handles a short enc value by falling back to 17321 // ClientHelloOuter. 17322 testCases = append(testCases, testCase{ 17323 testType: serverTest, 17324 protocol: protocol, 17325 name: prefix + "ECH-Server-ShortEnc", 17326 config: Config{ 17327 ServerName: "secret.example", 17328 ClientECHConfig: echConfig.ECHConfig, 17329 Bugs: ProtocolBugs{ 17330 ExpectECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw), 17331 TruncateClientECHEnc: true, 17332 }, 17333 }, 17334 flags: []string{ 17335 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17336 "-ech-server-key", base64FlagValue(echConfig.Key), 17337 "-ech-is-retry-config", "1", 17338 "-expect-server-name", "public.example", 17339 }, 17340 }) 17341 17342 // Test that the server handles decryption failure by falling back to 17343 // ClientHelloOuter. 17344 testCases = append(testCases, testCase{ 17345 testType: serverTest, 17346 protocol: protocol, 17347 name: prefix + "ECH-Server-CorruptEncryptedClientHello", 17348 config: Config{ 17349 ServerName: "secret.example", 17350 ClientECHConfig: echConfig.ECHConfig, 17351 Bugs: ProtocolBugs{ 17352 ExpectECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw), 17353 CorruptEncryptedClientHello: true, 17354 }, 17355 }, 17356 flags: []string{ 17357 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17358 "-ech-server-key", base64FlagValue(echConfig.Key), 17359 "-ech-is-retry-config", "1", 17360 }, 17361 }) 17362 17363 // Test that the server treats decryption failure in the second 17364 // ClientHello as fatal. 17365 testCases = append(testCases, testCase{ 17366 testType: serverTest, 17367 protocol: protocol, 17368 name: prefix + "ECH-Server-CorruptSecondEncryptedClientHello", 17369 config: Config{ 17370 ServerName: "secret.example", 17371 ClientECHConfig: echConfig.ECHConfig, 17372 // Force a HelloRetryRequest. 17373 DefaultCurves: []CurveID{}, 17374 Bugs: ProtocolBugs{ 17375 CorruptSecondEncryptedClientHello: true, 17376 }, 17377 }, 17378 flags: []string{ 17379 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17380 "-ech-server-key", base64FlagValue(echConfig.Key), 17381 "-ech-is-retry-config", "1", 17382 }, 17383 shouldFail: true, 17384 expectedError: ":DECRYPTION_FAILED:", 17385 expectedLocalError: "remote error: error decrypting message", 17386 }) 17387 17388 // Test that the server treats a missing second ECH extension as fatal. 17389 testCases = append(testCases, testCase{ 17390 testType: serverTest, 17391 protocol: protocol, 17392 name: prefix + "ECH-Server-OmitSecondEncryptedClientHello", 17393 config: Config{ 17394 ServerName: "secret.example", 17395 ClientECHConfig: echConfig.ECHConfig, 17396 // Force a HelloRetryRequest. 17397 DefaultCurves: []CurveID{}, 17398 Bugs: ProtocolBugs{ 17399 OmitSecondEncryptedClientHello: true, 17400 }, 17401 }, 17402 flags: []string{ 17403 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17404 "-ech-server-key", base64FlagValue(echConfig.Key), 17405 "-ech-is-retry-config", "1", 17406 }, 17407 shouldFail: true, 17408 expectedError: ":MISSING_EXTENSION:", 17409 expectedLocalError: "remote error: missing extension", 17410 }) 17411 17412 // Test that the server treats a mismatched config ID in the second ClientHello as fatal. 17413 testCases = append(testCases, testCase{ 17414 testType: serverTest, 17415 protocol: protocol, 17416 name: prefix + "ECH-Server-DifferentConfigIDSecondClientHello", 17417 config: Config{ 17418 ServerName: "secret.example", 17419 ClientECHConfig: echConfig.ECHConfig, 17420 // Force a HelloRetryRequest. 17421 DefaultCurves: []CurveID{}, 17422 Bugs: ProtocolBugs{ 17423 CorruptSecondEncryptedClientHelloConfigID: true, 17424 }, 17425 }, 17426 flags: []string{ 17427 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17428 "-ech-server-key", base64FlagValue(echConfig.Key), 17429 "-ech-is-retry-config", "1", 17430 }, 17431 shouldFail: true, 17432 expectedError: ":DECODE_ERROR:", 17433 expectedLocalError: "remote error: illegal parameter", 17434 }) 17435 17436 // Test early data works with ECH, in both accept and reject cases. 17437 testCases = append(testCases, testCase{ 17438 testType: serverTest, 17439 protocol: protocol, 17440 name: prefix + "ECH-Server-EarlyData", 17441 config: Config{ 17442 ServerName: "secret.example", 17443 ClientECHConfig: echConfig.ECHConfig, 17444 }, 17445 resumeSession: true, 17446 earlyData: true, 17447 flags: []string{ 17448 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17449 "-ech-server-key", base64FlagValue(echConfig.Key), 17450 "-ech-is-retry-config", "1", 17451 "-expect-ech-accept", 17452 }, 17453 expectations: connectionExpectations{ 17454 echAccepted: true, 17455 }, 17456 }) 17457 testCases = append(testCases, testCase{ 17458 testType: serverTest, 17459 protocol: protocol, 17460 name: prefix + "ECH-Server-EarlyDataRejected", 17461 config: Config{ 17462 ServerName: "secret.example", 17463 ClientECHConfig: echConfig.ECHConfig, 17464 Bugs: ProtocolBugs{ 17465 // Cause the server to reject 0-RTT with a bad ticket age. 17466 SendTicketAge: 1 * time.Hour, 17467 }, 17468 }, 17469 resumeSession: true, 17470 earlyData: true, 17471 expectEarlyDataRejected: true, 17472 flags: []string{ 17473 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17474 "-ech-server-key", base64FlagValue(echConfig.Key), 17475 "-ech-is-retry-config", "1", 17476 "-expect-ech-accept", 17477 }, 17478 expectations: connectionExpectations{ 17479 echAccepted: true, 17480 }, 17481 }) 17482 17483 // Test servers with ECH disabled correctly ignore the extension and 17484 // handshake with the ClientHelloOuter. 17485 testCases = append(testCases, testCase{ 17486 testType: serverTest, 17487 protocol: protocol, 17488 name: prefix + "ECH-Server-Disabled", 17489 config: Config{ 17490 ServerName: "secret.example", 17491 ClientECHConfig: echConfig.ECHConfig, 17492 }, 17493 flags: []string{ 17494 "-expect-server-name", "public.example", 17495 }, 17496 }) 17497 17498 // Test that ECH can be used with client certificates. In particular, 17499 // the name override logic should not interfere with the server. 17500 // Test the server can accept ECH. 17501 testCases = append(testCases, testCase{ 17502 testType: serverTest, 17503 protocol: protocol, 17504 name: prefix + "ECH-Server-ClientAuth", 17505 config: Config{ 17506 Certificates: []Certificate{rsaCertificate}, 17507 ClientECHConfig: echConfig.ECHConfig, 17508 }, 17509 flags: []string{ 17510 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17511 "-ech-server-key", base64FlagValue(echConfig.Key), 17512 "-ech-is-retry-config", "1", 17513 "-expect-ech-accept", 17514 "-require-any-client-certificate", 17515 }, 17516 expectations: connectionExpectations{ 17517 echAccepted: true, 17518 }, 17519 }) 17520 testCases = append(testCases, testCase{ 17521 testType: serverTest, 17522 protocol: protocol, 17523 name: prefix + "ECH-Server-Decline-ClientAuth", 17524 config: Config{ 17525 Certificates: []Certificate{rsaCertificate}, 17526 ClientECHConfig: echConfig.ECHConfig, 17527 Bugs: ProtocolBugs{ 17528 ExpectECHRetryConfigs: CreateECHConfigList(echConfig1.ECHConfig.Raw), 17529 }, 17530 }, 17531 flags: []string{ 17532 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 17533 "-ech-server-key", base64FlagValue(echConfig1.Key), 17534 "-ech-is-retry-config", "1", 17535 "-require-any-client-certificate", 17536 }, 17537 }) 17538 17539 // Test that the server accepts padding. 17540 testCases = append(testCases, testCase{ 17541 testType: serverTest, 17542 protocol: protocol, 17543 name: prefix + "ECH-Server-Padding", 17544 config: Config{ 17545 ClientECHConfig: echConfig.ECHConfig, 17546 Bugs: ProtocolBugs{ 17547 ClientECHPadding: 10, 17548 }, 17549 }, 17550 flags: []string{ 17551 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17552 "-ech-server-key", base64FlagValue(echConfig.Key), 17553 "-ech-is-retry-config", "1", 17554 "-expect-ech-accept", 17555 }, 17556 expectations: connectionExpectations{ 17557 echAccepted: true, 17558 }, 17559 }) 17560 17561 // Test that the server rejects bad padding. 17562 testCases = append(testCases, testCase{ 17563 testType: serverTest, 17564 protocol: protocol, 17565 name: prefix + "ECH-Server-BadPadding", 17566 config: Config{ 17567 ClientECHConfig: echConfig.ECHConfig, 17568 Bugs: ProtocolBugs{ 17569 ClientECHPadding: 10, 17570 BadClientECHPadding: true, 17571 }, 17572 }, 17573 flags: []string{ 17574 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17575 "-ech-server-key", base64FlagValue(echConfig.Key), 17576 "-ech-is-retry-config", "1", 17577 "-expect-ech-accept", 17578 }, 17579 expectations: connectionExpectations{ 17580 echAccepted: true, 17581 }, 17582 shouldFail: true, 17583 expectedError: ":DECODE_ERROR", 17584 expectedLocalError: "remote error: illegal parameter", 17585 }) 17586 17587 // Test the client's behavior when the server ignores ECH GREASE. 17588 testCases = append(testCases, testCase{ 17589 testType: clientTest, 17590 protocol: protocol, 17591 name: prefix + "ECH-GREASE-Client-TLS13", 17592 config: Config{ 17593 MinVersion: VersionTLS13, 17594 MaxVersion: VersionTLS13, 17595 Bugs: ProtocolBugs{ 17596 ExpectClientECH: true, 17597 }, 17598 }, 17599 flags: []string{"-enable-ech-grease"}, 17600 }) 17601 17602 // Test the client's ECH GREASE behavior when responding to server's 17603 // HelloRetryRequest. This test implicitly checks that the first and second 17604 // ClientHello messages have identical ECH extensions. 17605 testCases = append(testCases, testCase{ 17606 testType: clientTest, 17607 protocol: protocol, 17608 name: prefix + "ECH-GREASE-Client-TLS13-HelloRetryRequest", 17609 config: Config{ 17610 MaxVersion: VersionTLS13, 17611 MinVersion: VersionTLS13, 17612 // P-384 requires a HelloRetryRequest against BoringSSL's default 17613 // configuration. Assert this with ExpectMissingKeyShare. 17614 CurvePreferences: []CurveID{CurveP384}, 17615 Bugs: ProtocolBugs{ 17616 ExpectMissingKeyShare: true, 17617 ExpectClientECH: true, 17618 }, 17619 }, 17620 flags: []string{"-enable-ech-grease", "-expect-hrr"}, 17621 }) 17622 17623 unsupportedVersion := []byte{ 17624 // version 17625 0xba, 0xdd, 17626 // length 17627 0x00, 0x05, 17628 // contents 17629 0x05, 0x04, 0x03, 0x02, 0x01, 17630 } 17631 17632 // Test that the client accepts a well-formed encrypted_client_hello 17633 // extension in response to ECH GREASE. The response includes one ECHConfig 17634 // with a supported version and one with an unsupported version. 17635 testCases = append(testCases, testCase{ 17636 testType: clientTest, 17637 protocol: protocol, 17638 name: prefix + "ECH-GREASE-Client-TLS13-Retry-Configs", 17639 config: Config{ 17640 MinVersion: VersionTLS13, 17641 MaxVersion: VersionTLS13, 17642 Bugs: ProtocolBugs{ 17643 ExpectClientECH: true, 17644 // Include an additional well-formed ECHConfig with an 17645 // unsupported version. This ensures the client can skip 17646 // unsupported configs. 17647 SendECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw, unsupportedVersion), 17648 }, 17649 }, 17650 flags: []string{"-enable-ech-grease"}, 17651 }) 17652 17653 // TLS 1.2 ServerHellos cannot contain retry configs. 17654 if protocol != quic { 17655 testCases = append(testCases, testCase{ 17656 testType: clientTest, 17657 protocol: protocol, 17658 name: prefix + "ECH-GREASE-Client-TLS12-RejectRetryConfigs", 17659 config: Config{ 17660 MinVersion: VersionTLS12, 17661 MaxVersion: VersionTLS12, 17662 ServerECHConfigs: []ServerECHConfig{echConfig}, 17663 Bugs: ProtocolBugs{ 17664 ExpectClientECH: true, 17665 AlwaysSendECHRetryConfigs: true, 17666 }, 17667 }, 17668 flags: []string{"-enable-ech-grease"}, 17669 shouldFail: true, 17670 expectedLocalError: "remote error: unsupported extension", 17671 expectedError: ":UNEXPECTED_EXTENSION:", 17672 }) 17673 testCases = append(testCases, testCase{ 17674 testType: clientTest, 17675 protocol: protocol, 17676 name: prefix + "ECH-Client-TLS12-RejectRetryConfigs", 17677 config: Config{ 17678 MinVersion: VersionTLS12, 17679 MaxVersion: VersionTLS12, 17680 ServerECHConfigs: []ServerECHConfig{echConfig}, 17681 Bugs: ProtocolBugs{ 17682 ExpectClientECH: true, 17683 AlwaysSendECHRetryConfigs: true, 17684 }, 17685 }, 17686 flags: []string{ 17687 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig1.ECHConfig.Raw)), 17688 }, 17689 shouldFail: true, 17690 expectedLocalError: "remote error: unsupported extension", 17691 expectedError: ":UNEXPECTED_EXTENSION:", 17692 }) 17693 } 17694 17695 // Retry configs must be rejected when ECH is accepted. 17696 testCases = append(testCases, testCase{ 17697 testType: clientTest, 17698 protocol: protocol, 17699 name: prefix + "ECH-Client-Accept-RejectRetryConfigs", 17700 config: Config{ 17701 ServerECHConfigs: []ServerECHConfig{echConfig}, 17702 Bugs: ProtocolBugs{ 17703 ExpectClientECH: true, 17704 AlwaysSendECHRetryConfigs: true, 17705 }, 17706 }, 17707 flags: []string{ 17708 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17709 }, 17710 shouldFail: true, 17711 expectedLocalError: "remote error: unsupported extension", 17712 expectedError: ":UNEXPECTED_EXTENSION:", 17713 }) 17714 17715 // Unsolicited ECH HelloRetryRequest extensions should be rejected. 17716 testCases = append(testCases, testCase{ 17717 testType: clientTest, 17718 protocol: protocol, 17719 name: prefix + "ECH-Client-UnsolictedHRRExtension", 17720 config: Config{ 17721 ServerECHConfigs: []ServerECHConfig{echConfig}, 17722 CurvePreferences: []CurveID{CurveP384}, 17723 Bugs: ProtocolBugs{ 17724 AlwaysSendECHHelloRetryRequest: true, 17725 ExpectMissingKeyShare: true, // Check we triggered HRR. 17726 }, 17727 }, 17728 shouldFail: true, 17729 expectedLocalError: "remote error: unsupported extension", 17730 expectedError: ":UNEXPECTED_EXTENSION:", 17731 }) 17732 17733 // GREASE should ignore ECH HelloRetryRequest extensions. 17734 testCases = append(testCases, testCase{ 17735 testType: clientTest, 17736 protocol: protocol, 17737 name: prefix + "ECH-Client-GREASE-IgnoreHRRExtension", 17738 config: Config{ 17739 CurvePreferences: []CurveID{CurveP384}, 17740 Bugs: ProtocolBugs{ 17741 AlwaysSendECHHelloRetryRequest: true, 17742 ExpectMissingKeyShare: true, // Check we triggered HRR. 17743 }, 17744 }, 17745 flags: []string{"-enable-ech-grease"}, 17746 }) 17747 17748 // Random ECH HelloRetryRequest extensions also signal ECH reject. 17749 testCases = append(testCases, testCase{ 17750 testType: clientTest, 17751 protocol: protocol, 17752 name: prefix + "ECH-Client-Reject-RandomHRRExtension", 17753 config: Config{ 17754 CurvePreferences: []CurveID{CurveP384}, 17755 Bugs: ProtocolBugs{ 17756 AlwaysSendECHHelloRetryRequest: true, 17757 ExpectMissingKeyShare: true, // Check we triggered HRR. 17758 }, 17759 }, 17760 flags: []string{ 17761 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17762 }, 17763 shouldFail: true, 17764 expectedLocalError: "remote error: ECH required", 17765 expectedError: ":ECH_REJECTED:", 17766 }) 17767 17768 // Test that the client aborts with a decode_error alert when it receives a 17769 // syntactically-invalid encrypted_client_hello extension from the server. 17770 testCases = append(testCases, testCase{ 17771 testType: clientTest, 17772 protocol: protocol, 17773 name: prefix + "ECH-GREASE-Client-TLS13-Invalid-Retry-Configs", 17774 config: Config{ 17775 MinVersion: VersionTLS13, 17776 MaxVersion: VersionTLS13, 17777 Bugs: ProtocolBugs{ 17778 ExpectClientECH: true, 17779 SendECHRetryConfigs: []byte{0xba, 0xdd, 0xec, 0xcc}, 17780 }, 17781 }, 17782 flags: []string{"-enable-ech-grease"}, 17783 shouldFail: true, 17784 expectedLocalError: "remote error: error decoding message", 17785 expectedError: ":ERROR_PARSING_EXTENSION:", 17786 }) 17787 17788 // Test that the server responds to an inner ECH extension with the 17789 // acceptance confirmation. 17790 testCases = append(testCases, testCase{ 17791 testType: serverTest, 17792 protocol: protocol, 17793 name: prefix + "ECH-Server-ECHInner", 17794 config: Config{ 17795 MinVersion: VersionTLS13, 17796 MaxVersion: VersionTLS13, 17797 Bugs: ProtocolBugs{ 17798 AlwaysSendECHInner: true, 17799 }, 17800 }, 17801 resumeSession: true, 17802 }) 17803 testCases = append(testCases, testCase{ 17804 testType: serverTest, 17805 protocol: protocol, 17806 name: prefix + "ECH-Server-ECHInner-HelloRetryRequest", 17807 config: Config{ 17808 MinVersion: VersionTLS13, 17809 MaxVersion: VersionTLS13, 17810 // Force a HelloRetryRequest. 17811 DefaultCurves: []CurveID{}, 17812 Bugs: ProtocolBugs{ 17813 AlwaysSendECHInner: true, 17814 }, 17815 }, 17816 resumeSession: true, 17817 }) 17818 17819 // Test that server fails the handshake when it sees a non-empty 17820 // inner ECH extension. 17821 testCases = append(testCases, testCase{ 17822 testType: serverTest, 17823 protocol: protocol, 17824 name: prefix + "ECH-Server-ECHInner-NotEmpty", 17825 config: Config{ 17826 MinVersion: VersionTLS13, 17827 MaxVersion: VersionTLS13, 17828 Bugs: ProtocolBugs{ 17829 AlwaysSendECHInner: true, 17830 SendInvalidECHInner: []byte{42, 42, 42}, 17831 }, 17832 }, 17833 shouldFail: true, 17834 expectedLocalError: "remote error: error decoding message", 17835 expectedError: ":ERROR_PARSING_EXTENSION:", 17836 }) 17837 17838 // Test that a TLS 1.3 server that receives an inner ECH extension can 17839 // negotiate TLS 1.2 without clobbering the downgrade signal. 17840 if protocol != quic { 17841 testCases = append(testCases, testCase{ 17842 testType: serverTest, 17843 protocol: protocol, 17844 name: prefix + "ECH-Server-ECHInner-Absent-TLS12", 17845 config: Config{ 17846 MinVersion: VersionTLS12, 17847 MaxVersion: VersionTLS13, 17848 Bugs: ProtocolBugs{ 17849 // Omit supported_versions extension so the server negotiates 17850 // TLS 1.2. 17851 OmitSupportedVersions: true, 17852 AlwaysSendECHInner: true, 17853 }, 17854 }, 17855 // Check that the client sees the TLS 1.3 downgrade signal in 17856 // ServerHello.random. 17857 shouldFail: true, 17858 expectedLocalError: "tls: downgrade from TLS 1.3 detected", 17859 }) 17860 } 17861 17862 // Test the client can negotiate ECH, with and without HelloRetryRequest. 17863 testCases = append(testCases, testCase{ 17864 testType: clientTest, 17865 protocol: protocol, 17866 name: prefix + "ECH-Client", 17867 config: Config{ 17868 MinVersion: VersionTLS13, 17869 MaxVersion: VersionTLS13, 17870 ServerECHConfigs: []ServerECHConfig{echConfig}, 17871 Bugs: ProtocolBugs{ 17872 ExpectServerName: "secret.example", 17873 ExpectOuterServerName: "public.example", 17874 }, 17875 }, 17876 flags: []string{ 17877 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17878 "-host-name", "secret.example", 17879 "-expect-ech-accept", 17880 }, 17881 resumeSession: true, 17882 expectations: connectionExpectations{echAccepted: true}, 17883 }) 17884 testCases = append(testCases, testCase{ 17885 testType: clientTest, 17886 protocol: protocol, 17887 name: prefix + "ECH-Client-HelloRetryRequest", 17888 config: Config{ 17889 MinVersion: VersionTLS13, 17890 MaxVersion: VersionTLS13, 17891 CurvePreferences: []CurveID{CurveP384}, 17892 ServerECHConfigs: []ServerECHConfig{echConfig}, 17893 Bugs: ProtocolBugs{ 17894 ExpectServerName: "secret.example", 17895 ExpectOuterServerName: "public.example", 17896 ExpectMissingKeyShare: true, // Check we triggered HRR. 17897 }, 17898 }, 17899 resumeSession: true, 17900 flags: []string{ 17901 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17902 "-host-name", "secret.example", 17903 "-expect-ech-accept", 17904 "-expect-hrr", // Check we triggered HRR. 17905 }, 17906 expectations: connectionExpectations{echAccepted: true}, 17907 }) 17908 17909 // Test the client can negotiate ECH with early data. 17910 testCases = append(testCases, testCase{ 17911 testType: clientTest, 17912 protocol: protocol, 17913 name: prefix + "ECH-Client-EarlyData", 17914 config: Config{ 17915 MinVersion: VersionTLS13, 17916 MaxVersion: VersionTLS13, 17917 ServerECHConfigs: []ServerECHConfig{echConfig}, 17918 Bugs: ProtocolBugs{ 17919 ExpectServerName: "secret.example", 17920 }, 17921 }, 17922 flags: []string{ 17923 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17924 "-host-name", "secret.example", 17925 "-expect-ech-accept", 17926 }, 17927 resumeSession: true, 17928 earlyData: true, 17929 expectations: connectionExpectations{echAccepted: true}, 17930 }) 17931 testCases = append(testCases, testCase{ 17932 testType: clientTest, 17933 protocol: protocol, 17934 name: prefix + "ECH-Client-EarlyDataRejected", 17935 config: Config{ 17936 MinVersion: VersionTLS13, 17937 MaxVersion: VersionTLS13, 17938 ServerECHConfigs: []ServerECHConfig{echConfig}, 17939 Bugs: ProtocolBugs{ 17940 ExpectServerName: "secret.example", 17941 AlwaysRejectEarlyData: true, 17942 }, 17943 }, 17944 flags: []string{ 17945 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17946 "-host-name", "secret.example", 17947 "-expect-ech-accept", 17948 }, 17949 resumeSession: true, 17950 earlyData: true, 17951 expectEarlyDataRejected: true, 17952 expectations: connectionExpectations{echAccepted: true}, 17953 }) 17954 17955 if protocol != quic { 17956 // Test that an ECH client does not offer a TLS 1.2 session. 17957 testCases = append(testCases, testCase{ 17958 testType: clientTest, 17959 protocol: protocol, 17960 name: prefix + "ECH-Client-TLS12SessionID", 17961 config: Config{ 17962 MaxVersion: VersionTLS12, 17963 SessionTicketsDisabled: true, 17964 }, 17965 resumeConfig: &Config{ 17966 ServerECHConfigs: []ServerECHConfig{echConfig}, 17967 Bugs: ProtocolBugs{ 17968 ExpectNoTLS12Session: true, 17969 }, 17970 }, 17971 flags: []string{ 17972 "-on-resume-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17973 "-on-resume-expect-ech-accept", 17974 }, 17975 resumeSession: true, 17976 expectResumeRejected: true, 17977 resumeExpectations: &connectionExpectations{echAccepted: true}, 17978 }) 17979 testCases = append(testCases, testCase{ 17980 testType: clientTest, 17981 protocol: protocol, 17982 name: prefix + "ECH-Client-TLS12SessionTicket", 17983 config: Config{ 17984 MaxVersion: VersionTLS12, 17985 }, 17986 resumeConfig: &Config{ 17987 ServerECHConfigs: []ServerECHConfig{echConfig}, 17988 Bugs: ProtocolBugs{ 17989 ExpectNoTLS12Session: true, 17990 }, 17991 }, 17992 flags: []string{ 17993 "-on-resume-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17994 "-on-resume-expect-ech-accept", 17995 }, 17996 resumeSession: true, 17997 expectResumeRejected: true, 17998 resumeExpectations: &connectionExpectations{echAccepted: true}, 17999 }) 18000 } 18001 18002 // ClientHelloInner should not include NPN, which is a TLS 1.2-only 18003 // extensions. The Go server will enforce this, so this test only needs 18004 // to configure the feature on the shim. Other application extensions 18005 // are sent implicitly. 18006 testCases = append(testCases, testCase{ 18007 testType: clientTest, 18008 protocol: protocol, 18009 name: prefix + "ECH-Client-NoNPN", 18010 config: Config{ 18011 ServerECHConfigs: []ServerECHConfig{echConfig}, 18012 }, 18013 flags: []string{ 18014 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18015 "-expect-ech-accept", 18016 // Enable NPN. 18017 "-select-next-proto", "foo", 18018 }, 18019 expectations: connectionExpectations{echAccepted: true}, 18020 }) 18021 18022 // Test that the client iterates over configurations in the 18023 // ECHConfigList and selects the first with supported parameters. 18024 p256Key := ecdsaP256Certificate.PrivateKey.(*ecdsa.PrivateKey) 18025 unsupportedKEM := generateServerECHConfig(&ECHConfig{ 18026 KEM: hpke.P256WithHKDFSHA256, 18027 PublicKey: elliptic.Marshal(elliptic.P256(), p256Key.X, p256Key.Y), 18028 }).ECHConfig 18029 unsupportedCipherSuites := generateServerECHConfig(&ECHConfig{ 18030 CipherSuites: []HPKECipherSuite{{0x1111, 0x2222}}, 18031 }).ECHConfig 18032 unsupportedMandatoryExtension := generateServerECHConfig(&ECHConfig{ 18033 UnsupportedMandatoryExtension: true, 18034 }).ECHConfig 18035 testCases = append(testCases, testCase{ 18036 testType: clientTest, 18037 protocol: protocol, 18038 name: prefix + "ECH-Client-SelectECHConfig", 18039 config: Config{ 18040 ServerECHConfigs: []ServerECHConfig{echConfig}, 18041 }, 18042 flags: []string{ 18043 "-ech-config-list", base64FlagValue(CreateECHConfigList( 18044 unsupportedVersion, 18045 unsupportedKEM.Raw, 18046 unsupportedCipherSuites.Raw, 18047 unsupportedMandatoryExtension.Raw, 18048 echConfig.ECHConfig.Raw, 18049 // |echConfig1| is also supported, but the client should 18050 // select the first one. 18051 echConfig1.ECHConfig.Raw, 18052 )), 18053 "-expect-ech-accept", 18054 }, 18055 expectations: connectionExpectations{ 18056 echAccepted: true, 18057 }, 18058 }) 18059 18060 // Test that the client skips sending ECH if all ECHConfigs are 18061 // unsupported. 18062 testCases = append(testCases, testCase{ 18063 testType: clientTest, 18064 protocol: protocol, 18065 name: prefix + "ECH-Client-NoSupportedConfigs", 18066 config: Config{ 18067 Bugs: ProtocolBugs{ 18068 ExpectNoClientECH: true, 18069 }, 18070 }, 18071 flags: []string{ 18072 "-ech-config-list", base64FlagValue(CreateECHConfigList( 18073 unsupportedVersion, 18074 unsupportedKEM.Raw, 18075 unsupportedCipherSuites.Raw, 18076 unsupportedMandatoryExtension.Raw, 18077 )), 18078 }, 18079 }) 18080 18081 // If ECH GREASE is enabled, the client should send ECH GREASE when no 18082 // configured ECHConfig is suitable. 18083 testCases = append(testCases, testCase{ 18084 testType: clientTest, 18085 protocol: protocol, 18086 name: prefix + "ECH-Client-NoSupportedConfigs-GREASE", 18087 config: Config{ 18088 Bugs: ProtocolBugs{ 18089 ExpectClientECH: true, 18090 }, 18091 }, 18092 flags: []string{ 18093 "-ech-config-list", base64FlagValue(CreateECHConfigList( 18094 unsupportedVersion, 18095 unsupportedKEM.Raw, 18096 unsupportedCipherSuites.Raw, 18097 unsupportedMandatoryExtension.Raw, 18098 )), 18099 "-enable-ech-grease", 18100 }, 18101 }) 18102 18103 // If both ECH GREASE and suitable ECHConfigs are available, the 18104 // client should send normal ECH. 18105 testCases = append(testCases, testCase{ 18106 testType: clientTest, 18107 protocol: protocol, 18108 name: prefix + "ECH-Client-GREASE", 18109 config: Config{ 18110 ServerECHConfigs: []ServerECHConfig{echConfig}, 18111 }, 18112 flags: []string{ 18113 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18114 "-expect-ech-accept", 18115 }, 18116 resumeSession: true, 18117 expectations: connectionExpectations{echAccepted: true}, 18118 }) 18119 18120 // Test that GREASE extensions correctly interact with ECH. Both the 18121 // inner and outer ClientHellos should include GREASE extensions. 18122 testCases = append(testCases, testCase{ 18123 testType: clientTest, 18124 protocol: protocol, 18125 name: prefix + "ECH-Client-GREASEExtensions", 18126 config: Config{ 18127 ServerECHConfigs: []ServerECHConfig{echConfig}, 18128 Bugs: ProtocolBugs{ 18129 ExpectGREASE: true, 18130 }, 18131 }, 18132 flags: []string{ 18133 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18134 "-expect-ech-accept", 18135 "-enable-grease", 18136 }, 18137 resumeSession: true, 18138 expectations: connectionExpectations{echAccepted: true}, 18139 }) 18140 18141 // Test that the client tolerates unsupported extensions if the 18142 // mandatory bit is not set. 18143 unsupportedExtension := generateServerECHConfig(&ECHConfig{UnsupportedExtension: true}) 18144 testCases = append(testCases, testCase{ 18145 testType: clientTest, 18146 protocol: protocol, 18147 name: prefix + "ECH-Client-UnsupportedExtension", 18148 config: Config{ 18149 ServerECHConfigs: []ServerECHConfig{unsupportedExtension}, 18150 }, 18151 flags: []string{ 18152 "-ech-config-list", base64FlagValue(CreateECHConfigList(unsupportedExtension.ECHConfig.Raw)), 18153 "-expect-ech-accept", 18154 }, 18155 expectations: connectionExpectations{echAccepted: true}, 18156 }) 18157 18158 // Syntax errors in the ECHConfigList should be rejected. 18159 testCases = append(testCases, testCase{ 18160 testType: clientTest, 18161 protocol: protocol, 18162 name: prefix + "ECH-Client-InvalidECHConfigList", 18163 flags: []string{ 18164 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw[1:])), 18165 }, 18166 shouldFail: true, 18167 expectedError: ":INVALID_ECH_CONFIG_LIST:", 18168 }) 18169 18170 // If the ClientHelloInner has no server_name extension, while the 18171 // ClientHelloOuter has one, the client must check for unsolicited 18172 // extensions based on the selected ClientHello. 18173 testCases = append(testCases, testCase{ 18174 testType: clientTest, 18175 protocol: protocol, 18176 name: prefix + "ECH-Client-UnsolicitedInnerServerNameAck", 18177 config: Config{ 18178 ServerECHConfigs: []ServerECHConfig{echConfig}, 18179 Bugs: ProtocolBugs{ 18180 // ClientHelloOuter should have a server name. 18181 ExpectOuterServerName: "public.example", 18182 // The server will acknowledge the server_name extension. 18183 // This option runs whether or not the client requested the 18184 // extension. 18185 SendServerNameAck: true, 18186 }, 18187 }, 18188 flags: []string{ 18189 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18190 // No -host-name flag. 18191 "-expect-ech-accept", 18192 }, 18193 shouldFail: true, 18194 expectedError: ":UNEXPECTED_EXTENSION:", 18195 expectedLocalError: "remote error: unsupported extension", 18196 expectations: connectionExpectations{echAccepted: true}, 18197 }) 18198 18199 // Most extensions are the same between ClientHelloInner and 18200 // ClientHelloOuter and can be compressed. 18201 testCases = append(testCases, testCase{ 18202 testType: clientTest, 18203 protocol: protocol, 18204 name: prefix + "ECH-Client-ExpectECHOuterExtensions", 18205 config: Config{ 18206 ServerECHConfigs: []ServerECHConfig{echConfig}, 18207 NextProtos: []string{"proto"}, 18208 Bugs: ProtocolBugs{ 18209 ExpectECHOuterExtensions: []uint16{ 18210 extensionALPN, 18211 extensionKeyShare, 18212 extensionPSKKeyExchangeModes, 18213 extensionSignatureAlgorithms, 18214 extensionSupportedCurves, 18215 }, 18216 }, 18217 }, 18218 flags: []string{ 18219 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18220 "-expect-ech-accept", 18221 "-advertise-alpn", "\x05proto", 18222 "-expect-alpn", "proto", 18223 "-host-name", "secret.example", 18224 }, 18225 expectations: connectionExpectations{ 18226 echAccepted: true, 18227 nextProto: "proto", 18228 }, 18229 skipQUICALPNConfig: true, 18230 }) 18231 18232 // If the server name happens to match the public name, it still should 18233 // not be compressed. It is not publicly known that they match. 18234 testCases = append(testCases, testCase{ 18235 testType: clientTest, 18236 protocol: protocol, 18237 name: prefix + "ECH-Client-NeverCompressServerName", 18238 config: Config{ 18239 ServerECHConfigs: []ServerECHConfig{echConfig}, 18240 NextProtos: []string{"proto"}, 18241 Bugs: ProtocolBugs{ 18242 ExpectECHUncompressedExtensions: []uint16{extensionServerName}, 18243 ExpectServerName: "public.example", 18244 ExpectOuterServerName: "public.example", 18245 }, 18246 }, 18247 flags: []string{ 18248 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18249 "-expect-ech-accept", 18250 "-host-name", "public.example", 18251 }, 18252 expectations: connectionExpectations{echAccepted: true}, 18253 }) 18254 18255 // If the ClientHelloOuter disables TLS 1.3, e.g. in QUIC, the client 18256 // should also compress supported_versions. 18257 testCases = append(testCases, testCase{ 18258 testType: clientTest, 18259 protocol: protocol, 18260 name: prefix + "ECH-Client-CompressSupportedVersions", 18261 config: Config{ 18262 ServerECHConfigs: []ServerECHConfig{echConfig}, 18263 Bugs: ProtocolBugs{ 18264 ExpectECHOuterExtensions: []uint16{ 18265 extensionSupportedVersions, 18266 }, 18267 }, 18268 }, 18269 flags: []string{ 18270 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18271 "-host-name", "secret.example", 18272 "-expect-ech-accept", 18273 "-min-version", strconv.Itoa(int(VersionTLS13)), 18274 }, 18275 expectations: connectionExpectations{echAccepted: true}, 18276 }) 18277 18278 // Test that the client can still offer server names that exceed the 18279 // maximum name length. It is only a padding hint. 18280 maxNameLen10 := generateServerECHConfig(&ECHConfig{MaxNameLen: 10}) 18281 testCases = append(testCases, testCase{ 18282 testType: clientTest, 18283 protocol: protocol, 18284 name: prefix + "ECH-Client-NameTooLong", 18285 config: Config{ 18286 ServerECHConfigs: []ServerECHConfig{maxNameLen10}, 18287 Bugs: ProtocolBugs{ 18288 ExpectServerName: "test0123456789.example", 18289 }, 18290 }, 18291 flags: []string{ 18292 "-ech-config-list", base64FlagValue(CreateECHConfigList(maxNameLen10.ECHConfig.Raw)), 18293 "-host-name", "test0123456789.example", 18294 "-expect-ech-accept", 18295 }, 18296 expectations: connectionExpectations{echAccepted: true}, 18297 }) 18298 18299 // Test the client can recognize when ECH is rejected. 18300 testCases = append(testCases, testCase{ 18301 testType: clientTest, 18302 protocol: protocol, 18303 name: prefix + "ECH-Client-Reject", 18304 config: Config{ 18305 ServerECHConfigs: []ServerECHConfig{echConfig2, echConfig3}, 18306 Bugs: ProtocolBugs{ 18307 ExpectServerName: "public.example", 18308 }, 18309 }, 18310 flags: []string{ 18311 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18312 "-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw)), 18313 }, 18314 shouldFail: true, 18315 expectedLocalError: "remote error: ECH required", 18316 expectedError: ":ECH_REJECTED:", 18317 }) 18318 testCases = append(testCases, testCase{ 18319 testType: clientTest, 18320 protocol: protocol, 18321 name: prefix + "ECH-Client-Reject-HelloRetryRequest", 18322 config: Config{ 18323 ServerECHConfigs: []ServerECHConfig{echConfig2, echConfig3}, 18324 CurvePreferences: []CurveID{CurveP384}, 18325 Bugs: ProtocolBugs{ 18326 ExpectServerName: "public.example", 18327 ExpectMissingKeyShare: true, // Check we triggered HRR. 18328 }, 18329 }, 18330 flags: []string{ 18331 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18332 "-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw)), 18333 "-expect-hrr", // Check we triggered HRR. 18334 }, 18335 shouldFail: true, 18336 expectedLocalError: "remote error: ECH required", 18337 expectedError: ":ECH_REJECTED:", 18338 }) 18339 testCases = append(testCases, testCase{ 18340 testType: clientTest, 18341 protocol: protocol, 18342 name: prefix + "ECH-Client-Reject-NoRetryConfigs", 18343 config: Config{ 18344 Bugs: ProtocolBugs{ 18345 ExpectServerName: "public.example", 18346 }, 18347 }, 18348 flags: []string{ 18349 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18350 "-expect-no-ech-retry-configs", 18351 }, 18352 shouldFail: true, 18353 expectedLocalError: "remote error: ECH required", 18354 expectedError: ":ECH_REJECTED:", 18355 }) 18356 if protocol != quic { 18357 testCases = append(testCases, testCase{ 18358 testType: clientTest, 18359 protocol: protocol, 18360 name: prefix + "ECH-Client-Reject-TLS12", 18361 config: Config{ 18362 MaxVersion: VersionTLS12, 18363 Bugs: ProtocolBugs{ 18364 ExpectServerName: "public.example", 18365 }, 18366 }, 18367 flags: []string{ 18368 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18369 // TLS 1.2 cannot provide retry configs. 18370 "-expect-no-ech-retry-configs", 18371 }, 18372 shouldFail: true, 18373 expectedLocalError: "remote error: ECH required", 18374 expectedError: ":ECH_REJECTED:", 18375 }) 18376 18377 // Test that the client disables False Start when ECH is rejected. 18378 testCases = append(testCases, testCase{ 18379 name: prefix + "ECH-Client-Reject-TLS12-NoFalseStart", 18380 config: Config{ 18381 MaxVersion: VersionTLS12, 18382 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 18383 NextProtos: []string{"foo"}, 18384 Bugs: ProtocolBugs{ 18385 // The options below cause the server to, immediately 18386 // after client Finished, send an alert and try to read 18387 // application data without sending server Finished. 18388 ExpectFalseStart: true, 18389 AlertBeforeFalseStartTest: alertAccessDenied, 18390 }, 18391 }, 18392 flags: []string{ 18393 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18394 "-false-start", 18395 "-advertise-alpn", "\x03foo", 18396 "-expect-alpn", "foo", 18397 }, 18398 shimWritesFirst: true, 18399 shouldFail: true, 18400 // Ensure the client does not send application data at the False 18401 // Start point. EOF comes from the client closing the connection 18402 // in response ot the alert. 18403 expectedLocalError: "tls: peer did not false start: EOF", 18404 // Ensures the client picks up the alert before reporting an 18405 // authenticated |SSL_R_ECH_REJECTED|. 18406 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 18407 }) 18408 } 18409 18410 // Test that unsupported retry configs in a valid ECHConfigList are 18411 // allowed. They will be skipped when configured in the retry. 18412 retryConfigs := CreateECHConfigList( 18413 unsupportedVersion, 18414 unsupportedKEM.Raw, 18415 unsupportedCipherSuites.Raw, 18416 unsupportedMandatoryExtension.Raw, 18417 echConfig2.ECHConfig.Raw) 18418 testCases = append(testCases, testCase{ 18419 testType: clientTest, 18420 protocol: protocol, 18421 name: prefix + "ECH-Client-Reject-UnsupportedRetryConfigs", 18422 config: Config{ 18423 Bugs: ProtocolBugs{ 18424 SendECHRetryConfigs: retryConfigs, 18425 ExpectServerName: "public.example", 18426 }, 18427 }, 18428 flags: []string{ 18429 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18430 "-expect-ech-retry-configs", base64FlagValue(retryConfigs), 18431 }, 18432 shouldFail: true, 18433 expectedLocalError: "remote error: ECH required", 18434 expectedError: ":ECH_REJECTED:", 18435 }) 18436 18437 // Test that the client rejects ClientHelloOuter handshakes that attempt 18438 // to resume the ClientHelloInner's ticket, at TLS 1.2 and TLS 1.3. 18439 testCases = append(testCases, testCase{ 18440 testType: clientTest, 18441 protocol: protocol, 18442 name: prefix + "ECH-Client-Reject-ResumeInnerSession-TLS13", 18443 config: Config{ 18444 ServerECHConfigs: []ServerECHConfig{echConfig}, 18445 Bugs: ProtocolBugs{ 18446 ExpectServerName: "secret.example", 18447 }, 18448 }, 18449 resumeConfig: &Config{ 18450 MaxVersion: VersionTLS13, 18451 ServerECHConfigs: []ServerECHConfig{echConfig}, 18452 Bugs: ProtocolBugs{ 18453 ExpectServerName: "public.example", 18454 UseInnerSessionWithClientHelloOuter: true, 18455 }, 18456 }, 18457 resumeSession: true, 18458 flags: []string{ 18459 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18460 "-host-name", "secret.example", 18461 "-on-initial-expect-ech-accept", 18462 }, 18463 shouldFail: true, 18464 expectedError: ":UNEXPECTED_EXTENSION:", 18465 expectations: connectionExpectations{echAccepted: true}, 18466 resumeExpectations: &connectionExpectations{echAccepted: false}, 18467 }) 18468 if protocol != quic { 18469 testCases = append(testCases, testCase{ 18470 testType: clientTest, 18471 protocol: protocol, 18472 name: prefix + "ECH-Client-Reject-ResumeInnerSession-TLS12", 18473 config: Config{ 18474 ServerECHConfigs: []ServerECHConfig{echConfig}, 18475 Bugs: ProtocolBugs{ 18476 ExpectServerName: "secret.example", 18477 }, 18478 }, 18479 resumeConfig: &Config{ 18480 MinVersion: VersionTLS12, 18481 MaxVersion: VersionTLS12, 18482 ServerECHConfigs: []ServerECHConfig{echConfig}, 18483 Bugs: ProtocolBugs{ 18484 ExpectServerName: "public.example", 18485 UseInnerSessionWithClientHelloOuter: true, 18486 // The client only ever offers TLS 1.3 sessions in 18487 // ClientHelloInner. AcceptAnySession allows them to be 18488 // resumed at TLS 1.2. 18489 AcceptAnySession: true, 18490 }, 18491 }, 18492 resumeSession: true, 18493 flags: []string{ 18494 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18495 "-host-name", "secret.example", 18496 "-on-initial-expect-ech-accept", 18497 }, 18498 // From the client's perspective, the server echoed a session ID to 18499 // signal resumption, but the selected ClientHello had nothing to 18500 // resume. 18501 shouldFail: true, 18502 expectedError: ":SERVER_ECHOED_INVALID_SESSION_ID:", 18503 expectedLocalError: "remote error: illegal parameter", 18504 expectations: connectionExpectations{echAccepted: true}, 18505 resumeExpectations: &connectionExpectations{echAccepted: false}, 18506 }) 18507 } 18508 18509 // Test that the client can process ECH rejects after an early data reject. 18510 testCases = append(testCases, testCase{ 18511 testType: clientTest, 18512 protocol: protocol, 18513 name: prefix + "ECH-Client-Reject-EarlyDataRejected", 18514 config: Config{ 18515 ServerECHConfigs: []ServerECHConfig{echConfig}, 18516 Bugs: ProtocolBugs{ 18517 ExpectServerName: "secret.example", 18518 }, 18519 }, 18520 resumeConfig: &Config{ 18521 ServerECHConfigs: []ServerECHConfig{echConfig2}, 18522 Bugs: ProtocolBugs{ 18523 ExpectServerName: "public.example", 18524 }, 18525 }, 18526 flags: []string{ 18527 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18528 "-host-name", "secret.example", 18529 // Although the resumption connection does not accept ECH, the 18530 // API will report ECH was accepted at the 0-RTT point. 18531 "-expect-ech-accept", 18532 // -on-retry refers to the retried handshake after 0-RTT reject, 18533 // while ech-retry-configs refers to the ECHConfigs to use in 18534 // the next connection attempt. 18535 "-on-retry-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw)), 18536 }, 18537 resumeSession: true, 18538 expectResumeRejected: true, 18539 earlyData: true, 18540 expectEarlyDataRejected: true, 18541 expectations: connectionExpectations{echAccepted: true}, 18542 resumeExpectations: &connectionExpectations{echAccepted: false}, 18543 shouldFail: true, 18544 expectedLocalError: "remote error: ECH required", 18545 expectedError: ":ECH_REJECTED:", 18546 }) 18547 if protocol != quic { 18548 testCases = append(testCases, testCase{ 18549 testType: clientTest, 18550 protocol: protocol, 18551 name: prefix + "ECH-Client-Reject-EarlyDataRejected-TLS12", 18552 config: Config{ 18553 ServerECHConfigs: []ServerECHConfig{echConfig}, 18554 Bugs: ProtocolBugs{ 18555 ExpectServerName: "secret.example", 18556 }, 18557 }, 18558 resumeConfig: &Config{ 18559 MaxVersion: VersionTLS12, 18560 Bugs: ProtocolBugs{ 18561 ExpectServerName: "public.example", 18562 }, 18563 }, 18564 flags: []string{ 18565 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18566 "-host-name", "secret.example", 18567 // Although the resumption connection does not accept ECH, the 18568 // API will report ECH was accepted at the 0-RTT point. 18569 "-expect-ech-accept", 18570 }, 18571 resumeSession: true, 18572 expectResumeRejected: true, 18573 earlyData: true, 18574 expectEarlyDataRejected: true, 18575 expectations: connectionExpectations{echAccepted: true}, 18576 resumeExpectations: &connectionExpectations{echAccepted: false}, 18577 // ClientHellos with early data cannot negotiate TLS 1.2, with 18578 // or without ECH. The shim should first report 18579 // |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. The caller will then 18580 // repair the first error by retrying without early data. That 18581 // will look like ECH-Client-Reject-TLS12 and select TLS 1.2 18582 // and ClientHelloOuter. The caller will then trigger a third 18583 // attempt, which will succeed. 18584 shouldFail: true, 18585 expectedError: ":WRONG_VERSION_ON_EARLY_DATA:", 18586 }) 18587 } 18588 18589 // Test that the client ignores ECHConfigs with invalid public names. 18590 invalidPublicName := generateServerECHConfig(&ECHConfig{PublicName: "dns_names_have_no_underscores.example"}) 18591 testCases = append(testCases, testCase{ 18592 testType: clientTest, 18593 protocol: protocol, 18594 name: prefix + "ECH-Client-SkipInvalidPublicName", 18595 config: Config{ 18596 Bugs: ProtocolBugs{ 18597 // No ECHConfigs are supported, so the client should fall 18598 // back to cleartext. 18599 ExpectNoClientECH: true, 18600 ExpectServerName: "secret.example", 18601 }, 18602 }, 18603 flags: []string{ 18604 "-ech-config-list", base64FlagValue(CreateECHConfigList(invalidPublicName.ECHConfig.Raw)), 18605 "-host-name", "secret.example", 18606 }, 18607 }) 18608 testCases = append(testCases, testCase{ 18609 testType: clientTest, 18610 protocol: protocol, 18611 name: prefix + "ECH-Client-SkipInvalidPublicName-2", 18612 config: Config{ 18613 // The client should skip |invalidPublicName| and use |echConfig|. 18614 ServerECHConfigs: []ServerECHConfig{echConfig}, 18615 Bugs: ProtocolBugs{ 18616 ExpectOuterServerName: "public.example", 18617 ExpectServerName: "secret.example", 18618 }, 18619 }, 18620 flags: []string{ 18621 "-ech-config-list", base64FlagValue(CreateECHConfigList(invalidPublicName.ECHConfig.Raw, echConfig.ECHConfig.Raw)), 18622 "-host-name", "secret.example", 18623 "-expect-ech-accept", 18624 }, 18625 expectations: connectionExpectations{echAccepted: true}, 18626 }) 18627 18628 // Test both sync and async mode, to test both with and without the 18629 // client certificate callback. 18630 for _, async := range []bool{false, true} { 18631 var flags []string 18632 var suffix string 18633 if async { 18634 flags = []string{"-async"} 18635 suffix = "-Async" 18636 } 18637 18638 // Test that ECH and client certificates can be used together. 18639 testCases = append(testCases, testCase{ 18640 testType: clientTest, 18641 protocol: protocol, 18642 name: prefix + "ECH-Client-ClientCertificate" + suffix, 18643 config: Config{ 18644 ServerECHConfigs: []ServerECHConfig{echConfig}, 18645 ClientAuth: RequireAnyClientCert, 18646 }, 18647 flags: append([]string{ 18648 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 18649 "-key-file", path.Join(*resourceDir, rsaKeyFile), 18650 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18651 "-expect-ech-accept", 18652 }, flags...), 18653 expectations: connectionExpectations{echAccepted: true}, 18654 }) 18655 18656 // Test that, when ECH is rejected, the client does not send a client 18657 // certificate. 18658 testCases = append(testCases, testCase{ 18659 testType: clientTest, 18660 protocol: protocol, 18661 name: prefix + "ECH-Client-Reject-NoClientCertificate-TLS13" + suffix, 18662 config: Config{ 18663 MinVersion: VersionTLS13, 18664 MaxVersion: VersionTLS13, 18665 ClientAuth: RequireAnyClientCert, 18666 }, 18667 flags: append([]string{ 18668 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 18669 "-key-file", path.Join(*resourceDir, rsaKeyFile), 18670 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18671 }, flags...), 18672 shouldFail: true, 18673 expectedLocalError: "tls: client didn't provide a certificate", 18674 }) 18675 if protocol != quic { 18676 testCases = append(testCases, testCase{ 18677 testType: clientTest, 18678 protocol: protocol, 18679 name: prefix + "ECH-Client-Reject-NoClientCertificate-TLS12" + suffix, 18680 config: Config{ 18681 MinVersion: VersionTLS12, 18682 MaxVersion: VersionTLS12, 18683 ClientAuth: RequireAnyClientCert, 18684 }, 18685 flags: append([]string{ 18686 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 18687 "-key-file", path.Join(*resourceDir, rsaKeyFile), 18688 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18689 }, flags...), 18690 shouldFail: true, 18691 expectedLocalError: "tls: client didn't provide a certificate", 18692 }) 18693 } 18694 } 18695 18696 // Test that ECH and Channel ID can be used together. 18697 testCases = append(testCases, testCase{ 18698 testType: clientTest, 18699 protocol: protocol, 18700 name: prefix + "ECH-Client-ChannelID", 18701 config: Config{ 18702 ServerECHConfigs: []ServerECHConfig{echConfig}, 18703 RequestChannelID: true, 18704 }, 18705 flags: []string{ 18706 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 18707 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18708 "-expect-ech-accept", 18709 }, 18710 resumeSession: true, 18711 expectations: connectionExpectations{ 18712 channelID: true, 18713 echAccepted: true, 18714 }, 18715 }) 18716 18717 // Handshakes where ECH is rejected do not offer or accept Channel ID. 18718 testCases = append(testCases, testCase{ 18719 testType: clientTest, 18720 protocol: protocol, 18721 name: prefix + "ECH-Client-Reject-NoChannelID-TLS13", 18722 config: Config{ 18723 MinVersion: VersionTLS13, 18724 MaxVersion: VersionTLS13, 18725 Bugs: ProtocolBugs{ 18726 AlwaysNegotiateChannelID: true, 18727 }, 18728 }, 18729 flags: []string{ 18730 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 18731 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18732 }, 18733 shouldFail: true, 18734 expectedLocalError: "remote error: unsupported extension", 18735 expectedError: ":UNEXPECTED_EXTENSION:", 18736 }) 18737 if protocol != quic { 18738 testCases = append(testCases, testCase{ 18739 testType: clientTest, 18740 protocol: protocol, 18741 name: prefix + "ECH-Client-Reject-NoChannelID-TLS12", 18742 config: Config{ 18743 MinVersion: VersionTLS12, 18744 MaxVersion: VersionTLS12, 18745 Bugs: ProtocolBugs{ 18746 AlwaysNegotiateChannelID: true, 18747 }, 18748 }, 18749 flags: []string{ 18750 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 18751 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18752 }, 18753 shouldFail: true, 18754 expectedLocalError: "remote error: unsupported extension", 18755 expectedError: ":UNEXPECTED_EXTENSION:", 18756 }) 18757 } 18758 18759 // Test that ECH correctly overrides the host name for certificate 18760 // verification. 18761 testCases = append(testCases, testCase{ 18762 testType: clientTest, 18763 protocol: protocol, 18764 name: prefix + "ECH-Client-NotOffered-NoOverrideName", 18765 flags: []string{ 18766 "-verify-peer", 18767 "-use-custom-verify-callback", 18768 // When not offering ECH, verify the usual name in both full 18769 // and resumption handshakes. 18770 "-reverify-on-resume", 18771 "-expect-no-ech-name-override", 18772 }, 18773 resumeSession: true, 18774 }) 18775 testCases = append(testCases, testCase{ 18776 testType: clientTest, 18777 protocol: protocol, 18778 name: prefix + "ECH-Client-GREASE-NoOverrideName", 18779 flags: []string{ 18780 "-verify-peer", 18781 "-use-custom-verify-callback", 18782 "-enable-ech-grease", 18783 // When offering ECH GREASE, verify the usual name in both full 18784 // and resumption handshakes. 18785 "-reverify-on-resume", 18786 "-expect-no-ech-name-override", 18787 }, 18788 resumeSession: true, 18789 }) 18790 if protocol != quic { 18791 testCases = append(testCases, testCase{ 18792 testType: clientTest, 18793 protocol: protocol, 18794 name: prefix + "ECH-Client-Rejected-OverrideName-TLS12", 18795 config: Config{ 18796 MinVersion: VersionTLS12, 18797 MaxVersion: VersionTLS12, 18798 }, 18799 flags: []string{ 18800 "-verify-peer", 18801 "-use-custom-verify-callback", 18802 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18803 // When ECH is rejected, verify the public name. This can 18804 // only happen in full handshakes. 18805 "-expect-ech-name-override", "public.example", 18806 }, 18807 shouldFail: true, 18808 expectedError: ":ECH_REJECTED:", 18809 expectedLocalError: "remote error: ECH required", 18810 }) 18811 } 18812 testCases = append(testCases, testCase{ 18813 testType: clientTest, 18814 protocol: protocol, 18815 name: prefix + "ECH-Client-Reject-OverrideName-TLS13", 18816 config: Config{ 18817 MinVersion: VersionTLS13, 18818 MaxVersion: VersionTLS13, 18819 }, 18820 flags: []string{ 18821 "-verify-peer", 18822 "-use-custom-verify-callback", 18823 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18824 // When ECH is rejected, verify the public name. This can 18825 // only happen in full handshakes. 18826 "-expect-ech-name-override", "public.example", 18827 }, 18828 shouldFail: true, 18829 expectedError: ":ECH_REJECTED:", 18830 expectedLocalError: "remote error: ECH required", 18831 }) 18832 testCases = append(testCases, testCase{ 18833 testType: clientTest, 18834 protocol: protocol, 18835 name: prefix + "ECH-Client-Accept-NoOverrideName", 18836 config: Config{ 18837 ServerECHConfigs: []ServerECHConfig{echConfig}, 18838 }, 18839 flags: []string{ 18840 "-verify-peer", 18841 "-use-custom-verify-callback", 18842 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18843 "-expect-ech-accept", 18844 // When ECH is accepted, verify the usual name in both full and 18845 // resumption handshakes. 18846 "-reverify-on-resume", 18847 "-expect-no-ech-name-override", 18848 }, 18849 resumeSession: true, 18850 expectations: connectionExpectations{echAccepted: true}, 18851 }) 18852 testCases = append(testCases, testCase{ 18853 testType: clientTest, 18854 protocol: protocol, 18855 name: prefix + "ECH-Client-Reject-EarlyDataRejected-OverrideNameOnRetry", 18856 config: Config{ 18857 ServerECHConfigs: []ServerECHConfig{echConfig}, 18858 }, 18859 resumeConfig: &Config{}, 18860 flags: []string{ 18861 "-verify-peer", 18862 "-use-custom-verify-callback", 18863 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18864 // Although the resumption connection does not accept ECH, the 18865 // API will report ECH was accepted at the 0-RTT point. 18866 "-expect-ech-accept", 18867 // The resumption connection verifies certificates twice. First, 18868 // if reverification is enabled, we verify the 0-RTT certificate 18869 // as if ECH as accepted. There should be no name override. 18870 // Next, on the post-0-RTT-rejection retry, we verify the new 18871 // server certificate. This picks up the ECH reject, so it 18872 // should use public.example. 18873 "-reverify-on-resume", 18874 "-on-resume-expect-no-ech-name-override", 18875 "-on-retry-expect-ech-name-override", "public.example", 18876 }, 18877 resumeSession: true, 18878 expectResumeRejected: true, 18879 earlyData: true, 18880 expectEarlyDataRejected: true, 18881 expectations: connectionExpectations{echAccepted: true}, 18882 resumeExpectations: &connectionExpectations{echAccepted: false}, 18883 shouldFail: true, 18884 expectedError: ":ECH_REJECTED:", 18885 expectedLocalError: "remote error: ECH required", 18886 }) 18887 18888 // Test that the client checks both HelloRetryRequest and ServerHello 18889 // for a confirmation signal. 18890 testCases = append(testCases, testCase{ 18891 testType: clientTest, 18892 protocol: protocol, 18893 name: prefix + "ECH-Client-HelloRetryRequest-MissingServerHelloConfirmation", 18894 config: Config{ 18895 MinVersion: VersionTLS13, 18896 MaxVersion: VersionTLS13, 18897 CurvePreferences: []CurveID{CurveP384}, 18898 ServerECHConfigs: []ServerECHConfig{echConfig}, 18899 Bugs: ProtocolBugs{ 18900 ExpectMissingKeyShare: true, // Check we triggered HRR. 18901 OmitServerHelloECHConfirmation: true, 18902 }, 18903 }, 18904 resumeSession: true, 18905 flags: []string{ 18906 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18907 "-expect-hrr", // Check we triggered HRR. 18908 }, 18909 shouldFail: true, 18910 expectedError: ":INCONSISTENT_ECH_NEGOTIATION:", 18911 }) 18912 18913 // Test the message callback is correctly reported, with and without 18914 // HelloRetryRequest. 18915 clientAndServerHello := "write clienthelloinner\nwrite hs 1\nread hs 2\n" 18916 // EncryptedExtensions onwards. 18917 finishHandshake := `read hs 8 18918read hs 11 18919read hs 15 18920read hs 20 18921write hs 20 18922read hs 4 18923read hs 4 18924` 18925 testCases = append(testCases, testCase{ 18926 testType: clientTest, 18927 protocol: protocol, 18928 name: prefix + "ECH-Client-MessageCallback", 18929 config: Config{ 18930 MinVersion: VersionTLS13, 18931 MaxVersion: VersionTLS13, 18932 ServerECHConfigs: []ServerECHConfig{echConfig}, 18933 Bugs: ProtocolBugs{ 18934 NoCloseNotify: true, // Align QUIC and TCP traces. 18935 }, 18936 }, 18937 flags: []string{ 18938 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18939 "-expect-ech-accept", 18940 "-expect-msg-callback", clientAndServerHello + "write ccs\n" + finishHandshake, 18941 }, 18942 expectations: connectionExpectations{echAccepted: true}, 18943 }) 18944 testCases = append(testCases, testCase{ 18945 testType: clientTest, 18946 protocol: protocol, 18947 name: prefix + "ECH-Client-MessageCallback-HelloRetryRequest", 18948 config: Config{ 18949 MinVersion: VersionTLS13, 18950 MaxVersion: VersionTLS13, 18951 CurvePreferences: []CurveID{CurveP384}, 18952 ServerECHConfigs: []ServerECHConfig{echConfig}, 18953 Bugs: ProtocolBugs{ 18954 ExpectMissingKeyShare: true, // Check we triggered HRR. 18955 NoCloseNotify: true, // Align QUIC and TCP traces. 18956 }, 18957 }, 18958 flags: []string{ 18959 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18960 "-expect-ech-accept", 18961 "-expect-hrr", // Check we triggered HRR. 18962 "-expect-msg-callback", clientAndServerHello + "write ccs\n" + clientAndServerHello + finishHandshake, 18963 }, 18964 expectations: connectionExpectations{echAccepted: true}, 18965 }) 18966 } 18967} 18968 18969func addHintMismatchTests() { 18970 // Each of these tests skips split handshakes because split handshakes does 18971 // not handle a mismatch between shim and handshaker. Handshake hints, 18972 // however, are designed to tolerate the mismatch. 18973 // 18974 // Note also these tests do not specify -handshake-hints directly. Instead, 18975 // we define normal tests, that run even without a handshaker, and rely on 18976 // convertToSplitHandshakeTests to generate a handshaker hints variant. This 18977 // avoids repeating the -is-handshaker-supported and -handshaker-path logic. 18978 // (While not useful, the tests will still pass without a handshaker.) 18979 for _, protocol := range []protocol{tls, quic} { 18980 // If the signing payload is different, the handshake still completes 18981 // successfully. Different ALPN preferences will trigger a mismatch. 18982 testCases = append(testCases, testCase{ 18983 name: protocol.String() + "-HintMismatch-SignatureInput", 18984 testType: serverTest, 18985 protocol: protocol, 18986 skipSplitHandshake: true, 18987 config: Config{ 18988 MinVersion: VersionTLS13, 18989 MaxVersion: VersionTLS13, 18990 NextProtos: []string{"foo", "bar"}, 18991 }, 18992 flags: []string{ 18993 "-allow-hint-mismatch", 18994 "-on-shim-select-alpn", "foo", 18995 "-on-handshaker-select-alpn", "bar", 18996 }, 18997 expectations: connectionExpectations{ 18998 nextProto: "foo", 18999 nextProtoType: alpn, 19000 }, 19001 }) 19002 19003 // The shim and handshaker may have different curve preferences. 19004 testCases = append(testCases, testCase{ 19005 name: protocol.String() + "-HintMismatch-KeyShare", 19006 testType: serverTest, 19007 protocol: protocol, 19008 skipSplitHandshake: true, 19009 config: Config{ 19010 MinVersion: VersionTLS13, 19011 MaxVersion: VersionTLS13, 19012 // Send both curves in the key share list, to avoid getting 19013 // mixed up with HelloRetryRequest. 19014 DefaultCurves: []CurveID{CurveX25519, CurveP256}, 19015 }, 19016 flags: []string{ 19017 "-allow-hint-mismatch", 19018 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 19019 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 19020 }, 19021 expectations: connectionExpectations{ 19022 curveID: CurveX25519, 19023 }, 19024 }) 19025 if protocol != quic { 19026 testCases = append(testCases, testCase{ 19027 name: protocol.String() + "-HintMismatch-ECDHE-Group", 19028 testType: serverTest, 19029 protocol: protocol, 19030 skipSplitHandshake: true, 19031 config: Config{ 19032 MinVersion: VersionTLS12, 19033 MaxVersion: VersionTLS12, 19034 DefaultCurves: []CurveID{CurveX25519, CurveP256}, 19035 }, 19036 flags: []string{ 19037 "-allow-hint-mismatch", 19038 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 19039 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 19040 }, 19041 expectations: connectionExpectations{ 19042 curveID: CurveX25519, 19043 }, 19044 }) 19045 } 19046 19047 // If the handshaker does HelloRetryRequest, it will omit most hints. 19048 // The shim should still work. 19049 testCases = append(testCases, testCase{ 19050 name: protocol.String() + "-HintMismatch-HandshakerHelloRetryRequest", 19051 testType: serverTest, 19052 protocol: protocol, 19053 skipSplitHandshake: true, 19054 config: Config{ 19055 MinVersion: VersionTLS13, 19056 MaxVersion: VersionTLS13, 19057 DefaultCurves: []CurveID{CurveX25519}, 19058 }, 19059 flags: []string{ 19060 "-allow-hint-mismatch", 19061 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 19062 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 19063 }, 19064 expectations: connectionExpectations{ 19065 curveID: CurveX25519, 19066 }, 19067 }) 19068 19069 // If the shim does HelloRetryRequest, the hints from the handshaker 19070 // will be ignored. This is not reported as a mismatch because hints 19071 // would not have helped the shim anyway. 19072 testCases = append(testCases, testCase{ 19073 name: protocol.String() + "-HintMismatch-ShimHelloRetryRequest", 19074 testType: serverTest, 19075 protocol: protocol, 19076 skipSplitHandshake: true, 19077 config: Config{ 19078 MinVersion: VersionTLS13, 19079 MaxVersion: VersionTLS13, 19080 DefaultCurves: []CurveID{CurveX25519}, 19081 }, 19082 flags: []string{ 19083 "-on-shim-curves", strconv.Itoa(int(CurveP256)), 19084 "-on-handshaker-curves", strconv.Itoa(int(CurveX25519)), 19085 }, 19086 expectations: connectionExpectations{ 19087 curveID: CurveP256, 19088 }, 19089 }) 19090 19091 // The shim and handshaker may have different signature algorithm 19092 // preferences. 19093 testCases = append(testCases, testCase{ 19094 name: protocol.String() + "-HintMismatch-SignatureAlgorithm-TLS13", 19095 testType: serverTest, 19096 protocol: protocol, 19097 skipSplitHandshake: true, 19098 config: Config{ 19099 MinVersion: VersionTLS13, 19100 MaxVersion: VersionTLS13, 19101 VerifySignatureAlgorithms: []signatureAlgorithm{ 19102 signatureRSAPSSWithSHA256, 19103 signatureRSAPSSWithSHA384, 19104 }, 19105 }, 19106 flags: []string{ 19107 "-allow-hint-mismatch", 19108 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 19109 "-key-file", path.Join(*resourceDir, rsaKeyFile), 19110 "-on-shim-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 19111 "-on-handshaker-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 19112 }, 19113 expectations: connectionExpectations{ 19114 peerSignatureAlgorithm: signatureRSAPSSWithSHA256, 19115 }, 19116 }) 19117 if protocol != quic { 19118 testCases = append(testCases, testCase{ 19119 name: protocol.String() + "-HintMismatch-SignatureAlgorithm-TLS12", 19120 testType: serverTest, 19121 protocol: protocol, 19122 skipSplitHandshake: true, 19123 config: Config{ 19124 MinVersion: VersionTLS12, 19125 MaxVersion: VersionTLS12, 19126 VerifySignatureAlgorithms: []signatureAlgorithm{ 19127 signatureRSAPSSWithSHA256, 19128 signatureRSAPSSWithSHA384, 19129 }, 19130 }, 19131 flags: []string{ 19132 "-allow-hint-mismatch", 19133 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 19134 "-key-file", path.Join(*resourceDir, rsaKeyFile), 19135 "-on-shim-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 19136 "-on-handshaker-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 19137 }, 19138 expectations: connectionExpectations{ 19139 peerSignatureAlgorithm: signatureRSAPSSWithSHA256, 19140 }, 19141 }) 19142 } 19143 19144 // The shim and handshaker may disagree on whether resumption is allowed. 19145 // We run the first connection with tickets enabled, so the client is 19146 // issued a ticket, then disable tickets on the second connection. 19147 testCases = append(testCases, testCase{ 19148 name: protocol.String() + "-HintMismatch-NoTickets1-TLS13", 19149 testType: serverTest, 19150 protocol: protocol, 19151 skipSplitHandshake: true, 19152 config: Config{ 19153 MinVersion: VersionTLS13, 19154 MaxVersion: VersionTLS13, 19155 }, 19156 flags: []string{ 19157 "-on-resume-allow-hint-mismatch", 19158 "-on-shim-on-resume-no-ticket", 19159 }, 19160 resumeSession: true, 19161 expectResumeRejected: true, 19162 }) 19163 testCases = append(testCases, testCase{ 19164 name: protocol.String() + "-HintMismatch-NoTickets2-TLS13", 19165 testType: serverTest, 19166 protocol: protocol, 19167 skipSplitHandshake: true, 19168 config: Config{ 19169 MinVersion: VersionTLS13, 19170 MaxVersion: VersionTLS13, 19171 }, 19172 flags: []string{ 19173 "-on-resume-allow-hint-mismatch", 19174 "-on-handshaker-on-resume-no-ticket", 19175 }, 19176 resumeSession: true, 19177 }) 19178 if protocol != quic { 19179 testCases = append(testCases, testCase{ 19180 name: protocol.String() + "-HintMismatch-NoTickets1-TLS12", 19181 testType: serverTest, 19182 protocol: protocol, 19183 skipSplitHandshake: true, 19184 config: Config{ 19185 MinVersion: VersionTLS12, 19186 MaxVersion: VersionTLS12, 19187 }, 19188 flags: []string{ 19189 "-on-resume-allow-hint-mismatch", 19190 "-on-shim-on-resume-no-ticket", 19191 }, 19192 resumeSession: true, 19193 expectResumeRejected: true, 19194 }) 19195 testCases = append(testCases, testCase{ 19196 name: protocol.String() + "-HintMismatch-NoTickets2-TLS12", 19197 testType: serverTest, 19198 protocol: protocol, 19199 skipSplitHandshake: true, 19200 config: Config{ 19201 MinVersion: VersionTLS12, 19202 MaxVersion: VersionTLS12, 19203 }, 19204 flags: []string{ 19205 "-on-resume-allow-hint-mismatch", 19206 "-on-handshaker-on-resume-no-ticket", 19207 }, 19208 resumeSession: true, 19209 }) 19210 } 19211 19212 // The shim and handshaker may disagree on whether to request a client 19213 // certificate. 19214 testCases = append(testCases, testCase{ 19215 name: protocol.String() + "-HintMismatch-CertificateRequest", 19216 testType: serverTest, 19217 protocol: protocol, 19218 skipSplitHandshake: true, 19219 config: Config{ 19220 MinVersion: VersionTLS13, 19221 MaxVersion: VersionTLS13, 19222 Certificates: []Certificate{rsaCertificate}, 19223 }, 19224 flags: []string{ 19225 "-allow-hint-mismatch", 19226 "-on-shim-require-any-client-certificate", 19227 }, 19228 }) 19229 19230 // The shim and handshaker may negotiate different versions altogether. 19231 if protocol != quic { 19232 testCases = append(testCases, testCase{ 19233 name: protocol.String() + "-HintMismatch-Version1", 19234 testType: serverTest, 19235 protocol: protocol, 19236 skipSplitHandshake: true, 19237 config: Config{ 19238 MinVersion: VersionTLS12, 19239 MaxVersion: VersionTLS13, 19240 }, 19241 flags: []string{ 19242 "-allow-hint-mismatch", 19243 "-on-shim-max-version", strconv.Itoa(VersionTLS12), 19244 "-on-handshaker-max-version", strconv.Itoa(VersionTLS13), 19245 }, 19246 expectations: connectionExpectations{ 19247 version: VersionTLS12, 19248 }, 19249 }) 19250 testCases = append(testCases, testCase{ 19251 name: protocol.String() + "-HintMismatch-Version2", 19252 testType: serverTest, 19253 protocol: protocol, 19254 skipSplitHandshake: true, 19255 config: Config{ 19256 MinVersion: VersionTLS12, 19257 MaxVersion: VersionTLS13, 19258 }, 19259 flags: []string{ 19260 "-allow-hint-mismatch", 19261 "-on-shim-max-version", strconv.Itoa(VersionTLS13), 19262 "-on-handshaker-max-version", strconv.Itoa(VersionTLS12), 19263 }, 19264 expectations: connectionExpectations{ 19265 version: VersionTLS13, 19266 }, 19267 }) 19268 } 19269 19270 // The shim and handshaker may disagree on the certificate compression 19271 // algorithm, whether to enable certificate compression, or certificate 19272 // compression inputs. 19273 testCases = append(testCases, testCase{ 19274 name: protocol.String() + "-HintMismatch-CertificateCompression-ShimOnly", 19275 testType: serverTest, 19276 protocol: protocol, 19277 skipSplitHandshake: true, 19278 config: Config{ 19279 MinVersion: VersionTLS13, 19280 MaxVersion: VersionTLS13, 19281 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19282 shrinkingCompressionAlgID: shrinkingCompression, 19283 }, 19284 Bugs: ProtocolBugs{ 19285 ExpectedCompressedCert: shrinkingCompressionAlgID, 19286 }, 19287 }, 19288 flags: []string{ 19289 "-allow-hint-mismatch", 19290 "-on-shim-install-cert-compression-algs", 19291 }, 19292 }) 19293 testCases = append(testCases, testCase{ 19294 name: protocol.String() + "-HintMismatch-CertificateCompression-HandshakerOnly", 19295 testType: serverTest, 19296 protocol: protocol, 19297 skipSplitHandshake: true, 19298 config: Config{ 19299 MinVersion: VersionTLS13, 19300 MaxVersion: VersionTLS13, 19301 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19302 shrinkingCompressionAlgID: shrinkingCompression, 19303 }, 19304 Bugs: ProtocolBugs{ 19305 ExpectUncompressedCert: true, 19306 }, 19307 }, 19308 flags: []string{ 19309 "-allow-hint-mismatch", 19310 "-on-handshaker-install-cert-compression-algs", 19311 }, 19312 }) 19313 testCases = append(testCases, testCase{ 19314 testType: serverTest, 19315 name: protocol.String() + "-HintMismatch-CertificateCompression-AlgorithmMismatch", 19316 protocol: protocol, 19317 skipSplitHandshake: true, 19318 config: Config{ 19319 MinVersion: VersionTLS13, 19320 MaxVersion: VersionTLS13, 19321 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19322 shrinkingCompressionAlgID: shrinkingCompression, 19323 expandingCompressionAlgID: expandingCompression, 19324 }, 19325 Bugs: ProtocolBugs{ 19326 // The shim's preferences should take effect. 19327 ExpectedCompressedCert: shrinkingCompressionAlgID, 19328 }, 19329 }, 19330 flags: []string{ 19331 "-allow-hint-mismatch", 19332 "-on-shim-install-one-cert-compression-alg", strconv.Itoa(shrinkingCompressionAlgID), 19333 "-on-handshaker-install-one-cert-compression-alg", strconv.Itoa(expandingCompressionAlgID), 19334 }, 19335 }) 19336 testCases = append(testCases, testCase{ 19337 testType: serverTest, 19338 name: protocol.String() + "-HintMismatch-CertificateCompression-InputMismatch", 19339 protocol: protocol, 19340 skipSplitHandshake: true, 19341 config: Config{ 19342 MinVersion: VersionTLS13, 19343 MaxVersion: VersionTLS13, 19344 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19345 shrinkingCompressionAlgID: shrinkingCompression, 19346 }, 19347 Bugs: ProtocolBugs{ 19348 ExpectedCompressedCert: shrinkingCompressionAlgID, 19349 }, 19350 }, 19351 flags: []string{ 19352 "-allow-hint-mismatch", 19353 "-install-cert-compression-algs", 19354 // Configure the shim and handshaker with different OCSP 19355 // responses, so the compression inputs do not match. 19356 "-on-shim-ocsp-response", base64FlagValue(testOCSPResponse), 19357 "-on-handshaker-ocsp-response", base64FlagValue(testOCSPResponse2), 19358 }, 19359 expectations: connectionExpectations{ 19360 // The shim's configuration should take precendence. 19361 ocspResponse: testOCSPResponse, 19362 }, 19363 }) 19364 19365 // The shim and handshaker may disagree on cipher suite, to the point 19366 // that one selects RSA key exchange (no applicable hint) and the other 19367 // selects ECDHE_RSA (hints are useful). 19368 if protocol != quic { 19369 testCases = append(testCases, testCase{ 19370 testType: serverTest, 19371 name: protocol.String() + "-HintMismatch-CipherMismatch1", 19372 protocol: protocol, 19373 skipSplitHandshake: true, 19374 config: Config{ 19375 MinVersion: VersionTLS12, 19376 MaxVersion: VersionTLS12, 19377 }, 19378 flags: []string{ 19379 "-allow-hint-mismatch", 19380 "-on-shim-cipher", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 19381 "-on-handshaker-cipher", "TLS_RSA_WITH_AES_128_GCM_SHA256", 19382 }, 19383 expectations: connectionExpectations{ 19384 cipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 19385 }, 19386 }) 19387 testCases = append(testCases, testCase{ 19388 testType: serverTest, 19389 name: protocol.String() + "-HintMismatch-CipherMismatch2", 19390 protocol: protocol, 19391 skipSplitHandshake: true, 19392 config: Config{ 19393 MinVersion: VersionTLS12, 19394 MaxVersion: VersionTLS12, 19395 }, 19396 flags: []string{ 19397 // There is no need to pass -allow-hint-mismatch. The 19398 // handshaker will unnecessarily generate a signature hints. 19399 // This is not reported as a mismatch because hints would 19400 // not have helped the shim anyway. 19401 "-on-shim-cipher", "TLS_RSA_WITH_AES_128_GCM_SHA256", 19402 "-on-handshaker-cipher", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 19403 }, 19404 expectations: connectionExpectations{ 19405 cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, 19406 }, 19407 }) 19408 } 19409 } 19410} 19411 19412func addCompliancePolicyTests() { 19413 for _, protocol := range []protocol{tls, quic} { 19414 for _, suite := range testCipherSuites { 19415 var isFIPSCipherSuite bool 19416 switch suite.id { 19417 case TLS_AES_128_GCM_SHA256, 19418 TLS_AES_256_GCM_SHA384, 19419 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 19420 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 19421 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 19422 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: 19423 isFIPSCipherSuite = true 19424 } 19425 19426 var isWPACipherSuite bool 19427 switch suite.id { 19428 case TLS_AES_256_GCM_SHA384, 19429 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 19430 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: 19431 isWPACipherSuite = true 19432 } 19433 19434 var certFile string 19435 var keyFile string 19436 var certs []Certificate 19437 if hasComponent(suite.name, "ECDSA") { 19438 certFile = ecdsaP384CertificateFile 19439 keyFile = ecdsaP384KeyFile 19440 certs = []Certificate{ecdsaP384Certificate} 19441 } else { 19442 certFile = rsaCertificateFile 19443 keyFile = rsaKeyFile 19444 certs = []Certificate{rsaCertificate} 19445 } 19446 19447 maxVersion := uint16(VersionTLS13) 19448 if !isTLS13Suite(suite.name) { 19449 if protocol == quic { 19450 continue 19451 } 19452 maxVersion = VersionTLS12 19453 } 19454 19455 policies := []struct { 19456 flag string 19457 cipherSuiteOk bool 19458 }{ 19459 {"-fips-202205", isFIPSCipherSuite}, 19460 {"-wpa-202304", isWPACipherSuite}, 19461 } 19462 19463 for _, policy := range policies { 19464 testCases = append(testCases, testCase{ 19465 testType: serverTest, 19466 protocol: protocol, 19467 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + suite.name, 19468 config: Config{ 19469 MinVersion: VersionTLS12, 19470 MaxVersion: maxVersion, 19471 CipherSuites: []uint16{suite.id}, 19472 }, 19473 certFile: certFile, 19474 keyFile: keyFile, 19475 flags: []string{ 19476 policy.flag, 19477 }, 19478 shouldFail: !policy.cipherSuiteOk, 19479 }) 19480 19481 testCases = append(testCases, testCase{ 19482 testType: clientTest, 19483 protocol: protocol, 19484 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + suite.name, 19485 config: Config{ 19486 MinVersion: VersionTLS12, 19487 MaxVersion: maxVersion, 19488 CipherSuites: []uint16{suite.id}, 19489 Certificates: certs, 19490 }, 19491 flags: []string{ 19492 policy.flag, 19493 }, 19494 shouldFail: !policy.cipherSuiteOk, 19495 }) 19496 } 19497 } 19498 19499 // Check that a TLS 1.3 client won't accept ChaCha20 even if the server 19500 // picks it without it being in the client's cipher list. 19501 testCases = append(testCases, testCase{ 19502 testType: clientTest, 19503 protocol: protocol, 19504 name: "Compliance-fips202205-" + protocol.String() + "-Client-ReallyWontAcceptChaCha", 19505 config: Config{ 19506 MinVersion: VersionTLS12, 19507 MaxVersion: maxVersion, 19508 Bugs: ProtocolBugs{ 19509 SendCipherSuite: TLS_CHACHA20_POLY1305_SHA256, 19510 }, 19511 }, 19512 flags: []string{ 19513 "-fips-202205", 19514 }, 19515 shouldFail: true, 19516 expectedError: ":WRONG_CIPHER_RETURNED:", 19517 }) 19518 19519 for _, curve := range testCurves { 19520 var isFIPSCurve bool 19521 switch curve.id { 19522 case CurveP256, CurveP384: 19523 isFIPSCurve = true 19524 } 19525 19526 var isWPACurve bool 19527 switch curve.id { 19528 case CurveP384: 19529 isWPACurve = true 19530 } 19531 19532 policies := []struct { 19533 flag string 19534 curveOk bool 19535 }{ 19536 {"-fips-202205", isFIPSCurve}, 19537 {"-wpa-202304", isWPACurve}, 19538 } 19539 19540 for _, policy := range policies { 19541 testCases = append(testCases, testCase{ 19542 testType: serverTest, 19543 protocol: protocol, 19544 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + curve.name, 19545 config: Config{ 19546 MinVersion: VersionTLS12, 19547 MaxVersion: VersionTLS13, 19548 CurvePreferences: []CurveID{curve.id}, 19549 }, 19550 flags: []string{ 19551 policy.flag, 19552 }, 19553 shouldFail: !policy.curveOk, 19554 }) 19555 19556 testCases = append(testCases, testCase{ 19557 testType: clientTest, 19558 protocol: protocol, 19559 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + curve.name, 19560 config: Config{ 19561 MinVersion: VersionTLS12, 19562 MaxVersion: VersionTLS13, 19563 CurvePreferences: []CurveID{curve.id}, 19564 }, 19565 flags: []string{ 19566 policy.flag, 19567 }, 19568 shouldFail: !policy.curveOk, 19569 }) 19570 } 19571 } 19572 19573 for _, sigalg := range testSignatureAlgorithms { 19574 var isFIPSSigAlg bool 19575 switch sigalg.id { 19576 case signatureRSAPKCS1WithSHA256, 19577 signatureRSAPKCS1WithSHA384, 19578 signatureRSAPKCS1WithSHA512, 19579 signatureECDSAWithP256AndSHA256, 19580 signatureECDSAWithP384AndSHA384, 19581 signatureRSAPSSWithSHA256, 19582 signatureRSAPSSWithSHA384, 19583 signatureRSAPSSWithSHA512: 19584 isFIPSSigAlg = true 19585 } 19586 19587 var isWPASigAlg bool 19588 switch sigalg.id { 19589 case signatureRSAPKCS1WithSHA384, 19590 signatureRSAPKCS1WithSHA512, 19591 signatureECDSAWithP384AndSHA384, 19592 signatureRSAPSSWithSHA384, 19593 signatureRSAPSSWithSHA512: 19594 isWPASigAlg = true 19595 } 19596 19597 if sigalg.cert == testCertECDSAP224 { 19598 // This can work in TLS 1.2, but not with TLS 1.3. 19599 // For consistency it's not permitted in FIPS mode. 19600 isFIPSSigAlg = false 19601 } 19602 19603 maxVersion := uint16(VersionTLS13) 19604 if hasComponent(sigalg.name, "PKCS1") { 19605 if protocol == quic { 19606 continue 19607 } 19608 maxVersion = VersionTLS12 19609 } 19610 19611 policies := []struct { 19612 flag string 19613 sigAlgOk bool 19614 }{ 19615 {"-fips-202205", isFIPSSigAlg}, 19616 {"-wpa-202304", isWPASigAlg}, 19617 } 19618 19619 for _, policy := range policies { 19620 testCases = append(testCases, testCase{ 19621 testType: serverTest, 19622 protocol: protocol, 19623 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + sigalg.name, 19624 config: Config{ 19625 MinVersion: VersionTLS12, 19626 MaxVersion: maxVersion, 19627 VerifySignatureAlgorithms: []signatureAlgorithm{sigalg.id}, 19628 }, 19629 flags: []string{ 19630 policy.flag, 19631 "-cert-file", path.Join(*resourceDir, getShimCertificate(sigalg.cert)), 19632 "-key-file", path.Join(*resourceDir, getShimKey(sigalg.cert)), 19633 }, 19634 shouldFail: !policy.sigAlgOk, 19635 }) 19636 19637 testCases = append(testCases, testCase{ 19638 testType: clientTest, 19639 protocol: protocol, 19640 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + sigalg.name, 19641 config: Config{ 19642 MinVersion: VersionTLS12, 19643 MaxVersion: maxVersion, 19644 SignSignatureAlgorithms: []signatureAlgorithm{sigalg.id}, 19645 Certificates: []Certificate{getRunnerCertificate(sigalg.cert)}, 19646 }, 19647 flags: []string{ 19648 policy.flag, 19649 }, 19650 shouldFail: !policy.sigAlgOk, 19651 }) 19652 } 19653 } 19654 } 19655} 19656 19657func worker(dispatcher *shimDispatcher, statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { 19658 defer wg.Done() 19659 19660 for test := range c { 19661 var err error 19662 19663 if *mallocTest >= 0 { 19664 for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ { 19665 statusChan <- statusMsg{test: test, statusType: statusStarted} 19666 if err = runTest(dispatcher, statusChan, test, shimPath, mallocNumToFail); err != errMoreMallocs { 19667 if err != nil { 19668 fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err) 19669 } 19670 break 19671 } 19672 } 19673 } else if *repeatUntilFailure { 19674 for err == nil { 19675 statusChan <- statusMsg{test: test, statusType: statusStarted} 19676 err = runTest(dispatcher, statusChan, test, shimPath, -1) 19677 } 19678 } else { 19679 statusChan <- statusMsg{test: test, statusType: statusStarted} 19680 err = runTest(dispatcher, statusChan, test, shimPath, -1) 19681 } 19682 statusChan <- statusMsg{test: test, statusType: statusDone, err: err} 19683 } 19684} 19685 19686type statusType int 19687 19688const ( 19689 statusStarted statusType = iota 19690 statusShimStarted 19691 statusDone 19692) 19693 19694type statusMsg struct { 19695 test *testCase 19696 statusType statusType 19697 pid int 19698 err error 19699} 19700 19701func statusPrinter(doneChan chan *testresult.Results, statusChan chan statusMsg, total int) { 19702 var started, done, failed, unimplemented, lineLen int 19703 19704 testOutput := testresult.NewResults() 19705 for msg := range statusChan { 19706 if !*pipe { 19707 // Erase the previous status line. 19708 var erase string 19709 for i := 0; i < lineLen; i++ { 19710 erase += "\b \b" 19711 } 19712 fmt.Print(erase) 19713 } 19714 19715 if msg.statusType == statusStarted { 19716 started++ 19717 } else if msg.statusType == statusDone { 19718 done++ 19719 19720 if msg.err != nil { 19721 if msg.err == errUnimplemented { 19722 if *pipe { 19723 // Print each test instead of a status line. 19724 fmt.Printf("UNIMPLEMENTED (%s)\n", msg.test.name) 19725 } 19726 unimplemented++ 19727 if *allowUnimplemented { 19728 testOutput.AddSkip(msg.test.name) 19729 } else { 19730 testOutput.AddResult(msg.test.name, "SKIP") 19731 } 19732 } else { 19733 fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err) 19734 failed++ 19735 testOutput.AddResult(msg.test.name, "FAIL") 19736 } 19737 } else { 19738 if *pipe { 19739 // Print each test instead of a status line. 19740 fmt.Printf("PASSED (%s)\n", msg.test.name) 19741 } 19742 testOutput.AddResult(msg.test.name, "PASS") 19743 } 19744 } 19745 19746 if !*pipe { 19747 // Print a new status line. 19748 line := fmt.Sprintf("%d/%d/%d/%d/%d", failed, unimplemented, done, started, total) 19749 if msg.statusType == statusShimStarted && *waitForDebugger { 19750 // Note -wait-for-debugger limits the test to one worker, 19751 // otherwise some output would be skipped. 19752 line += fmt.Sprintf(" (%s: attach to process %d to continue)", msg.test.name, msg.pid) 19753 } 19754 lineLen = len(line) 19755 os.Stdout.WriteString(line) 19756 } 19757 } 19758 19759 doneChan <- testOutput 19760} 19761 19762func match(oneOfPatternIfAny []string, noneOfPattern []string, candidate string) (matched bool, err error) { 19763 matched = len(oneOfPatternIfAny) == 0 19764 19765 var didMatch bool 19766 for _, pattern := range oneOfPatternIfAny { 19767 didMatch, err = filepath.Match(pattern, candidate) 19768 if err != nil { 19769 return false, err 19770 } 19771 19772 matched = didMatch || matched 19773 } 19774 19775 for _, pattern := range noneOfPattern { 19776 didMatch, err = filepath.Match(pattern, candidate) 19777 if err != nil { 19778 return false, err 19779 } 19780 19781 matched = !didMatch && matched 19782 } 19783 19784 return matched, nil 19785} 19786 19787func checkTests() { 19788 for _, test := range testCases { 19789 if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) { 19790 panic("Error expected without shouldFail in " + test.name) 19791 } 19792 19793 if test.expectResumeRejected && !test.resumeSession { 19794 panic("expectResumeRejected without resumeSession in " + test.name) 19795 } 19796 19797 if !test.skipVersionNameCheck { 19798 for _, ver := range tlsVersions { 19799 if !strings.Contains("-"+test.name+"-", "-"+ver.name+"-") { 19800 continue 19801 } 19802 19803 found := test.config.MaxVersion == ver.version || test.config.MinVersion == ver.version || test.expectations.version == ver.version 19804 if test.resumeConfig != nil { 19805 found = found || test.resumeConfig.MaxVersion == ver.version || test.resumeConfig.MinVersion == ver.version 19806 } 19807 if test.resumeExpectations != nil { 19808 found = found || test.resumeExpectations.version == ver.version 19809 } 19810 shimFlag := ver.shimFlag(test.protocol) 19811 for _, flag := range test.flags { 19812 if flag == shimFlag { 19813 found = true 19814 break 19815 } 19816 } 19817 if !found { 19818 panic(fmt.Sprintf("The name of test %q suggests that it's version specific, but the test does not reference %s", test.name, ver.name)) 19819 } 19820 } 19821 } 19822 19823 for _, protocol := range []protocol{tls, dtls, quic} { 19824 if strings.Contains("-"+test.name+"-", "-"+protocol.String()+"-") && test.protocol != protocol { 19825 panic(fmt.Sprintf("The name of test %q suggests that it tests %q, but the test does not reference it", test.name, protocol)) 19826 } 19827 } 19828 } 19829} 19830 19831func main() { 19832 flag.Parse() 19833 *resourceDir = path.Clean(*resourceDir) 19834 initCertificates() 19835 19836 if len(*shimConfigFile) != 0 { 19837 encoded, err := os.ReadFile(*shimConfigFile) 19838 if err != nil { 19839 fmt.Fprintf(os.Stderr, "Couldn't read config file %q: %s\n", *shimConfigFile, err) 19840 os.Exit(1) 19841 } 19842 19843 if err := json.Unmarshal(encoded, &shimConfig); err != nil { 19844 fmt.Fprintf(os.Stderr, "Couldn't decode config file %q: %s\n", *shimConfigFile, err) 19845 os.Exit(1) 19846 } 19847 } 19848 19849 if shimConfig.AllCurves == nil { 19850 for _, curve := range testCurves { 19851 shimConfig.AllCurves = append(shimConfig.AllCurves, int(curve.id)) 19852 } 19853 } 19854 19855 addBasicTests() 19856 addCipherSuiteTests() 19857 addBadECDSASignatureTests() 19858 addCBCPaddingTests() 19859 addCBCSplittingTests() 19860 addClientAuthTests() 19861 addDDoSCallbackTests() 19862 addVersionNegotiationTests() 19863 addMinimumVersionTests() 19864 addExtensionTests() 19865 addResumptionVersionTests() 19866 addExtendedMasterSecretTests() 19867 addRenegotiationTests() 19868 addDTLSReplayTests() 19869 addSignatureAlgorithmTests() 19870 addDTLSRetransmitTests() 19871 addExportKeyingMaterialTests() 19872 addExportTrafficSecretsTests() 19873 addTLSUniqueTests() 19874 addCustomExtensionTests() 19875 addRSAClientKeyExchangeTests() 19876 addCurveTests() 19877 addSessionTicketTests() 19878 addTLS13RecordTests() 19879 addAllStateMachineCoverageTests() 19880 addChangeCipherSpecTests() 19881 addEndOfFlightTests() 19882 addWrongMessageTypeTests() 19883 addTrailingMessageDataTests() 19884 addTLS13HandshakeTests() 19885 addTLS13CipherPreferenceTests() 19886 addPeekTests() 19887 addRecordVersionTests() 19888 addCertificateTests() 19889 addRetainOnlySHA256ClientCertTests() 19890 addECDSAKeyUsageTests() 19891 addRSAKeyUsageTests() 19892 addExtraHandshakeTests() 19893 addOmitExtensionsTests() 19894 addCertCompressionTests() 19895 addJDK11WorkaroundTests() 19896 addDelegatedCredentialTests() 19897 addEncryptedClientHelloTests() 19898 addHintMismatchTests() 19899 addCompliancePolicyTests() 19900 19901 toAppend, err := convertToSplitHandshakeTests(testCases) 19902 if err != nil { 19903 fmt.Fprintf(os.Stderr, "Error making split handshake tests: %s", err) 19904 os.Exit(1) 19905 } 19906 testCases = append(testCases, toAppend...) 19907 19908 checkTests() 19909 19910 dispatcher, err := newShimDispatcher() 19911 if err != nil { 19912 fmt.Fprintf(os.Stderr, "Error opening socket: %s", err) 19913 os.Exit(1) 19914 } 19915 defer dispatcher.Close() 19916 19917 numWorkers := *numWorkersFlag 19918 if useDebugger() { 19919 numWorkers = 1 19920 } 19921 19922 statusChan := make(chan statusMsg, numWorkers) 19923 testChan := make(chan *testCase, numWorkers) 19924 doneChan := make(chan *testresult.Results) 19925 19926 go statusPrinter(doneChan, statusChan, len(testCases)) 19927 19928 var wg sync.WaitGroup 19929 for i := 0; i < numWorkers; i++ { 19930 wg.Add(1) 19931 go worker(dispatcher, statusChan, testChan, *shimPath, &wg) 19932 } 19933 19934 var oneOfPatternIfAny, noneOfPattern []string 19935 if len(*testToRun) > 0 { 19936 oneOfPatternIfAny = strings.Split(*testToRun, ";") 19937 } 19938 if len(*skipTest) > 0 { 19939 noneOfPattern = strings.Split(*skipTest, ";") 19940 } 19941 19942 shardIndex, shardTotal, err := getSharding() 19943 if err != nil { 19944 fmt.Fprintln(os.Stderr, err) 19945 os.Exit(1) 19946 } 19947 19948 if shardTotal > 0 { 19949 fmt.Printf("This is shard %d of 0..%d (inclusive)\n", shardIndex, shardTotal-1) 19950 } 19951 19952 var foundTest bool 19953 for i := range testCases { 19954 if shardTotal > 0 && i%shardTotal != shardIndex { 19955 continue 19956 } 19957 19958 matched, err := match(oneOfPatternIfAny, noneOfPattern, testCases[i].name) 19959 if err != nil { 19960 fmt.Fprintf(os.Stderr, "Error matching pattern: %s\n", err) 19961 os.Exit(1) 19962 } 19963 19964 if !*includeDisabled { 19965 for pattern := range shimConfig.DisabledTests { 19966 isDisabled, err := filepath.Match(pattern, testCases[i].name) 19967 if err != nil { 19968 fmt.Fprintf(os.Stderr, "Error matching pattern %q from config file: %s\n", pattern, err) 19969 os.Exit(1) 19970 } 19971 19972 if isDisabled { 19973 matched = false 19974 break 19975 } 19976 } 19977 } 19978 19979 if matched { 19980 if foundTest && *useRR { 19981 fmt.Fprintf(os.Stderr, "Too many matching tests. Only one test can run when RR is enabled.\n") 19982 os.Exit(1) 19983 } 19984 19985 foundTest = true 19986 testChan <- &testCases[i] 19987 19988 // Only run one test if repeating until failure. 19989 if *repeatUntilFailure { 19990 break 19991 } 19992 } 19993 } 19994 19995 if !foundTest && shardTotal == 0 { 19996 fmt.Fprintf(os.Stderr, "No tests run\n") 19997 os.Exit(1) 19998 } 19999 20000 close(testChan) 20001 wg.Wait() 20002 close(statusChan) 20003 testOutput := <-doneChan 20004 20005 fmt.Printf("\n") 20006 20007 if *jsonOutput != "" { 20008 if err := testOutput.WriteToFile(*jsonOutput); err != nil { 20009 fmt.Fprintf(os.Stderr, "Error: %s\n", err) 20010 } 20011 } 20012 20013 if *useRR { 20014 fmt.Println("RR trace recorded. Replay with `rr replay`.") 20015 } 20016 20017 if !testOutput.HasUnexpectedResults() { 20018 os.Exit(1) 20019 } 20020} 20021