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 "io/ioutil" 36 "math/big" 37 "net" 38 "os" 39 "os/exec" 40 "path" 41 "path/filepath" 42 "runtime" 43 "strconv" 44 "strings" 45 "sync" 46 "syscall" 47 "time" 48 49 "boringssl.googlesource.com/boringssl/ssl/test/runner/hpke" 50 "boringssl.googlesource.com/boringssl/util/testresult" 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 handshakerPath = flag.String("handshaker-path", "../../../build/ssl/test/handshaker", "The location of the handshaker binary.") 70 resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.") 71 fuzzer = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.") 72 transcriptDir = flag.String("transcript-dir", "", "The directory in which to write transcripts.") 73 idleTimeout = flag.Duration("idle-timeout", 15*time.Second, "The number of seconds to wait for a read or write to bssl_shim.") 74 deterministic = flag.Bool("deterministic", false, "If true, uses a deterministic PRNG in the runner.") 75 allowUnimplemented = flag.Bool("allow-unimplemented", false, "If true, report pass even if some tests are unimplemented.") 76 looseErrors = flag.Bool("loose-errors", false, "If true, allow shims to report an untranslated error code.") 77 shimConfigFile = flag.String("shim-config", "", "A config file to use to configure the tests for this shim.") 78 includeDisabled = flag.Bool("include-disabled", false, "If true, also runs disabled tests.") 79 repeatUntilFailure = flag.Bool("repeat-until-failure", false, "If true, the first selected test will be run repeatedly until failure.") 80) 81 82// ShimConfigurations is used with the “json” package and represents a shim 83// config file. 84type ShimConfiguration struct { 85 // DisabledTests maps from a glob-based pattern to a freeform string. 86 // The glob pattern is used to exclude tests from being run and the 87 // freeform string is unparsed but expected to explain why the test is 88 // disabled. 89 DisabledTests map[string]string 90 91 // ErrorMap maps from expected error strings to the correct error 92 // string for the shim in question. For example, it might map 93 // “:NO_SHARED_CIPHER:” (a BoringSSL error string) to something 94 // like “SSL_ERROR_NO_CYPHER_OVERLAP”. 95 ErrorMap map[string]string 96 97 // HalfRTTTickets is the number of half-RTT tickets the client should 98 // expect before half-RTT data when testing 0-RTT. 99 HalfRTTTickets int 100 101 // AllCurves is the list of all curve code points supported by the shim. 102 // This is currently used to control tests that enable all curves but may 103 // automatically disable tests in the future. 104 AllCurves []int 105} 106 107// Setup shimConfig defaults aligning with BoringSSL. 108var shimConfig ShimConfiguration = ShimConfiguration{ 109 HalfRTTTickets: 2, 110} 111 112type testCert int 113 114const ( 115 testCertRSA testCert = iota 116 testCertRSA1024 117 testCertRSAChain 118 testCertECDSAP224 119 testCertECDSAP256 120 testCertECDSAP384 121 testCertECDSAP521 122 testCertEd25519 123) 124 125const ( 126 rsaCertificateFile = "cert.pem" 127 rsa1024CertificateFile = "rsa_1024_cert.pem" 128 rsaChainCertificateFile = "rsa_chain_cert.pem" 129 ecdsaP224CertificateFile = "ecdsa_p224_cert.pem" 130 ecdsaP256CertificateFile = "ecdsa_p256_cert.pem" 131 ecdsaP384CertificateFile = "ecdsa_p384_cert.pem" 132 ecdsaP521CertificateFile = "ecdsa_p521_cert.pem" 133 ed25519CertificateFile = "ed25519_cert.pem" 134) 135 136const ( 137 rsaKeyFile = "key.pem" 138 rsa1024KeyFile = "rsa_1024_key.pem" 139 rsaChainKeyFile = "rsa_chain_key.pem" 140 ecdsaP224KeyFile = "ecdsa_p224_key.pem" 141 ecdsaP256KeyFile = "ecdsa_p256_key.pem" 142 ecdsaP384KeyFile = "ecdsa_p384_key.pem" 143 ecdsaP521KeyFile = "ecdsa_p521_key.pem" 144 ed25519KeyFile = "ed25519_key.pem" 145 channelIDKeyFile = "channel_id_key.pem" 146) 147 148var ( 149 rsaCertificate Certificate 150 rsa1024Certificate Certificate 151 rsaChainCertificate Certificate 152 ecdsaP224Certificate Certificate 153 ecdsaP256Certificate Certificate 154 ecdsaP384Certificate Certificate 155 ecdsaP521Certificate Certificate 156 ed25519Certificate Certificate 157 garbageCertificate Certificate 158) 159 160var testCerts = []struct { 161 id testCert 162 certFile, keyFile string 163 cert *Certificate 164}{ 165 { 166 id: testCertRSA, 167 certFile: rsaCertificateFile, 168 keyFile: rsaKeyFile, 169 cert: &rsaCertificate, 170 }, 171 { 172 id: testCertRSA1024, 173 certFile: rsa1024CertificateFile, 174 keyFile: rsa1024KeyFile, 175 cert: &rsa1024Certificate, 176 }, 177 { 178 id: testCertRSAChain, 179 certFile: rsaChainCertificateFile, 180 keyFile: rsaChainKeyFile, 181 cert: &rsaChainCertificate, 182 }, 183 { 184 id: testCertECDSAP224, 185 certFile: ecdsaP224CertificateFile, 186 keyFile: ecdsaP224KeyFile, 187 cert: &ecdsaP224Certificate, 188 }, 189 { 190 id: testCertECDSAP256, 191 certFile: ecdsaP256CertificateFile, 192 keyFile: ecdsaP256KeyFile, 193 cert: &ecdsaP256Certificate, 194 }, 195 { 196 id: testCertECDSAP384, 197 certFile: ecdsaP384CertificateFile, 198 keyFile: ecdsaP384KeyFile, 199 cert: &ecdsaP384Certificate, 200 }, 201 { 202 id: testCertECDSAP521, 203 certFile: ecdsaP521CertificateFile, 204 keyFile: ecdsaP521KeyFile, 205 cert: &ecdsaP521Certificate, 206 }, 207 { 208 id: testCertEd25519, 209 certFile: ed25519CertificateFile, 210 keyFile: ed25519KeyFile, 211 cert: &ed25519Certificate, 212 }, 213} 214 215var channelIDKey *ecdsa.PrivateKey 216var channelIDBytes []byte 217 218var testOCSPResponse = []byte{1, 2, 3, 4} 219var testOCSPResponse2 = []byte{5, 6, 7, 8} 220var testSCTList = []byte{0, 6, 0, 4, 5, 6, 7, 8} 221var testSCTList2 = []byte{0, 6, 0, 4, 1, 2, 3, 4} 222 223var testOCSPExtension = append([]byte{byte(extensionStatusRequest) >> 8, byte(extensionStatusRequest), 0, 8, statusTypeOCSP, 0, 0, 4}, testOCSPResponse...) 224var testSCTExtension = append([]byte{byte(extensionSignedCertificateTimestamp) >> 8, byte(extensionSignedCertificateTimestamp), 0, byte(len(testSCTList))}, testSCTList...) 225 226func initCertificates() { 227 for i := range testCerts { 228 cert, err := LoadX509KeyPair(path.Join(*resourceDir, testCerts[i].certFile), path.Join(*resourceDir, testCerts[i].keyFile)) 229 if err != nil { 230 panic(err) 231 } 232 cert.OCSPStaple = testOCSPResponse 233 cert.SignedCertificateTimestampList = testSCTList 234 *testCerts[i].cert = cert 235 } 236 237 channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile)) 238 if err != nil { 239 panic(err) 240 } 241 channelIDDERBlock, _ := pem.Decode(channelIDPEMBlock) 242 if channelIDDERBlock.Type != "EC PRIVATE KEY" { 243 panic("bad key type") 244 } 245 channelIDKey, err = x509.ParseECPrivateKey(channelIDDERBlock.Bytes) 246 if err != nil { 247 panic(err) 248 } 249 if channelIDKey.Curve != elliptic.P256() { 250 panic("bad curve") 251 } 252 253 channelIDBytes = make([]byte, 64) 254 writeIntPadded(channelIDBytes[:32], channelIDKey.X) 255 writeIntPadded(channelIDBytes[32:], channelIDKey.Y) 256 257 garbageCertificate.Certificate = [][]byte{[]byte("GARBAGE")} 258 garbageCertificate.PrivateKey = rsaCertificate.PrivateKey 259} 260 261func flagInts(flagName string, vals []int) []string { 262 ret := make([]string, 0, 2*len(vals)) 263 for _, val := range vals { 264 ret = append(ret, flagName, strconv.Itoa(val)) 265 } 266 return ret 267} 268 269func base64FlagValue(in []byte) string { 270 return base64.StdEncoding.EncodeToString(in) 271} 272 273func useDebugger() bool { 274 return *useGDB || *useLLDB || *useRR || *waitForDebugger 275} 276 277// delegatedCredentialConfig specifies the shape of a delegated credential, not 278// including the keys themselves. 279type delegatedCredentialConfig struct { 280 // lifetime is the amount of time, from the notBefore of the parent 281 // certificate, that the delegated credential is valid for. If zero, then 24 282 // hours is assumed. 283 lifetime time.Duration 284 // expectedAlgo is the signature scheme that should be used with this 285 // delegated credential. If zero, ECDSA with P-256 is assumed. 286 expectedAlgo signatureAlgorithm 287 // tlsVersion is the version of TLS that should be used with this delegated 288 // credential. If zero, TLS 1.3 is assumed. 289 tlsVersion uint16 290 // algo is the signature algorithm that the delegated credential itself is 291 // signed with. Cannot be zero. 292 algo signatureAlgorithm 293} 294 295func loadRSAPrivateKey(filename string) (priv *rsa.PrivateKey, privPKCS8 []byte, err error) { 296 pemPath := path.Join(*resourceDir, filename) 297 pemBytes, err := ioutil.ReadFile(pemPath) 298 if err != nil { 299 return nil, nil, err 300 } 301 302 block, _ := pem.Decode(pemBytes) 303 if block == nil { 304 return nil, nil, fmt.Errorf("no PEM block found in %q", pemPath) 305 } 306 privPKCS8 = block.Bytes 307 308 parsed, err := x509.ParsePKCS8PrivateKey(privPKCS8) 309 if err != nil { 310 return nil, nil, fmt.Errorf("failed to parse PKCS#8 key from %q", pemPath) 311 } 312 313 priv, ok := parsed.(*rsa.PrivateKey) 314 if !ok { 315 return nil, nil, fmt.Errorf("found %T in %q rather than an RSA private key", parsed, pemPath) 316 } 317 318 return priv, privPKCS8, nil 319} 320 321func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byte, parentPriv crypto.PrivateKey) (dc, privPKCS8 []uint8, err error) { 322 expectedAlgo := config.expectedAlgo 323 if expectedAlgo == signatureAlgorithm(0) { 324 expectedAlgo = signatureECDSAWithP256AndSHA256 325 } 326 327 var pub crypto.PublicKey 328 329 switch expectedAlgo { 330 case signatureRSAPKCS1WithMD5, signatureRSAPKCS1WithSHA1, signatureRSAPKCS1WithSHA256, signatureRSAPKCS1WithSHA384, signatureRSAPKCS1WithSHA512, signatureRSAPSSWithSHA256, signatureRSAPSSWithSHA384, signatureRSAPSSWithSHA512: 331 // RSA keys are expensive to generate so load from disk instead. 332 var priv *rsa.PrivateKey 333 if priv, privPKCS8, err = loadRSAPrivateKey(rsaKeyFile); err != nil { 334 return nil, nil, err 335 } 336 337 pub = &priv.PublicKey 338 339 case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256, signatureECDSAWithP384AndSHA384, signatureECDSAWithP521AndSHA512: 340 var curve elliptic.Curve 341 switch expectedAlgo { 342 case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256: 343 curve = elliptic.P256() 344 case signatureECDSAWithP384AndSHA384: 345 curve = elliptic.P384() 346 case signatureECDSAWithP521AndSHA512: 347 curve = elliptic.P521() 348 default: 349 panic("internal error") 350 } 351 352 priv, err := ecdsa.GenerateKey(curve, rand.Reader) 353 if err != nil { 354 return nil, nil, err 355 } 356 357 if privPKCS8, err = x509.MarshalPKCS8PrivateKey(priv); err != nil { 358 return nil, nil, err 359 } 360 361 pub = &priv.PublicKey 362 363 default: 364 return nil, nil, fmt.Errorf("unsupported expected signature algorithm: %x", expectedAlgo) 365 } 366 367 lifetime := config.lifetime 368 if lifetime == 0 { 369 lifetime = 24 * time.Hour 370 } 371 lifetimeSecs := int64(lifetime.Seconds()) 372 if lifetimeSecs > 1<<32 { 373 return nil, nil, fmt.Errorf("lifetime %s is too long to be expressed", lifetime) 374 } 375 tlsVersion := config.tlsVersion 376 if tlsVersion == 0 { 377 tlsVersion = VersionTLS13 378 } 379 380 if tlsVersion < VersionTLS13 { 381 return nil, nil, fmt.Errorf("delegated credentials require TLS 1.3") 382 } 383 384 // https://tools.ietf.org/html/draft-ietf-tls-subcerts-03#section-3 385 dc = append(dc, byte(lifetimeSecs>>24), byte(lifetimeSecs>>16), byte(lifetimeSecs>>8), byte(lifetimeSecs)) 386 dc = append(dc, byte(expectedAlgo>>8), byte(expectedAlgo)) 387 388 pubBytes, err := x509.MarshalPKIXPublicKey(pub) 389 if err != nil { 390 return nil, nil, err 391 } 392 393 dc = append(dc, byte(len(pubBytes)>>16), byte(len(pubBytes)>>8), byte(len(pubBytes))) 394 dc = append(dc, pubBytes...) 395 396 var dummyConfig Config 397 parentSigner, err := getSigner(tlsVersion, parentPriv, &dummyConfig, config.algo, false /* not for verification */) 398 if err != nil { 399 return nil, nil, err 400 } 401 402 parentSignature, err := parentSigner.signMessage(parentPriv, &dummyConfig, delegatedCredentialSignedMessage(dc, config.algo, parentDER)) 403 if err != nil { 404 return nil, nil, err 405 } 406 407 dc = append(dc, byte(config.algo>>8), byte(config.algo)) 408 dc = append(dc, byte(len(parentSignature)>>8), byte(len(parentSignature))) 409 dc = append(dc, parentSignature...) 410 411 return dc, privPKCS8, nil 412} 413 414func getRunnerCertificate(t testCert) Certificate { 415 for _, cert := range testCerts { 416 if cert.id == t { 417 return *cert.cert 418 } 419 } 420 panic("Unknown test certificate") 421} 422 423func getShimCertificate(t testCert) string { 424 for _, cert := range testCerts { 425 if cert.id == t { 426 return cert.certFile 427 } 428 } 429 panic("Unknown test certificate") 430} 431 432func getShimKey(t testCert) string { 433 for _, cert := range testCerts { 434 if cert.id == t { 435 return cert.keyFile 436 } 437 } 438 panic("Unknown test certificate") 439} 440 441// recordVersionToWire maps a record-layer protocol version to its wire 442// representation. 443func recordVersionToWire(vers uint16, protocol protocol) uint16 { 444 if protocol == dtls { 445 switch vers { 446 case VersionTLS12: 447 return VersionDTLS12 448 case VersionTLS10: 449 return VersionDTLS10 450 } 451 } else { 452 switch vers { 453 case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12: 454 return vers 455 } 456 } 457 458 panic("unknown version") 459} 460 461// encodeDERValues encodes a series of bytestrings in comma-separated-hex form. 462func encodeDERValues(values [][]byte) string { 463 var ret string 464 for i, v := range values { 465 if i > 0 { 466 ret += "," 467 } 468 ret += hex.EncodeToString(v) 469 } 470 471 return ret 472} 473 474func decodeHexOrPanic(in string) []byte { 475 ret, err := hex.DecodeString(in) 476 if err != nil { 477 panic(err) 478 } 479 return ret 480} 481 482type testType int 483 484const ( 485 clientTest testType = iota 486 serverTest 487) 488 489type protocol int 490 491const ( 492 tls protocol = iota 493 dtls 494 quic 495) 496 497func (p protocol) String() string { 498 switch p { 499 case tls: 500 return "TLS" 501 case dtls: 502 return "DTLS" 503 case quic: 504 return "QUIC" 505 } 506 return "unknown protocol" 507} 508 509const ( 510 alpn = 1 511 npn = 2 512) 513 514// connectionExpectations contains connection-level test expectations to check 515// on the runner side. 516type connectionExpectations struct { 517 // version, if non-zero, specifies the TLS version that must be negotiated. 518 version uint16 519 // cipher, if non-zero, specifies the TLS cipher suite that should be 520 // negotiated. 521 cipher uint16 522 // channelID controls whether the connection should have negotiated a 523 // Channel ID with channelIDKey. 524 channelID bool 525 // nextProto controls whether the connection should negotiate a next 526 // protocol via NPN or ALPN. 527 nextProto string 528 // noNextProto, if true, means that no next protocol should be negotiated. 529 noNextProto bool 530 // nextProtoType, if non-zero, is the next protocol negotiation mechanism. 531 nextProtoType int 532 // srtpProtectionProfile is the DTLS-SRTP profile that should be negotiated. 533 // If zero, none should be negotiated. 534 srtpProtectionProfile uint16 535 // ocspResponse, if not nil, is the OCSP response to be received. 536 ocspResponse []uint8 537 // sctList, if not nil, is the SCT list to be received. 538 sctList []uint8 539 // peerSignatureAlgorithm, if not zero, is the signature algorithm that the 540 // peer should have used in the handshake. 541 peerSignatureAlgorithm signatureAlgorithm 542 // curveID, if not zero, is the curve that the handshake should have used. 543 curveID CurveID 544 // peerCertificate, if not nil, is the certificate chain the peer is 545 // expected to send. 546 peerCertificate *Certificate 547 // quicTransportParams contains the QUIC transport parameters that are to be 548 // sent by the peer using codepoint 57. 549 quicTransportParams []byte 550 // quicTransportParamsLegacy contains the QUIC transport parameters that are 551 // to be sent by the peer using legacy codepoint 0xffa5. 552 quicTransportParamsLegacy []byte 553 // peerApplicationSettings are the expected application settings for the 554 // connection. If nil, no application settings are expected. 555 peerApplicationSettings []byte 556 // echAccepted is whether ECH should have been accepted on this connection. 557 echAccepted bool 558} 559 560type testCase struct { 561 testType testType 562 protocol protocol 563 name string 564 config Config 565 shouldFail bool 566 expectedError string 567 // expectedLocalError, if not empty, contains a substring that must be 568 // found in the local error. 569 expectedLocalError string 570 // expectations contains test expectations for the initial 571 // connection. 572 expectations connectionExpectations 573 // resumeExpectations, if non-nil, contains test expectations for the 574 // resumption connection. If nil, |expectations| is used. 575 resumeExpectations *connectionExpectations 576 // messageLen is the length, in bytes, of the test message that will be 577 // sent. 578 messageLen int 579 // messageCount is the number of test messages that will be sent. 580 messageCount int 581 // certFile is the path to the certificate to use for the server. 582 certFile string 583 // keyFile is the path to the private key to use for the server. 584 keyFile string 585 // resumeSession controls whether a second connection should be tested 586 // which attempts to resume the first session. 587 resumeSession bool 588 // resumeRenewedSession controls whether a third connection should be 589 // tested which attempts to resume the second connection's session. 590 resumeRenewedSession bool 591 // expectResumeRejected, if true, specifies that the attempted 592 // resumption must be rejected by the client. This is only valid for a 593 // serverTest. 594 expectResumeRejected bool 595 // resumeConfig, if not nil, points to a Config to be used on 596 // resumption. Unless newSessionsOnResume is set, 597 // SessionTicketKey, ServerSessionCache, and 598 // ClientSessionCache are copied from the initial connection's 599 // config. If nil, the initial connection's config is used. 600 resumeConfig *Config 601 // newSessionsOnResume, if true, will cause resumeConfig to 602 // use a different session resumption context. 603 newSessionsOnResume bool 604 // noSessionCache, if true, will cause the server to run without a 605 // session cache. 606 noSessionCache bool 607 // sendPrefix sends a prefix on the socket before actually performing a 608 // handshake. 609 sendPrefix string 610 // shimWritesFirst controls whether the shim sends an initial "hello" 611 // message before doing a roundtrip with the runner. 612 shimWritesFirst bool 613 // readWithUnfinishedWrite behaves like shimWritesFirst, but the shim 614 // does not complete the write until responding to the first runner 615 // message. 616 readWithUnfinishedWrite bool 617 // shimShutsDown, if true, runs a test where the shim shuts down the 618 // connection immediately after the handshake rather than echoing 619 // messages from the runner. The runner will default to not sending 620 // application data. 621 shimShutsDown bool 622 // renegotiate indicates the number of times the connection should be 623 // renegotiated during the exchange. 624 renegotiate int 625 // sendHalfHelloRequest, if true, causes the server to send half a 626 // HelloRequest when the handshake completes. 627 sendHalfHelloRequest bool 628 // renegotiateCiphers is a list of ciphersuite ids that will be 629 // switched in just before renegotiation. 630 renegotiateCiphers []uint16 631 // replayWrites, if true, configures the underlying transport 632 // to replay every write it makes in DTLS tests. 633 replayWrites bool 634 // damageFirstWrite, if true, configures the underlying transport to 635 // damage the final byte of the first application data write. 636 damageFirstWrite bool 637 // exportKeyingMaterial, if non-zero, configures the test to exchange 638 // keying material and verify they match. 639 exportKeyingMaterial int 640 exportLabel string 641 exportContext string 642 useExportContext bool 643 // flags, if not empty, contains a list of command-line flags that will 644 // be passed to the shim program. 645 flags []string 646 // testTLSUnique, if true, causes the shim to send the tls-unique value 647 // which will be compared against the expected value. 648 testTLSUnique bool 649 // sendEmptyRecords is the number of consecutive empty records to send 650 // before each test message. 651 sendEmptyRecords int 652 // sendWarningAlerts is the number of consecutive warning alerts to send 653 // before each test message. 654 sendWarningAlerts int 655 // sendUserCanceledAlerts is the number of consecutive user_canceled alerts to 656 // send before each test message. 657 sendUserCanceledAlerts int 658 // sendBogusAlertType, if true, causes a bogus alert of invalid type to 659 // be sent before each test message. 660 sendBogusAlertType bool 661 // sendKeyUpdates is the number of consecutive key updates to send 662 // before and after the test message. 663 sendKeyUpdates int 664 // keyUpdateRequest is the KeyUpdateRequest value to send in KeyUpdate messages. 665 keyUpdateRequest byte 666 // expectUnsolicitedKeyUpdate makes the test expect a one or more KeyUpdate 667 // messages while reading data from the shim. Don't use this in combination 668 // with any of the fields that send a KeyUpdate otherwise any received 669 // KeyUpdate might not be as unsolicited as expected. 670 expectUnsolicitedKeyUpdate bool 671 // expectMessageDropped, if true, means the test message is expected to 672 // be dropped by the client rather than echoed back. 673 expectMessageDropped bool 674 // shimPrefix is the prefix that the shim will send to the server. 675 shimPrefix string 676 // resumeShimPrefix is the prefix that the shim will send to the server on a 677 // resumption. 678 resumeShimPrefix string 679 // exportTrafficSecrets, if true, configures the test to export the TLS 1.3 680 // traffic secrets and confirms that they match. 681 exportTrafficSecrets bool 682 // skipTransportParamsConfig, if true, will skip automatic configuration of 683 // sending QUIC transport parameters when protocol == quic. 684 skipTransportParamsConfig bool 685 // skipQUICALPNConfig, if true, will skip automatic configuration of 686 // sending a fake ALPN when protocol == quic. 687 skipQUICALPNConfig bool 688 // earlyData, if true, configures default settings for an early data test. 689 // expectEarlyDataRejected controls whether the test is for early data 690 // accept or reject. In a client test, the shim will be configured to send 691 // an initial write in early data which, on accept, the runner will enforce. 692 // In a server test, the runner will send some default message in early 693 // data, which the shim is expected to echo in half-RTT. 694 earlyData bool 695 // expectEarlyDataRejected, if earlyData is true, is whether early data is 696 // expected to be rejected. In a client test, this controls whether the shim 697 // should retry for early rejection. In a server test, this is whether the 698 // test expects the shim to reject early data. 699 expectEarlyDataRejected bool 700 // skipSplitHandshake, if true, will skip the generation of a split 701 // handshake copy of the test. 702 skipSplitHandshake bool 703 // skipVersionNameCheck, if true, will skip the consistency check between 704 // test name and the versions. 705 skipVersionNameCheck bool 706} 707 708var testCases []testCase 709 710func appendTranscript(path string, data []byte) error { 711 if len(data) == 0 { 712 return nil 713 } 714 715 settings, err := ioutil.ReadFile(path) 716 if err != nil { 717 if !os.IsNotExist(err) { 718 return err 719 } 720 // If the shim aborted before writing a file, use a default 721 // settings block, so the transcript is still somewhat valid. 722 settings = []byte{0, 0} // kDataTag 723 } 724 725 settings = append(settings, data...) 726 return ioutil.WriteFile(path, settings, 0644) 727} 728 729// A timeoutConn implements an idle timeout on each Read and Write operation. 730type timeoutConn struct { 731 net.Conn 732 timeout time.Duration 733} 734 735func (t *timeoutConn) Read(b []byte) (int, error) { 736 if !*useGDB { 737 if err := t.SetReadDeadline(time.Now().Add(t.timeout)); err != nil { 738 return 0, err 739 } 740 } 741 return t.Conn.Read(b) 742} 743 744func (t *timeoutConn) Write(b []byte) (int, error) { 745 if !*useGDB { 746 if err := t.SetWriteDeadline(time.Now().Add(t.timeout)); err != nil { 747 return 0, err 748 } 749 } 750 return t.Conn.Write(b) 751} 752 753func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool, transcripts *[][]byte, num int) error { 754 if !test.noSessionCache { 755 if config.ClientSessionCache == nil { 756 config.ClientSessionCache = NewLRUClientSessionCache(1) 757 } 758 if config.ServerSessionCache == nil { 759 config.ServerSessionCache = NewLRUServerSessionCache(1) 760 } 761 } 762 if test.testType == clientTest { 763 if len(config.Certificates) == 0 { 764 config.Certificates = []Certificate{rsaCertificate} 765 } 766 } else { 767 // Supply a ServerName to ensure a constant session cache key, 768 // rather than falling back to net.Conn.RemoteAddr. 769 if len(config.ServerName) == 0 { 770 config.ServerName = "test" 771 } 772 } 773 if *fuzzer { 774 config.Bugs.NullAllCiphers = true 775 } 776 if *deterministic { 777 config.Time = func() time.Time { return time.Unix(1234, 1234) } 778 } 779 780 if !useDebugger() { 781 conn = &timeoutConn{conn, *idleTimeout} 782 } 783 784 if test.protocol == dtls { 785 config.Bugs.PacketAdaptor = newPacketAdaptor(conn) 786 conn = config.Bugs.PacketAdaptor 787 } 788 789 if *flagDebug || len(*transcriptDir) != 0 { 790 local, peer := "client", "server" 791 if test.testType == clientTest { 792 local, peer = peer, local 793 } 794 connDebug := &recordingConn{ 795 Conn: conn, 796 isDatagram: test.protocol == dtls, 797 local: local, 798 peer: peer, 799 } 800 conn = connDebug 801 if *flagDebug { 802 defer connDebug.WriteTo(os.Stdout) 803 } 804 if len(*transcriptDir) != 0 { 805 defer func() { 806 if num == len(*transcripts) { 807 *transcripts = append(*transcripts, connDebug.Transcript()) 808 } else { 809 panic("transcripts are out of sync") 810 } 811 }() 812 813 // Record ClientHellos for the decode_client_hello_inner fuzzer. 814 var clientHelloCount int 815 config.Bugs.RecordClientHelloInner = func(encodedInner, outer []byte) error { 816 name := fmt.Sprintf("%s-%d-%d", test.name, num, clientHelloCount) 817 clientHelloCount++ 818 dir := filepath.Join(*transcriptDir, "decode_client_hello_inner") 819 if err := os.MkdirAll(dir, 0755); err != nil { 820 return err 821 } 822 bb := newByteBuilder() 823 bb.addU24LengthPrefixed().addBytes(encodedInner) 824 bb.addBytes(outer) 825 return ioutil.WriteFile(filepath.Join(dir, name), bb.finish(), 0644) 826 } 827 } 828 829 if config.Bugs.PacketAdaptor != nil { 830 config.Bugs.PacketAdaptor.debug = connDebug 831 } 832 } 833 if test.protocol == quic { 834 config.Bugs.MockQUICTransport = newMockQUICTransport(conn) 835 // The MockQUICTransport will panic if Read or Write is 836 // called. When a MockQUICTransport is set, separate 837 // methods should be used to actually read and write 838 // records. By setting the conn to it here, it ensures 839 // Read or Write aren't accidentally used instead of the 840 // methods provided by MockQUICTransport. 841 conn = config.Bugs.MockQUICTransport 842 } 843 844 if test.replayWrites { 845 conn = newReplayAdaptor(conn) 846 } 847 848 var connDamage *damageAdaptor 849 if test.damageFirstWrite { 850 connDamage = newDamageAdaptor(conn) 851 conn = connDamage 852 } 853 854 if test.sendPrefix != "" { 855 if _, err := conn.Write([]byte(test.sendPrefix)); err != nil { 856 return err 857 } 858 } 859 860 var tlsConn *Conn 861 if test.testType == clientTest { 862 if test.protocol == dtls { 863 tlsConn = DTLSServer(conn, config) 864 } else { 865 tlsConn = Server(conn, config) 866 } 867 } else { 868 config.InsecureSkipVerify = true 869 if test.protocol == dtls { 870 tlsConn = DTLSClient(conn, config) 871 } else { 872 tlsConn = Client(conn, config) 873 } 874 } 875 defer tlsConn.Close() 876 877 if err := tlsConn.Handshake(); err != nil { 878 return err 879 } 880 881 expectations := &test.expectations 882 if isResume && test.resumeExpectations != nil { 883 expectations = test.resumeExpectations 884 } 885 connState := tlsConn.ConnectionState() 886 if vers := connState.Version; expectations.version != 0 && vers != expectations.version { 887 return fmt.Errorf("got version %x, expected %x", vers, expectations.version) 888 } 889 890 if cipher := connState.CipherSuite; expectations.cipher != 0 && cipher != expectations.cipher { 891 return fmt.Errorf("got cipher %x, expected %x", cipher, expectations.cipher) 892 } 893 if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected { 894 return fmt.Errorf("didResume is %t, but we expected the opposite", didResume) 895 } 896 897 if expectations.channelID { 898 channelID := connState.ChannelID 899 if channelID == nil { 900 return fmt.Errorf("no channel ID negotiated") 901 } 902 if channelID.Curve != channelIDKey.Curve || 903 channelIDKey.X.Cmp(channelIDKey.X) != 0 || 904 channelIDKey.Y.Cmp(channelIDKey.Y) != 0 { 905 return fmt.Errorf("incorrect channel ID") 906 } 907 } else if connState.ChannelID != nil { 908 return fmt.Errorf("channel ID unexpectedly negotiated") 909 } 910 911 if expected := expectations.nextProto; expected != "" { 912 if actual := connState.NegotiatedProtocol; actual != expected { 913 return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected) 914 } 915 } 916 917 if expectations.noNextProto { 918 if actual := connState.NegotiatedProtocol; actual != "" { 919 return fmt.Errorf("got unexpected next proto %s", actual) 920 } 921 } 922 923 if expectations.nextProtoType != 0 { 924 if (expectations.nextProtoType == alpn) != connState.NegotiatedProtocolFromALPN { 925 return fmt.Errorf("next proto type mismatch") 926 } 927 } 928 929 if expectations.peerApplicationSettings != nil { 930 if !connState.HasApplicationSettings { 931 return errors.New("application settings should have been negotiated") 932 } 933 if !bytes.Equal(connState.PeerApplicationSettings, expectations.peerApplicationSettings) { 934 return fmt.Errorf("peer application settings mismatch: got %q, wanted %q", connState.PeerApplicationSettings, expectations.peerApplicationSettings) 935 } 936 } else if connState.HasApplicationSettings { 937 return errors.New("application settings unexpectedly negotiated") 938 } 939 940 if p := connState.SRTPProtectionProfile; p != expectations.srtpProtectionProfile { 941 return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, expectations.srtpProtectionProfile) 942 } 943 944 if expectations.ocspResponse != nil && !bytes.Equal(expectations.ocspResponse, connState.OCSPResponse) { 945 return fmt.Errorf("OCSP Response mismatch: got %x, wanted %x", connState.OCSPResponse, expectations.ocspResponse) 946 } 947 948 if expectations.sctList != nil && !bytes.Equal(expectations.sctList, connState.SCTList) { 949 return fmt.Errorf("SCT list mismatch") 950 } 951 952 if expected := expectations.peerSignatureAlgorithm; expected != 0 && expected != connState.PeerSignatureAlgorithm { 953 return fmt.Errorf("expected peer to use signature algorithm %04x, but got %04x", expected, connState.PeerSignatureAlgorithm) 954 } 955 956 if expected := expectations.curveID; expected != 0 && expected != connState.CurveID { 957 return fmt.Errorf("expected peer to use curve %04x, but got %04x", expected, connState.CurveID) 958 } 959 960 if expectations.peerCertificate != nil { 961 if len(connState.PeerCertificates) != len(expectations.peerCertificate.Certificate) { 962 return fmt.Errorf("expected peer to send %d certificates, but got %d", len(connState.PeerCertificates), len(expectations.peerCertificate.Certificate)) 963 } 964 for i, cert := range connState.PeerCertificates { 965 if !bytes.Equal(cert.Raw, expectations.peerCertificate.Certificate[i]) { 966 return fmt.Errorf("peer certificate %d did not match", i+1) 967 } 968 } 969 } 970 971 if len(expectations.quicTransportParams) > 0 { 972 if !bytes.Equal(expectations.quicTransportParams, connState.QUICTransportParams) { 973 return errors.New("Peer did not send expected QUIC transport params") 974 } 975 } 976 977 if len(expectations.quicTransportParamsLegacy) > 0 { 978 if !bytes.Equal(expectations.quicTransportParamsLegacy, connState.QUICTransportParamsLegacy) { 979 return errors.New("Peer did not send expected legacy QUIC transport params") 980 } 981 } 982 983 if expectations.echAccepted { 984 if !connState.ECHAccepted { 985 return errors.New("tls: server did not accept ECH") 986 } 987 } else { 988 if connState.ECHAccepted { 989 return errors.New("tls: server unexpectedly accepted ECH") 990 } 991 } 992 993 if test.exportKeyingMaterial > 0 { 994 actual := make([]byte, test.exportKeyingMaterial) 995 if _, err := io.ReadFull(tlsConn, actual); err != nil { 996 return err 997 } 998 expected, err := tlsConn.ExportKeyingMaterial(test.exportKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext), test.useExportContext) 999 if err != nil { 1000 return err 1001 } 1002 if !bytes.Equal(actual, expected) { 1003 return fmt.Errorf("keying material mismatch; got %x, wanted %x", actual, expected) 1004 } 1005 } 1006 1007 if test.exportTrafficSecrets { 1008 secretLenBytes := make([]byte, 2) 1009 if _, err := io.ReadFull(tlsConn, secretLenBytes); err != nil { 1010 return err 1011 } 1012 secretLen := binary.LittleEndian.Uint16(secretLenBytes) 1013 1014 theirReadSecret := make([]byte, secretLen) 1015 theirWriteSecret := make([]byte, secretLen) 1016 if _, err := io.ReadFull(tlsConn, theirReadSecret); err != nil { 1017 return err 1018 } 1019 if _, err := io.ReadFull(tlsConn, theirWriteSecret); err != nil { 1020 return err 1021 } 1022 1023 myReadSecret := tlsConn.in.trafficSecret 1024 myWriteSecret := tlsConn.out.trafficSecret 1025 if !bytes.Equal(myWriteSecret, theirReadSecret) { 1026 return fmt.Errorf("read traffic-secret mismatch; got %x, wanted %x", theirReadSecret, myWriteSecret) 1027 } 1028 if !bytes.Equal(myReadSecret, theirWriteSecret) { 1029 return fmt.Errorf("write traffic-secret mismatch; got %x, wanted %x", theirWriteSecret, myReadSecret) 1030 } 1031 } 1032 1033 if test.testTLSUnique { 1034 var peersValue [12]byte 1035 if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil { 1036 return err 1037 } 1038 expected := tlsConn.ConnectionState().TLSUnique 1039 if !bytes.Equal(peersValue[:], expected) { 1040 return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected) 1041 } 1042 } 1043 1044 if test.sendHalfHelloRequest { 1045 tlsConn.SendHalfHelloRequest() 1046 } 1047 1048 shimPrefix := test.shimPrefix 1049 if isResume { 1050 shimPrefix = test.resumeShimPrefix 1051 } 1052 if test.shimWritesFirst || test.readWithUnfinishedWrite { 1053 shimPrefix = shimInitialWrite 1054 } 1055 if test.renegotiate > 0 { 1056 // If readWithUnfinishedWrite is set, the shim prefix will be 1057 // available later. 1058 if shimPrefix != "" && !test.readWithUnfinishedWrite { 1059 var buf = make([]byte, len(shimPrefix)) 1060 _, err := io.ReadFull(tlsConn, buf) 1061 if err != nil { 1062 return err 1063 } 1064 if string(buf) != shimPrefix { 1065 return fmt.Errorf("bad initial message %v vs %v", string(buf), shimPrefix) 1066 } 1067 shimPrefix = "" 1068 } 1069 1070 if test.renegotiateCiphers != nil { 1071 config.CipherSuites = test.renegotiateCiphers 1072 } 1073 for i := 0; i < test.renegotiate; i++ { 1074 if err := tlsConn.Renegotiate(); err != nil { 1075 return err 1076 } 1077 } 1078 } else if test.renegotiateCiphers != nil { 1079 panic("renegotiateCiphers without renegotiate") 1080 } 1081 1082 if test.damageFirstWrite { 1083 connDamage.setDamage(true) 1084 tlsConn.Write([]byte("DAMAGED WRITE")) 1085 connDamage.setDamage(false) 1086 } 1087 1088 messageLen := test.messageLen 1089 if messageLen < 0 { 1090 if test.protocol == dtls { 1091 return fmt.Errorf("messageLen < 0 not supported for DTLS tests") 1092 } 1093 // Read until EOF. 1094 _, err := io.Copy(ioutil.Discard, tlsConn) 1095 return err 1096 } 1097 if messageLen == 0 { 1098 messageLen = 32 1099 } 1100 1101 messageCount := test.messageCount 1102 // shimShutsDown sets the default message count to zero. 1103 if messageCount == 0 && !test.shimShutsDown { 1104 messageCount = 1 1105 } 1106 1107 for j := 0; j < messageCount; j++ { 1108 for i := 0; i < test.sendKeyUpdates; i++ { 1109 tlsConn.SendKeyUpdate(test.keyUpdateRequest) 1110 } 1111 1112 for i := 0; i < test.sendEmptyRecords; i++ { 1113 tlsConn.Write(nil) 1114 } 1115 1116 for i := 0; i < test.sendWarningAlerts; i++ { 1117 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage) 1118 } 1119 1120 for i := 0; i < test.sendUserCanceledAlerts; i++ { 1121 tlsConn.SendAlert(alertLevelWarning, alertUserCanceled) 1122 } 1123 1124 if test.sendBogusAlertType { 1125 tlsConn.SendAlert(0x42, alertUnexpectedMessage) 1126 } 1127 1128 testMessage := make([]byte, messageLen) 1129 for i := range testMessage { 1130 testMessage[i] = 0x42 ^ byte(j) 1131 } 1132 tlsConn.Write(testMessage) 1133 1134 // Consume the shim prefix if needed. 1135 if shimPrefix != "" { 1136 var buf = make([]byte, len(shimPrefix)) 1137 _, err := io.ReadFull(tlsConn, buf) 1138 if err != nil { 1139 return err 1140 } 1141 if string(buf) != shimPrefix { 1142 return fmt.Errorf("bad initial message %v vs %v", string(buf), shimPrefix) 1143 } 1144 shimPrefix = "" 1145 } 1146 1147 if test.shimShutsDown || test.expectMessageDropped { 1148 // The shim will not respond. 1149 continue 1150 } 1151 1152 // Process the KeyUpdate ACK. However many KeyUpdates the runner 1153 // sends, the shim should respond only once. 1154 if test.sendKeyUpdates > 0 && test.keyUpdateRequest == keyUpdateRequested { 1155 if err := tlsConn.ReadKeyUpdateACK(); err != nil { 1156 return err 1157 } 1158 } 1159 1160 buf := make([]byte, len(testMessage)) 1161 if test.protocol == dtls { 1162 bufTmp := make([]byte, len(buf)+1) 1163 n, err := tlsConn.Read(bufTmp) 1164 if err != nil { 1165 return err 1166 } 1167 if config.Bugs.SplitAndPackAppData { 1168 m, err := tlsConn.Read(bufTmp[n:]) 1169 if err != nil { 1170 return err 1171 } 1172 n += m 1173 } 1174 if n != len(buf) { 1175 return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf)) 1176 } 1177 copy(buf, bufTmp) 1178 } else { 1179 _, err := io.ReadFull(tlsConn, buf) 1180 if err != nil { 1181 return err 1182 } 1183 } 1184 1185 for i, v := range buf { 1186 if v != testMessage[i]^0xff { 1187 return fmt.Errorf("bad reply contents at byte %d; got %q and wanted %q", i, buf, testMessage) 1188 } 1189 } 1190 1191 if seen := tlsConn.keyUpdateSeen; seen != test.expectUnsolicitedKeyUpdate { 1192 return fmt.Errorf("keyUpdateSeen (%t) != expectUnsolicitedKeyUpdate", seen) 1193 } 1194 } 1195 1196 return nil 1197} 1198 1199const xtermSize = "140x50" 1200 1201func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd { 1202 valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full", "--quiet"} 1203 if dbAttach { 1204 valgrindArgs = append(valgrindArgs, "--db-attach=yes", "--db-command=xterm -geometry "+xtermSize+" -e gdb -nw %f %p") 1205 } 1206 valgrindArgs = append(valgrindArgs, path) 1207 valgrindArgs = append(valgrindArgs, args...) 1208 1209 return exec.Command("valgrind", valgrindArgs...) 1210} 1211 1212func gdbOf(path string, args ...string) *exec.Cmd { 1213 xtermArgs := []string{"-geometry", xtermSize, "-e", "gdb", "--args"} 1214 xtermArgs = append(xtermArgs, path) 1215 xtermArgs = append(xtermArgs, args...) 1216 1217 return exec.Command("xterm", xtermArgs...) 1218} 1219 1220func lldbOf(path string, args ...string) *exec.Cmd { 1221 xtermArgs := []string{"-geometry", xtermSize, "-e", "lldb", "--"} 1222 xtermArgs = append(xtermArgs, path) 1223 xtermArgs = append(xtermArgs, args...) 1224 1225 return exec.Command("xterm", xtermArgs...) 1226} 1227 1228func rrOf(path string, args ...string) *exec.Cmd { 1229 rrArgs := []string{"record", path} 1230 rrArgs = append(rrArgs, args...) 1231 return exec.Command("rr", rrArgs...) 1232} 1233 1234func removeFirstLineIfSuffix(s, suffix string) string { 1235 idx := strings.IndexByte(s, '\n') 1236 if idx < 0 { 1237 return s 1238 } 1239 if strings.HasSuffix(s[:idx], suffix) { 1240 return s[idx+1:] 1241 } 1242 return s 1243} 1244 1245var ( 1246 errMoreMallocs = errors.New("child process did not exhaust all allocation calls") 1247 errUnimplemented = errors.New("child process does not implement needed flags") 1248) 1249 1250type shimProcess struct { 1251 cmd *exec.Cmd 1252 waitChan chan error 1253 listener *net.TCPListener 1254 stdout, stderr bytes.Buffer 1255} 1256 1257// newShimProcess starts a new shim with the specified executable, flags, and 1258// environment. It internally creates a TCP listener and adds the the -port 1259// flag. 1260func newShimProcess(shimPath string, flags []string, env []string) (*shimProcess, error) { 1261 shim := new(shimProcess) 1262 var err error 1263 shim.listener, err = net.ListenTCP("tcp", &net.TCPAddr{IP: net.IPv6loopback}) 1264 if err != nil { 1265 shim.listener, err = net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}}) 1266 } 1267 if err != nil { 1268 return nil, err 1269 } 1270 1271 flags = append([]string{"-port", strconv.Itoa(shim.listener.Addr().(*net.TCPAddr).Port)}, flags...) 1272 if *useValgrind { 1273 shim.cmd = valgrindOf(false, shimPath, flags...) 1274 } else if *useGDB { 1275 shim.cmd = gdbOf(shimPath, flags...) 1276 } else if *useLLDB { 1277 shim.cmd = lldbOf(shimPath, flags...) 1278 } else if *useRR { 1279 shim.cmd = rrOf(shimPath, flags...) 1280 } else { 1281 shim.cmd = exec.Command(shimPath, flags...) 1282 } 1283 shim.cmd.Stdin = os.Stdin 1284 shim.cmd.Stdout = &shim.stdout 1285 shim.cmd.Stderr = &shim.stderr 1286 shim.cmd.Env = env 1287 1288 if err := shim.cmd.Start(); err != nil { 1289 shim.listener.Close() 1290 return nil, err 1291 } 1292 1293 shim.waitChan = make(chan error, 1) 1294 go func() { shim.waitChan <- shim.cmd.Wait() }() 1295 return shim, nil 1296} 1297 1298// accept returns a new TCP connection with the shim process, or returns an 1299// error on timeout or shim exit. 1300func (s *shimProcess) accept() (net.Conn, error) { 1301 type connOrError struct { 1302 conn net.Conn 1303 err error 1304 } 1305 connChan := make(chan connOrError, 1) 1306 go func() { 1307 if !useDebugger() { 1308 s.listener.SetDeadline(time.Now().Add(*idleTimeout)) 1309 } 1310 conn, err := s.listener.Accept() 1311 connChan <- connOrError{conn, err} 1312 close(connChan) 1313 }() 1314 select { 1315 case result := <-connChan: 1316 return result.conn, result.err 1317 case childErr := <-s.waitChan: 1318 s.waitChan <- childErr 1319 if childErr == nil { 1320 return nil, fmt.Errorf("child exited early with no error") 1321 } 1322 return nil, fmt.Errorf("child exited early: %s", childErr) 1323 } 1324} 1325 1326// wait finishes the test and waits for the shim process to exit. 1327func (s *shimProcess) wait() error { 1328 // Close the listener now. This is to avoid hangs if the shim tries to open 1329 // more connections than expected. 1330 s.listener.Close() 1331 1332 if !useDebugger() { 1333 waitTimeout := time.AfterFunc(*idleTimeout, func() { 1334 s.cmd.Process.Kill() 1335 }) 1336 defer waitTimeout.Stop() 1337 } 1338 1339 err := <-s.waitChan 1340 s.waitChan <- err 1341 return err 1342} 1343 1344// close releases resources associated with the shimProcess. This is safe to 1345// call before or after |wait|. 1346func (s *shimProcess) close() { 1347 s.listener.Close() 1348 s.cmd.Process.Kill() 1349} 1350 1351func doExchanges(test *testCase, shim *shimProcess, resumeCount int, transcripts *[][]byte) error { 1352 config := test.config 1353 if *deterministic { 1354 config.Rand = &deterministicRand{} 1355 } 1356 1357 conn, err := shim.accept() 1358 if err != nil { 1359 return err 1360 } 1361 err = doExchange(test, &config, conn, false /* not a resumption */, transcripts, 0) 1362 conn.Close() 1363 if err != nil { 1364 return err 1365 } 1366 1367 nextTicketKey := config.SessionTicketKey 1368 for i := 0; i < resumeCount; i++ { 1369 var resumeConfig Config 1370 if test.resumeConfig != nil { 1371 resumeConfig = *test.resumeConfig 1372 resumeConfig.Rand = config.Rand 1373 } else { 1374 resumeConfig = config 1375 } 1376 1377 if test.newSessionsOnResume { 1378 resumeConfig.ClientSessionCache = nil 1379 resumeConfig.ServerSessionCache = nil 1380 if _, err := resumeConfig.rand().Read(resumeConfig.SessionTicketKey[:]); err != nil { 1381 return err 1382 } 1383 } else { 1384 resumeConfig.ClientSessionCache = config.ClientSessionCache 1385 resumeConfig.ServerSessionCache = config.ServerSessionCache 1386 // Rotate the ticket keys between each connection, with each connection 1387 // encrypting with next connection's keys. This ensures that we test 1388 // the renewed sessions. 1389 resumeConfig.SessionTicketKey = nextTicketKey 1390 if _, err := resumeConfig.rand().Read(nextTicketKey[:]); err != nil { 1391 return err 1392 } 1393 resumeConfig.Bugs.EncryptSessionTicketKey = &nextTicketKey 1394 } 1395 1396 var connResume net.Conn 1397 connResume, err = shim.accept() 1398 if err != nil { 1399 return err 1400 } 1401 err = doExchange(test, &resumeConfig, connResume, true /* resumption */, transcripts, i+1) 1402 connResume.Close() 1403 if err != nil { 1404 return err 1405 } 1406 } 1407 1408 return nil 1409} 1410 1411func translateExpectedError(errorStr string) string { 1412 if translated, ok := shimConfig.ErrorMap[errorStr]; ok { 1413 return translated 1414 } 1415 1416 if *looseErrors { 1417 return "" 1418 } 1419 1420 return errorStr 1421} 1422 1423// shimInitialWrite is the data we expect from the shim when the 1424// -shim-writes-first flag is used. 1425const shimInitialWrite = "hello" 1426 1427func runTest(statusChan chan statusMsg, test *testCase, shimPath string, mallocNumToFail int64) error { 1428 // Help debugging panics on the Go side. 1429 defer func() { 1430 if r := recover(); r != nil { 1431 fmt.Fprintf(os.Stderr, "Test '%s' panicked.\n", test.name) 1432 panic(r) 1433 } 1434 }() 1435 1436 var flags []string 1437 if test.testType == serverTest { 1438 flags = append(flags, "-server") 1439 1440 flags = append(flags, "-key-file") 1441 if test.keyFile == "" { 1442 flags = append(flags, path.Join(*resourceDir, rsaKeyFile)) 1443 } else { 1444 flags = append(flags, path.Join(*resourceDir, test.keyFile)) 1445 } 1446 1447 flags = append(flags, "-cert-file") 1448 if test.certFile == "" { 1449 flags = append(flags, path.Join(*resourceDir, rsaCertificateFile)) 1450 } else { 1451 flags = append(flags, path.Join(*resourceDir, test.certFile)) 1452 } 1453 } 1454 1455 if test.protocol == dtls { 1456 flags = append(flags, "-dtls") 1457 } else if test.protocol == quic { 1458 flags = append(flags, "-quic") 1459 if !test.skipTransportParamsConfig { 1460 test.config.QUICTransportParams = []byte{1, 2} 1461 test.config.QUICTransportParamsUseLegacyCodepoint = QUICUseCodepointStandard 1462 if test.resumeConfig != nil { 1463 test.resumeConfig.QUICTransportParams = []byte{1, 2} 1464 test.resumeConfig.QUICTransportParamsUseLegacyCodepoint = QUICUseCodepointStandard 1465 } 1466 test.expectations.quicTransportParams = []byte{3, 4} 1467 if test.resumeExpectations != nil { 1468 test.resumeExpectations.quicTransportParams = []byte{3, 4} 1469 } 1470 useCodepointFlag := "0" 1471 if test.config.QUICTransportParamsUseLegacyCodepoint == QUICUseCodepointLegacy { 1472 useCodepointFlag = "1" 1473 } 1474 flags = append(flags, 1475 "-quic-transport-params", 1476 base64FlagValue([]byte{3, 4}), 1477 "-expect-quic-transport-params", 1478 base64FlagValue([]byte{1, 2}), 1479 "-quic-use-legacy-codepoint", useCodepointFlag) 1480 } 1481 if !test.skipQUICALPNConfig { 1482 flags = append(flags, 1483 []string{ 1484 "-advertise-alpn", "\x03foo", 1485 "-select-alpn", "foo", 1486 "-expect-alpn", "foo", 1487 }...) 1488 test.config.NextProtos = []string{"foo"} 1489 if test.resumeConfig != nil { 1490 test.resumeConfig.NextProtos = []string{"foo"} 1491 } 1492 test.expectations.nextProto = "foo" 1493 test.expectations.nextProtoType = alpn 1494 if test.resumeExpectations != nil { 1495 test.resumeExpectations.nextProto = "foo" 1496 test.resumeExpectations.nextProtoType = alpn 1497 } 1498 } 1499 } 1500 1501 if test.earlyData { 1502 if !test.resumeSession { 1503 panic("earlyData set without resumeSession in " + test.name) 1504 } 1505 1506 resumeConfig := test.resumeConfig 1507 if resumeConfig == nil { 1508 resumeConfig = &test.config 1509 } 1510 if test.expectEarlyDataRejected { 1511 flags = append(flags, "-on-resume-expect-reject-early-data") 1512 } else { 1513 flags = append(flags, "-on-resume-expect-accept-early-data") 1514 } 1515 1516 if test.protocol == quic { 1517 // QUIC requires an early data context string. 1518 flags = append(flags, "-quic-early-data-context", "context") 1519 } 1520 1521 flags = append(flags, "-enable-early-data") 1522 if test.testType == clientTest { 1523 // Configure the runner with default maximum early data. 1524 flags = append(flags, "-expect-ticket-supports-early-data") 1525 if test.config.MaxEarlyDataSize == 0 { 1526 test.config.MaxEarlyDataSize = 16384 1527 } 1528 if resumeConfig.MaxEarlyDataSize == 0 { 1529 resumeConfig.MaxEarlyDataSize = 16384 1530 } 1531 1532 // Configure the shim to send some data in early data. 1533 flags = append(flags, "-on-resume-shim-writes-first") 1534 if resumeConfig.Bugs.ExpectEarlyData == nil { 1535 resumeConfig.Bugs.ExpectEarlyData = [][]byte{[]byte(shimInitialWrite)} 1536 } 1537 } else { 1538 // By default, send some early data and expect half-RTT data response. 1539 if resumeConfig.Bugs.SendEarlyData == nil { 1540 resumeConfig.Bugs.SendEarlyData = [][]byte{{1, 2, 3, 4}} 1541 } 1542 if resumeConfig.Bugs.ExpectHalfRTTData == nil { 1543 resumeConfig.Bugs.ExpectHalfRTTData = [][]byte{{254, 253, 252, 251}} 1544 } 1545 resumeConfig.Bugs.ExpectEarlyDataAccepted = !test.expectEarlyDataRejected 1546 } 1547 } 1548 1549 var resumeCount int 1550 if test.resumeSession { 1551 resumeCount++ 1552 if test.resumeRenewedSession { 1553 resumeCount++ 1554 } 1555 } 1556 1557 if resumeCount > 0 { 1558 flags = append(flags, "-resume-count", strconv.Itoa(resumeCount)) 1559 } 1560 1561 if test.shimWritesFirst { 1562 flags = append(flags, "-shim-writes-first") 1563 } 1564 1565 if test.readWithUnfinishedWrite { 1566 flags = append(flags, "-read-with-unfinished-write") 1567 } 1568 1569 if test.shimShutsDown { 1570 flags = append(flags, "-shim-shuts-down") 1571 } 1572 1573 if test.exportKeyingMaterial > 0 { 1574 flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial)) 1575 if test.useExportContext { 1576 flags = append(flags, "-use-export-context") 1577 } 1578 } 1579 if test.exportKeyingMaterial > 0 { 1580 flags = append(flags, "-export-label", test.exportLabel) 1581 flags = append(flags, "-export-context", test.exportContext) 1582 } 1583 1584 if test.exportTrafficSecrets { 1585 flags = append(flags, "-export-traffic-secrets") 1586 } 1587 1588 if test.expectResumeRejected { 1589 flags = append(flags, "-expect-session-miss") 1590 } 1591 1592 if test.testTLSUnique { 1593 flags = append(flags, "-tls-unique") 1594 } 1595 1596 if *waitForDebugger { 1597 flags = append(flags, "-wait-for-debugger") 1598 } 1599 1600 var transcriptPrefix string 1601 var transcripts [][]byte 1602 if len(*transcriptDir) != 0 { 1603 protocol := "tls" 1604 if test.protocol == dtls { 1605 protocol = "dtls" 1606 } else if test.protocol == quic { 1607 protocol = "quic" 1608 } 1609 1610 side := "client" 1611 if test.testType == serverTest { 1612 side = "server" 1613 } 1614 1615 dir := filepath.Join(*transcriptDir, protocol, side) 1616 if err := os.MkdirAll(dir, 0755); err != nil { 1617 return err 1618 } 1619 transcriptPrefix = filepath.Join(dir, test.name+"-") 1620 flags = append(flags, "-write-settings", transcriptPrefix) 1621 } 1622 1623 flags = append(flags, test.flags...) 1624 1625 var env []string 1626 if mallocNumToFail >= 0 { 1627 env = os.Environ() 1628 env = append(env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10)) 1629 if *mallocTestDebug { 1630 env = append(env, "MALLOC_BREAK_ON_FAIL=1") 1631 } 1632 env = append(env, "_MALLOC_CHECK=1") 1633 } 1634 1635 shim, err := newShimProcess(shimPath, flags, env) 1636 if err != nil { 1637 return err 1638 } 1639 statusChan <- statusMsg{test: test, statusType: statusShimStarted, pid: shim.cmd.Process.Pid} 1640 defer shim.close() 1641 1642 localErr := doExchanges(test, shim, resumeCount, &transcripts) 1643 childErr := shim.wait() 1644 1645 // Now that the shim has exited, all the settings files have been 1646 // written. Append the saved transcripts. 1647 for i, transcript := range transcripts { 1648 if err := appendTranscript(transcriptPrefix+strconv.Itoa(i), transcript); err != nil { 1649 return err 1650 } 1651 } 1652 1653 var isValgrindError, mustFail bool 1654 if exitError, ok := childErr.(*exec.ExitError); ok { 1655 switch exitError.Sys().(syscall.WaitStatus).ExitStatus() { 1656 case 88: 1657 return errMoreMallocs 1658 case 89: 1659 return errUnimplemented 1660 case 90: 1661 mustFail = true 1662 case 99: 1663 isValgrindError = true 1664 } 1665 } 1666 1667 // Account for Windows line endings. 1668 stdout := strings.Replace(shim.stdout.String(), "\r\n", "\n", -1) 1669 stderr := strings.Replace(shim.stderr.String(), "\r\n", "\n", -1) 1670 1671 // Work around an NDK / Android bug. The NDK r16 sometimes generates 1672 // binaries with the DF_1_PIE, which the runtime linker on Android N 1673 // complains about. The next NDK revision should work around this but, 1674 // in the meantime, strip its error out. 1675 // 1676 // https://github.com/android-ndk/ndk/issues/602 1677 // https://android-review.googlesource.com/c/platform/bionic/+/259790 1678 // https://android-review.googlesource.com/c/toolchain/binutils/+/571550 1679 // 1680 // Remove this after switching to the r17 NDK. 1681 stderr = removeFirstLineIfSuffix(stderr, ": unsupported flags DT_FLAGS_1=0x8000001") 1682 1683 // Separate the errors from the shim and those from tools like 1684 // AddressSanitizer. 1685 var extraStderr string 1686 if stderrParts := strings.SplitN(stderr, "--- DONE ---\n", 2); len(stderrParts) == 2 { 1687 stderr = stderrParts[0] 1688 extraStderr = stderrParts[1] 1689 } 1690 1691 failed := localErr != nil || childErr != nil 1692 expectedError := translateExpectedError(test.expectedError) 1693 correctFailure := len(expectedError) == 0 || strings.Contains(stderr, expectedError) 1694 1695 localErrString := "none" 1696 if localErr != nil { 1697 localErrString = localErr.Error() 1698 } 1699 if len(test.expectedLocalError) != 0 { 1700 correctFailure = correctFailure && strings.Contains(localErrString, test.expectedLocalError) 1701 } 1702 1703 if failed != test.shouldFail || failed && !correctFailure || mustFail { 1704 childErrString := "none" 1705 if childErr != nil { 1706 childErrString = childErr.Error() 1707 } 1708 1709 var msg string 1710 switch { 1711 case failed && !test.shouldFail: 1712 msg = "unexpected failure" 1713 case !failed && test.shouldFail: 1714 msg = "unexpected success" 1715 case failed && !correctFailure: 1716 msg = "bad error (wanted '" + expectedError + "' / '" + test.expectedLocalError + "')" 1717 case mustFail: 1718 msg = "test failure" 1719 default: 1720 panic("internal error") 1721 } 1722 1723 return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s\n%s", msg, localErrString, childErrString, stdout, stderr, extraStderr) 1724 } 1725 1726 if len(extraStderr) > 0 || (!failed && len(stderr) > 0) { 1727 return fmt.Errorf("unexpected error output:\n%s\n%s", stderr, extraStderr) 1728 } 1729 1730 if *useValgrind && isValgrindError { 1731 return fmt.Errorf("valgrind error:\n%s\n%s", stderr, extraStderr) 1732 } 1733 1734 return nil 1735} 1736 1737type tlsVersion struct { 1738 name string 1739 // version is the protocol version. 1740 version uint16 1741 // excludeFlag is the legacy shim flag to disable the version. 1742 excludeFlag string 1743 hasDTLS bool 1744 hasQUIC bool 1745 // versionDTLS, if non-zero, is the DTLS-specific representation of the version. 1746 versionDTLS uint16 1747 // versionWire, if non-zero, is the wire representation of the 1748 // version. Otherwise the wire version is the protocol version or 1749 // versionDTLS. 1750 versionWire uint16 1751} 1752 1753func (vers tlsVersion) shimFlag(protocol protocol) string { 1754 // The shim uses the protocol version in its public API, but uses the 1755 // DTLS-specific version if it exists. 1756 if protocol == dtls && vers.versionDTLS != 0 { 1757 return strconv.Itoa(int(vers.versionDTLS)) 1758 } 1759 return strconv.Itoa(int(vers.version)) 1760} 1761 1762func (vers tlsVersion) wire(protocol protocol) uint16 { 1763 if protocol == dtls && vers.versionDTLS != 0 { 1764 return vers.versionDTLS 1765 } 1766 if vers.versionWire != 0 { 1767 return vers.versionWire 1768 } 1769 return vers.version 1770} 1771 1772func (vers tlsVersion) supportsProtocol(protocol protocol) bool { 1773 if protocol == dtls { 1774 return vers.hasDTLS 1775 } 1776 if protocol == quic { 1777 return vers.hasQUIC 1778 } 1779 return true 1780} 1781 1782var tlsVersions = []tlsVersion{ 1783 { 1784 name: "TLS1", 1785 version: VersionTLS10, 1786 excludeFlag: "-no-tls1", 1787 hasDTLS: true, 1788 versionDTLS: VersionDTLS10, 1789 }, 1790 { 1791 name: "TLS11", 1792 version: VersionTLS11, 1793 excludeFlag: "-no-tls11", 1794 }, 1795 { 1796 name: "TLS12", 1797 version: VersionTLS12, 1798 excludeFlag: "-no-tls12", 1799 hasDTLS: true, 1800 versionDTLS: VersionDTLS12, 1801 }, 1802 { 1803 name: "TLS13", 1804 version: VersionTLS13, 1805 excludeFlag: "-no-tls13", 1806 hasQUIC: true, 1807 versionWire: VersionTLS13, 1808 }, 1809} 1810 1811func allVersions(protocol protocol) []tlsVersion { 1812 if protocol == tls { 1813 return tlsVersions 1814 } 1815 1816 var ret []tlsVersion 1817 for _, vers := range tlsVersions { 1818 if vers.supportsProtocol(protocol) { 1819 ret = append(ret, vers) 1820 } 1821 } 1822 return ret 1823} 1824 1825type testCipherSuite struct { 1826 name string 1827 id uint16 1828} 1829 1830var testCipherSuites = []testCipherSuite{ 1831 {"RSA_WITH_3DES_EDE_CBC_SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 1832 {"RSA_WITH_AES_128_GCM_SHA256", TLS_RSA_WITH_AES_128_GCM_SHA256}, 1833 {"RSA_WITH_AES_128_CBC_SHA", TLS_RSA_WITH_AES_128_CBC_SHA}, 1834 {"RSA_WITH_AES_256_GCM_SHA384", TLS_RSA_WITH_AES_256_GCM_SHA384}, 1835 {"RSA_WITH_AES_256_CBC_SHA", TLS_RSA_WITH_AES_256_CBC_SHA}, 1836 {"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 1837 {"ECDHE_ECDSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA}, 1838 {"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}, 1839 {"ECDHE_ECDSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}, 1840 {"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, 1841 {"ECDHE_RSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1842 {"ECDHE_RSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 1843 {"ECDHE_RSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, 1844 {"ECDHE_RSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, 1845 {"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 1846 {"PSK_WITH_AES_128_CBC_SHA", TLS_PSK_WITH_AES_128_CBC_SHA}, 1847 {"PSK_WITH_AES_256_CBC_SHA", TLS_PSK_WITH_AES_256_CBC_SHA}, 1848 {"ECDHE_PSK_WITH_AES_128_CBC_SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 1849 {"ECDHE_PSK_WITH_AES_256_CBC_SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA}, 1850 {"ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256}, 1851 {"CHACHA20_POLY1305_SHA256", TLS_CHACHA20_POLY1305_SHA256}, 1852 {"AES_128_GCM_SHA256", TLS_AES_128_GCM_SHA256}, 1853 {"AES_256_GCM_SHA384", TLS_AES_256_GCM_SHA384}, 1854 {"RSA_WITH_NULL_SHA", TLS_RSA_WITH_NULL_SHA}, 1855} 1856 1857func hasComponent(suiteName, component string) bool { 1858 return strings.Contains("_"+suiteName+"_", "_"+component+"_") 1859} 1860 1861func isTLS12Only(suiteName string) bool { 1862 return hasComponent(suiteName, "GCM") || 1863 hasComponent(suiteName, "SHA256") || 1864 hasComponent(suiteName, "SHA384") || 1865 hasComponent(suiteName, "POLY1305") 1866} 1867 1868func isTLS13Suite(suiteName string) bool { 1869 return !hasComponent(suiteName, "WITH") 1870} 1871 1872func bigFromHex(hex string) *big.Int { 1873 ret, ok := new(big.Int).SetString(hex, 16) 1874 if !ok { 1875 panic("failed to parse hex number 0x" + hex) 1876 } 1877 return ret 1878} 1879 1880func convertToSplitHandshakeTests(tests []testCase) (splitHandshakeTests []testCase, err error) { 1881 var stdout bytes.Buffer 1882 shim := exec.Command(*shimPath, "-is-handshaker-supported") 1883 shim.Stdout = &stdout 1884 if err := shim.Run(); err != nil { 1885 return nil, err 1886 } 1887 1888 switch strings.TrimSpace(string(stdout.Bytes())) { 1889 case "No": 1890 return 1891 case "Yes": 1892 break 1893 default: 1894 return nil, fmt.Errorf("unknown output from shim: %q", stdout.Bytes()) 1895 } 1896 1897 var allowHintMismatchPattern []string 1898 if len(*allowHintMismatch) > 0 { 1899 allowHintMismatchPattern = strings.Split(*allowHintMismatch, ";") 1900 } 1901 1902NextTest: 1903 for _, test := range tests { 1904 if test.protocol != tls || 1905 test.testType != serverTest || 1906 strings.Contains(test.name, "DelegatedCredentials") || 1907 strings.Contains(test.name, "ECH-Server") || 1908 test.skipSplitHandshake { 1909 continue 1910 } 1911 1912 for _, flag := range test.flags { 1913 if flag == "-implicit-handshake" { 1914 continue NextTest 1915 } 1916 } 1917 1918 shTest := test 1919 shTest.name += "-Split" 1920 shTest.flags = make([]string, len(test.flags), len(test.flags)+3) 1921 copy(shTest.flags, test.flags) 1922 shTest.flags = append(shTest.flags, "-handoff", "-handshaker-path", *handshakerPath) 1923 1924 splitHandshakeTests = append(splitHandshakeTests, shTest) 1925 } 1926 1927 for _, test := range tests { 1928 if test.protocol == dtls || 1929 test.testType != serverTest { 1930 continue 1931 } 1932 1933 var matched bool 1934 if len(allowHintMismatchPattern) > 0 { 1935 matched, err = match(allowHintMismatchPattern, nil, test.name) 1936 if err != nil { 1937 return nil, fmt.Errorf("error matching pattern: %s", err) 1938 } 1939 } 1940 1941 shTest := test 1942 shTest.name += "-Hints" 1943 shTest.flags = make([]string, len(test.flags), len(test.flags)+3) 1944 copy(shTest.flags, test.flags) 1945 shTest.flags = append(shTest.flags, "-handshake-hints", "-handshaker-path", *handshakerPath) 1946 if matched { 1947 shTest.flags = append(shTest.flags, "-allow-hint-mismatch") 1948 } 1949 1950 splitHandshakeTests = append(splitHandshakeTests, shTest) 1951 } 1952 1953 return splitHandshakeTests, nil 1954} 1955 1956func addBasicTests() { 1957 basicTests := []testCase{ 1958 { 1959 name: "NoFallbackSCSV", 1960 config: Config{ 1961 Bugs: ProtocolBugs{ 1962 FailIfNotFallbackSCSV: true, 1963 }, 1964 }, 1965 shouldFail: true, 1966 expectedLocalError: "no fallback SCSV found", 1967 }, 1968 { 1969 name: "SendFallbackSCSV", 1970 config: Config{ 1971 Bugs: ProtocolBugs{ 1972 FailIfNotFallbackSCSV: true, 1973 }, 1974 }, 1975 flags: []string{"-fallback-scsv"}, 1976 }, 1977 { 1978 name: "ClientCertificateTypes", 1979 config: Config{ 1980 MaxVersion: VersionTLS12, 1981 ClientAuth: RequestClientCert, 1982 ClientCertificateTypes: []byte{ 1983 CertTypeDSSSign, 1984 CertTypeRSASign, 1985 CertTypeECDSASign, 1986 }, 1987 }, 1988 flags: []string{ 1989 "-expect-certificate-types", 1990 base64FlagValue([]byte{ 1991 CertTypeDSSSign, 1992 CertTypeRSASign, 1993 CertTypeECDSASign, 1994 }), 1995 }, 1996 }, 1997 { 1998 name: "UnauthenticatedECDH", 1999 config: Config{ 2000 MaxVersion: VersionTLS12, 2001 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2002 Bugs: ProtocolBugs{ 2003 UnauthenticatedECDH: true, 2004 }, 2005 }, 2006 shouldFail: true, 2007 expectedError: ":UNEXPECTED_MESSAGE:", 2008 }, 2009 { 2010 name: "SkipCertificateStatus", 2011 config: Config{ 2012 MaxVersion: VersionTLS12, 2013 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2014 Bugs: ProtocolBugs{ 2015 SkipCertificateStatus: true, 2016 }, 2017 }, 2018 flags: []string{ 2019 "-enable-ocsp-stapling", 2020 // This test involves an optional message. Test the message callback 2021 // trace to ensure we do not miss or double-report any. 2022 "-expect-msg-callback", 2023 `write hs 1 2024read hs 2 2025read hs 11 2026read hs 12 2027read hs 14 2028write hs 16 2029write ccs 2030write hs 20 2031read hs 4 2032read ccs 2033read hs 20 2034read alert 1 0 2035`, 2036 }, 2037 }, 2038 { 2039 protocol: dtls, 2040 name: "SkipCertificateStatus-DTLS", 2041 config: Config{ 2042 MaxVersion: VersionTLS12, 2043 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2044 Bugs: ProtocolBugs{ 2045 SkipCertificateStatus: true, 2046 }, 2047 }, 2048 flags: []string{ 2049 "-enable-ocsp-stapling", 2050 // This test involves an optional message. Test the message callback 2051 // trace to ensure we do not miss or double-report any. 2052 "-expect-msg-callback", 2053 `write hs 1 2054read hs 3 2055write hs 1 2056read hs 2 2057read hs 11 2058read hs 12 2059read hs 14 2060write hs 16 2061write ccs 2062write hs 20 2063read hs 4 2064read ccs 2065read hs 20 2066read alert 1 0 2067`, 2068 }, 2069 }, 2070 { 2071 name: "SkipServerKeyExchange", 2072 config: Config{ 2073 MaxVersion: VersionTLS12, 2074 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2075 Bugs: ProtocolBugs{ 2076 SkipServerKeyExchange: true, 2077 }, 2078 }, 2079 shouldFail: true, 2080 expectedError: ":UNEXPECTED_MESSAGE:", 2081 }, 2082 { 2083 testType: serverTest, 2084 name: "ServerSkipCertificateVerify", 2085 config: Config{ 2086 MaxVersion: VersionTLS12, 2087 Certificates: []Certificate{rsaChainCertificate}, 2088 Bugs: ProtocolBugs{ 2089 SkipCertificateVerify: true, 2090 }, 2091 }, 2092 expectations: connectionExpectations{ 2093 peerCertificate: &rsaChainCertificate, 2094 }, 2095 flags: []string{ 2096 "-require-any-client-certificate", 2097 }, 2098 shouldFail: true, 2099 expectedError: ":UNEXPECTED_RECORD:", 2100 expectedLocalError: "remote error: unexpected message", 2101 }, 2102 { 2103 testType: serverTest, 2104 name: "Alert", 2105 config: Config{ 2106 Bugs: ProtocolBugs{ 2107 SendSpuriousAlert: alertRecordOverflow, 2108 }, 2109 }, 2110 shouldFail: true, 2111 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2112 }, 2113 { 2114 protocol: dtls, 2115 testType: serverTest, 2116 name: "Alert-DTLS", 2117 config: Config{ 2118 Bugs: ProtocolBugs{ 2119 SendSpuriousAlert: alertRecordOverflow, 2120 }, 2121 }, 2122 shouldFail: true, 2123 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2124 }, 2125 { 2126 testType: serverTest, 2127 name: "FragmentAlert", 2128 config: Config{ 2129 Bugs: ProtocolBugs{ 2130 FragmentAlert: true, 2131 SendSpuriousAlert: alertRecordOverflow, 2132 }, 2133 }, 2134 shouldFail: true, 2135 expectedError: ":BAD_ALERT:", 2136 }, 2137 { 2138 protocol: dtls, 2139 testType: serverTest, 2140 name: "FragmentAlert-DTLS", 2141 config: Config{ 2142 Bugs: ProtocolBugs{ 2143 FragmentAlert: true, 2144 SendSpuriousAlert: alertRecordOverflow, 2145 }, 2146 }, 2147 shouldFail: true, 2148 expectedError: ":BAD_ALERT:", 2149 }, 2150 { 2151 testType: serverTest, 2152 name: "DoubleAlert", 2153 config: Config{ 2154 Bugs: ProtocolBugs{ 2155 DoubleAlert: true, 2156 SendSpuriousAlert: alertRecordOverflow, 2157 }, 2158 }, 2159 shouldFail: true, 2160 expectedError: ":BAD_ALERT:", 2161 }, 2162 { 2163 protocol: dtls, 2164 testType: serverTest, 2165 name: "DoubleAlert-DTLS", 2166 config: Config{ 2167 Bugs: ProtocolBugs{ 2168 DoubleAlert: true, 2169 SendSpuriousAlert: alertRecordOverflow, 2170 }, 2171 }, 2172 shouldFail: true, 2173 expectedError: ":BAD_ALERT:", 2174 }, 2175 { 2176 name: "SkipNewSessionTicket", 2177 config: Config{ 2178 MaxVersion: VersionTLS12, 2179 Bugs: ProtocolBugs{ 2180 SkipNewSessionTicket: true, 2181 }, 2182 }, 2183 shouldFail: true, 2184 expectedError: ":UNEXPECTED_RECORD:", 2185 }, 2186 { 2187 testType: serverTest, 2188 name: "FallbackSCSV", 2189 config: Config{ 2190 MaxVersion: VersionTLS11, 2191 Bugs: ProtocolBugs{ 2192 SendFallbackSCSV: true, 2193 }, 2194 }, 2195 shouldFail: true, 2196 expectedError: ":INAPPROPRIATE_FALLBACK:", 2197 expectedLocalError: "remote error: inappropriate fallback", 2198 }, 2199 { 2200 testType: serverTest, 2201 name: "FallbackSCSV-VersionMatch-TLS13", 2202 config: Config{ 2203 MaxVersion: VersionTLS13, 2204 Bugs: ProtocolBugs{ 2205 SendFallbackSCSV: true, 2206 }, 2207 }, 2208 }, 2209 { 2210 testType: serverTest, 2211 name: "FallbackSCSV-VersionMatch-TLS12", 2212 config: Config{ 2213 MaxVersion: VersionTLS12, 2214 Bugs: ProtocolBugs{ 2215 SendFallbackSCSV: true, 2216 }, 2217 }, 2218 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 2219 }, 2220 { 2221 testType: serverTest, 2222 name: "FragmentedClientVersion", 2223 config: Config{ 2224 Bugs: ProtocolBugs{ 2225 MaxHandshakeRecordLength: 1, 2226 FragmentClientVersion: true, 2227 }, 2228 }, 2229 expectations: connectionExpectations{ 2230 version: VersionTLS13, 2231 }, 2232 }, 2233 { 2234 testType: serverTest, 2235 name: "HttpGET", 2236 sendPrefix: "GET / HTTP/1.0\n", 2237 shouldFail: true, 2238 expectedError: ":HTTP_REQUEST:", 2239 }, 2240 { 2241 testType: serverTest, 2242 name: "HttpPOST", 2243 sendPrefix: "POST / HTTP/1.0\n", 2244 shouldFail: true, 2245 expectedError: ":HTTP_REQUEST:", 2246 }, 2247 { 2248 testType: serverTest, 2249 name: "HttpHEAD", 2250 sendPrefix: "HEAD / HTTP/1.0\n", 2251 shouldFail: true, 2252 expectedError: ":HTTP_REQUEST:", 2253 }, 2254 { 2255 testType: serverTest, 2256 name: "HttpPUT", 2257 sendPrefix: "PUT / HTTP/1.0\n", 2258 shouldFail: true, 2259 expectedError: ":HTTP_REQUEST:", 2260 }, 2261 { 2262 testType: serverTest, 2263 name: "HttpCONNECT", 2264 sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n", 2265 shouldFail: true, 2266 expectedError: ":HTTPS_PROXY_REQUEST:", 2267 }, 2268 { 2269 testType: serverTest, 2270 name: "Garbage", 2271 sendPrefix: "blah", 2272 shouldFail: true, 2273 expectedError: ":WRONG_VERSION_NUMBER:", 2274 }, 2275 { 2276 name: "RSAEphemeralKey", 2277 config: Config{ 2278 MaxVersion: VersionTLS12, 2279 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 2280 Bugs: ProtocolBugs{ 2281 RSAEphemeralKey: true, 2282 }, 2283 }, 2284 shouldFail: true, 2285 expectedError: ":UNEXPECTED_MESSAGE:", 2286 }, 2287 { 2288 name: "DisableEverything", 2289 flags: []string{"-no-tls13", "-no-tls12", "-no-tls11", "-no-tls1"}, 2290 shouldFail: true, 2291 expectedError: ":NO_SUPPORTED_VERSIONS_ENABLED:", 2292 }, 2293 { 2294 protocol: dtls, 2295 name: "DisableEverything-DTLS", 2296 flags: []string{"-no-tls12", "-no-tls1"}, 2297 shouldFail: true, 2298 expectedError: ":NO_SUPPORTED_VERSIONS_ENABLED:", 2299 }, 2300 { 2301 protocol: dtls, 2302 testType: serverTest, 2303 name: "MTU", 2304 config: Config{ 2305 Bugs: ProtocolBugs{ 2306 MaxPacketLength: 256, 2307 }, 2308 }, 2309 flags: []string{"-mtu", "256"}, 2310 }, 2311 { 2312 protocol: dtls, 2313 testType: serverTest, 2314 name: "MTUExceeded", 2315 config: Config{ 2316 Bugs: ProtocolBugs{ 2317 MaxPacketLength: 255, 2318 }, 2319 }, 2320 flags: []string{"-mtu", "256"}, 2321 shouldFail: true, 2322 expectedLocalError: "dtls: exceeded maximum packet length", 2323 }, 2324 { 2325 name: "EmptyCertificateList", 2326 config: Config{ 2327 MaxVersion: VersionTLS12, 2328 Bugs: ProtocolBugs{ 2329 EmptyCertificateList: true, 2330 }, 2331 }, 2332 shouldFail: true, 2333 expectedError: ":DECODE_ERROR:", 2334 }, 2335 { 2336 name: "EmptyCertificateList-TLS13", 2337 config: Config{ 2338 MaxVersion: VersionTLS13, 2339 Bugs: ProtocolBugs{ 2340 EmptyCertificateList: true, 2341 }, 2342 }, 2343 shouldFail: true, 2344 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 2345 }, 2346 { 2347 name: "TLSFatalBadPackets", 2348 damageFirstWrite: true, 2349 shouldFail: true, 2350 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 2351 }, 2352 { 2353 protocol: dtls, 2354 name: "DTLSIgnoreBadPackets", 2355 damageFirstWrite: true, 2356 }, 2357 { 2358 protocol: dtls, 2359 name: "DTLSIgnoreBadPackets-Async", 2360 damageFirstWrite: true, 2361 flags: []string{"-async"}, 2362 }, 2363 { 2364 name: "AppDataBeforeHandshake", 2365 config: Config{ 2366 Bugs: ProtocolBugs{ 2367 AppDataBeforeHandshake: []byte("TEST MESSAGE"), 2368 }, 2369 }, 2370 shouldFail: true, 2371 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2372 }, 2373 { 2374 name: "AppDataBeforeHandshake-Empty", 2375 config: Config{ 2376 Bugs: ProtocolBugs{ 2377 AppDataBeforeHandshake: []byte{}, 2378 }, 2379 }, 2380 shouldFail: true, 2381 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2382 }, 2383 { 2384 protocol: dtls, 2385 name: "AppDataBeforeHandshake-DTLS", 2386 config: Config{ 2387 Bugs: ProtocolBugs{ 2388 AppDataBeforeHandshake: []byte("TEST MESSAGE"), 2389 }, 2390 }, 2391 shouldFail: true, 2392 expectedError: ":UNEXPECTED_RECORD:", 2393 }, 2394 { 2395 protocol: dtls, 2396 name: "AppDataBeforeHandshake-DTLS-Empty", 2397 config: Config{ 2398 Bugs: ProtocolBugs{ 2399 AppDataBeforeHandshake: []byte{}, 2400 }, 2401 }, 2402 shouldFail: true, 2403 expectedError: ":UNEXPECTED_RECORD:", 2404 }, 2405 { 2406 name: "AppDataAfterChangeCipherSpec", 2407 config: Config{ 2408 MaxVersion: VersionTLS12, 2409 Bugs: ProtocolBugs{ 2410 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"), 2411 }, 2412 }, 2413 shouldFail: true, 2414 expectedError: ":UNEXPECTED_RECORD:", 2415 }, 2416 { 2417 name: "AppDataAfterChangeCipherSpec-Empty", 2418 config: Config{ 2419 MaxVersion: VersionTLS12, 2420 Bugs: ProtocolBugs{ 2421 AppDataAfterChangeCipherSpec: []byte{}, 2422 }, 2423 }, 2424 shouldFail: true, 2425 expectedError: ":UNEXPECTED_RECORD:", 2426 }, 2427 { 2428 protocol: dtls, 2429 name: "AppDataAfterChangeCipherSpec-DTLS", 2430 config: Config{ 2431 MaxVersion: VersionTLS12, 2432 Bugs: ProtocolBugs{ 2433 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"), 2434 }, 2435 }, 2436 // BoringSSL's DTLS implementation will drop the out-of-order 2437 // application data. 2438 }, 2439 { 2440 protocol: dtls, 2441 name: "AppDataAfterChangeCipherSpec-DTLS-Empty", 2442 config: Config{ 2443 MaxVersion: VersionTLS12, 2444 Bugs: ProtocolBugs{ 2445 AppDataAfterChangeCipherSpec: []byte{}, 2446 }, 2447 }, 2448 // BoringSSL's DTLS implementation will drop the out-of-order 2449 // application data. 2450 }, 2451 { 2452 name: "AlertAfterChangeCipherSpec", 2453 config: Config{ 2454 MaxVersion: VersionTLS12, 2455 Bugs: ProtocolBugs{ 2456 AlertAfterChangeCipherSpec: alertRecordOverflow, 2457 }, 2458 }, 2459 shouldFail: true, 2460 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2461 }, 2462 { 2463 protocol: dtls, 2464 name: "AlertAfterChangeCipherSpec-DTLS", 2465 config: Config{ 2466 MaxVersion: VersionTLS12, 2467 Bugs: ProtocolBugs{ 2468 AlertAfterChangeCipherSpec: alertRecordOverflow, 2469 }, 2470 }, 2471 shouldFail: true, 2472 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2473 }, 2474 { 2475 protocol: dtls, 2476 name: "ReorderHandshakeFragments-Small-DTLS", 2477 config: Config{ 2478 Bugs: ProtocolBugs{ 2479 ReorderHandshakeFragments: true, 2480 // Small enough that every handshake message is 2481 // fragmented. 2482 MaxHandshakeRecordLength: 2, 2483 }, 2484 }, 2485 }, 2486 { 2487 protocol: dtls, 2488 name: "ReorderHandshakeFragments-Large-DTLS", 2489 config: Config{ 2490 Bugs: ProtocolBugs{ 2491 ReorderHandshakeFragments: true, 2492 // Large enough that no handshake message is 2493 // fragmented. 2494 MaxHandshakeRecordLength: 2048, 2495 }, 2496 }, 2497 }, 2498 { 2499 protocol: dtls, 2500 name: "MixCompleteMessageWithFragments-DTLS", 2501 config: Config{ 2502 Bugs: ProtocolBugs{ 2503 ReorderHandshakeFragments: true, 2504 MixCompleteMessageWithFragments: true, 2505 MaxHandshakeRecordLength: 2, 2506 }, 2507 }, 2508 }, 2509 { 2510 name: "SendInvalidRecordType", 2511 config: Config{ 2512 Bugs: ProtocolBugs{ 2513 SendInvalidRecordType: true, 2514 }, 2515 }, 2516 shouldFail: true, 2517 expectedError: ":UNEXPECTED_RECORD:", 2518 }, 2519 { 2520 protocol: dtls, 2521 name: "SendInvalidRecordType-DTLS", 2522 config: Config{ 2523 Bugs: ProtocolBugs{ 2524 SendInvalidRecordType: true, 2525 }, 2526 }, 2527 shouldFail: true, 2528 expectedError: ":UNEXPECTED_RECORD:", 2529 }, 2530 { 2531 name: "FalseStart-SkipServerSecondLeg", 2532 config: Config{ 2533 MaxVersion: VersionTLS12, 2534 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2535 NextProtos: []string{"foo"}, 2536 Bugs: ProtocolBugs{ 2537 SkipNewSessionTicket: true, 2538 SkipChangeCipherSpec: true, 2539 SkipFinished: true, 2540 ExpectFalseStart: true, 2541 }, 2542 }, 2543 flags: []string{ 2544 "-false-start", 2545 "-handshake-never-done", 2546 "-advertise-alpn", "\x03foo", 2547 "-expect-alpn", "foo", 2548 }, 2549 shimWritesFirst: true, 2550 shouldFail: true, 2551 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2552 }, 2553 { 2554 name: "FalseStart-SkipServerSecondLeg-Implicit", 2555 config: Config{ 2556 MaxVersion: VersionTLS12, 2557 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2558 NextProtos: []string{"foo"}, 2559 Bugs: ProtocolBugs{ 2560 SkipNewSessionTicket: true, 2561 SkipChangeCipherSpec: true, 2562 SkipFinished: true, 2563 }, 2564 }, 2565 flags: []string{ 2566 "-implicit-handshake", 2567 "-false-start", 2568 "-handshake-never-done", 2569 "-advertise-alpn", "\x03foo", 2570 }, 2571 shouldFail: true, 2572 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2573 }, 2574 { 2575 testType: serverTest, 2576 name: "FailEarlyCallback", 2577 flags: []string{"-fail-early-callback"}, 2578 shouldFail: true, 2579 expectedError: ":CONNECTION_REJECTED:", 2580 expectedLocalError: "remote error: handshake failure", 2581 }, 2582 { 2583 name: "FailCertCallback-Client-TLS12", 2584 config: Config{ 2585 MaxVersion: VersionTLS12, 2586 ClientAuth: RequestClientCert, 2587 }, 2588 flags: []string{"-fail-cert-callback"}, 2589 shouldFail: true, 2590 expectedError: ":CERT_CB_ERROR:", 2591 expectedLocalError: "remote error: internal error", 2592 }, 2593 { 2594 testType: serverTest, 2595 name: "FailCertCallback-Server-TLS12", 2596 config: Config{ 2597 MaxVersion: VersionTLS12, 2598 }, 2599 flags: []string{"-fail-cert-callback"}, 2600 shouldFail: true, 2601 expectedError: ":CERT_CB_ERROR:", 2602 expectedLocalError: "remote error: internal error", 2603 }, 2604 { 2605 name: "FailCertCallback-Client-TLS13", 2606 config: Config{ 2607 MaxVersion: VersionTLS13, 2608 ClientAuth: RequestClientCert, 2609 }, 2610 flags: []string{"-fail-cert-callback"}, 2611 shouldFail: true, 2612 expectedError: ":CERT_CB_ERROR:", 2613 expectedLocalError: "remote error: internal error", 2614 }, 2615 { 2616 testType: serverTest, 2617 name: "FailCertCallback-Server-TLS13", 2618 config: Config{ 2619 MaxVersion: VersionTLS13, 2620 }, 2621 flags: []string{"-fail-cert-callback"}, 2622 shouldFail: true, 2623 expectedError: ":CERT_CB_ERROR:", 2624 expectedLocalError: "remote error: internal error", 2625 }, 2626 { 2627 protocol: dtls, 2628 name: "FragmentMessageTypeMismatch-DTLS", 2629 config: Config{ 2630 Bugs: ProtocolBugs{ 2631 MaxHandshakeRecordLength: 2, 2632 FragmentMessageTypeMismatch: true, 2633 }, 2634 }, 2635 shouldFail: true, 2636 expectedError: ":FRAGMENT_MISMATCH:", 2637 }, 2638 { 2639 protocol: dtls, 2640 name: "FragmentMessageLengthMismatch-DTLS", 2641 config: Config{ 2642 Bugs: ProtocolBugs{ 2643 MaxHandshakeRecordLength: 2, 2644 FragmentMessageLengthMismatch: true, 2645 }, 2646 }, 2647 shouldFail: true, 2648 expectedError: ":FRAGMENT_MISMATCH:", 2649 }, 2650 { 2651 protocol: dtls, 2652 name: "SplitFragments-Header-DTLS", 2653 config: Config{ 2654 Bugs: ProtocolBugs{ 2655 SplitFragments: 2, 2656 }, 2657 }, 2658 shouldFail: true, 2659 expectedError: ":BAD_HANDSHAKE_RECORD:", 2660 }, 2661 { 2662 protocol: dtls, 2663 name: "SplitFragments-Boundary-DTLS", 2664 config: Config{ 2665 Bugs: ProtocolBugs{ 2666 SplitFragments: dtlsRecordHeaderLen, 2667 }, 2668 }, 2669 shouldFail: true, 2670 expectedError: ":BAD_HANDSHAKE_RECORD:", 2671 }, 2672 { 2673 protocol: dtls, 2674 name: "SplitFragments-Body-DTLS", 2675 config: Config{ 2676 Bugs: ProtocolBugs{ 2677 SplitFragments: dtlsRecordHeaderLen + 1, 2678 }, 2679 }, 2680 shouldFail: true, 2681 expectedError: ":BAD_HANDSHAKE_RECORD:", 2682 }, 2683 { 2684 protocol: dtls, 2685 name: "SendEmptyFragments-DTLS", 2686 config: Config{ 2687 Bugs: ProtocolBugs{ 2688 SendEmptyFragments: true, 2689 }, 2690 }, 2691 }, 2692 { 2693 testType: serverTest, 2694 protocol: dtls, 2695 name: "SendEmptyFragments-Padded-DTLS", 2696 config: Config{ 2697 Bugs: ProtocolBugs{ 2698 // Test empty fragments for a message with a 2699 // nice power-of-two length. 2700 PadClientHello: 64, 2701 SendEmptyFragments: true, 2702 }, 2703 }, 2704 }, 2705 { 2706 name: "BadFinished-Client", 2707 config: Config{ 2708 MaxVersion: VersionTLS12, 2709 Bugs: ProtocolBugs{ 2710 BadFinished: true, 2711 }, 2712 }, 2713 shouldFail: true, 2714 expectedError: ":DIGEST_CHECK_FAILED:", 2715 }, 2716 { 2717 name: "BadFinished-Client-TLS13", 2718 config: Config{ 2719 MaxVersion: VersionTLS13, 2720 Bugs: ProtocolBugs{ 2721 BadFinished: true, 2722 }, 2723 }, 2724 shouldFail: true, 2725 expectedError: ":DIGEST_CHECK_FAILED:", 2726 }, 2727 { 2728 testType: serverTest, 2729 name: "BadFinished-Server", 2730 config: Config{ 2731 MaxVersion: VersionTLS12, 2732 Bugs: ProtocolBugs{ 2733 BadFinished: true, 2734 }, 2735 }, 2736 shouldFail: true, 2737 expectedError: ":DIGEST_CHECK_FAILED:", 2738 }, 2739 { 2740 testType: serverTest, 2741 name: "BadFinished-Server-TLS13", 2742 config: Config{ 2743 MaxVersion: VersionTLS13, 2744 Bugs: ProtocolBugs{ 2745 BadFinished: true, 2746 }, 2747 }, 2748 shouldFail: true, 2749 expectedError: ":DIGEST_CHECK_FAILED:", 2750 }, 2751 { 2752 name: "FalseStart-BadFinished", 2753 config: Config{ 2754 MaxVersion: VersionTLS12, 2755 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2756 NextProtos: []string{"foo"}, 2757 Bugs: ProtocolBugs{ 2758 BadFinished: true, 2759 ExpectFalseStart: true, 2760 }, 2761 }, 2762 flags: []string{ 2763 "-false-start", 2764 "-handshake-never-done", 2765 "-advertise-alpn", "\x03foo", 2766 "-expect-alpn", "foo", 2767 }, 2768 shimWritesFirst: true, 2769 shouldFail: true, 2770 expectedError: ":DIGEST_CHECK_FAILED:", 2771 }, 2772 { 2773 name: "NoFalseStart-NoALPN", 2774 config: Config{ 2775 MaxVersion: VersionTLS12, 2776 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2777 Bugs: ProtocolBugs{ 2778 ExpectFalseStart: true, 2779 AlertBeforeFalseStartTest: alertAccessDenied, 2780 }, 2781 }, 2782 flags: []string{ 2783 "-false-start", 2784 }, 2785 shimWritesFirst: true, 2786 shouldFail: true, 2787 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 2788 expectedLocalError: "tls: peer did not false start: EOF", 2789 }, 2790 { 2791 name: "FalseStart-NoALPNAllowed", 2792 config: Config{ 2793 MaxVersion: VersionTLS12, 2794 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2795 Bugs: ProtocolBugs{ 2796 ExpectFalseStart: true, 2797 }, 2798 }, 2799 flags: []string{ 2800 "-false-start", 2801 "-allow-false-start-without-alpn", 2802 }, 2803 shimWritesFirst: true, 2804 }, 2805 { 2806 name: "NoFalseStart-NoAEAD", 2807 config: Config{ 2808 MaxVersion: VersionTLS12, 2809 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 2810 NextProtos: []string{"foo"}, 2811 Bugs: ProtocolBugs{ 2812 ExpectFalseStart: true, 2813 AlertBeforeFalseStartTest: alertAccessDenied, 2814 }, 2815 }, 2816 flags: []string{ 2817 "-false-start", 2818 "-advertise-alpn", "\x03foo", 2819 }, 2820 shimWritesFirst: true, 2821 shouldFail: true, 2822 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 2823 expectedLocalError: "tls: peer did not false start: EOF", 2824 }, 2825 { 2826 name: "NoFalseStart-RSA", 2827 config: Config{ 2828 MaxVersion: VersionTLS12, 2829 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 2830 NextProtos: []string{"foo"}, 2831 Bugs: ProtocolBugs{ 2832 ExpectFalseStart: true, 2833 AlertBeforeFalseStartTest: alertAccessDenied, 2834 }, 2835 }, 2836 flags: []string{ 2837 "-false-start", 2838 "-advertise-alpn", "\x03foo", 2839 }, 2840 shimWritesFirst: true, 2841 shouldFail: true, 2842 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 2843 expectedLocalError: "tls: peer did not false start: EOF", 2844 }, 2845 { 2846 protocol: dtls, 2847 name: "SendSplitAlert-Sync", 2848 config: Config{ 2849 Bugs: ProtocolBugs{ 2850 SendSplitAlert: true, 2851 }, 2852 }, 2853 }, 2854 { 2855 protocol: dtls, 2856 name: "SendSplitAlert-Async", 2857 config: Config{ 2858 Bugs: ProtocolBugs{ 2859 SendSplitAlert: true, 2860 }, 2861 }, 2862 flags: []string{"-async"}, 2863 }, 2864 { 2865 name: "SendEmptyRecords-Pass", 2866 sendEmptyRecords: 32, 2867 }, 2868 { 2869 name: "SendEmptyRecords", 2870 sendEmptyRecords: 33, 2871 shouldFail: true, 2872 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 2873 }, 2874 { 2875 name: "SendEmptyRecords-Async", 2876 sendEmptyRecords: 33, 2877 flags: []string{"-async"}, 2878 shouldFail: true, 2879 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 2880 }, 2881 { 2882 name: "SendWarningAlerts-Pass", 2883 config: Config{ 2884 MaxVersion: VersionTLS12, 2885 }, 2886 sendWarningAlerts: 4, 2887 }, 2888 { 2889 protocol: dtls, 2890 name: "SendWarningAlerts-DTLS-Pass", 2891 config: Config{ 2892 MaxVersion: VersionTLS12, 2893 }, 2894 sendWarningAlerts: 4, 2895 }, 2896 { 2897 name: "SendWarningAlerts-TLS13", 2898 config: Config{ 2899 MaxVersion: VersionTLS13, 2900 }, 2901 sendWarningAlerts: 4, 2902 shouldFail: true, 2903 expectedError: ":BAD_ALERT:", 2904 expectedLocalError: "remote error: error decoding message", 2905 }, 2906 // Although TLS 1.3 intended to remove warning alerts, it left in 2907 // user_canceled. JDK11 misuses this alert as a post-handshake 2908 // full-duplex signal. As a workaround, skip user_canceled as in 2909 // TLS 1.2, which is consistent with NSS and OpenSSL. 2910 { 2911 name: "SendUserCanceledAlerts-TLS13", 2912 config: Config{ 2913 MaxVersion: VersionTLS13, 2914 }, 2915 sendUserCanceledAlerts: 4, 2916 }, 2917 { 2918 name: "SendUserCanceledAlerts-TooMany-TLS13", 2919 config: Config{ 2920 MaxVersion: VersionTLS13, 2921 }, 2922 sendUserCanceledAlerts: 5, 2923 shouldFail: true, 2924 expectedError: ":TOO_MANY_WARNING_ALERTS:", 2925 }, 2926 { 2927 name: "SendWarningAlerts-TooMany", 2928 config: Config{ 2929 MaxVersion: VersionTLS12, 2930 }, 2931 sendWarningAlerts: 5, 2932 shouldFail: true, 2933 expectedError: ":TOO_MANY_WARNING_ALERTS:", 2934 }, 2935 { 2936 name: "SendWarningAlerts-TooMany-Async", 2937 config: Config{ 2938 MaxVersion: VersionTLS12, 2939 }, 2940 sendWarningAlerts: 5, 2941 flags: []string{"-async"}, 2942 shouldFail: true, 2943 expectedError: ":TOO_MANY_WARNING_ALERTS:", 2944 }, 2945 { 2946 name: "SendBogusAlertType", 2947 sendBogusAlertType: true, 2948 shouldFail: true, 2949 expectedError: ":UNKNOWN_ALERT_TYPE:", 2950 expectedLocalError: "remote error: illegal parameter", 2951 }, 2952 { 2953 protocol: dtls, 2954 name: "SendBogusAlertType-DTLS", 2955 sendBogusAlertType: true, 2956 shouldFail: true, 2957 expectedError: ":UNKNOWN_ALERT_TYPE:", 2958 expectedLocalError: "remote error: illegal parameter", 2959 }, 2960 { 2961 name: "TooManyKeyUpdates", 2962 config: Config{ 2963 MaxVersion: VersionTLS13, 2964 }, 2965 sendKeyUpdates: 33, 2966 keyUpdateRequest: keyUpdateNotRequested, 2967 shouldFail: true, 2968 expectedError: ":TOO_MANY_KEY_UPDATES:", 2969 }, 2970 { 2971 name: "EmptySessionID", 2972 config: Config{ 2973 MaxVersion: VersionTLS12, 2974 SessionTicketsDisabled: true, 2975 }, 2976 noSessionCache: true, 2977 flags: []string{"-expect-no-session"}, 2978 }, 2979 { 2980 name: "Unclean-Shutdown", 2981 config: Config{ 2982 Bugs: ProtocolBugs{ 2983 NoCloseNotify: true, 2984 ExpectCloseNotify: true, 2985 }, 2986 }, 2987 shimShutsDown: true, 2988 flags: []string{"-check-close-notify"}, 2989 shouldFail: true, 2990 expectedError: "Unexpected SSL_shutdown result: -1 != 1", 2991 }, 2992 { 2993 name: "Unclean-Shutdown-Ignored", 2994 config: Config{ 2995 Bugs: ProtocolBugs{ 2996 NoCloseNotify: true, 2997 }, 2998 }, 2999 shimShutsDown: true, 3000 }, 3001 { 3002 name: "Unclean-Shutdown-Alert", 3003 config: Config{ 3004 Bugs: ProtocolBugs{ 3005 SendAlertOnShutdown: alertDecompressionFailure, 3006 ExpectCloseNotify: true, 3007 }, 3008 }, 3009 shimShutsDown: true, 3010 flags: []string{"-check-close-notify"}, 3011 shouldFail: true, 3012 expectedError: ":SSLV3_ALERT_DECOMPRESSION_FAILURE:", 3013 }, 3014 { 3015 name: "LargePlaintext", 3016 config: Config{ 3017 Bugs: ProtocolBugs{ 3018 SendLargeRecords: true, 3019 }, 3020 }, 3021 messageLen: maxPlaintext + 1, 3022 shouldFail: true, 3023 expectedError: ":DATA_LENGTH_TOO_LONG:", 3024 expectedLocalError: "remote error: record overflow", 3025 }, 3026 { 3027 protocol: dtls, 3028 name: "LargePlaintext-DTLS", 3029 config: Config{ 3030 Bugs: ProtocolBugs{ 3031 SendLargeRecords: true, 3032 }, 3033 }, 3034 messageLen: maxPlaintext + 1, 3035 shouldFail: true, 3036 expectedError: ":DATA_LENGTH_TOO_LONG:", 3037 expectedLocalError: "remote error: record overflow", 3038 }, 3039 { 3040 name: "LargePlaintext-TLS13-Padded-8192-8192", 3041 config: Config{ 3042 MinVersion: VersionTLS13, 3043 MaxVersion: VersionTLS13, 3044 Bugs: ProtocolBugs{ 3045 RecordPadding: 8192, 3046 SendLargeRecords: true, 3047 }, 3048 }, 3049 messageLen: 8192, 3050 }, 3051 { 3052 name: "LargePlaintext-TLS13-Padded-8193-8192", 3053 config: Config{ 3054 MinVersion: VersionTLS13, 3055 MaxVersion: VersionTLS13, 3056 Bugs: ProtocolBugs{ 3057 RecordPadding: 8193, 3058 SendLargeRecords: true, 3059 }, 3060 }, 3061 messageLen: 8192, 3062 shouldFail: true, 3063 expectedError: ":DATA_LENGTH_TOO_LONG:", 3064 expectedLocalError: "remote error: record overflow", 3065 }, 3066 { 3067 name: "LargePlaintext-TLS13-Padded-16383-1", 3068 config: Config{ 3069 MinVersion: VersionTLS13, 3070 MaxVersion: VersionTLS13, 3071 Bugs: ProtocolBugs{ 3072 RecordPadding: 1, 3073 SendLargeRecords: true, 3074 }, 3075 }, 3076 messageLen: 16383, 3077 }, 3078 { 3079 name: "LargePlaintext-TLS13-Padded-16384-1", 3080 config: Config{ 3081 MinVersion: VersionTLS13, 3082 MaxVersion: VersionTLS13, 3083 Bugs: ProtocolBugs{ 3084 RecordPadding: 1, 3085 SendLargeRecords: true, 3086 }, 3087 }, 3088 messageLen: 16384, 3089 shouldFail: true, 3090 expectedError: ":DATA_LENGTH_TOO_LONG:", 3091 expectedLocalError: "remote error: record overflow", 3092 }, 3093 { 3094 name: "LargeCiphertext", 3095 config: Config{ 3096 Bugs: ProtocolBugs{ 3097 SendLargeRecords: true, 3098 }, 3099 }, 3100 messageLen: maxPlaintext * 2, 3101 shouldFail: true, 3102 expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:", 3103 }, 3104 { 3105 protocol: dtls, 3106 name: "LargeCiphertext-DTLS", 3107 config: Config{ 3108 Bugs: ProtocolBugs{ 3109 SendLargeRecords: true, 3110 }, 3111 }, 3112 messageLen: maxPlaintext * 2, 3113 // Unlike the other four cases, DTLS drops records which 3114 // are invalid before authentication, so the connection 3115 // does not fail. 3116 expectMessageDropped: true, 3117 }, 3118 { 3119 name: "BadHelloRequest-1", 3120 renegotiate: 1, 3121 config: Config{ 3122 MaxVersion: VersionTLS12, 3123 Bugs: ProtocolBugs{ 3124 BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1}, 3125 }, 3126 }, 3127 flags: []string{ 3128 "-renegotiate-freely", 3129 "-expect-total-renegotiations", "1", 3130 }, 3131 shouldFail: true, 3132 expectedError: ":BAD_HELLO_REQUEST:", 3133 }, 3134 { 3135 name: "BadHelloRequest-2", 3136 renegotiate: 1, 3137 config: Config{ 3138 MaxVersion: VersionTLS12, 3139 Bugs: ProtocolBugs{ 3140 BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0}, 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 testType: serverTest, 3152 name: "SupportTicketsWithSessionID", 3153 config: Config{ 3154 MaxVersion: VersionTLS12, 3155 SessionTicketsDisabled: true, 3156 }, 3157 resumeConfig: &Config{ 3158 MaxVersion: VersionTLS12, 3159 }, 3160 resumeSession: true, 3161 }, 3162 { 3163 protocol: dtls, 3164 name: "DTLS-SendExtraFinished", 3165 config: Config{ 3166 Bugs: ProtocolBugs{ 3167 SendExtraFinished: true, 3168 }, 3169 }, 3170 shouldFail: true, 3171 expectedError: ":UNEXPECTED_RECORD:", 3172 }, 3173 { 3174 protocol: dtls, 3175 name: "DTLS-SendExtraFinished-Reordered", 3176 config: Config{ 3177 Bugs: ProtocolBugs{ 3178 MaxHandshakeRecordLength: 2, 3179 ReorderHandshakeFragments: true, 3180 SendExtraFinished: true, 3181 }, 3182 }, 3183 shouldFail: true, 3184 expectedError: ":UNEXPECTED_RECORD:", 3185 }, 3186 { 3187 testType: serverTest, 3188 name: "V2ClientHello-EmptyRecordPrefix", 3189 config: Config{ 3190 // Choose a cipher suite that does not involve 3191 // elliptic curves, so no extensions are 3192 // involved. 3193 MaxVersion: VersionTLS12, 3194 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 3195 Bugs: ProtocolBugs{ 3196 SendV2ClientHello: true, 3197 }, 3198 }, 3199 sendPrefix: string([]byte{ 3200 byte(recordTypeHandshake), 3201 3, 1, // version 3202 0, 0, // length 3203 }), 3204 // A no-op empty record may not be sent before V2ClientHello. 3205 shouldFail: true, 3206 expectedError: ":WRONG_VERSION_NUMBER:", 3207 }, 3208 { 3209 testType: serverTest, 3210 name: "V2ClientHello-WarningAlertPrefix", 3211 config: Config{ 3212 // Choose a cipher suite that does not involve 3213 // elliptic curves, so no extensions are 3214 // involved. 3215 MaxVersion: VersionTLS12, 3216 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 3217 Bugs: ProtocolBugs{ 3218 SendV2ClientHello: true, 3219 }, 3220 }, 3221 sendPrefix: string([]byte{ 3222 byte(recordTypeAlert), 3223 3, 1, // version 3224 0, 2, // length 3225 alertLevelWarning, byte(alertDecompressionFailure), 3226 }), 3227 // A no-op warning alert may not be sent before V2ClientHello. 3228 shouldFail: true, 3229 expectedError: ":WRONG_VERSION_NUMBER:", 3230 }, 3231 { 3232 name: "KeyUpdate-ToClient", 3233 config: Config{ 3234 MaxVersion: VersionTLS13, 3235 }, 3236 sendKeyUpdates: 1, 3237 keyUpdateRequest: keyUpdateNotRequested, 3238 }, 3239 { 3240 testType: serverTest, 3241 name: "KeyUpdate-ToServer", 3242 config: Config{ 3243 MaxVersion: VersionTLS13, 3244 }, 3245 sendKeyUpdates: 1, 3246 keyUpdateRequest: keyUpdateNotRequested, 3247 }, 3248 { 3249 name: "KeyUpdate-FromClient", 3250 config: Config{ 3251 MaxVersion: VersionTLS13, 3252 }, 3253 expectUnsolicitedKeyUpdate: true, 3254 flags: []string{"-key-update"}, 3255 }, 3256 { 3257 testType: serverTest, 3258 name: "KeyUpdate-FromServer", 3259 config: Config{ 3260 MaxVersion: VersionTLS13, 3261 }, 3262 expectUnsolicitedKeyUpdate: true, 3263 flags: []string{"-key-update"}, 3264 }, 3265 { 3266 name: "KeyUpdate-InvalidRequestMode", 3267 config: Config{ 3268 MaxVersion: VersionTLS13, 3269 }, 3270 sendKeyUpdates: 1, 3271 keyUpdateRequest: 42, 3272 shouldFail: true, 3273 expectedError: ":DECODE_ERROR:", 3274 }, 3275 { 3276 // Test that KeyUpdates are acknowledged properly. 3277 name: "KeyUpdate-RequestACK", 3278 config: Config{ 3279 MaxVersion: VersionTLS13, 3280 Bugs: ProtocolBugs{ 3281 RejectUnsolicitedKeyUpdate: true, 3282 }, 3283 }, 3284 // Test the shim receiving many KeyUpdates in a row. 3285 sendKeyUpdates: 5, 3286 messageCount: 5, 3287 keyUpdateRequest: keyUpdateRequested, 3288 }, 3289 { 3290 // Test that KeyUpdates are acknowledged properly if the 3291 // peer's KeyUpdate is discovered while a write is 3292 // pending. 3293 name: "KeyUpdate-RequestACK-UnfinishedWrite", 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 readWithUnfinishedWrite: true, 3305 flags: []string{"-async"}, 3306 }, 3307 { 3308 name: "SendSNIWarningAlert", 3309 config: Config{ 3310 MaxVersion: VersionTLS12, 3311 Bugs: ProtocolBugs{ 3312 SendSNIWarningAlert: true, 3313 }, 3314 }, 3315 }, 3316 { 3317 testType: serverTest, 3318 name: "ExtraCompressionMethods-TLS12", 3319 config: Config{ 3320 MaxVersion: VersionTLS12, 3321 Bugs: ProtocolBugs{ 3322 SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6}, 3323 }, 3324 }, 3325 }, 3326 { 3327 testType: serverTest, 3328 name: "ExtraCompressionMethods-TLS13", 3329 config: Config{ 3330 MaxVersion: VersionTLS13, 3331 Bugs: ProtocolBugs{ 3332 SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6}, 3333 }, 3334 }, 3335 shouldFail: true, 3336 expectedError: ":INVALID_COMPRESSION_LIST:", 3337 expectedLocalError: "remote error: illegal parameter", 3338 }, 3339 { 3340 testType: serverTest, 3341 name: "NoNullCompression-TLS12", 3342 config: Config{ 3343 MaxVersion: VersionTLS12, 3344 Bugs: ProtocolBugs{ 3345 SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6}, 3346 }, 3347 }, 3348 shouldFail: true, 3349 expectedError: ":INVALID_COMPRESSION_LIST:", 3350 expectedLocalError: "remote error: illegal parameter", 3351 }, 3352 { 3353 testType: serverTest, 3354 name: "NoNullCompression-TLS13", 3355 config: Config{ 3356 MaxVersion: VersionTLS13, 3357 Bugs: ProtocolBugs{ 3358 SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6}, 3359 }, 3360 }, 3361 shouldFail: true, 3362 expectedError: ":INVALID_COMPRESSION_LIST:", 3363 expectedLocalError: "remote error: illegal parameter", 3364 }, 3365 // Test that the client rejects invalid compression methods 3366 // from the server. 3367 { 3368 testType: clientTest, 3369 name: "InvalidCompressionMethod", 3370 config: Config{ 3371 MaxVersion: VersionTLS12, 3372 Bugs: ProtocolBugs{ 3373 SendCompressionMethod: 1, 3374 }, 3375 }, 3376 shouldFail: true, 3377 expectedError: ":UNSUPPORTED_COMPRESSION_ALGORITHM:", 3378 expectedLocalError: "remote error: illegal parameter", 3379 }, 3380 { 3381 testType: clientTest, 3382 name: "TLS13-InvalidCompressionMethod", 3383 config: Config{ 3384 MaxVersion: VersionTLS13, 3385 Bugs: ProtocolBugs{ 3386 SendCompressionMethod: 1, 3387 }, 3388 }, 3389 shouldFail: true, 3390 expectedError: ":DECODE_ERROR:", 3391 }, 3392 { 3393 testType: clientTest, 3394 name: "TLS13-HRR-InvalidCompressionMethod", 3395 config: Config{ 3396 MaxVersion: VersionTLS13, 3397 CurvePreferences: []CurveID{CurveP384}, 3398 Bugs: ProtocolBugs{ 3399 SendCompressionMethod: 1, 3400 }, 3401 }, 3402 shouldFail: true, 3403 expectedError: ":DECODE_ERROR:", 3404 expectedLocalError: "remote error: error decoding message", 3405 }, 3406 { 3407 name: "GREASE-Client-TLS12", 3408 config: Config{ 3409 MaxVersion: VersionTLS12, 3410 Bugs: ProtocolBugs{ 3411 ExpectGREASE: true, 3412 }, 3413 }, 3414 flags: []string{"-enable-grease"}, 3415 }, 3416 { 3417 name: "GREASE-Client-TLS13", 3418 config: Config{ 3419 MaxVersion: VersionTLS13, 3420 Bugs: ProtocolBugs{ 3421 ExpectGREASE: true, 3422 }, 3423 }, 3424 flags: []string{"-enable-grease"}, 3425 }, 3426 { 3427 testType: serverTest, 3428 name: "GREASE-Server-TLS13", 3429 config: Config{ 3430 MaxVersion: VersionTLS13, 3431 Bugs: ProtocolBugs{ 3432 // TLS 1.3 servers are expected to 3433 // always enable GREASE. TLS 1.3 is new, 3434 // so there is no existing ecosystem to 3435 // worry about. 3436 ExpectGREASE: true, 3437 }, 3438 }, 3439 }, 3440 { 3441 // Test the TLS 1.2 server so there is a large 3442 // unencrypted certificate as well as application data. 3443 testType: serverTest, 3444 name: "MaxSendFragment-TLS12", 3445 config: Config{ 3446 MaxVersion: VersionTLS12, 3447 Bugs: ProtocolBugs{ 3448 MaxReceivePlaintext: 512, 3449 }, 3450 }, 3451 messageLen: 1024, 3452 flags: []string{ 3453 "-max-send-fragment", "512", 3454 "-read-size", "1024", 3455 }, 3456 }, 3457 { 3458 // Test the TLS 1.2 server so there is a large 3459 // unencrypted certificate as well as application data. 3460 testType: serverTest, 3461 name: "MaxSendFragment-TLS12-TooLarge", 3462 config: Config{ 3463 MaxVersion: VersionTLS12, 3464 Bugs: ProtocolBugs{ 3465 // Ensure that some of the records are 3466 // 512. 3467 MaxReceivePlaintext: 511, 3468 }, 3469 }, 3470 messageLen: 1024, 3471 flags: []string{ 3472 "-max-send-fragment", "512", 3473 "-read-size", "1024", 3474 }, 3475 shouldFail: true, 3476 expectedLocalError: "local error: record overflow", 3477 }, 3478 { 3479 // Test the TLS 1.3 server so there is a large encrypted 3480 // certificate as well as application data. 3481 testType: serverTest, 3482 name: "MaxSendFragment-TLS13", 3483 config: Config{ 3484 MaxVersion: VersionTLS13, 3485 Bugs: ProtocolBugs{ 3486 MaxReceivePlaintext: 512, 3487 ExpectPackedEncryptedHandshake: 512, 3488 }, 3489 }, 3490 messageLen: 1024, 3491 flags: []string{ 3492 "-max-send-fragment", "512", 3493 "-read-size", "1024", 3494 }, 3495 }, 3496 { 3497 // Test the TLS 1.3 server so there is a large encrypted 3498 // certificate as well as application data. 3499 testType: serverTest, 3500 name: "MaxSendFragment-TLS13-TooLarge", 3501 config: Config{ 3502 MaxVersion: VersionTLS13, 3503 Bugs: ProtocolBugs{ 3504 // Ensure that some of the records are 3505 // 512. 3506 MaxReceivePlaintext: 511, 3507 }, 3508 }, 3509 messageLen: 1024, 3510 flags: []string{ 3511 "-max-send-fragment", "512", 3512 "-read-size", "1024", 3513 }, 3514 shouldFail: true, 3515 expectedLocalError: "local error: record overflow", 3516 }, 3517 { 3518 // Test that handshake data is tightly packed in TLS 1.3. 3519 testType: serverTest, 3520 name: "PackedEncryptedHandshake-TLS13", 3521 config: Config{ 3522 MaxVersion: VersionTLS13, 3523 Bugs: ProtocolBugs{ 3524 ExpectPackedEncryptedHandshake: 16384, 3525 }, 3526 }, 3527 }, 3528 { 3529 // Test that DTLS can handle multiple application data 3530 // records in a single packet. 3531 protocol: dtls, 3532 name: "SplitAndPackAppData-DTLS", 3533 config: Config{ 3534 Bugs: ProtocolBugs{ 3535 SplitAndPackAppData: true, 3536 }, 3537 }, 3538 }, 3539 { 3540 protocol: dtls, 3541 name: "SplitAndPackAppData-DTLS-Async", 3542 config: Config{ 3543 Bugs: ProtocolBugs{ 3544 SplitAndPackAppData: true, 3545 }, 3546 }, 3547 flags: []string{"-async"}, 3548 }, 3549 } 3550 testCases = append(testCases, basicTests...) 3551 3552 // Test that very large messages can be received. 3553 cert := rsaCertificate 3554 for i := 0; i < 50; i++ { 3555 cert.Certificate = append(cert.Certificate, cert.Certificate[0]) 3556 } 3557 testCases = append(testCases, testCase{ 3558 name: "LargeMessage", 3559 config: Config{ 3560 Certificates: []Certificate{cert}, 3561 }, 3562 }) 3563 testCases = append(testCases, testCase{ 3564 protocol: dtls, 3565 name: "LargeMessage-DTLS", 3566 config: Config{ 3567 Certificates: []Certificate{cert}, 3568 }, 3569 }) 3570 3571 // They are rejected if the maximum certificate chain length is capped. 3572 testCases = append(testCases, testCase{ 3573 name: "LargeMessage-Reject", 3574 config: Config{ 3575 Certificates: []Certificate{cert}, 3576 }, 3577 flags: []string{"-max-cert-list", "16384"}, 3578 shouldFail: true, 3579 expectedError: ":EXCESSIVE_MESSAGE_SIZE:", 3580 }) 3581 testCases = append(testCases, testCase{ 3582 protocol: dtls, 3583 name: "LargeMessage-Reject-DTLS", 3584 config: Config{ 3585 Certificates: []Certificate{cert}, 3586 }, 3587 flags: []string{"-max-cert-list", "16384"}, 3588 shouldFail: true, 3589 expectedError: ":EXCESSIVE_MESSAGE_SIZE:", 3590 }) 3591 3592 // Servers echoing the TLS 1.3 compatibility mode session ID should be 3593 // rejected. 3594 testCases = append(testCases, testCase{ 3595 name: "EchoTLS13CompatibilitySessionID", 3596 config: Config{ 3597 MaxVersion: VersionTLS12, 3598 Bugs: ProtocolBugs{ 3599 EchoSessionIDInFullHandshake: true, 3600 }, 3601 }, 3602 shouldFail: true, 3603 expectedError: ":SERVER_ECHOED_INVALID_SESSION_ID:", 3604 expectedLocalError: "remote error: illegal parameter", 3605 }) 3606 3607 // Servers should reject QUIC client hellos that have a legacy 3608 // session ID. 3609 testCases = append(testCases, testCase{ 3610 name: "QUICCompatibilityMode", 3611 testType: serverTest, 3612 protocol: quic, 3613 config: Config{ 3614 MinVersion: VersionTLS13, 3615 Bugs: ProtocolBugs{ 3616 CompatModeWithQUIC: true, 3617 }, 3618 }, 3619 shouldFail: true, 3620 expectedError: ":UNEXPECTED_COMPATIBILITY_MODE:", 3621 }) 3622} 3623 3624func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol protocol) { 3625 const psk = "12345" 3626 const pskIdentity = "luggage combo" 3627 3628 if !ver.supportsProtocol(protocol) { 3629 return 3630 } 3631 prefix := protocol.String() + "-" 3632 3633 var cert Certificate 3634 var certFile string 3635 var keyFile string 3636 if hasComponent(suite.name, "ECDSA") { 3637 cert = ecdsaP256Certificate 3638 certFile = ecdsaP256CertificateFile 3639 keyFile = ecdsaP256KeyFile 3640 } else { 3641 cert = rsaCertificate 3642 certFile = rsaCertificateFile 3643 keyFile = rsaKeyFile 3644 } 3645 3646 var flags []string 3647 if hasComponent(suite.name, "PSK") { 3648 flags = append(flags, 3649 "-psk", psk, 3650 "-psk-identity", pskIdentity) 3651 } 3652 if hasComponent(suite.name, "NULL") { 3653 // NULL ciphers must be explicitly enabled. 3654 flags = append(flags, "-cipher", "DEFAULT:NULL-SHA") 3655 } 3656 3657 var shouldFail bool 3658 if isTLS12Only(suite.name) && ver.version < VersionTLS12 { 3659 shouldFail = true 3660 } 3661 if !isTLS13Suite(suite.name) && ver.version >= VersionTLS13 { 3662 shouldFail = true 3663 } 3664 if isTLS13Suite(suite.name) && ver.version < VersionTLS13 { 3665 shouldFail = true 3666 } 3667 3668 var sendCipherSuite uint16 3669 var expectedServerError, expectedClientError string 3670 serverCipherSuites := []uint16{suite.id} 3671 if shouldFail { 3672 expectedServerError = ":NO_SHARED_CIPHER:" 3673 expectedClientError = ":WRONG_CIPHER_RETURNED:" 3674 // Configure the server to select ciphers as normal but 3675 // select an incompatible cipher in ServerHello. 3676 serverCipherSuites = nil 3677 sendCipherSuite = suite.id 3678 } 3679 3680 // Verify exporters interoperate. 3681 exportKeyingMaterial := 1024 3682 3683 testCases = append(testCases, testCase{ 3684 testType: serverTest, 3685 protocol: protocol, 3686 name: prefix + ver.name + "-" + suite.name + "-server", 3687 config: Config{ 3688 MinVersion: ver.version, 3689 MaxVersion: ver.version, 3690 CipherSuites: []uint16{suite.id}, 3691 Certificates: []Certificate{cert}, 3692 PreSharedKey: []byte(psk), 3693 PreSharedKeyIdentity: pskIdentity, 3694 Bugs: ProtocolBugs{ 3695 AdvertiseAllConfiguredCiphers: true, 3696 }, 3697 }, 3698 certFile: certFile, 3699 keyFile: keyFile, 3700 flags: flags, 3701 resumeSession: true, 3702 shouldFail: shouldFail, 3703 expectedError: expectedServerError, 3704 exportKeyingMaterial: exportKeyingMaterial, 3705 }) 3706 3707 testCases = append(testCases, testCase{ 3708 testType: clientTest, 3709 protocol: protocol, 3710 name: prefix + ver.name + "-" + suite.name + "-client", 3711 config: Config{ 3712 MinVersion: ver.version, 3713 MaxVersion: ver.version, 3714 CipherSuites: serverCipherSuites, 3715 Certificates: []Certificate{cert}, 3716 PreSharedKey: []byte(psk), 3717 PreSharedKeyIdentity: pskIdentity, 3718 Bugs: ProtocolBugs{ 3719 IgnorePeerCipherPreferences: shouldFail, 3720 SendCipherSuite: sendCipherSuite, 3721 }, 3722 }, 3723 flags: flags, 3724 resumeSession: true, 3725 shouldFail: shouldFail, 3726 expectedError: expectedClientError, 3727 exportKeyingMaterial: exportKeyingMaterial, 3728 }) 3729 3730 if shouldFail { 3731 return 3732 } 3733 3734 // Ensure the maximum record size is accepted. 3735 testCases = append(testCases, testCase{ 3736 protocol: protocol, 3737 name: prefix + ver.name + "-" + suite.name + "-LargeRecord", 3738 config: Config{ 3739 MinVersion: ver.version, 3740 MaxVersion: ver.version, 3741 CipherSuites: []uint16{suite.id}, 3742 Certificates: []Certificate{cert}, 3743 PreSharedKey: []byte(psk), 3744 PreSharedKeyIdentity: pskIdentity, 3745 }, 3746 flags: flags, 3747 messageLen: maxPlaintext, 3748 }) 3749 3750 // Test bad records for all ciphers. Bad records are fatal in TLS 3751 // and ignored in DTLS. 3752 shouldFail = protocol == tls 3753 var expectedError string 3754 if shouldFail { 3755 expectedError = ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:" 3756 } 3757 3758 // When QUIC is used, the QUIC stack handles record encryption/decryption. 3759 // Thus it is not possible for the TLS stack in QUIC mode to receive a 3760 // bad record (i.e. one that fails to decrypt). 3761 if protocol != quic { 3762 testCases = append(testCases, testCase{ 3763 protocol: protocol, 3764 name: prefix + ver.name + "-" + suite.name + "-BadRecord", 3765 config: Config{ 3766 MinVersion: ver.version, 3767 MaxVersion: ver.version, 3768 CipherSuites: []uint16{suite.id}, 3769 Certificates: []Certificate{cert}, 3770 PreSharedKey: []byte(psk), 3771 PreSharedKeyIdentity: pskIdentity, 3772 }, 3773 flags: flags, 3774 damageFirstWrite: true, 3775 messageLen: maxPlaintext, 3776 shouldFail: shouldFail, 3777 expectedError: expectedError, 3778 }) 3779 } 3780} 3781 3782func addCipherSuiteTests() { 3783 const bogusCipher = 0xfe00 3784 3785 for _, suite := range testCipherSuites { 3786 for _, ver := range tlsVersions { 3787 for _, protocol := range []protocol{tls, dtls, quic} { 3788 addTestForCipherSuite(suite, ver, protocol) 3789 } 3790 } 3791 } 3792 3793 testCases = append(testCases, testCase{ 3794 name: "NoSharedCipher", 3795 config: Config{ 3796 MaxVersion: VersionTLS12, 3797 CipherSuites: []uint16{}, 3798 }, 3799 shouldFail: true, 3800 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:", 3801 }) 3802 3803 testCases = append(testCases, testCase{ 3804 name: "NoSharedCipher-TLS13", 3805 config: Config{ 3806 MaxVersion: VersionTLS13, 3807 CipherSuites: []uint16{}, 3808 }, 3809 shouldFail: true, 3810 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:", 3811 }) 3812 3813 testCases = append(testCases, testCase{ 3814 name: "UnsupportedCipherSuite", 3815 config: Config{ 3816 MaxVersion: VersionTLS12, 3817 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 3818 Bugs: ProtocolBugs{ 3819 IgnorePeerCipherPreferences: true, 3820 }, 3821 }, 3822 flags: []string{"-cipher", "DEFAULT:!AES"}, 3823 shouldFail: true, 3824 expectedError: ":WRONG_CIPHER_RETURNED:", 3825 }) 3826 3827 testCases = append(testCases, testCase{ 3828 name: "ServerHelloBogusCipher", 3829 config: Config{ 3830 MaxVersion: VersionTLS12, 3831 Bugs: ProtocolBugs{ 3832 SendCipherSuite: bogusCipher, 3833 }, 3834 }, 3835 shouldFail: true, 3836 expectedError: ":WRONG_CIPHER_RETURNED:", 3837 }) 3838 testCases = append(testCases, testCase{ 3839 name: "ServerHelloBogusCipher-TLS13", 3840 config: Config{ 3841 MaxVersion: VersionTLS13, 3842 Bugs: ProtocolBugs{ 3843 SendCipherSuite: bogusCipher, 3844 }, 3845 }, 3846 shouldFail: true, 3847 expectedError: ":WRONG_CIPHER_RETURNED:", 3848 }) 3849 3850 // The server must be tolerant to bogus ciphers. 3851 testCases = append(testCases, testCase{ 3852 testType: serverTest, 3853 name: "UnknownCipher", 3854 config: Config{ 3855 MaxVersion: VersionTLS12, 3856 CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3857 Bugs: ProtocolBugs{ 3858 AdvertiseAllConfiguredCiphers: true, 3859 }, 3860 }, 3861 }) 3862 3863 // The server must be tolerant to bogus ciphers. 3864 testCases = append(testCases, testCase{ 3865 testType: serverTest, 3866 name: "UnknownCipher-TLS13", 3867 config: Config{ 3868 MaxVersion: VersionTLS13, 3869 CipherSuites: []uint16{bogusCipher, TLS_AES_128_GCM_SHA256}, 3870 Bugs: ProtocolBugs{ 3871 AdvertiseAllConfiguredCiphers: true, 3872 }, 3873 }, 3874 }) 3875 3876 // Test empty ECDHE_PSK identity hints work as expected. 3877 testCases = append(testCases, testCase{ 3878 name: "EmptyECDHEPSKHint", 3879 config: Config{ 3880 MaxVersion: VersionTLS12, 3881 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 3882 PreSharedKey: []byte("secret"), 3883 }, 3884 flags: []string{"-psk", "secret"}, 3885 }) 3886 3887 // Test empty PSK identity hints work as expected, even if an explicit 3888 // ServerKeyExchange is sent. 3889 testCases = append(testCases, testCase{ 3890 name: "ExplicitEmptyPSKHint", 3891 config: Config{ 3892 MaxVersion: VersionTLS12, 3893 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 3894 PreSharedKey: []byte("secret"), 3895 Bugs: ProtocolBugs{ 3896 AlwaysSendPreSharedKeyIdentityHint: true, 3897 }, 3898 }, 3899 flags: []string{"-psk", "secret"}, 3900 }) 3901 3902 // Test that clients enforce that the server-sent certificate and cipher 3903 // suite match in TLS 1.2. 3904 testCases = append(testCases, testCase{ 3905 name: "CertificateCipherMismatch-RSA", 3906 config: Config{ 3907 MaxVersion: VersionTLS12, 3908 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3909 Certificates: []Certificate{rsaCertificate}, 3910 Bugs: ProtocolBugs{ 3911 SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 3912 }, 3913 }, 3914 shouldFail: true, 3915 expectedError: ":WRONG_CERTIFICATE_TYPE:", 3916 }) 3917 testCases = append(testCases, testCase{ 3918 name: "CertificateCipherMismatch-ECDSA", 3919 config: Config{ 3920 MaxVersion: VersionTLS12, 3921 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 3922 Certificates: []Certificate{ecdsaP256Certificate}, 3923 Bugs: ProtocolBugs{ 3924 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 3925 }, 3926 }, 3927 shouldFail: true, 3928 expectedError: ":WRONG_CERTIFICATE_TYPE:", 3929 }) 3930 testCases = append(testCases, testCase{ 3931 name: "CertificateCipherMismatch-Ed25519", 3932 config: Config{ 3933 MaxVersion: VersionTLS12, 3934 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 3935 Certificates: []Certificate{ed25519Certificate}, 3936 Bugs: ProtocolBugs{ 3937 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 3938 }, 3939 }, 3940 shouldFail: true, 3941 expectedError: ":WRONG_CERTIFICATE_TYPE:", 3942 }) 3943 3944 // Test that servers decline to select a cipher suite which is 3945 // inconsistent with their configured certificate. 3946 testCases = append(testCases, testCase{ 3947 testType: serverTest, 3948 name: "ServerCipherFilter-RSA", 3949 config: Config{ 3950 MaxVersion: VersionTLS12, 3951 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 3952 }, 3953 flags: []string{ 3954 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 3955 "-key-file", path.Join(*resourceDir, rsaKeyFile), 3956 }, 3957 shouldFail: true, 3958 expectedError: ":NO_SHARED_CIPHER:", 3959 }) 3960 testCases = append(testCases, testCase{ 3961 testType: serverTest, 3962 name: "ServerCipherFilter-ECDSA", 3963 config: Config{ 3964 MaxVersion: VersionTLS12, 3965 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3966 }, 3967 flags: []string{ 3968 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 3969 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 3970 }, 3971 shouldFail: true, 3972 expectedError: ":NO_SHARED_CIPHER:", 3973 }) 3974 testCases = append(testCases, testCase{ 3975 testType: serverTest, 3976 name: "ServerCipherFilter-Ed25519", 3977 config: Config{ 3978 MaxVersion: VersionTLS12, 3979 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3980 }, 3981 flags: []string{ 3982 "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), 3983 "-key-file", path.Join(*resourceDir, ed25519KeyFile), 3984 }, 3985 shouldFail: true, 3986 expectedError: ":NO_SHARED_CIPHER:", 3987 }) 3988 3989 // Test cipher suite negotiation works as expected. Configure a 3990 // complicated cipher suite configuration. 3991 const negotiationTestCiphers = "" + 3992 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:" + 3993 "[TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384|TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256|TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]:" + 3994 "TLS_RSA_WITH_AES_128_GCM_SHA256:" + 3995 "TLS_RSA_WITH_AES_128_CBC_SHA:" + 3996 "[TLS_RSA_WITH_AES_256_GCM_SHA384|TLS_RSA_WITH_AES_256_CBC_SHA]" 3997 negotiationTests := []struct { 3998 ciphers []uint16 3999 expected uint16 4000 }{ 4001 // Server preferences are honored, including when 4002 // equipreference groups are involved. 4003 { 4004 []uint16{ 4005 TLS_RSA_WITH_AES_256_GCM_SHA384, 4006 TLS_RSA_WITH_AES_128_CBC_SHA, 4007 TLS_RSA_WITH_AES_128_GCM_SHA256, 4008 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4009 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 4010 }, 4011 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 4012 }, 4013 { 4014 []uint16{ 4015 TLS_RSA_WITH_AES_256_GCM_SHA384, 4016 TLS_RSA_WITH_AES_128_CBC_SHA, 4017 TLS_RSA_WITH_AES_128_GCM_SHA256, 4018 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4019 }, 4020 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4021 }, 4022 { 4023 []uint16{ 4024 TLS_RSA_WITH_AES_256_GCM_SHA384, 4025 TLS_RSA_WITH_AES_128_CBC_SHA, 4026 TLS_RSA_WITH_AES_128_GCM_SHA256, 4027 }, 4028 TLS_RSA_WITH_AES_128_GCM_SHA256, 4029 }, 4030 { 4031 []uint16{ 4032 TLS_RSA_WITH_AES_256_GCM_SHA384, 4033 TLS_RSA_WITH_AES_128_CBC_SHA, 4034 }, 4035 TLS_RSA_WITH_AES_128_CBC_SHA, 4036 }, 4037 // Equipreference groups use the client preference. 4038 { 4039 []uint16{ 4040 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4041 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4042 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4043 }, 4044 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4045 }, 4046 { 4047 []uint16{ 4048 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4049 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4050 }, 4051 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4052 }, 4053 { 4054 []uint16{ 4055 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4056 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4057 }, 4058 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4059 }, 4060 { 4061 []uint16{ 4062 TLS_RSA_WITH_AES_256_GCM_SHA384, 4063 TLS_RSA_WITH_AES_256_CBC_SHA, 4064 }, 4065 TLS_RSA_WITH_AES_256_GCM_SHA384, 4066 }, 4067 { 4068 []uint16{ 4069 TLS_RSA_WITH_AES_256_CBC_SHA, 4070 TLS_RSA_WITH_AES_256_GCM_SHA384, 4071 }, 4072 TLS_RSA_WITH_AES_256_CBC_SHA, 4073 }, 4074 // If there are two equipreference groups, the preferred one 4075 // takes precedence. 4076 { 4077 []uint16{ 4078 TLS_RSA_WITH_AES_256_GCM_SHA384, 4079 TLS_RSA_WITH_AES_256_CBC_SHA, 4080 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4081 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4082 }, 4083 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4084 }, 4085 } 4086 for i, t := range negotiationTests { 4087 testCases = append(testCases, testCase{ 4088 testType: serverTest, 4089 name: "CipherNegotiation-" + strconv.Itoa(i), 4090 config: Config{ 4091 MaxVersion: VersionTLS12, 4092 CipherSuites: t.ciphers, 4093 }, 4094 flags: []string{"-cipher", negotiationTestCiphers}, 4095 expectations: connectionExpectations{ 4096 cipher: t.expected, 4097 }, 4098 }) 4099 } 4100} 4101 4102func addBadECDSASignatureTests() { 4103 for badR := BadValue(1); badR < NumBadValues; badR++ { 4104 for badS := BadValue(1); badS < NumBadValues; badS++ { 4105 testCases = append(testCases, testCase{ 4106 name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS), 4107 config: Config{ 4108 MaxVersion: VersionTLS12, 4109 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 4110 Certificates: []Certificate{ecdsaP256Certificate}, 4111 Bugs: ProtocolBugs{ 4112 BadECDSAR: badR, 4113 BadECDSAS: badS, 4114 }, 4115 }, 4116 shouldFail: true, 4117 expectedError: ":BAD_SIGNATURE:", 4118 }) 4119 testCases = append(testCases, testCase{ 4120 name: fmt.Sprintf("BadECDSA-%d-%d-TLS13", badR, badS), 4121 config: Config{ 4122 MaxVersion: VersionTLS13, 4123 Certificates: []Certificate{ecdsaP256Certificate}, 4124 Bugs: ProtocolBugs{ 4125 BadECDSAR: badR, 4126 BadECDSAS: badS, 4127 }, 4128 }, 4129 shouldFail: true, 4130 expectedError: ":BAD_SIGNATURE:", 4131 }) 4132 } 4133 } 4134} 4135 4136func addCBCPaddingTests() { 4137 testCases = append(testCases, testCase{ 4138 name: "MaxCBCPadding", 4139 config: Config{ 4140 MaxVersion: VersionTLS12, 4141 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4142 Bugs: ProtocolBugs{ 4143 MaxPadding: true, 4144 }, 4145 }, 4146 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size 4147 }) 4148 testCases = append(testCases, testCase{ 4149 name: "BadCBCPadding", 4150 config: Config{ 4151 MaxVersion: VersionTLS12, 4152 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4153 Bugs: ProtocolBugs{ 4154 PaddingFirstByteBad: true, 4155 }, 4156 }, 4157 shouldFail: true, 4158 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 4159 }) 4160 // OpenSSL previously had an issue where the first byte of padding in 4161 // 255 bytes of padding wasn't checked. 4162 testCases = append(testCases, testCase{ 4163 name: "BadCBCPadding255", 4164 config: Config{ 4165 MaxVersion: VersionTLS12, 4166 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4167 Bugs: ProtocolBugs{ 4168 MaxPadding: true, 4169 PaddingFirstByteBadIf255: true, 4170 }, 4171 }, 4172 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size 4173 shouldFail: true, 4174 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 4175 }) 4176} 4177 4178func addCBCSplittingTests() { 4179 var cbcCiphers = []struct { 4180 name string 4181 cipher uint16 4182 }{ 4183 {"3DES", TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 4184 {"AES128", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4185 {"AES256", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, 4186 } 4187 for _, t := range cbcCiphers { 4188 testCases = append(testCases, testCase{ 4189 name: "CBCRecordSplitting-" + t.name, 4190 config: Config{ 4191 MaxVersion: VersionTLS10, 4192 MinVersion: VersionTLS10, 4193 CipherSuites: []uint16{t.cipher}, 4194 Bugs: ProtocolBugs{ 4195 ExpectRecordSplitting: true, 4196 }, 4197 }, 4198 messageLen: -1, // read until EOF 4199 resumeSession: true, 4200 flags: []string{ 4201 "-async", 4202 "-write-different-record-sizes", 4203 "-cbc-record-splitting", 4204 }, 4205 }) 4206 testCases = append(testCases, testCase{ 4207 name: "CBCRecordSplittingPartialWrite-" + t.name, 4208 config: Config{ 4209 MaxVersion: VersionTLS10, 4210 MinVersion: VersionTLS10, 4211 CipherSuites: []uint16{t.cipher}, 4212 Bugs: ProtocolBugs{ 4213 ExpectRecordSplitting: true, 4214 }, 4215 }, 4216 messageLen: -1, // read until EOF 4217 flags: []string{ 4218 "-async", 4219 "-write-different-record-sizes", 4220 "-cbc-record-splitting", 4221 "-partial-write", 4222 }, 4223 }) 4224 } 4225} 4226 4227func addClientAuthTests() { 4228 // Add a dummy cert pool to stress certificate authority parsing. 4229 certPool := x509.NewCertPool() 4230 for _, cert := range []Certificate{rsaCertificate, rsa1024Certificate} { 4231 cert, err := x509.ParseCertificate(cert.Certificate[0]) 4232 if err != nil { 4233 panic(err) 4234 } 4235 certPool.AddCert(cert) 4236 } 4237 caNames := certPool.Subjects() 4238 4239 for _, ver := range tlsVersions { 4240 testCases = append(testCases, testCase{ 4241 testType: clientTest, 4242 name: ver.name + "-Client-ClientAuth-RSA", 4243 config: Config{ 4244 MinVersion: ver.version, 4245 MaxVersion: ver.version, 4246 ClientAuth: RequireAnyClientCert, 4247 ClientCAs: certPool, 4248 }, 4249 flags: []string{ 4250 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4251 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4252 }, 4253 }) 4254 testCases = append(testCases, testCase{ 4255 testType: serverTest, 4256 name: ver.name + "-Server-ClientAuth-RSA", 4257 config: Config{ 4258 MinVersion: ver.version, 4259 MaxVersion: ver.version, 4260 Certificates: []Certificate{rsaCertificate}, 4261 }, 4262 flags: []string{"-require-any-client-certificate"}, 4263 }) 4264 testCases = append(testCases, testCase{ 4265 testType: serverTest, 4266 name: ver.name + "-Server-ClientAuth-ECDSA", 4267 config: Config{ 4268 MinVersion: ver.version, 4269 MaxVersion: ver.version, 4270 Certificates: []Certificate{ecdsaP256Certificate}, 4271 }, 4272 flags: []string{"-require-any-client-certificate"}, 4273 }) 4274 testCases = append(testCases, testCase{ 4275 testType: clientTest, 4276 name: ver.name + "-Client-ClientAuth-ECDSA", 4277 config: Config{ 4278 MinVersion: ver.version, 4279 MaxVersion: ver.version, 4280 ClientAuth: RequireAnyClientCert, 4281 ClientCAs: certPool, 4282 }, 4283 flags: []string{ 4284 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 4285 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 4286 }, 4287 }) 4288 4289 testCases = append(testCases, testCase{ 4290 name: "NoClientCertificate-" + ver.name, 4291 config: Config{ 4292 MinVersion: ver.version, 4293 MaxVersion: ver.version, 4294 ClientAuth: RequireAnyClientCert, 4295 }, 4296 shouldFail: true, 4297 expectedLocalError: "client didn't provide a certificate", 4298 }) 4299 4300 testCases = append(testCases, testCase{ 4301 // Even if not configured to expect a certificate, OpenSSL will 4302 // return X509_V_OK as the verify_result. 4303 testType: serverTest, 4304 name: "NoClientCertificateRequested-Server-" + ver.name, 4305 config: Config{ 4306 MinVersion: ver.version, 4307 MaxVersion: ver.version, 4308 }, 4309 flags: []string{ 4310 "-expect-verify-result", 4311 }, 4312 resumeSession: true, 4313 }) 4314 4315 testCases = append(testCases, testCase{ 4316 // If a client certificate is not provided, OpenSSL will still 4317 // return X509_V_OK as the verify_result. 4318 testType: serverTest, 4319 name: "NoClientCertificate-Server-" + ver.name, 4320 config: Config{ 4321 MinVersion: ver.version, 4322 MaxVersion: ver.version, 4323 }, 4324 flags: []string{ 4325 "-expect-verify-result", 4326 "-verify-peer", 4327 }, 4328 resumeSession: true, 4329 }) 4330 4331 certificateRequired := "remote error: certificate required" 4332 if ver.version < VersionTLS13 { 4333 // Prior to TLS 1.3, the generic handshake_failure alert 4334 // was used. 4335 certificateRequired = "remote error: handshake failure" 4336 } 4337 testCases = append(testCases, testCase{ 4338 testType: serverTest, 4339 name: "RequireAnyClientCertificate-" + ver.name, 4340 config: Config{ 4341 MinVersion: ver.version, 4342 MaxVersion: ver.version, 4343 }, 4344 flags: []string{"-require-any-client-certificate"}, 4345 shouldFail: true, 4346 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 4347 expectedLocalError: certificateRequired, 4348 }) 4349 4350 testCases = append(testCases, testCase{ 4351 testType: serverTest, 4352 name: "SkipClientCertificate-" + ver.name, 4353 config: Config{ 4354 MinVersion: ver.version, 4355 MaxVersion: ver.version, 4356 Bugs: ProtocolBugs{ 4357 SkipClientCertificate: true, 4358 }, 4359 }, 4360 // Setting SSL_VERIFY_PEER allows anonymous clients. 4361 flags: []string{"-verify-peer"}, 4362 shouldFail: true, 4363 expectedError: ":UNEXPECTED_MESSAGE:", 4364 }) 4365 4366 testCases = append(testCases, testCase{ 4367 testType: serverTest, 4368 name: "VerifyPeerIfNoOBC-NoChannelID-" + ver.name, 4369 config: Config{ 4370 MinVersion: ver.version, 4371 MaxVersion: ver.version, 4372 }, 4373 flags: []string{ 4374 "-enable-channel-id", 4375 "-verify-peer-if-no-obc", 4376 }, 4377 shouldFail: true, 4378 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 4379 expectedLocalError: certificateRequired, 4380 }) 4381 4382 testCases = append(testCases, testCase{ 4383 testType: serverTest, 4384 name: "VerifyPeerIfNoOBC-ChannelID-" + ver.name, 4385 config: Config{ 4386 MinVersion: ver.version, 4387 MaxVersion: ver.version, 4388 ChannelID: channelIDKey, 4389 }, 4390 expectations: connectionExpectations{ 4391 channelID: true, 4392 }, 4393 flags: []string{ 4394 "-enable-channel-id", 4395 "-verify-peer-if-no-obc", 4396 }, 4397 }) 4398 4399 testCases = append(testCases, testCase{ 4400 testType: serverTest, 4401 name: ver.name + "-Server-CertReq-CA-List", 4402 config: Config{ 4403 MinVersion: ver.version, 4404 MaxVersion: ver.version, 4405 Certificates: []Certificate{rsaCertificate}, 4406 Bugs: ProtocolBugs{ 4407 ExpectCertificateReqNames: caNames, 4408 }, 4409 }, 4410 flags: []string{ 4411 "-require-any-client-certificate", 4412 "-use-client-ca-list", encodeDERValues(caNames), 4413 }, 4414 }) 4415 4416 testCases = append(testCases, testCase{ 4417 testType: clientTest, 4418 name: ver.name + "-Client-CertReq-CA-List", 4419 config: Config{ 4420 MinVersion: ver.version, 4421 MaxVersion: ver.version, 4422 Certificates: []Certificate{rsaCertificate}, 4423 ClientAuth: RequireAnyClientCert, 4424 ClientCAs: certPool, 4425 }, 4426 flags: []string{ 4427 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4428 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4429 "-expect-client-ca-list", encodeDERValues(caNames), 4430 }, 4431 }) 4432 } 4433 4434 // Client auth is only legal in certificate-based ciphers. 4435 testCases = append(testCases, testCase{ 4436 testType: clientTest, 4437 name: "ClientAuth-PSK", 4438 config: Config{ 4439 MaxVersion: VersionTLS12, 4440 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 4441 PreSharedKey: []byte("secret"), 4442 ClientAuth: RequireAnyClientCert, 4443 }, 4444 flags: []string{ 4445 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4446 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4447 "-psk", "secret", 4448 }, 4449 shouldFail: true, 4450 expectedError: ":UNEXPECTED_MESSAGE:", 4451 }) 4452 testCases = append(testCases, testCase{ 4453 testType: clientTest, 4454 name: "ClientAuth-ECDHE_PSK", 4455 config: Config{ 4456 MaxVersion: VersionTLS12, 4457 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 4458 PreSharedKey: []byte("secret"), 4459 ClientAuth: RequireAnyClientCert, 4460 }, 4461 flags: []string{ 4462 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 4463 "-key-file", path.Join(*resourceDir, rsaKeyFile), 4464 "-psk", "secret", 4465 }, 4466 shouldFail: true, 4467 expectedError: ":UNEXPECTED_MESSAGE:", 4468 }) 4469 4470 // Regression test for a bug where the client CA list, if explicitly 4471 // set to NULL, was mis-encoded. 4472 testCases = append(testCases, testCase{ 4473 testType: serverTest, 4474 name: "Null-Client-CA-List", 4475 config: Config{ 4476 MaxVersion: VersionTLS12, 4477 Certificates: []Certificate{rsaCertificate}, 4478 Bugs: ProtocolBugs{ 4479 ExpectCertificateReqNames: [][]byte{}, 4480 }, 4481 }, 4482 flags: []string{ 4483 "-require-any-client-certificate", 4484 "-use-client-ca-list", "<NULL>", 4485 }, 4486 }) 4487 4488 // Test that an empty client CA list doesn't send a CA extension. 4489 testCases = append(testCases, testCase{ 4490 testType: serverTest, 4491 name: "TLS13-Empty-Client-CA-List", 4492 config: Config{ 4493 MaxVersion: VersionTLS13, 4494 Certificates: []Certificate{rsaCertificate}, 4495 Bugs: ProtocolBugs{ 4496 ExpectNoCertificateAuthoritiesExtension: true, 4497 }, 4498 }, 4499 flags: []string{ 4500 "-require-any-client-certificate", 4501 "-use-client-ca-list", "<EMPTY>", 4502 }, 4503 }) 4504 4505} 4506 4507func addExtendedMasterSecretTests() { 4508 const expectEMSFlag = "-expect-extended-master-secret" 4509 4510 for _, with := range []bool{false, true} { 4511 prefix := "No" 4512 if with { 4513 prefix = "" 4514 } 4515 4516 for _, isClient := range []bool{false, true} { 4517 suffix := "-Server" 4518 testType := serverTest 4519 if isClient { 4520 suffix = "-Client" 4521 testType = clientTest 4522 } 4523 4524 for _, ver := range tlsVersions { 4525 // In TLS 1.3, the extension is irrelevant and 4526 // always reports as enabled. 4527 var flags []string 4528 if with || ver.version >= VersionTLS13 { 4529 flags = []string{expectEMSFlag} 4530 } 4531 4532 testCases = append(testCases, testCase{ 4533 testType: testType, 4534 name: prefix + "ExtendedMasterSecret-" + ver.name + suffix, 4535 config: Config{ 4536 MinVersion: ver.version, 4537 MaxVersion: ver.version, 4538 Bugs: ProtocolBugs{ 4539 NoExtendedMasterSecret: !with, 4540 RequireExtendedMasterSecret: with, 4541 }, 4542 }, 4543 flags: flags, 4544 }) 4545 } 4546 } 4547 } 4548 4549 for _, isClient := range []bool{false, true} { 4550 for _, supportedInFirstConnection := range []bool{false, true} { 4551 for _, supportedInResumeConnection := range []bool{false, true} { 4552 boolToWord := func(b bool) string { 4553 if b { 4554 return "Yes" 4555 } 4556 return "No" 4557 } 4558 suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-" 4559 if isClient { 4560 suffix += "Client" 4561 } else { 4562 suffix += "Server" 4563 } 4564 4565 supportedConfig := Config{ 4566 MaxVersion: VersionTLS12, 4567 Bugs: ProtocolBugs{ 4568 RequireExtendedMasterSecret: true, 4569 }, 4570 } 4571 4572 noSupportConfig := Config{ 4573 MaxVersion: VersionTLS12, 4574 Bugs: ProtocolBugs{ 4575 NoExtendedMasterSecret: true, 4576 }, 4577 } 4578 4579 test := testCase{ 4580 name: "ExtendedMasterSecret-" + suffix, 4581 resumeSession: true, 4582 } 4583 4584 if !isClient { 4585 test.testType = serverTest 4586 } 4587 4588 if supportedInFirstConnection { 4589 test.config = supportedConfig 4590 } else { 4591 test.config = noSupportConfig 4592 } 4593 4594 if supportedInResumeConnection { 4595 test.resumeConfig = &supportedConfig 4596 } else { 4597 test.resumeConfig = &noSupportConfig 4598 } 4599 4600 switch suffix { 4601 case "YesToYes-Client", "YesToYes-Server": 4602 // When a session is resumed, it should 4603 // still be aware that its master 4604 // secret was generated via EMS and 4605 // thus it's safe to use tls-unique. 4606 test.flags = []string{expectEMSFlag} 4607 case "NoToYes-Server": 4608 // If an original connection did not 4609 // contain EMS, but a resumption 4610 // handshake does, then a server should 4611 // not resume the session. 4612 test.expectResumeRejected = true 4613 case "YesToNo-Server": 4614 // Resuming an EMS session without the 4615 // EMS extension should cause the 4616 // server to abort the connection. 4617 test.shouldFail = true 4618 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" 4619 case "NoToYes-Client": 4620 // A client should abort a connection 4621 // where the server resumed a non-EMS 4622 // session but echoed the EMS 4623 // extension. 4624 test.shouldFail = true 4625 test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:" 4626 case "YesToNo-Client": 4627 // A client should abort a connection 4628 // where the server didn't echo EMS 4629 // when the session used it. 4630 test.shouldFail = true 4631 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" 4632 } 4633 4634 testCases = append(testCases, test) 4635 } 4636 } 4637 } 4638 4639 // Switching EMS on renegotiation is forbidden. 4640 testCases = append(testCases, testCase{ 4641 name: "ExtendedMasterSecret-Renego-NoEMS", 4642 config: Config{ 4643 MaxVersion: VersionTLS12, 4644 Bugs: ProtocolBugs{ 4645 NoExtendedMasterSecret: true, 4646 NoExtendedMasterSecretOnRenegotiation: true, 4647 }, 4648 }, 4649 renegotiate: 1, 4650 flags: []string{ 4651 "-renegotiate-freely", 4652 "-expect-total-renegotiations", "1", 4653 }, 4654 }) 4655 4656 testCases = append(testCases, testCase{ 4657 name: "ExtendedMasterSecret-Renego-Upgrade", 4658 config: Config{ 4659 MaxVersion: VersionTLS12, 4660 Bugs: ProtocolBugs{ 4661 NoExtendedMasterSecret: true, 4662 }, 4663 }, 4664 renegotiate: 1, 4665 flags: []string{ 4666 "-renegotiate-freely", 4667 "-expect-total-renegotiations", "1", 4668 }, 4669 shouldFail: true, 4670 expectedError: ":RENEGOTIATION_EMS_MISMATCH:", 4671 }) 4672 4673 testCases = append(testCases, testCase{ 4674 name: "ExtendedMasterSecret-Renego-Downgrade", 4675 config: Config{ 4676 MaxVersion: VersionTLS12, 4677 Bugs: ProtocolBugs{ 4678 NoExtendedMasterSecretOnRenegotiation: true, 4679 }, 4680 }, 4681 renegotiate: 1, 4682 flags: []string{ 4683 "-renegotiate-freely", 4684 "-expect-total-renegotiations", "1", 4685 }, 4686 shouldFail: true, 4687 expectedError: ":RENEGOTIATION_EMS_MISMATCH:", 4688 }) 4689} 4690 4691type stateMachineTestConfig struct { 4692 protocol protocol 4693 async bool 4694 splitHandshake bool 4695 packHandshake bool 4696 implicitHandshake bool 4697} 4698 4699// Adds tests that try to cover the range of the handshake state machine, under 4700// various conditions. Some of these are redundant with other tests, but they 4701// only cover the synchronous case. 4702func addAllStateMachineCoverageTests() { 4703 for _, async := range []bool{false, true} { 4704 for _, protocol := range []protocol{tls, dtls, quic} { 4705 addStateMachineCoverageTests(stateMachineTestConfig{ 4706 protocol: protocol, 4707 async: async, 4708 }) 4709 // QUIC doesn't work with the implicit handshake API. Additionally, 4710 // splitting or packing handshake records is meaningless in QUIC. 4711 if protocol != quic { 4712 addStateMachineCoverageTests(stateMachineTestConfig{ 4713 protocol: protocol, 4714 async: async, 4715 implicitHandshake: true, 4716 }) 4717 addStateMachineCoverageTests(stateMachineTestConfig{ 4718 protocol: protocol, 4719 async: async, 4720 splitHandshake: true, 4721 }) 4722 addStateMachineCoverageTests(stateMachineTestConfig{ 4723 protocol: protocol, 4724 async: async, 4725 packHandshake: true, 4726 }) 4727 } 4728 } 4729 } 4730} 4731 4732func addStateMachineCoverageTests(config stateMachineTestConfig) { 4733 var tests []testCase 4734 4735 // Basic handshake, with resumption. Client and server, 4736 // session ID and session ticket. 4737 // The following tests have a max version of 1.2, so they are not suitable 4738 // for use with QUIC. 4739 if config.protocol != quic { 4740 tests = append(tests, testCase{ 4741 name: "Basic-Client", 4742 config: Config{ 4743 MaxVersion: VersionTLS12, 4744 }, 4745 resumeSession: true, 4746 // Ensure session tickets are used, not session IDs. 4747 noSessionCache: true, 4748 flags: []string{"-expect-no-hrr"}, 4749 }) 4750 tests = append(tests, testCase{ 4751 name: "Basic-Client-RenewTicket", 4752 config: Config{ 4753 MaxVersion: VersionTLS12, 4754 Bugs: ProtocolBugs{ 4755 RenewTicketOnResume: true, 4756 }, 4757 }, 4758 flags: []string{"-expect-ticket-renewal"}, 4759 resumeSession: true, 4760 resumeRenewedSession: true, 4761 }) 4762 tests = append(tests, testCase{ 4763 name: "Basic-Client-NoTicket", 4764 config: Config{ 4765 MaxVersion: VersionTLS12, 4766 SessionTicketsDisabled: true, 4767 }, 4768 resumeSession: true, 4769 }) 4770 tests = append(tests, testCase{ 4771 testType: serverTest, 4772 name: "Basic-Server", 4773 config: Config{ 4774 MaxVersion: VersionTLS12, 4775 Bugs: ProtocolBugs{ 4776 RequireSessionTickets: true, 4777 }, 4778 }, 4779 resumeSession: true, 4780 flags: []string{ 4781 "-expect-no-session-id", 4782 "-expect-no-hrr", 4783 }, 4784 }) 4785 tests = append(tests, testCase{ 4786 testType: serverTest, 4787 name: "Basic-Server-NoTickets", 4788 config: Config{ 4789 MaxVersion: VersionTLS12, 4790 SessionTicketsDisabled: true, 4791 }, 4792 resumeSession: true, 4793 flags: []string{"-expect-session-id"}, 4794 }) 4795 tests = append(tests, testCase{ 4796 testType: serverTest, 4797 name: "Basic-Server-EarlyCallback", 4798 config: Config{ 4799 MaxVersion: VersionTLS12, 4800 }, 4801 flags: []string{"-use-early-callback"}, 4802 resumeSession: true, 4803 }) 4804 } 4805 4806 // TLS 1.3 basic handshake shapes. DTLS 1.3 isn't supported yet. 4807 if config.protocol != dtls { 4808 tests = append(tests, testCase{ 4809 name: "TLS13-1RTT-Client", 4810 config: Config{ 4811 MaxVersion: VersionTLS13, 4812 MinVersion: VersionTLS13, 4813 }, 4814 resumeSession: true, 4815 resumeRenewedSession: true, 4816 // 0-RTT being disabled overrides all other 0-RTT reasons. 4817 flags: []string{"-expect-early-data-reason", "disabled"}, 4818 }) 4819 4820 tests = append(tests, testCase{ 4821 testType: serverTest, 4822 name: "TLS13-1RTT-Server", 4823 config: Config{ 4824 MaxVersion: VersionTLS13, 4825 MinVersion: VersionTLS13, 4826 }, 4827 resumeSession: true, 4828 resumeRenewedSession: true, 4829 flags: []string{ 4830 // TLS 1.3 uses tickets, so the session should not be 4831 // cached statefully. 4832 "-expect-no-session-id", 4833 // 0-RTT being disabled overrides all other 0-RTT reasons. 4834 "-expect-early-data-reason", "disabled", 4835 }, 4836 }) 4837 4838 tests = append(tests, testCase{ 4839 name: "TLS13-HelloRetryRequest-Client", 4840 config: Config{ 4841 MaxVersion: VersionTLS13, 4842 MinVersion: VersionTLS13, 4843 // P-384 requires a HelloRetryRequest against BoringSSL's default 4844 // configuration. Assert this with ExpectMissingKeyShare. 4845 CurvePreferences: []CurveID{CurveP384}, 4846 Bugs: ProtocolBugs{ 4847 ExpectMissingKeyShare: true, 4848 }, 4849 }, 4850 // Cover HelloRetryRequest during an ECDHE-PSK resumption. 4851 resumeSession: true, 4852 flags: []string{"-expect-hrr"}, 4853 }) 4854 4855 tests = append(tests, testCase{ 4856 testType: serverTest, 4857 name: "TLS13-HelloRetryRequest-Server", 4858 config: Config{ 4859 MaxVersion: VersionTLS13, 4860 MinVersion: VersionTLS13, 4861 // Require a HelloRetryRequest for every curve. 4862 DefaultCurves: []CurveID{}, 4863 }, 4864 // Cover HelloRetryRequest during an ECDHE-PSK resumption. 4865 resumeSession: true, 4866 flags: []string{"-expect-hrr"}, 4867 }) 4868 4869 // Tests that specify a MaxEarlyDataSize don't work with QUIC. 4870 if config.protocol != quic { 4871 tests = append(tests, testCase{ 4872 testType: clientTest, 4873 name: "TLS13-EarlyData-TooMuchData-Client", 4874 config: Config{ 4875 MaxVersion: VersionTLS13, 4876 MinVersion: VersionTLS13, 4877 MaxEarlyDataSize: 2, 4878 }, 4879 resumeConfig: &Config{ 4880 MaxVersion: VersionTLS13, 4881 MinVersion: VersionTLS13, 4882 MaxEarlyDataSize: 2, 4883 Bugs: ProtocolBugs{ 4884 ExpectEarlyData: [][]byte{[]byte(shimInitialWrite[:2])}, 4885 }, 4886 }, 4887 resumeShimPrefix: shimInitialWrite[2:], 4888 resumeSession: true, 4889 earlyData: true, 4890 }) 4891 } 4892 4893 // Unfinished writes can only be tested when operations are async. EarlyData 4894 // can't be tested as part of an ImplicitHandshake in this case since 4895 // otherwise the early data will be sent as normal data. 4896 // 4897 // Note application data is external in QUIC, so unfinished writes do not 4898 // apply. 4899 if config.async && !config.implicitHandshake && config.protocol != quic { 4900 tests = append(tests, testCase{ 4901 testType: clientTest, 4902 name: "TLS13-EarlyData-UnfinishedWrite-Client", 4903 config: Config{ 4904 MaxVersion: VersionTLS13, 4905 MinVersion: VersionTLS13, 4906 Bugs: ProtocolBugs{ 4907 // Write the server response before expecting early data. 4908 ExpectEarlyData: [][]byte{}, 4909 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 4910 }, 4911 }, 4912 resumeSession: true, 4913 earlyData: true, 4914 flags: []string{"-on-resume-read-with-unfinished-write"}, 4915 }) 4916 4917 // Rejected unfinished writes are discarded (from the 4918 // perspective of the calling application) on 0-RTT 4919 // reject. 4920 tests = append(tests, testCase{ 4921 testType: clientTest, 4922 name: "TLS13-EarlyData-RejectUnfinishedWrite-Client", 4923 config: Config{ 4924 MaxVersion: VersionTLS13, 4925 MinVersion: VersionTLS13, 4926 Bugs: ProtocolBugs{ 4927 AlwaysRejectEarlyData: true, 4928 }, 4929 }, 4930 resumeSession: true, 4931 earlyData: true, 4932 expectEarlyDataRejected: true, 4933 flags: []string{"-on-resume-read-with-unfinished-write"}, 4934 }) 4935 } 4936 4937 // Early data has no size limit in QUIC. 4938 if config.protocol != quic { 4939 tests = append(tests, testCase{ 4940 testType: serverTest, 4941 name: "TLS13-MaxEarlyData-Server", 4942 config: Config{ 4943 MaxVersion: VersionTLS13, 4944 MinVersion: VersionTLS13, 4945 Bugs: ProtocolBugs{ 4946 SendEarlyData: [][]byte{bytes.Repeat([]byte{1}, 14336+1)}, 4947 ExpectEarlyDataAccepted: true, 4948 }, 4949 }, 4950 messageCount: 2, 4951 resumeSession: true, 4952 earlyData: true, 4953 shouldFail: true, 4954 expectedError: ":TOO_MUCH_READ_EARLY_DATA:", 4955 }) 4956 } 4957 } 4958 4959 // TLS client auth. 4960 // The following tests have a max version of 1.2, so they are not suitable 4961 // for use with QUIC. 4962 if config.protocol != quic { 4963 tests = append(tests, testCase{ 4964 testType: clientTest, 4965 name: "ClientAuth-NoCertificate-Client", 4966 config: Config{ 4967 MaxVersion: VersionTLS12, 4968 ClientAuth: RequestClientCert, 4969 }, 4970 }) 4971 tests = append(tests, testCase{ 4972 testType: serverTest, 4973 name: "ClientAuth-NoCertificate-Server", 4974 config: Config{ 4975 MaxVersion: VersionTLS12, 4976 }, 4977 // Setting SSL_VERIFY_PEER allows anonymous clients. 4978 flags: []string{"-verify-peer"}, 4979 }) 4980 } 4981 if config.protocol != dtls { 4982 tests = append(tests, testCase{ 4983 testType: clientTest, 4984 name: "ClientAuth-NoCertificate-Client-TLS13", 4985 config: Config{ 4986 MaxVersion: VersionTLS13, 4987 ClientAuth: RequestClientCert, 4988 }, 4989 }) 4990 tests = append(tests, testCase{ 4991 testType: serverTest, 4992 name: "ClientAuth-NoCertificate-Server-TLS13", 4993 config: Config{ 4994 MaxVersion: VersionTLS13, 4995 }, 4996 // Setting SSL_VERIFY_PEER allows anonymous clients. 4997 flags: []string{"-verify-peer"}, 4998 }) 4999 } 5000 if config.protocol != quic { 5001 tests = append(tests, testCase{ 5002 testType: clientTest, 5003 name: "ClientAuth-RSA-Client", 5004 config: Config{ 5005 MaxVersion: VersionTLS12, 5006 ClientAuth: RequireAnyClientCert, 5007 }, 5008 flags: []string{ 5009 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5010 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5011 }, 5012 }) 5013 } 5014 tests = append(tests, testCase{ 5015 testType: clientTest, 5016 name: "ClientAuth-RSA-Client-TLS13", 5017 config: Config{ 5018 MaxVersion: VersionTLS13, 5019 ClientAuth: RequireAnyClientCert, 5020 }, 5021 flags: []string{ 5022 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5023 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5024 }, 5025 }) 5026 if config.protocol != quic { 5027 tests = append(tests, testCase{ 5028 testType: clientTest, 5029 name: "ClientAuth-ECDSA-Client", 5030 config: Config{ 5031 MaxVersion: VersionTLS12, 5032 ClientAuth: RequireAnyClientCert, 5033 }, 5034 flags: []string{ 5035 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 5036 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 5037 }, 5038 }) 5039 } 5040 tests = append(tests, testCase{ 5041 testType: clientTest, 5042 name: "ClientAuth-ECDSA-Client-TLS13", 5043 config: Config{ 5044 MaxVersion: VersionTLS13, 5045 ClientAuth: RequireAnyClientCert, 5046 }, 5047 flags: []string{ 5048 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 5049 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 5050 }, 5051 }) 5052 if config.protocol != quic { 5053 tests = append(tests, testCase{ 5054 testType: clientTest, 5055 name: "ClientAuth-NoCertificate-OldCallback", 5056 config: Config{ 5057 MaxVersion: VersionTLS12, 5058 ClientAuth: RequestClientCert, 5059 }, 5060 flags: []string{"-use-old-client-cert-callback"}, 5061 }) 5062 } 5063 tests = append(tests, testCase{ 5064 testType: clientTest, 5065 name: "ClientAuth-NoCertificate-OldCallback-TLS13", 5066 config: Config{ 5067 MaxVersion: VersionTLS13, 5068 ClientAuth: RequestClientCert, 5069 }, 5070 flags: []string{"-use-old-client-cert-callback"}, 5071 }) 5072 if config.protocol != quic { 5073 tests = append(tests, testCase{ 5074 testType: clientTest, 5075 name: "ClientAuth-OldCallback", 5076 config: Config{ 5077 MaxVersion: VersionTLS12, 5078 ClientAuth: RequireAnyClientCert, 5079 }, 5080 flags: []string{ 5081 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5082 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5083 "-use-old-client-cert-callback", 5084 }, 5085 }) 5086 } 5087 tests = append(tests, testCase{ 5088 testType: clientTest, 5089 name: "ClientAuth-OldCallback-TLS13", 5090 config: Config{ 5091 MaxVersion: VersionTLS13, 5092 ClientAuth: RequireAnyClientCert, 5093 }, 5094 flags: []string{ 5095 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5096 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5097 "-use-old-client-cert-callback", 5098 }, 5099 }) 5100 if config.protocol != quic { 5101 tests = append(tests, testCase{ 5102 testType: serverTest, 5103 name: "ClientAuth-Server", 5104 config: Config{ 5105 MaxVersion: VersionTLS12, 5106 Certificates: []Certificate{rsaCertificate}, 5107 }, 5108 flags: []string{"-require-any-client-certificate"}, 5109 }) 5110 } 5111 tests = append(tests, testCase{ 5112 testType: serverTest, 5113 name: "ClientAuth-Server-TLS13", 5114 config: Config{ 5115 MaxVersion: VersionTLS13, 5116 Certificates: []Certificate{rsaCertificate}, 5117 }, 5118 flags: []string{"-require-any-client-certificate"}, 5119 }) 5120 5121 // Test each key exchange on the server side for async keys. 5122 if config.protocol != quic { 5123 tests = append(tests, testCase{ 5124 testType: serverTest, 5125 name: "Basic-Server-RSA", 5126 config: Config{ 5127 MaxVersion: VersionTLS12, 5128 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 5129 }, 5130 flags: []string{ 5131 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5132 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5133 }, 5134 }) 5135 tests = append(tests, testCase{ 5136 testType: serverTest, 5137 name: "Basic-Server-ECDHE-RSA", 5138 config: Config{ 5139 MaxVersion: VersionTLS12, 5140 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5141 }, 5142 flags: []string{ 5143 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 5144 "-key-file", path.Join(*resourceDir, rsaKeyFile), 5145 }, 5146 }) 5147 tests = append(tests, testCase{ 5148 testType: serverTest, 5149 name: "Basic-Server-ECDHE-ECDSA", 5150 config: Config{ 5151 MaxVersion: VersionTLS12, 5152 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 5153 }, 5154 flags: []string{ 5155 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 5156 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 5157 }, 5158 }) 5159 tests = append(tests, testCase{ 5160 testType: serverTest, 5161 name: "Basic-Server-Ed25519", 5162 config: Config{ 5163 MaxVersion: VersionTLS12, 5164 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 5165 }, 5166 flags: []string{ 5167 "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), 5168 "-key-file", path.Join(*resourceDir, ed25519KeyFile), 5169 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 5170 }, 5171 }) 5172 5173 // No session ticket support; server doesn't send NewSessionTicket. 5174 tests = append(tests, testCase{ 5175 name: "SessionTicketsDisabled-Client", 5176 config: Config{ 5177 MaxVersion: VersionTLS12, 5178 SessionTicketsDisabled: true, 5179 }, 5180 }) 5181 tests = append(tests, testCase{ 5182 testType: serverTest, 5183 name: "SessionTicketsDisabled-Server", 5184 config: Config{ 5185 MaxVersion: VersionTLS12, 5186 SessionTicketsDisabled: true, 5187 }, 5188 }) 5189 5190 // Skip ServerKeyExchange in PSK key exchange if there's no 5191 // identity hint. 5192 tests = append(tests, testCase{ 5193 name: "EmptyPSKHint-Client", 5194 config: Config{ 5195 MaxVersion: VersionTLS12, 5196 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 5197 PreSharedKey: []byte("secret"), 5198 }, 5199 flags: []string{"-psk", "secret"}, 5200 }) 5201 tests = append(tests, testCase{ 5202 testType: serverTest, 5203 name: "EmptyPSKHint-Server", 5204 config: Config{ 5205 MaxVersion: VersionTLS12, 5206 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 5207 PreSharedKey: []byte("secret"), 5208 }, 5209 flags: []string{"-psk", "secret"}, 5210 }) 5211 } 5212 5213 // OCSP stapling tests. 5214 for _, vers := range allVersions(config.protocol) { 5215 tests = append(tests, testCase{ 5216 testType: clientTest, 5217 name: "OCSPStapling-Client-" + vers.name, 5218 config: Config{ 5219 MaxVersion: vers.version, 5220 }, 5221 flags: []string{ 5222 "-enable-ocsp-stapling", 5223 "-expect-ocsp-response", 5224 base64FlagValue(testOCSPResponse), 5225 "-verify-peer", 5226 }, 5227 resumeSession: true, 5228 }) 5229 tests = append(tests, testCase{ 5230 testType: serverTest, 5231 name: "OCSPStapling-Server-" + vers.name, 5232 config: Config{ 5233 MaxVersion: vers.version, 5234 }, 5235 expectations: connectionExpectations{ 5236 ocspResponse: testOCSPResponse, 5237 }, 5238 flags: []string{ 5239 "-ocsp-response", 5240 base64FlagValue(testOCSPResponse), 5241 }, 5242 resumeSession: true, 5243 }) 5244 5245 // The client OCSP callback is an alternate certificate 5246 // verification callback. 5247 tests = append(tests, testCase{ 5248 testType: clientTest, 5249 name: "ClientOCSPCallback-Pass-" + vers.name, 5250 config: Config{ 5251 MaxVersion: vers.version, 5252 Certificates: []Certificate{rsaCertificate}, 5253 }, 5254 flags: []string{ 5255 "-enable-ocsp-stapling", 5256 "-use-ocsp-callback", 5257 }, 5258 }) 5259 var expectedLocalError string 5260 if !config.async { 5261 // TODO(davidben): Asynchronous fatal alerts are never 5262 // sent. https://crbug.com/boringssl/130. 5263 expectedLocalError = "remote error: bad certificate status response" 5264 } 5265 tests = append(tests, testCase{ 5266 testType: clientTest, 5267 name: "ClientOCSPCallback-Fail-" + vers.name, 5268 config: Config{ 5269 MaxVersion: vers.version, 5270 Certificates: []Certificate{rsaCertificate}, 5271 }, 5272 flags: []string{ 5273 "-enable-ocsp-stapling", 5274 "-use-ocsp-callback", 5275 "-fail-ocsp-callback", 5276 }, 5277 shouldFail: true, 5278 expectedLocalError: expectedLocalError, 5279 expectedError: ":OCSP_CB_ERROR:", 5280 }) 5281 // The callback still runs if the server does not send an OCSP 5282 // response. 5283 certNoStaple := rsaCertificate 5284 certNoStaple.OCSPStaple = nil 5285 tests = append(tests, testCase{ 5286 testType: clientTest, 5287 name: "ClientOCSPCallback-FailNoStaple-" + vers.name, 5288 config: Config{ 5289 MaxVersion: vers.version, 5290 Certificates: []Certificate{certNoStaple}, 5291 }, 5292 flags: []string{ 5293 "-enable-ocsp-stapling", 5294 "-use-ocsp-callback", 5295 "-fail-ocsp-callback", 5296 }, 5297 shouldFail: true, 5298 expectedLocalError: expectedLocalError, 5299 expectedError: ":OCSP_CB_ERROR:", 5300 }) 5301 5302 // The server OCSP callback is a legacy mechanism for 5303 // configuring OCSP, used by unreliable server software. 5304 tests = append(tests, testCase{ 5305 testType: serverTest, 5306 name: "ServerOCSPCallback-SetInCallback-" + vers.name, 5307 config: Config{ 5308 MaxVersion: vers.version, 5309 }, 5310 expectations: connectionExpectations{ 5311 ocspResponse: testOCSPResponse, 5312 }, 5313 flags: []string{ 5314 "-use-ocsp-callback", 5315 "-set-ocsp-in-callback", 5316 "-ocsp-response", 5317 base64FlagValue(testOCSPResponse), 5318 }, 5319 resumeSession: true, 5320 }) 5321 5322 // The callback may decline OCSP, in which case we act as if 5323 // the client did not support it, even if a response was 5324 // configured. 5325 tests = append(tests, testCase{ 5326 testType: serverTest, 5327 name: "ServerOCSPCallback-Decline-" + vers.name, 5328 config: Config{ 5329 MaxVersion: vers.version, 5330 }, 5331 expectations: connectionExpectations{ 5332 ocspResponse: []byte{}, 5333 }, 5334 flags: []string{ 5335 "-use-ocsp-callback", 5336 "-decline-ocsp-callback", 5337 "-ocsp-response", 5338 base64FlagValue(testOCSPResponse), 5339 }, 5340 resumeSession: true, 5341 }) 5342 5343 // The callback may also signal an internal error. 5344 tests = append(tests, testCase{ 5345 testType: serverTest, 5346 name: "ServerOCSPCallback-Fail-" + vers.name, 5347 config: Config{ 5348 MaxVersion: vers.version, 5349 }, 5350 flags: []string{ 5351 "-use-ocsp-callback", 5352 "-fail-ocsp-callback", 5353 "-ocsp-response", 5354 base64FlagValue(testOCSPResponse), 5355 }, 5356 shouldFail: true, 5357 expectedError: ":OCSP_CB_ERROR:", 5358 }) 5359 } 5360 5361 // Certificate verification tests. 5362 for _, vers := range allVersions(config.protocol) { 5363 for _, useCustomCallback := range []bool{false, true} { 5364 for _, testType := range []testType{clientTest, serverTest} { 5365 suffix := "-Client" 5366 if testType == serverTest { 5367 suffix = "-Server" 5368 } 5369 suffix += "-" + vers.name 5370 if useCustomCallback { 5371 suffix += "-CustomCallback" 5372 } 5373 5374 // The custom callback and legacy callback have different default 5375 // alerts. 5376 verifyFailLocalError := "remote error: handshake failure" 5377 if useCustomCallback { 5378 verifyFailLocalError = "remote error: unknown certificate" 5379 } 5380 5381 // We do not reliably send asynchronous fatal alerts. See 5382 // https://crbug.com/boringssl/130. 5383 if config.async { 5384 verifyFailLocalError = "" 5385 } 5386 5387 flags := []string{"-verify-peer"} 5388 if testType == serverTest { 5389 flags = append(flags, "-require-any-client-certificate") 5390 } 5391 if useCustomCallback { 5392 flags = append(flags, "-use-custom-verify-callback") 5393 } 5394 5395 tests = append(tests, testCase{ 5396 testType: testType, 5397 name: "CertificateVerificationSucceed" + suffix, 5398 config: Config{ 5399 MaxVersion: vers.version, 5400 Certificates: []Certificate{rsaCertificate}, 5401 }, 5402 flags: append([]string{"-expect-verify-result"}, flags...), 5403 resumeSession: true, 5404 }) 5405 tests = append(tests, testCase{ 5406 testType: testType, 5407 name: "CertificateVerificationFail" + suffix, 5408 config: Config{ 5409 MaxVersion: vers.version, 5410 Certificates: []Certificate{rsaCertificate}, 5411 }, 5412 flags: append([]string{"-verify-fail"}, flags...), 5413 shouldFail: true, 5414 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5415 expectedLocalError: verifyFailLocalError, 5416 }) 5417 // Tests that although the verify callback fails on resumption, by default we don't call it. 5418 tests = append(tests, testCase{ 5419 testType: testType, 5420 name: "CertificateVerificationDoesNotFailOnResume" + suffix, 5421 config: Config{ 5422 MaxVersion: vers.version, 5423 Certificates: []Certificate{rsaCertificate}, 5424 }, 5425 flags: append([]string{"-on-resume-verify-fail"}, flags...), 5426 resumeSession: true, 5427 }) 5428 if testType == clientTest && useCustomCallback { 5429 tests = append(tests, testCase{ 5430 testType: testType, 5431 name: "CertificateVerificationFailsOnResume" + suffix, 5432 config: Config{ 5433 MaxVersion: vers.version, 5434 Certificates: []Certificate{rsaCertificate}, 5435 }, 5436 flags: append([]string{ 5437 "-on-resume-verify-fail", 5438 "-reverify-on-resume", 5439 }, flags...), 5440 resumeSession: true, 5441 shouldFail: true, 5442 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5443 expectedLocalError: verifyFailLocalError, 5444 }) 5445 tests = append(tests, testCase{ 5446 testType: testType, 5447 name: "CertificateVerificationPassesOnResume" + suffix, 5448 config: Config{ 5449 MaxVersion: vers.version, 5450 Certificates: []Certificate{rsaCertificate}, 5451 }, 5452 flags: append([]string{ 5453 "-reverify-on-resume", 5454 }, flags...), 5455 resumeSession: true, 5456 }) 5457 if vers.version >= VersionTLS13 { 5458 tests = append(tests, testCase{ 5459 testType: testType, 5460 name: "EarlyData-RejectTicket-Client-Reverify" + suffix, 5461 config: Config{ 5462 MaxVersion: vers.version, 5463 }, 5464 resumeConfig: &Config{ 5465 MaxVersion: vers.version, 5466 SessionTicketsDisabled: true, 5467 }, 5468 resumeSession: true, 5469 expectResumeRejected: true, 5470 earlyData: true, 5471 expectEarlyDataRejected: true, 5472 flags: append([]string{ 5473 "-reverify-on-resume", 5474 // Session tickets are disabled, so the runner will not send a ticket. 5475 "-on-retry-expect-no-session", 5476 }, flags...), 5477 }) 5478 tests = append(tests, testCase{ 5479 testType: testType, 5480 name: "EarlyData-Reject0RTT-Client-Reverify" + suffix, 5481 config: Config{ 5482 MaxVersion: vers.version, 5483 Bugs: ProtocolBugs{ 5484 AlwaysRejectEarlyData: true, 5485 }, 5486 }, 5487 resumeSession: true, 5488 expectResumeRejected: false, 5489 earlyData: true, 5490 expectEarlyDataRejected: true, 5491 flags: append([]string{ 5492 "-reverify-on-resume", 5493 }, flags...), 5494 }) 5495 tests = append(tests, testCase{ 5496 testType: testType, 5497 name: "EarlyData-RejectTicket-Client-ReverifyFails" + suffix, 5498 config: Config{ 5499 MaxVersion: vers.version, 5500 }, 5501 resumeConfig: &Config{ 5502 MaxVersion: vers.version, 5503 SessionTicketsDisabled: true, 5504 }, 5505 resumeSession: true, 5506 expectResumeRejected: true, 5507 earlyData: true, 5508 expectEarlyDataRejected: true, 5509 shouldFail: true, 5510 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5511 flags: append([]string{ 5512 "-reverify-on-resume", 5513 // Session tickets are disabled, so the runner will not send a ticket. 5514 "-on-retry-expect-no-session", 5515 "-on-retry-verify-fail", 5516 }, flags...), 5517 }) 5518 tests = append(tests, testCase{ 5519 testType: testType, 5520 name: "EarlyData-Reject0RTT-Client-ReverifyFails" + suffix, 5521 config: Config{ 5522 MaxVersion: vers.version, 5523 Bugs: ProtocolBugs{ 5524 AlwaysRejectEarlyData: true, 5525 }, 5526 }, 5527 resumeSession: true, 5528 expectResumeRejected: false, 5529 earlyData: true, 5530 expectEarlyDataRejected: true, 5531 shouldFail: true, 5532 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5533 expectedLocalError: verifyFailLocalError, 5534 flags: append([]string{ 5535 "-reverify-on-resume", 5536 "-on-retry-verify-fail", 5537 }, flags...), 5538 }) 5539 // This tests that we only call the verify callback once. 5540 tests = append(tests, testCase{ 5541 testType: testType, 5542 name: "EarlyData-Accept0RTT-Client-Reverify" + suffix, 5543 config: Config{ 5544 MaxVersion: vers.version, 5545 }, 5546 resumeSession: true, 5547 earlyData: true, 5548 flags: append([]string{ 5549 "-reverify-on-resume", 5550 }, flags...), 5551 }) 5552 tests = append(tests, testCase{ 5553 testType: testType, 5554 name: "EarlyData-Accept0RTT-Client-ReverifyFails" + suffix, 5555 config: Config{ 5556 MaxVersion: vers.version, 5557 }, 5558 resumeSession: true, 5559 earlyData: true, 5560 shouldFail: true, 5561 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5562 // We do not set expectedLocalError here because the shim rejects 5563 // the connection without an alert. 5564 flags: append([]string{ 5565 "-reverify-on-resume", 5566 "-on-resume-verify-fail", 5567 }, flags...), 5568 }) 5569 } 5570 } 5571 } 5572 } 5573 5574 // By default, the client is in a soft fail mode where the peer 5575 // certificate is verified but failures are non-fatal. 5576 tests = append(tests, testCase{ 5577 testType: clientTest, 5578 name: "CertificateVerificationSoftFail-" + vers.name, 5579 config: Config{ 5580 MaxVersion: vers.version, 5581 Certificates: []Certificate{rsaCertificate}, 5582 }, 5583 flags: []string{ 5584 "-verify-fail", 5585 "-expect-verify-result", 5586 }, 5587 resumeSession: true, 5588 }) 5589 } 5590 5591 tests = append(tests, testCase{ 5592 name: "ShimSendAlert", 5593 flags: []string{"-send-alert"}, 5594 shimWritesFirst: true, 5595 shouldFail: true, 5596 expectedLocalError: "remote error: decompression failure", 5597 }) 5598 5599 if config.protocol == tls { 5600 tests = append(tests, testCase{ 5601 name: "Renegotiate-Client", 5602 config: Config{ 5603 MaxVersion: VersionTLS12, 5604 }, 5605 renegotiate: 1, 5606 flags: []string{ 5607 "-renegotiate-freely", 5608 "-expect-total-renegotiations", "1", 5609 }, 5610 }) 5611 5612 tests = append(tests, testCase{ 5613 name: "Renegotiate-Client-Explicit", 5614 config: Config{ 5615 MaxVersion: VersionTLS12, 5616 }, 5617 renegotiate: 1, 5618 flags: []string{ 5619 "-renegotiate-explicit", 5620 "-expect-total-renegotiations", "1", 5621 }, 5622 }) 5623 5624 halfHelloRequestError := ":UNEXPECTED_RECORD:" 5625 if config.packHandshake { 5626 // If the HelloRequest is sent in the same record as the server Finished, 5627 // BoringSSL rejects it before the handshake completes. 5628 halfHelloRequestError = ":EXCESS_HANDSHAKE_DATA:" 5629 } 5630 tests = append(tests, testCase{ 5631 name: "SendHalfHelloRequest", 5632 config: Config{ 5633 MaxVersion: VersionTLS12, 5634 Bugs: ProtocolBugs{ 5635 PackHelloRequestWithFinished: config.packHandshake, 5636 }, 5637 }, 5638 sendHalfHelloRequest: true, 5639 flags: []string{"-renegotiate-ignore"}, 5640 shouldFail: true, 5641 expectedError: halfHelloRequestError, 5642 }) 5643 5644 // NPN on client and server; results in post-handshake message. 5645 tests = append(tests, testCase{ 5646 name: "NPN-Client", 5647 config: Config{ 5648 MaxVersion: VersionTLS12, 5649 NextProtos: []string{"foo"}, 5650 }, 5651 flags: []string{"-select-next-proto", "foo"}, 5652 resumeSession: true, 5653 expectations: connectionExpectations{ 5654 nextProto: "foo", 5655 nextProtoType: npn, 5656 }, 5657 }) 5658 tests = append(tests, testCase{ 5659 testType: serverTest, 5660 name: "NPN-Server", 5661 config: Config{ 5662 MaxVersion: VersionTLS12, 5663 NextProtos: []string{"bar"}, 5664 }, 5665 flags: []string{ 5666 "-advertise-npn", "\x03foo\x03bar\x03baz", 5667 "-expect-next-proto", "bar", 5668 }, 5669 resumeSession: true, 5670 expectations: connectionExpectations{ 5671 nextProto: "bar", 5672 nextProtoType: npn, 5673 }, 5674 }) 5675 5676 // Client does False Start and negotiates NPN. 5677 tests = append(tests, testCase{ 5678 name: "FalseStart", 5679 config: Config{ 5680 MaxVersion: VersionTLS12, 5681 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5682 NextProtos: []string{"foo"}, 5683 Bugs: ProtocolBugs{ 5684 ExpectFalseStart: true, 5685 }, 5686 }, 5687 flags: []string{ 5688 "-false-start", 5689 "-select-next-proto", "foo", 5690 }, 5691 shimWritesFirst: true, 5692 resumeSession: true, 5693 }) 5694 5695 // Client does False Start and negotiates ALPN. 5696 tests = append(tests, testCase{ 5697 name: "FalseStart-ALPN", 5698 config: Config{ 5699 MaxVersion: VersionTLS12, 5700 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5701 NextProtos: []string{"foo"}, 5702 Bugs: ProtocolBugs{ 5703 ExpectFalseStart: true, 5704 }, 5705 }, 5706 flags: []string{ 5707 "-false-start", 5708 "-advertise-alpn", "\x03foo", 5709 "-expect-alpn", "foo", 5710 }, 5711 shimWritesFirst: true, 5712 resumeSession: true, 5713 }) 5714 5715 // False Start without session tickets. 5716 tests = append(tests, testCase{ 5717 name: "FalseStart-SessionTicketsDisabled", 5718 config: Config{ 5719 MaxVersion: VersionTLS12, 5720 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5721 NextProtos: []string{"foo"}, 5722 SessionTicketsDisabled: true, 5723 Bugs: ProtocolBugs{ 5724 ExpectFalseStart: true, 5725 }, 5726 }, 5727 flags: []string{ 5728 "-false-start", 5729 "-select-next-proto", "foo", 5730 }, 5731 shimWritesFirst: true, 5732 }) 5733 5734 // Server parses a V2ClientHello. Test different lengths for the 5735 // challenge field. 5736 for _, challengeLength := range []int{16, 31, 32, 33, 48} { 5737 tests = append(tests, testCase{ 5738 testType: serverTest, 5739 name: fmt.Sprintf("SendV2ClientHello-%d", challengeLength), 5740 config: Config{ 5741 // Choose a cipher suite that does not involve 5742 // elliptic curves, so no extensions are 5743 // involved. 5744 MaxVersion: VersionTLS12, 5745 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 5746 Bugs: ProtocolBugs{ 5747 SendV2ClientHello: true, 5748 V2ClientHelloChallengeLength: challengeLength, 5749 }, 5750 }, 5751 flags: []string{ 5752 "-expect-msg-callback", 5753 `read v2clienthello 5754write hs 2 5755write hs 11 5756write hs 14 5757read hs 16 5758read ccs 5759read hs 20 5760write ccs 5761write hs 20 5762read alert 1 0 5763`, 5764 }, 5765 }) 5766 } 5767 5768 // Channel ID and NPN at the same time, to ensure their relative 5769 // ordering is correct. 5770 tests = append(tests, testCase{ 5771 name: "ChannelID-NPN-Client", 5772 config: Config{ 5773 MaxVersion: VersionTLS12, 5774 RequestChannelID: true, 5775 NextProtos: []string{"foo"}, 5776 }, 5777 flags: []string{ 5778 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 5779 "-select-next-proto", "foo", 5780 }, 5781 resumeSession: true, 5782 expectations: connectionExpectations{ 5783 channelID: true, 5784 nextProto: "foo", 5785 nextProtoType: npn, 5786 }, 5787 }) 5788 tests = append(tests, testCase{ 5789 testType: serverTest, 5790 name: "ChannelID-NPN-Server", 5791 config: Config{ 5792 MaxVersion: VersionTLS12, 5793 ChannelID: channelIDKey, 5794 NextProtos: []string{"bar"}, 5795 }, 5796 flags: []string{ 5797 "-expect-channel-id", 5798 base64FlagValue(channelIDBytes), 5799 "-advertise-npn", "\x03foo\x03bar\x03baz", 5800 "-expect-next-proto", "bar", 5801 }, 5802 resumeSession: true, 5803 expectations: connectionExpectations{ 5804 channelID: true, 5805 nextProto: "bar", 5806 nextProtoType: npn, 5807 }, 5808 }) 5809 5810 // Bidirectional shutdown with the runner initiating. 5811 tests = append(tests, testCase{ 5812 name: "Shutdown-Runner", 5813 config: Config{ 5814 Bugs: ProtocolBugs{ 5815 ExpectCloseNotify: true, 5816 }, 5817 }, 5818 flags: []string{"-check-close-notify"}, 5819 }) 5820 } 5821 if config.protocol != dtls { 5822 // Test Channel ID 5823 for _, ver := range allVersions(config.protocol) { 5824 if ver.version < VersionTLS10 { 5825 continue 5826 } 5827 // Client sends a Channel ID. 5828 tests = append(tests, testCase{ 5829 name: "ChannelID-Client-" + ver.name, 5830 config: Config{ 5831 MaxVersion: ver.version, 5832 RequestChannelID: true, 5833 }, 5834 flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)}, 5835 resumeSession: true, 5836 expectations: connectionExpectations{ 5837 channelID: true, 5838 }, 5839 }) 5840 5841 // Server accepts a Channel ID. 5842 tests = append(tests, testCase{ 5843 testType: serverTest, 5844 name: "ChannelID-Server-" + ver.name, 5845 config: Config{ 5846 MaxVersion: ver.version, 5847 ChannelID: channelIDKey, 5848 }, 5849 flags: []string{ 5850 "-expect-channel-id", 5851 base64FlagValue(channelIDBytes), 5852 }, 5853 resumeSession: true, 5854 expectations: connectionExpectations{ 5855 channelID: true, 5856 }, 5857 }) 5858 5859 tests = append(tests, testCase{ 5860 testType: serverTest, 5861 name: "InvalidChannelIDSignature-" + ver.name, 5862 config: Config{ 5863 MaxVersion: ver.version, 5864 ChannelID: channelIDKey, 5865 Bugs: ProtocolBugs{ 5866 InvalidChannelIDSignature: true, 5867 }, 5868 }, 5869 flags: []string{"-enable-channel-id"}, 5870 shouldFail: true, 5871 expectedError: ":CHANNEL_ID_SIGNATURE_INVALID:", 5872 }) 5873 5874 if ver.version < VersionTLS13 { 5875 // Channel ID requires ECDHE ciphers. 5876 tests = append(tests, testCase{ 5877 testType: serverTest, 5878 name: "ChannelID-NoECDHE-" + ver.name, 5879 config: Config{ 5880 MaxVersion: ver.version, 5881 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 5882 ChannelID: channelIDKey, 5883 }, 5884 expectations: connectionExpectations{ 5885 channelID: false, 5886 }, 5887 flags: []string{"-enable-channel-id"}, 5888 }) 5889 5890 // Sanity-check setting expectations.channelID false works. 5891 tests = append(tests, testCase{ 5892 testType: serverTest, 5893 name: "ChannelID-ECDHE-" + ver.name, 5894 config: Config{ 5895 MaxVersion: ver.version, 5896 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 5897 ChannelID: channelIDKey, 5898 }, 5899 expectations: connectionExpectations{ 5900 channelID: false, 5901 }, 5902 flags: []string{"-enable-channel-id"}, 5903 shouldFail: true, 5904 expectedLocalError: "channel ID unexpectedly negotiated", 5905 }) 5906 } 5907 } 5908 5909 if !config.implicitHandshake { 5910 // Bidirectional shutdown with the shim initiating. The runner, 5911 // in the meantime, sends garbage before the close_notify which 5912 // the shim must ignore. This test is disabled under implicit 5913 // handshake tests because the shim never reads or writes. 5914 5915 // Tests that require checking for a close notify alert don't work with 5916 // QUIC because alerts are handled outside of the TLS stack in QUIC. 5917 if config.protocol != quic { 5918 tests = append(tests, testCase{ 5919 name: "Shutdown-Shim", 5920 config: Config{ 5921 MaxVersion: VersionTLS12, 5922 Bugs: ProtocolBugs{ 5923 ExpectCloseNotify: true, 5924 }, 5925 }, 5926 shimShutsDown: true, 5927 sendEmptyRecords: 1, 5928 sendWarningAlerts: 1, 5929 flags: []string{"-check-close-notify"}, 5930 }) 5931 5932 // The shim should reject unexpected application data 5933 // when shutting down. 5934 tests = append(tests, testCase{ 5935 name: "Shutdown-Shim-ApplicationData", 5936 config: Config{ 5937 MaxVersion: VersionTLS12, 5938 Bugs: ProtocolBugs{ 5939 ExpectCloseNotify: true, 5940 }, 5941 }, 5942 shimShutsDown: true, 5943 messageCount: 1, 5944 sendEmptyRecords: 1, 5945 sendWarningAlerts: 1, 5946 flags: []string{"-check-close-notify"}, 5947 shouldFail: true, 5948 expectedError: ":APPLICATION_DATA_ON_SHUTDOWN:", 5949 }) 5950 5951 // Test that SSL_shutdown still processes KeyUpdate. 5952 tests = append(tests, testCase{ 5953 name: "Shutdown-Shim-KeyUpdate", 5954 config: Config{ 5955 MinVersion: VersionTLS13, 5956 MaxVersion: VersionTLS13, 5957 Bugs: ProtocolBugs{ 5958 ExpectCloseNotify: true, 5959 }, 5960 }, 5961 shimShutsDown: true, 5962 sendKeyUpdates: 1, 5963 keyUpdateRequest: keyUpdateRequested, 5964 flags: []string{"-check-close-notify"}, 5965 }) 5966 5967 // Test that SSL_shutdown processes HelloRequest 5968 // correctly. 5969 tests = append(tests, testCase{ 5970 name: "Shutdown-Shim-HelloRequest-Ignore", 5971 config: Config{ 5972 MinVersion: VersionTLS12, 5973 MaxVersion: VersionTLS12, 5974 Bugs: ProtocolBugs{ 5975 SendHelloRequestBeforeEveryAppDataRecord: true, 5976 ExpectCloseNotify: true, 5977 }, 5978 }, 5979 shimShutsDown: true, 5980 flags: []string{ 5981 "-renegotiate-ignore", 5982 "-check-close-notify", 5983 }, 5984 }) 5985 tests = append(tests, testCase{ 5986 name: "Shutdown-Shim-HelloRequest-Reject", 5987 config: Config{ 5988 MinVersion: VersionTLS12, 5989 MaxVersion: VersionTLS12, 5990 Bugs: ProtocolBugs{ 5991 ExpectCloseNotify: true, 5992 }, 5993 }, 5994 shimShutsDown: true, 5995 renegotiate: 1, 5996 shouldFail: true, 5997 expectedError: ":NO_RENEGOTIATION:", 5998 flags: []string{"-check-close-notify"}, 5999 }) 6000 tests = append(tests, testCase{ 6001 name: "Shutdown-Shim-HelloRequest-CannotHandshake", 6002 config: Config{ 6003 MinVersion: VersionTLS12, 6004 MaxVersion: VersionTLS12, 6005 Bugs: ProtocolBugs{ 6006 ExpectCloseNotify: true, 6007 }, 6008 }, 6009 shimShutsDown: true, 6010 renegotiate: 1, 6011 shouldFail: true, 6012 expectedError: ":NO_RENEGOTIATION:", 6013 flags: []string{ 6014 "-check-close-notify", 6015 "-renegotiate-freely", 6016 }, 6017 }) 6018 6019 tests = append(tests, testCase{ 6020 testType: serverTest, 6021 name: "Shutdown-Shim-Renegotiate-Server-Forbidden", 6022 config: Config{ 6023 MaxVersion: VersionTLS12, 6024 Bugs: ProtocolBugs{ 6025 ExpectCloseNotify: true, 6026 }, 6027 }, 6028 shimShutsDown: true, 6029 renegotiate: 1, 6030 shouldFail: true, 6031 expectedError: ":NO_RENEGOTIATION:", 6032 flags: []string{ 6033 "-check-close-notify", 6034 }, 6035 }) 6036 } 6037 } 6038 } 6039 if config.protocol == dtls { 6040 // TODO(davidben): DTLS 1.3 will want a similar thing for 6041 // HelloRetryRequest. 6042 tests = append(tests, testCase{ 6043 name: "SkipHelloVerifyRequest", 6044 config: Config{ 6045 MaxVersion: VersionTLS12, 6046 Bugs: ProtocolBugs{ 6047 SkipHelloVerifyRequest: true, 6048 }, 6049 }, 6050 }) 6051 } 6052 6053 for _, test := range tests { 6054 test.protocol = config.protocol 6055 test.name += "-" + config.protocol.String() 6056 if config.async { 6057 test.name += "-Async" 6058 test.flags = append(test.flags, "-async") 6059 } else { 6060 test.name += "-Sync" 6061 } 6062 if config.splitHandshake { 6063 test.name += "-SplitHandshakeRecords" 6064 test.config.Bugs.MaxHandshakeRecordLength = 1 6065 if config.protocol == dtls { 6066 test.config.Bugs.MaxPacketLength = 256 6067 test.flags = append(test.flags, "-mtu", "256") 6068 } 6069 } 6070 if config.packHandshake { 6071 test.name += "-PackHandshake" 6072 if config.protocol == dtls { 6073 test.config.Bugs.MaxHandshakeRecordLength = 2 6074 test.config.Bugs.PackHandshakeFragments = 20 6075 test.config.Bugs.PackHandshakeRecords = 1500 6076 test.config.Bugs.PackAppDataWithHandshake = true 6077 } else { 6078 test.config.Bugs.PackHandshakeFlight = true 6079 } 6080 } 6081 if config.implicitHandshake { 6082 test.name += "-ImplicitHandshake" 6083 test.flags = append(test.flags, "-implicit-handshake") 6084 } 6085 testCases = append(testCases, test) 6086 } 6087} 6088 6089func addDDoSCallbackTests() { 6090 // DDoS callback. 6091 for _, resume := range []bool{false, true} { 6092 suffix := "Resume" 6093 if resume { 6094 suffix = "No" + suffix 6095 } 6096 6097 testCases = append(testCases, testCase{ 6098 testType: serverTest, 6099 name: "Server-DDoS-OK-" + suffix, 6100 config: Config{ 6101 MaxVersion: VersionTLS12, 6102 }, 6103 flags: []string{"-install-ddos-callback"}, 6104 resumeSession: resume, 6105 }) 6106 testCases = append(testCases, testCase{ 6107 testType: serverTest, 6108 name: "Server-DDoS-OK-" + suffix + "-TLS13", 6109 config: Config{ 6110 MaxVersion: VersionTLS13, 6111 }, 6112 flags: []string{"-install-ddos-callback"}, 6113 resumeSession: resume, 6114 }) 6115 6116 failFlag := "-fail-ddos-callback" 6117 if resume { 6118 failFlag = "-on-resume-fail-ddos-callback" 6119 } 6120 testCases = append(testCases, testCase{ 6121 testType: serverTest, 6122 name: "Server-DDoS-Reject-" + suffix, 6123 config: Config{ 6124 MaxVersion: VersionTLS12, 6125 }, 6126 flags: []string{"-install-ddos-callback", failFlag}, 6127 resumeSession: resume, 6128 shouldFail: true, 6129 expectedError: ":CONNECTION_REJECTED:", 6130 expectedLocalError: "remote error: internal error", 6131 }) 6132 testCases = append(testCases, testCase{ 6133 testType: serverTest, 6134 name: "Server-DDoS-Reject-" + suffix + "-TLS13", 6135 config: Config{ 6136 MaxVersion: VersionTLS13, 6137 }, 6138 flags: []string{"-install-ddos-callback", failFlag}, 6139 resumeSession: resume, 6140 shouldFail: true, 6141 expectedError: ":CONNECTION_REJECTED:", 6142 expectedLocalError: "remote error: internal error", 6143 }) 6144 } 6145} 6146 6147func addVersionNegotiationTests() { 6148 for _, protocol := range []protocol{tls, dtls, quic} { 6149 for _, shimVers := range allVersions(protocol) { 6150 // Assemble flags to disable all newer versions on the shim. 6151 var flags []string 6152 for _, vers := range allVersions(protocol) { 6153 if vers.version > shimVers.version { 6154 flags = append(flags, vers.excludeFlag) 6155 } 6156 } 6157 6158 flags2 := []string{"-max-version", shimVers.shimFlag(protocol)} 6159 6160 // Test configuring the runner's maximum version. 6161 for _, runnerVers := range allVersions(protocol) { 6162 expectedVersion := shimVers.version 6163 if runnerVers.version < shimVers.version { 6164 expectedVersion = runnerVers.version 6165 } 6166 6167 suffix := shimVers.name + "-" + runnerVers.name 6168 suffix += "-" + protocol.String() 6169 6170 // Determine the expected initial record-layer versions. 6171 clientVers := shimVers.version 6172 if clientVers > VersionTLS10 { 6173 clientVers = VersionTLS10 6174 } 6175 clientVers = recordVersionToWire(clientVers, protocol) 6176 serverVers := expectedVersion 6177 if expectedVersion >= VersionTLS13 { 6178 serverVers = VersionTLS12 6179 } 6180 serverVers = recordVersionToWire(serverVers, protocol) 6181 6182 testCases = append(testCases, testCase{ 6183 protocol: protocol, 6184 testType: clientTest, 6185 name: "VersionNegotiation-Client-" + suffix, 6186 config: Config{ 6187 MaxVersion: runnerVers.version, 6188 Bugs: ProtocolBugs{ 6189 ExpectInitialRecordVersion: clientVers, 6190 }, 6191 }, 6192 flags: flags, 6193 expectations: connectionExpectations{ 6194 version: expectedVersion, 6195 }, 6196 // The version name check does not recognize the 6197 // |excludeFlag| construction in |flags|. 6198 skipVersionNameCheck: true, 6199 }) 6200 testCases = append(testCases, testCase{ 6201 protocol: protocol, 6202 testType: clientTest, 6203 name: "VersionNegotiation-Client2-" + suffix, 6204 config: Config{ 6205 MaxVersion: runnerVers.version, 6206 Bugs: ProtocolBugs{ 6207 ExpectInitialRecordVersion: clientVers, 6208 }, 6209 }, 6210 flags: flags2, 6211 expectations: connectionExpectations{ 6212 version: expectedVersion, 6213 }, 6214 }) 6215 6216 testCases = append(testCases, testCase{ 6217 protocol: protocol, 6218 testType: serverTest, 6219 name: "VersionNegotiation-Server-" + suffix, 6220 config: Config{ 6221 MaxVersion: runnerVers.version, 6222 Bugs: ProtocolBugs{ 6223 ExpectInitialRecordVersion: serverVers, 6224 }, 6225 }, 6226 flags: flags, 6227 expectations: connectionExpectations{ 6228 version: expectedVersion, 6229 }, 6230 // The version name check does not recognize the 6231 // |excludeFlag| construction in |flags|. 6232 skipVersionNameCheck: true, 6233 }) 6234 testCases = append(testCases, testCase{ 6235 protocol: protocol, 6236 testType: serverTest, 6237 name: "VersionNegotiation-Server2-" + suffix, 6238 config: Config{ 6239 MaxVersion: runnerVers.version, 6240 Bugs: ProtocolBugs{ 6241 ExpectInitialRecordVersion: serverVers, 6242 }, 6243 }, 6244 flags: flags2, 6245 expectations: connectionExpectations{ 6246 version: expectedVersion, 6247 }, 6248 }) 6249 } 6250 } 6251 } 6252 6253 // Test the version extension at all versions. 6254 for _, protocol := range []protocol{tls, dtls, quic} { 6255 for _, vers := range allVersions(protocol) { 6256 suffix := vers.name + "-" + protocol.String() 6257 6258 testCases = append(testCases, testCase{ 6259 protocol: protocol, 6260 testType: serverTest, 6261 name: "VersionNegotiationExtension-" + suffix, 6262 config: Config{ 6263 Bugs: ProtocolBugs{ 6264 SendSupportedVersions: []uint16{0x1111, vers.wire(protocol), 0x2222}, 6265 IgnoreTLS13DowngradeRandom: true, 6266 }, 6267 }, 6268 expectations: connectionExpectations{ 6269 version: vers.version, 6270 }, 6271 }) 6272 } 6273 } 6274 6275 // If all versions are unknown, negotiation fails. 6276 testCases = append(testCases, testCase{ 6277 testType: serverTest, 6278 name: "NoSupportedVersions", 6279 config: Config{ 6280 Bugs: ProtocolBugs{ 6281 SendSupportedVersions: []uint16{0x1111}, 6282 }, 6283 }, 6284 shouldFail: true, 6285 expectedError: ":UNSUPPORTED_PROTOCOL:", 6286 }) 6287 testCases = append(testCases, testCase{ 6288 protocol: dtls, 6289 testType: serverTest, 6290 name: "NoSupportedVersions-DTLS", 6291 config: Config{ 6292 Bugs: ProtocolBugs{ 6293 SendSupportedVersions: []uint16{0x1111}, 6294 }, 6295 }, 6296 shouldFail: true, 6297 expectedError: ":UNSUPPORTED_PROTOCOL:", 6298 }) 6299 6300 testCases = append(testCases, testCase{ 6301 testType: serverTest, 6302 name: "ClientHelloVersionTooHigh", 6303 config: Config{ 6304 MaxVersion: VersionTLS13, 6305 Bugs: ProtocolBugs{ 6306 SendClientVersion: 0x0304, 6307 OmitSupportedVersions: true, 6308 IgnoreTLS13DowngradeRandom: true, 6309 }, 6310 }, 6311 expectations: connectionExpectations{ 6312 version: VersionTLS12, 6313 }, 6314 }) 6315 6316 testCases = append(testCases, testCase{ 6317 testType: serverTest, 6318 name: "ConflictingVersionNegotiation", 6319 config: Config{ 6320 Bugs: ProtocolBugs{ 6321 SendClientVersion: VersionTLS12, 6322 SendSupportedVersions: []uint16{VersionTLS11}, 6323 IgnoreTLS13DowngradeRandom: true, 6324 }, 6325 }, 6326 // The extension takes precedence over the ClientHello version. 6327 expectations: connectionExpectations{ 6328 version: VersionTLS11, 6329 }, 6330 }) 6331 6332 testCases = append(testCases, testCase{ 6333 testType: serverTest, 6334 name: "ConflictingVersionNegotiation-2", 6335 config: Config{ 6336 Bugs: ProtocolBugs{ 6337 SendClientVersion: VersionTLS11, 6338 SendSupportedVersions: []uint16{VersionTLS12}, 6339 IgnoreTLS13DowngradeRandom: true, 6340 }, 6341 }, 6342 // The extension takes precedence over the ClientHello version. 6343 expectations: connectionExpectations{ 6344 version: VersionTLS12, 6345 }, 6346 }) 6347 6348 // Test that TLS 1.2 isn't negotiated by the supported_versions extension in 6349 // the ServerHello. 6350 testCases = append(testCases, testCase{ 6351 testType: clientTest, 6352 name: "SupportedVersionSelection-TLS12", 6353 config: Config{ 6354 MaxVersion: VersionTLS12, 6355 Bugs: ProtocolBugs{ 6356 SendServerSupportedVersionExtension: VersionTLS12, 6357 }, 6358 }, 6359 shouldFail: true, 6360 expectedError: ":UNEXPECTED_EXTENSION:", 6361 }) 6362 6363 // Test that the maximum version is selected regardless of the 6364 // client-sent order. 6365 testCases = append(testCases, testCase{ 6366 testType: serverTest, 6367 name: "IgnoreClientVersionOrder", 6368 config: Config{ 6369 Bugs: ProtocolBugs{ 6370 SendSupportedVersions: []uint16{VersionTLS12, VersionTLS13}, 6371 }, 6372 }, 6373 expectations: connectionExpectations{ 6374 version: VersionTLS13, 6375 }, 6376 }) 6377 6378 // Test for version tolerance. 6379 testCases = append(testCases, testCase{ 6380 testType: serverTest, 6381 name: "MinorVersionTolerance", 6382 config: Config{ 6383 Bugs: ProtocolBugs{ 6384 SendClientVersion: 0x03ff, 6385 OmitSupportedVersions: true, 6386 IgnoreTLS13DowngradeRandom: true, 6387 }, 6388 }, 6389 expectations: connectionExpectations{ 6390 version: VersionTLS12, 6391 }, 6392 }) 6393 testCases = append(testCases, testCase{ 6394 testType: serverTest, 6395 name: "MajorVersionTolerance", 6396 config: Config{ 6397 Bugs: ProtocolBugs{ 6398 SendClientVersion: 0x0400, 6399 OmitSupportedVersions: true, 6400 IgnoreTLS13DowngradeRandom: true, 6401 }, 6402 }, 6403 // TLS 1.3 must be negotiated with the supported_versions 6404 // extension, not ClientHello.version. 6405 expectations: connectionExpectations{ 6406 version: VersionTLS12, 6407 }, 6408 }) 6409 testCases = append(testCases, testCase{ 6410 testType: serverTest, 6411 name: "VersionTolerance-TLS13", 6412 config: Config{ 6413 Bugs: ProtocolBugs{ 6414 // Although TLS 1.3 does not use 6415 // ClientHello.version, it still tolerates high 6416 // values there. 6417 SendClientVersion: 0x0400, 6418 }, 6419 }, 6420 expectations: connectionExpectations{ 6421 version: VersionTLS13, 6422 }, 6423 }) 6424 6425 testCases = append(testCases, testCase{ 6426 protocol: dtls, 6427 testType: serverTest, 6428 name: "MinorVersionTolerance-DTLS", 6429 config: Config{ 6430 Bugs: ProtocolBugs{ 6431 SendClientVersion: 0xfe00, 6432 OmitSupportedVersions: true, 6433 }, 6434 }, 6435 expectations: connectionExpectations{ 6436 version: VersionTLS12, 6437 }, 6438 }) 6439 testCases = append(testCases, testCase{ 6440 protocol: dtls, 6441 testType: serverTest, 6442 name: "MajorVersionTolerance-DTLS", 6443 config: Config{ 6444 Bugs: ProtocolBugs{ 6445 SendClientVersion: 0xfdff, 6446 OmitSupportedVersions: true, 6447 }, 6448 }, 6449 expectations: connectionExpectations{ 6450 version: VersionTLS12, 6451 }, 6452 }) 6453 6454 // Test that versions below 3.0 are rejected. 6455 testCases = append(testCases, testCase{ 6456 testType: serverTest, 6457 name: "VersionTooLow", 6458 config: Config{ 6459 Bugs: ProtocolBugs{ 6460 SendClientVersion: 0x0200, 6461 OmitSupportedVersions: true, 6462 }, 6463 }, 6464 shouldFail: true, 6465 expectedError: ":UNSUPPORTED_PROTOCOL:", 6466 }) 6467 testCases = append(testCases, testCase{ 6468 protocol: dtls, 6469 testType: serverTest, 6470 name: "VersionTooLow-DTLS", 6471 config: Config{ 6472 Bugs: ProtocolBugs{ 6473 SendClientVersion: 0xffff, 6474 }, 6475 }, 6476 shouldFail: true, 6477 expectedError: ":UNSUPPORTED_PROTOCOL:", 6478 }) 6479 6480 testCases = append(testCases, testCase{ 6481 name: "ServerBogusVersion", 6482 config: Config{ 6483 Bugs: ProtocolBugs{ 6484 SendServerHelloVersion: 0x1234, 6485 }, 6486 }, 6487 shouldFail: true, 6488 expectedError: ":UNSUPPORTED_PROTOCOL:", 6489 }) 6490 6491 // Test TLS 1.3's downgrade signal. 6492 var downgradeTests = []struct { 6493 name string 6494 version uint16 6495 clientShimError string 6496 }{ 6497 {"TLS12", VersionTLS12, "tls: downgrade from TLS 1.3 detected"}, 6498 {"TLS11", VersionTLS11, "tls: downgrade from TLS 1.2 detected"}, 6499 // TLS 1.0 does not have a dedicated value. 6500 {"TLS10", VersionTLS10, "tls: downgrade from TLS 1.2 detected"}, 6501 } 6502 6503 for _, test := range downgradeTests { 6504 // The client should enforce the downgrade sentinel. 6505 testCases = append(testCases, testCase{ 6506 name: "Downgrade-" + test.name + "-Client", 6507 config: Config{ 6508 Bugs: ProtocolBugs{ 6509 NegotiateVersion: test.version, 6510 }, 6511 }, 6512 expectations: connectionExpectations{ 6513 version: test.version, 6514 }, 6515 shouldFail: true, 6516 expectedError: ":TLS13_DOWNGRADE:", 6517 expectedLocalError: "remote error: illegal parameter", 6518 }) 6519 6520 // The server should emit the downgrade signal. 6521 testCases = append(testCases, testCase{ 6522 testType: serverTest, 6523 name: "Downgrade-" + test.name + "-Server", 6524 config: Config{ 6525 Bugs: ProtocolBugs{ 6526 SendSupportedVersions: []uint16{test.version}, 6527 }, 6528 }, 6529 expectations: connectionExpectations{ 6530 version: test.version, 6531 }, 6532 shouldFail: true, 6533 expectedLocalError: test.clientShimError, 6534 }) 6535 } 6536 6537 // SSL 3.0 support has been removed. Test that the shim does not 6538 // support it. 6539 testCases = append(testCases, testCase{ 6540 name: "NoSSL3-Client", 6541 config: Config{ 6542 MinVersion: VersionSSL30, 6543 MaxVersion: VersionSSL30, 6544 }, 6545 shouldFail: true, 6546 expectedLocalError: "tls: client did not offer any supported protocol versions", 6547 }) 6548 testCases = append(testCases, testCase{ 6549 name: "NoSSL3-Client-Unsolicited", 6550 config: Config{ 6551 MinVersion: VersionSSL30, 6552 MaxVersion: VersionSSL30, 6553 Bugs: ProtocolBugs{ 6554 // The above test asserts the client does not 6555 // offer SSL 3.0 in the supported_versions 6556 // list. Additionally assert that it rejects an 6557 // unsolicited SSL 3.0 ServerHello. 6558 NegotiateVersion: VersionSSL30, 6559 }, 6560 }, 6561 shouldFail: true, 6562 expectedError: ":UNSUPPORTED_PROTOCOL:", 6563 expectedLocalError: "remote error: protocol version not supported", 6564 }) 6565 testCases = append(testCases, testCase{ 6566 testType: serverTest, 6567 name: "NoSSL3-Server", 6568 config: Config{ 6569 MinVersion: VersionSSL30, 6570 MaxVersion: VersionSSL30, 6571 }, 6572 shouldFail: true, 6573 expectedError: ":UNSUPPORTED_PROTOCOL:", 6574 expectedLocalError: "remote error: protocol version not supported", 6575 }) 6576} 6577 6578func addMinimumVersionTests() { 6579 for _, protocol := range []protocol{tls, dtls, quic} { 6580 for _, shimVers := range allVersions(protocol) { 6581 // Assemble flags to disable all older versions on the shim. 6582 var flags []string 6583 for _, vers := range allVersions(protocol) { 6584 if vers.version < shimVers.version { 6585 flags = append(flags, vers.excludeFlag) 6586 } 6587 } 6588 6589 flags2 := []string{"-min-version", shimVers.shimFlag(protocol)} 6590 6591 for _, runnerVers := range allVersions(protocol) { 6592 suffix := shimVers.name + "-" + runnerVers.name 6593 suffix += "-" + protocol.String() 6594 6595 var expectedVersion uint16 6596 var shouldFail bool 6597 var expectedError, expectedLocalError string 6598 if runnerVers.version >= shimVers.version { 6599 expectedVersion = runnerVers.version 6600 } else { 6601 shouldFail = true 6602 expectedError = ":UNSUPPORTED_PROTOCOL:" 6603 expectedLocalError = "remote error: protocol version not supported" 6604 } 6605 6606 testCases = append(testCases, testCase{ 6607 protocol: protocol, 6608 testType: clientTest, 6609 name: "MinimumVersion-Client-" + suffix, 6610 config: Config{ 6611 MaxVersion: runnerVers.version, 6612 Bugs: ProtocolBugs{ 6613 // Ensure the server does not decline to 6614 // select a version (versions extension) or 6615 // cipher (some ciphers depend on versions). 6616 NegotiateVersion: runnerVers.wire(protocol), 6617 IgnorePeerCipherPreferences: shouldFail, 6618 }, 6619 }, 6620 flags: flags, 6621 expectations: connectionExpectations{ 6622 version: expectedVersion, 6623 }, 6624 shouldFail: shouldFail, 6625 expectedError: expectedError, 6626 expectedLocalError: expectedLocalError, 6627 // The version name check does not recognize the 6628 // |excludeFlag| construction in |flags|. 6629 skipVersionNameCheck: true, 6630 }) 6631 testCases = append(testCases, testCase{ 6632 protocol: protocol, 6633 testType: clientTest, 6634 name: "MinimumVersion-Client2-" + suffix, 6635 config: Config{ 6636 MaxVersion: runnerVers.version, 6637 Bugs: ProtocolBugs{ 6638 // Ensure the server does not decline to 6639 // select a version (versions extension) or 6640 // cipher (some ciphers depend on versions). 6641 NegotiateVersion: runnerVers.wire(protocol), 6642 IgnorePeerCipherPreferences: shouldFail, 6643 }, 6644 }, 6645 flags: flags2, 6646 expectations: connectionExpectations{ 6647 version: expectedVersion, 6648 }, 6649 shouldFail: shouldFail, 6650 expectedError: expectedError, 6651 expectedLocalError: expectedLocalError, 6652 }) 6653 6654 testCases = append(testCases, testCase{ 6655 protocol: protocol, 6656 testType: serverTest, 6657 name: "MinimumVersion-Server-" + suffix, 6658 config: Config{ 6659 MaxVersion: runnerVers.version, 6660 }, 6661 flags: flags, 6662 expectations: connectionExpectations{ 6663 version: expectedVersion, 6664 }, 6665 shouldFail: shouldFail, 6666 expectedError: expectedError, 6667 expectedLocalError: expectedLocalError, 6668 // The version name check does not recognize the 6669 // |excludeFlag| construction in |flags|. 6670 skipVersionNameCheck: true, 6671 }) 6672 testCases = append(testCases, testCase{ 6673 protocol: protocol, 6674 testType: serverTest, 6675 name: "MinimumVersion-Server2-" + suffix, 6676 config: Config{ 6677 MaxVersion: runnerVers.version, 6678 }, 6679 flags: flags2, 6680 expectations: connectionExpectations{ 6681 version: expectedVersion, 6682 }, 6683 shouldFail: shouldFail, 6684 expectedError: expectedError, 6685 expectedLocalError: expectedLocalError, 6686 }) 6687 } 6688 } 6689 } 6690} 6691 6692func addExtensionTests() { 6693 // Repeat extensions tests at all versions. 6694 for _, protocol := range []protocol{tls, dtls, quic} { 6695 for _, ver := range allVersions(protocol) { 6696 suffix := fmt.Sprintf("%s-%s", protocol.String(), ver.name) 6697 6698 // Test that duplicate extensions are rejected. 6699 testCases = append(testCases, testCase{ 6700 protocol: protocol, 6701 testType: clientTest, 6702 name: "DuplicateExtensionClient-" + suffix, 6703 config: Config{ 6704 MaxVersion: ver.version, 6705 Bugs: ProtocolBugs{ 6706 DuplicateExtension: true, 6707 }, 6708 }, 6709 shouldFail: true, 6710 expectedLocalError: "remote error: error decoding message", 6711 }) 6712 testCases = append(testCases, testCase{ 6713 protocol: protocol, 6714 testType: serverTest, 6715 name: "DuplicateExtensionServer-" + suffix, 6716 config: Config{ 6717 MaxVersion: ver.version, 6718 Bugs: ProtocolBugs{ 6719 DuplicateExtension: true, 6720 }, 6721 }, 6722 shouldFail: true, 6723 expectedLocalError: "remote error: error decoding message", 6724 }) 6725 6726 // Test SNI. 6727 testCases = append(testCases, testCase{ 6728 protocol: protocol, 6729 testType: clientTest, 6730 name: "ServerNameExtensionClient-" + suffix, 6731 config: Config{ 6732 MaxVersion: ver.version, 6733 Bugs: ProtocolBugs{ 6734 ExpectServerName: "example.com", 6735 }, 6736 }, 6737 flags: []string{"-host-name", "example.com"}, 6738 }) 6739 testCases = append(testCases, testCase{ 6740 protocol: protocol, 6741 testType: clientTest, 6742 name: "ServerNameExtensionClientMismatch-" + suffix, 6743 config: Config{ 6744 MaxVersion: ver.version, 6745 Bugs: ProtocolBugs{ 6746 ExpectServerName: "mismatch.com", 6747 }, 6748 }, 6749 flags: []string{"-host-name", "example.com"}, 6750 shouldFail: true, 6751 expectedLocalError: "tls: unexpected server name", 6752 }) 6753 testCases = append(testCases, testCase{ 6754 protocol: protocol, 6755 testType: clientTest, 6756 name: "ServerNameExtensionClientMissing-" + suffix, 6757 config: Config{ 6758 MaxVersion: ver.version, 6759 Bugs: ProtocolBugs{ 6760 ExpectServerName: "missing.com", 6761 }, 6762 }, 6763 shouldFail: true, 6764 expectedLocalError: "tls: unexpected server name", 6765 }) 6766 testCases = append(testCases, testCase{ 6767 protocol: protocol, 6768 testType: clientTest, 6769 name: "TolerateServerNameAck-" + suffix, 6770 config: Config{ 6771 MaxVersion: ver.version, 6772 Bugs: ProtocolBugs{ 6773 SendServerNameAck: true, 6774 }, 6775 }, 6776 flags: []string{"-host-name", "example.com"}, 6777 resumeSession: true, 6778 }) 6779 testCases = append(testCases, testCase{ 6780 protocol: protocol, 6781 testType: clientTest, 6782 name: "UnsolicitedServerNameAck-" + suffix, 6783 config: Config{ 6784 MaxVersion: ver.version, 6785 Bugs: ProtocolBugs{ 6786 SendServerNameAck: true, 6787 }, 6788 }, 6789 shouldFail: true, 6790 expectedError: ":UNEXPECTED_EXTENSION:", 6791 expectedLocalError: "remote error: unsupported extension", 6792 }) 6793 testCases = append(testCases, testCase{ 6794 protocol: protocol, 6795 testType: serverTest, 6796 name: "ServerNameExtensionServer-" + suffix, 6797 config: Config{ 6798 MaxVersion: ver.version, 6799 ServerName: "example.com", 6800 }, 6801 flags: []string{"-expect-server-name", "example.com"}, 6802 resumeSession: true, 6803 }) 6804 6805 // Test ALPN. 6806 testCases = append(testCases, testCase{ 6807 protocol: protocol, 6808 testType: clientTest, 6809 skipQUICALPNConfig: true, 6810 name: "ALPNClient-" + suffix, 6811 config: Config{ 6812 MaxVersion: ver.version, 6813 NextProtos: []string{"foo"}, 6814 }, 6815 flags: []string{ 6816 "-advertise-alpn", "\x03foo\x03bar\x03baz", 6817 "-expect-alpn", "foo", 6818 }, 6819 expectations: connectionExpectations{ 6820 nextProto: "foo", 6821 nextProtoType: alpn, 6822 }, 6823 resumeSession: true, 6824 }) 6825 testCases = append(testCases, testCase{ 6826 protocol: protocol, 6827 testType: clientTest, 6828 skipQUICALPNConfig: true, 6829 name: "ALPNClient-RejectUnknown-" + suffix, 6830 config: Config{ 6831 MaxVersion: ver.version, 6832 Bugs: ProtocolBugs{ 6833 SendALPN: "baz", 6834 }, 6835 }, 6836 flags: []string{ 6837 "-advertise-alpn", "\x03foo\x03bar", 6838 }, 6839 shouldFail: true, 6840 expectedError: ":INVALID_ALPN_PROTOCOL:", 6841 expectedLocalError: "remote error: illegal parameter", 6842 }) 6843 testCases = append(testCases, testCase{ 6844 protocol: protocol, 6845 testType: clientTest, 6846 skipQUICALPNConfig: true, 6847 name: "ALPNClient-AllowUnknown-" + suffix, 6848 config: Config{ 6849 MaxVersion: ver.version, 6850 Bugs: ProtocolBugs{ 6851 SendALPN: "baz", 6852 }, 6853 }, 6854 flags: []string{ 6855 "-advertise-alpn", "\x03foo\x03bar", 6856 "-allow-unknown-alpn-protos", 6857 "-expect-alpn", "baz", 6858 }, 6859 }) 6860 testCases = append(testCases, testCase{ 6861 protocol: protocol, 6862 testType: serverTest, 6863 skipQUICALPNConfig: true, 6864 name: "ALPNServer-" + suffix, 6865 config: Config{ 6866 MaxVersion: ver.version, 6867 NextProtos: []string{"foo", "bar", "baz"}, 6868 }, 6869 flags: []string{ 6870 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 6871 "-select-alpn", "foo", 6872 }, 6873 expectations: connectionExpectations{ 6874 nextProto: "foo", 6875 nextProtoType: alpn, 6876 }, 6877 resumeSession: true, 6878 }) 6879 6880 var shouldDeclineALPNFail bool 6881 var declineALPNError, declineALPNLocalError string 6882 if protocol == quic { 6883 // ALPN is mandatory in QUIC. 6884 shouldDeclineALPNFail = true 6885 declineALPNError = ":NO_APPLICATION_PROTOCOL:" 6886 declineALPNLocalError = "remote error: no application protocol" 6887 } 6888 testCases = append(testCases, testCase{ 6889 protocol: protocol, 6890 testType: serverTest, 6891 skipQUICALPNConfig: true, 6892 name: "ALPNServer-Decline-" + suffix, 6893 config: Config{ 6894 MaxVersion: ver.version, 6895 NextProtos: []string{"foo", "bar", "baz"}, 6896 }, 6897 flags: []string{"-decline-alpn"}, 6898 expectations: connectionExpectations{ 6899 noNextProto: true, 6900 }, 6901 resumeSession: true, 6902 shouldFail: shouldDeclineALPNFail, 6903 expectedError: declineALPNError, 6904 expectedLocalError: declineALPNLocalError, 6905 }) 6906 6907 testCases = append(testCases, testCase{ 6908 protocol: protocol, 6909 testType: serverTest, 6910 skipQUICALPNConfig: true, 6911 name: "ALPNServer-Reject-" + suffix, 6912 config: Config{ 6913 MaxVersion: ver.version, 6914 NextProtos: []string{"foo", "bar", "baz"}, 6915 }, 6916 flags: []string{"-reject-alpn"}, 6917 shouldFail: true, 6918 expectedError: ":NO_APPLICATION_PROTOCOL:", 6919 expectedLocalError: "remote error: no application protocol", 6920 }) 6921 6922 // Test that the server implementation catches itself if the 6923 // callback tries to return an invalid empty ALPN protocol. 6924 testCases = append(testCases, testCase{ 6925 protocol: protocol, 6926 testType: serverTest, 6927 skipQUICALPNConfig: true, 6928 name: "ALPNServer-SelectEmpty-" + suffix, 6929 config: Config{ 6930 MaxVersion: ver.version, 6931 NextProtos: []string{"foo", "bar", "baz"}, 6932 }, 6933 flags: []string{ 6934 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 6935 "-select-empty-alpn", 6936 }, 6937 shouldFail: true, 6938 expectedLocalError: "remote error: internal error", 6939 expectedError: ":INVALID_ALPN_PROTOCOL:", 6940 }) 6941 6942 // Test ALPN in async mode as well to ensure that extensions callbacks are only 6943 // called once. 6944 testCases = append(testCases, testCase{ 6945 protocol: protocol, 6946 testType: serverTest, 6947 skipQUICALPNConfig: true, 6948 name: "ALPNServer-Async-" + suffix, 6949 config: Config{ 6950 MaxVersion: ver.version, 6951 NextProtos: []string{"foo", "bar", "baz"}, 6952 // Prior to TLS 1.3, exercise the asynchronous session callback. 6953 SessionTicketsDisabled: ver.version < VersionTLS13, 6954 }, 6955 flags: []string{ 6956 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 6957 "-select-alpn", "foo", 6958 "-async", 6959 }, 6960 expectations: connectionExpectations{ 6961 nextProto: "foo", 6962 nextProtoType: alpn, 6963 }, 6964 resumeSession: true, 6965 }) 6966 6967 var emptyString string 6968 testCases = append(testCases, testCase{ 6969 protocol: protocol, 6970 testType: clientTest, 6971 skipQUICALPNConfig: true, 6972 name: "ALPNClient-EmptyProtocolName-" + suffix, 6973 config: Config{ 6974 MaxVersion: ver.version, 6975 NextProtos: []string{""}, 6976 Bugs: ProtocolBugs{ 6977 // A server returning an empty ALPN protocol 6978 // should be rejected. 6979 ALPNProtocol: &emptyString, 6980 }, 6981 }, 6982 flags: []string{ 6983 "-advertise-alpn", "\x03foo", 6984 }, 6985 shouldFail: true, 6986 expectedError: ":PARSE_TLSEXT:", 6987 }) 6988 testCases = append(testCases, testCase{ 6989 protocol: protocol, 6990 testType: serverTest, 6991 skipQUICALPNConfig: true, 6992 name: "ALPNServer-EmptyProtocolName-" + suffix, 6993 config: Config{ 6994 MaxVersion: ver.version, 6995 // A ClientHello containing an empty ALPN protocol 6996 // should be rejected. 6997 NextProtos: []string{"foo", "", "baz"}, 6998 }, 6999 flags: []string{ 7000 "-select-alpn", "foo", 7001 }, 7002 shouldFail: true, 7003 expectedError: ":PARSE_TLSEXT:", 7004 }) 7005 7006 // Test NPN and the interaction with ALPN. 7007 if ver.version < VersionTLS13 && protocol == tls { 7008 // Test that the server prefers ALPN over NPN. 7009 testCases = append(testCases, testCase{ 7010 protocol: protocol, 7011 testType: serverTest, 7012 name: "ALPNServer-Preferred-" + suffix, 7013 config: Config{ 7014 MaxVersion: ver.version, 7015 NextProtos: []string{"foo", "bar", "baz"}, 7016 }, 7017 flags: []string{ 7018 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7019 "-select-alpn", "foo", 7020 "-advertise-npn", "\x03foo\x03bar\x03baz", 7021 }, 7022 expectations: connectionExpectations{ 7023 nextProto: "foo", 7024 nextProtoType: alpn, 7025 }, 7026 resumeSession: true, 7027 }) 7028 testCases = append(testCases, testCase{ 7029 protocol: protocol, 7030 testType: serverTest, 7031 name: "ALPNServer-Preferred-Swapped-" + suffix, 7032 config: Config{ 7033 MaxVersion: ver.version, 7034 NextProtos: []string{"foo", "bar", "baz"}, 7035 Bugs: ProtocolBugs{ 7036 SwapNPNAndALPN: true, 7037 }, 7038 }, 7039 flags: []string{ 7040 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7041 "-select-alpn", "foo", 7042 "-advertise-npn", "\x03foo\x03bar\x03baz", 7043 }, 7044 expectations: connectionExpectations{ 7045 nextProto: "foo", 7046 nextProtoType: alpn, 7047 }, 7048 resumeSession: true, 7049 }) 7050 7051 // Test that negotiating both NPN and ALPN is forbidden. 7052 testCases = append(testCases, testCase{ 7053 protocol: protocol, 7054 name: "NegotiateALPNAndNPN-" + suffix, 7055 config: Config{ 7056 MaxVersion: ver.version, 7057 NextProtos: []string{"foo", "bar", "baz"}, 7058 Bugs: ProtocolBugs{ 7059 NegotiateALPNAndNPN: true, 7060 }, 7061 }, 7062 flags: []string{ 7063 "-advertise-alpn", "\x03foo", 7064 "-select-next-proto", "foo", 7065 }, 7066 shouldFail: true, 7067 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:", 7068 }) 7069 testCases = append(testCases, testCase{ 7070 protocol: protocol, 7071 name: "NegotiateALPNAndNPN-Swapped-" + suffix, 7072 config: Config{ 7073 MaxVersion: ver.version, 7074 NextProtos: []string{"foo", "bar", "baz"}, 7075 Bugs: ProtocolBugs{ 7076 NegotiateALPNAndNPN: true, 7077 SwapNPNAndALPN: true, 7078 }, 7079 }, 7080 flags: []string{ 7081 "-advertise-alpn", "\x03foo", 7082 "-select-next-proto", "foo", 7083 }, 7084 shouldFail: true, 7085 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:", 7086 }) 7087 } 7088 7089 // Test missing ALPN in QUIC 7090 if protocol == quic { 7091 testCases = append(testCases, testCase{ 7092 testType: clientTest, 7093 protocol: protocol, 7094 name: "Client-ALPNMissingFromConfig-" + suffix, 7095 config: Config{ 7096 MinVersion: ver.version, 7097 MaxVersion: ver.version, 7098 }, 7099 skipQUICALPNConfig: true, 7100 shouldFail: true, 7101 expectedError: ":NO_APPLICATION_PROTOCOL:", 7102 }) 7103 testCases = append(testCases, testCase{ 7104 testType: clientTest, 7105 protocol: protocol, 7106 name: "Client-ALPNMissing-" + suffix, 7107 config: Config{ 7108 MinVersion: ver.version, 7109 MaxVersion: ver.version, 7110 }, 7111 flags: []string{ 7112 "-advertise-alpn", "\x03foo", 7113 }, 7114 skipQUICALPNConfig: true, 7115 shouldFail: true, 7116 expectedError: ":NO_APPLICATION_PROTOCOL:", 7117 expectedLocalError: "remote error: no application protocol", 7118 }) 7119 testCases = append(testCases, testCase{ 7120 testType: serverTest, 7121 protocol: protocol, 7122 name: "Server-ALPNMissing-" + suffix, 7123 config: Config{ 7124 MinVersion: ver.version, 7125 MaxVersion: ver.version, 7126 }, 7127 skipQUICALPNConfig: true, 7128 shouldFail: true, 7129 expectedError: ":NO_APPLICATION_PROTOCOL:", 7130 expectedLocalError: "remote error: no application protocol", 7131 }) 7132 testCases = append(testCases, testCase{ 7133 testType: serverTest, 7134 protocol: protocol, 7135 name: "Server-ALPNMismatch-" + suffix, 7136 config: Config{ 7137 MinVersion: ver.version, 7138 MaxVersion: ver.version, 7139 NextProtos: []string{"foo"}, 7140 }, 7141 flags: []string{ 7142 "-decline-alpn", 7143 }, 7144 skipQUICALPNConfig: true, 7145 shouldFail: true, 7146 expectedError: ":NO_APPLICATION_PROTOCOL:", 7147 expectedLocalError: "remote error: no application protocol", 7148 }) 7149 } 7150 7151 // Test ALPS. 7152 if ver.version >= VersionTLS13 { 7153 // Test that client and server can negotiate ALPS, including 7154 // different values on resumption. 7155 testCases = append(testCases, testCase{ 7156 protocol: protocol, 7157 testType: clientTest, 7158 name: "ALPS-Basic-Client-" + suffix, 7159 skipQUICALPNConfig: true, 7160 config: Config{ 7161 MaxVersion: ver.version, 7162 NextProtos: []string{"proto"}, 7163 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7164 }, 7165 resumeConfig: &Config{ 7166 MaxVersion: ver.version, 7167 NextProtos: []string{"proto"}, 7168 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7169 }, 7170 resumeSession: true, 7171 expectations: connectionExpectations{ 7172 peerApplicationSettings: []byte("shim1"), 7173 }, 7174 resumeExpectations: &connectionExpectations{ 7175 peerApplicationSettings: []byte("shim2"), 7176 }, 7177 flags: []string{ 7178 "-advertise-alpn", "\x05proto", 7179 "-expect-alpn", "proto", 7180 "-on-initial-application-settings", "proto,shim1", 7181 "-on-initial-expect-peer-application-settings", "runner1", 7182 "-on-resume-application-settings", "proto,shim2", 7183 "-on-resume-expect-peer-application-settings", "runner2", 7184 }, 7185 }) 7186 testCases = append(testCases, testCase{ 7187 protocol: protocol, 7188 testType: serverTest, 7189 name: "ALPS-Basic-Server-" + suffix, 7190 skipQUICALPNConfig: true, 7191 config: Config{ 7192 MaxVersion: ver.version, 7193 NextProtos: []string{"proto"}, 7194 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7195 }, 7196 resumeConfig: &Config{ 7197 MaxVersion: ver.version, 7198 NextProtos: []string{"proto"}, 7199 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7200 }, 7201 resumeSession: true, 7202 expectations: connectionExpectations{ 7203 peerApplicationSettings: []byte("shim1"), 7204 }, 7205 resumeExpectations: &connectionExpectations{ 7206 peerApplicationSettings: []byte("shim2"), 7207 }, 7208 flags: []string{ 7209 "-select-alpn", "proto", 7210 "-on-initial-application-settings", "proto,shim1", 7211 "-on-initial-expect-peer-application-settings", "runner1", 7212 "-on-resume-application-settings", "proto,shim2", 7213 "-on-resume-expect-peer-application-settings", "runner2", 7214 }, 7215 }) 7216 7217 // Test that the server can defer its ALPS configuration to the ALPN 7218 // selection callback. 7219 testCases = append(testCases, testCase{ 7220 protocol: protocol, 7221 testType: serverTest, 7222 name: "ALPS-Basic-Server-Defer-" + suffix, 7223 skipQUICALPNConfig: true, 7224 config: Config{ 7225 MaxVersion: ver.version, 7226 NextProtos: []string{"proto"}, 7227 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7228 }, 7229 resumeConfig: &Config{ 7230 MaxVersion: ver.version, 7231 NextProtos: []string{"proto"}, 7232 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7233 }, 7234 resumeSession: true, 7235 expectations: connectionExpectations{ 7236 peerApplicationSettings: []byte("shim1"), 7237 }, 7238 resumeExpectations: &connectionExpectations{ 7239 peerApplicationSettings: []byte("shim2"), 7240 }, 7241 flags: []string{ 7242 "-select-alpn", "proto", 7243 "-defer-alps", 7244 "-on-initial-application-settings", "proto,shim1", 7245 "-on-initial-expect-peer-application-settings", "runner1", 7246 "-on-resume-application-settings", "proto,shim2", 7247 "-on-resume-expect-peer-application-settings", "runner2", 7248 }, 7249 }) 7250 7251 // Test the client and server correctly handle empty settings. 7252 testCases = append(testCases, testCase{ 7253 protocol: protocol, 7254 testType: clientTest, 7255 name: "ALPS-Empty-Client-" + suffix, 7256 skipQUICALPNConfig: true, 7257 config: Config{ 7258 MaxVersion: ver.version, 7259 NextProtos: []string{"proto"}, 7260 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7261 }, 7262 resumeSession: true, 7263 expectations: connectionExpectations{ 7264 peerApplicationSettings: []byte{}, 7265 }, 7266 flags: []string{ 7267 "-advertise-alpn", "\x05proto", 7268 "-expect-alpn", "proto", 7269 "-application-settings", "proto,", 7270 "-expect-peer-application-settings", "", 7271 }, 7272 }) 7273 testCases = append(testCases, testCase{ 7274 protocol: protocol, 7275 testType: serverTest, 7276 name: "ALPS-Empty-Server-" + suffix, 7277 skipQUICALPNConfig: true, 7278 config: Config{ 7279 MaxVersion: ver.version, 7280 NextProtos: []string{"proto"}, 7281 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7282 }, 7283 resumeSession: true, 7284 expectations: connectionExpectations{ 7285 peerApplicationSettings: []byte{}, 7286 }, 7287 flags: []string{ 7288 "-select-alpn", "proto", 7289 "-application-settings", "proto,", 7290 "-expect-peer-application-settings", "", 7291 }, 7292 }) 7293 7294 // Test the client rejects application settings from the server on 7295 // protocols it doesn't have them. 7296 testCases = append(testCases, testCase{ 7297 protocol: protocol, 7298 testType: clientTest, 7299 name: "ALPS-UnsupportedProtocol-Client-" + suffix, 7300 skipQUICALPNConfig: true, 7301 config: Config{ 7302 MaxVersion: ver.version, 7303 NextProtos: []string{"proto1"}, 7304 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7305 Bugs: ProtocolBugs{ 7306 AlwaysNegotiateApplicationSettings: true, 7307 }, 7308 }, 7309 // The client supports ALPS with "proto2", but not "proto1". 7310 flags: []string{ 7311 "-advertise-alpn", "\x06proto1\x06proto2", 7312 "-application-settings", "proto2,shim", 7313 "-expect-alpn", "proto1", 7314 }, 7315 // The server sends ALPS with "proto1", which is invalid. 7316 shouldFail: true, 7317 expectedError: ":INVALID_ALPN_PROTOCOL:", 7318 expectedLocalError: "remote error: illegal parameter", 7319 }) 7320 7321 // Test the server declines ALPS if it doesn't support it for the 7322 // specified protocol. 7323 testCases = append(testCases, testCase{ 7324 protocol: protocol, 7325 testType: serverTest, 7326 name: "ALPS-UnsupportedProtocol-Server-" + suffix, 7327 skipQUICALPNConfig: true, 7328 config: Config{ 7329 MaxVersion: ver.version, 7330 NextProtos: []string{"proto1"}, 7331 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7332 }, 7333 // The server supports ALPS with "proto2", but not "proto1". 7334 flags: []string{ 7335 "-select-alpn", "proto1", 7336 "-application-settings", "proto2,shim", 7337 }, 7338 }) 7339 7340 // Test that the server rejects a missing application_settings extension. 7341 testCases = append(testCases, testCase{ 7342 protocol: protocol, 7343 testType: serverTest, 7344 name: "ALPS-OmitClientApplicationSettings-" + suffix, 7345 skipQUICALPNConfig: true, 7346 config: Config{ 7347 MaxVersion: ver.version, 7348 NextProtos: []string{"proto"}, 7349 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7350 Bugs: ProtocolBugs{ 7351 OmitClientApplicationSettings: true, 7352 }, 7353 }, 7354 flags: []string{ 7355 "-select-alpn", "proto", 7356 "-application-settings", "proto,shim", 7357 }, 7358 // The runner is a client, so it only processes the shim's alert 7359 // after checking connection state. 7360 expectations: connectionExpectations{ 7361 peerApplicationSettings: []byte("shim"), 7362 }, 7363 shouldFail: true, 7364 expectedError: ":MISSING_EXTENSION:", 7365 expectedLocalError: "remote error: missing extension", 7366 }) 7367 7368 // Test that the server rejects a missing EncryptedExtensions message. 7369 testCases = append(testCases, testCase{ 7370 protocol: protocol, 7371 testType: serverTest, 7372 name: "ALPS-OmitClientEncryptedExtensions-" + suffix, 7373 skipQUICALPNConfig: true, 7374 config: Config{ 7375 MaxVersion: ver.version, 7376 NextProtos: []string{"proto"}, 7377 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7378 Bugs: ProtocolBugs{ 7379 OmitClientEncryptedExtensions: true, 7380 }, 7381 }, 7382 flags: []string{ 7383 "-select-alpn", "proto", 7384 "-application-settings", "proto,shim", 7385 }, 7386 // The runner is a client, so it only processes the shim's alert 7387 // after checking connection state. 7388 expectations: connectionExpectations{ 7389 peerApplicationSettings: []byte("shim"), 7390 }, 7391 shouldFail: true, 7392 expectedError: ":UNEXPECTED_MESSAGE:", 7393 expectedLocalError: "remote error: unexpected message", 7394 }) 7395 7396 // Test that the server rejects an unexpected EncryptedExtensions message. 7397 testCases = append(testCases, testCase{ 7398 protocol: protocol, 7399 testType: serverTest, 7400 name: "UnexpectedClientEncryptedExtensions-" + suffix, 7401 config: Config{ 7402 MaxVersion: ver.version, 7403 Bugs: ProtocolBugs{ 7404 AlwaysSendClientEncryptedExtensions: true, 7405 }, 7406 }, 7407 shouldFail: true, 7408 expectedError: ":UNEXPECTED_MESSAGE:", 7409 expectedLocalError: "remote error: unexpected message", 7410 }) 7411 7412 // Test that the server rejects an unexpected extension in an 7413 // expected EncryptedExtensions message. 7414 testCases = append(testCases, testCase{ 7415 protocol: protocol, 7416 testType: serverTest, 7417 name: "ExtraClientEncryptedExtension-" + suffix, 7418 skipQUICALPNConfig: true, 7419 config: Config{ 7420 MaxVersion: ver.version, 7421 NextProtos: []string{"proto"}, 7422 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7423 Bugs: ProtocolBugs{ 7424 SendExtraClientEncryptedExtension: true, 7425 }, 7426 }, 7427 flags: []string{ 7428 "-select-alpn", "proto", 7429 "-application-settings", "proto,shim", 7430 }, 7431 // The runner is a client, so it only processes the shim's alert 7432 // after checking connection state. 7433 expectations: connectionExpectations{ 7434 peerApplicationSettings: []byte("shim"), 7435 }, 7436 shouldFail: true, 7437 expectedError: ":UNEXPECTED_EXTENSION:", 7438 expectedLocalError: "remote error: unsupported extension", 7439 }) 7440 7441 // Test that ALPS is carried over on 0-RTT. 7442 for _, empty := range []bool{false, true} { 7443 maybeEmpty := "" 7444 runnerSettings := "runner" 7445 shimSettings := "shim" 7446 if empty { 7447 maybeEmpty = "Empty-" 7448 runnerSettings = "" 7449 shimSettings = "" 7450 } 7451 7452 testCases = append(testCases, testCase{ 7453 protocol: protocol, 7454 testType: clientTest, 7455 name: "ALPS-EarlyData-Client-" + maybeEmpty + suffix, 7456 skipQUICALPNConfig: true, 7457 config: Config{ 7458 MaxVersion: ver.version, 7459 NextProtos: []string{"proto"}, 7460 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7461 }, 7462 resumeSession: true, 7463 earlyData: true, 7464 flags: []string{ 7465 "-advertise-alpn", "\x05proto", 7466 "-expect-alpn", "proto", 7467 "-application-settings", "proto," + shimSettings, 7468 "-expect-peer-application-settings", runnerSettings, 7469 }, 7470 expectations: connectionExpectations{ 7471 peerApplicationSettings: []byte(shimSettings), 7472 }, 7473 }) 7474 testCases = append(testCases, testCase{ 7475 protocol: protocol, 7476 testType: serverTest, 7477 name: "ALPS-EarlyData-Server-" + maybeEmpty + suffix, 7478 skipQUICALPNConfig: true, 7479 config: Config{ 7480 MaxVersion: ver.version, 7481 NextProtos: []string{"proto"}, 7482 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7483 }, 7484 resumeSession: true, 7485 earlyData: true, 7486 flags: []string{ 7487 "-select-alpn", "proto", 7488 "-application-settings", "proto," + shimSettings, 7489 "-expect-peer-application-settings", runnerSettings, 7490 }, 7491 expectations: connectionExpectations{ 7492 peerApplicationSettings: []byte(shimSettings), 7493 }, 7494 }) 7495 7496 // Sending application settings in 0-RTT handshakes is forbidden. 7497 testCases = append(testCases, testCase{ 7498 protocol: protocol, 7499 testType: clientTest, 7500 name: "ALPS-EarlyData-SendApplicationSettingsWithEarlyData-Client-" + maybeEmpty + suffix, 7501 skipQUICALPNConfig: true, 7502 config: Config{ 7503 MaxVersion: ver.version, 7504 NextProtos: []string{"proto"}, 7505 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7506 Bugs: ProtocolBugs{ 7507 SendApplicationSettingsWithEarlyData: true, 7508 }, 7509 }, 7510 resumeSession: true, 7511 earlyData: true, 7512 flags: []string{ 7513 "-advertise-alpn", "\x05proto", 7514 "-expect-alpn", "proto", 7515 "-application-settings", "proto," + shimSettings, 7516 "-expect-peer-application-settings", runnerSettings, 7517 }, 7518 expectations: connectionExpectations{ 7519 peerApplicationSettings: []byte(shimSettings), 7520 }, 7521 shouldFail: true, 7522 expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:", 7523 expectedLocalError: "remote error: illegal parameter", 7524 }) 7525 testCases = append(testCases, testCase{ 7526 protocol: protocol, 7527 testType: serverTest, 7528 name: "ALPS-EarlyData-SendApplicationSettingsWithEarlyData-Server-" + maybeEmpty + suffix, 7529 skipQUICALPNConfig: true, 7530 config: Config{ 7531 MaxVersion: ver.version, 7532 NextProtos: []string{"proto"}, 7533 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7534 Bugs: ProtocolBugs{ 7535 SendApplicationSettingsWithEarlyData: true, 7536 }, 7537 }, 7538 resumeSession: true, 7539 earlyData: true, 7540 flags: []string{ 7541 "-select-alpn", "proto", 7542 "-application-settings", "proto," + shimSettings, 7543 "-expect-peer-application-settings", runnerSettings, 7544 }, 7545 expectations: connectionExpectations{ 7546 peerApplicationSettings: []byte(shimSettings), 7547 }, 7548 shouldFail: true, 7549 expectedError: ":UNEXPECTED_MESSAGE:", 7550 expectedLocalError: "remote error: unexpected message", 7551 }) 7552 } 7553 7554 // Test that the client and server each decline early data if local 7555 // ALPS preferences has changed for the current connection. 7556 alpsMismatchTests := []struct { 7557 name string 7558 initialSettings, resumeSettings []byte 7559 }{ 7560 {"DifferentValues", []byte("settings1"), []byte("settings2")}, 7561 {"OnOff", []byte("settings"), nil}, 7562 {"OffOn", nil, []byte("settings")}, 7563 // The empty settings value should not be mistaken for ALPS not 7564 // being negotiated. 7565 {"OnEmpty", []byte("settings"), []byte{}}, 7566 {"EmptyOn", []byte{}, []byte("settings")}, 7567 {"EmptyOff", []byte{}, nil}, 7568 {"OffEmpty", nil, []byte{}}, 7569 } 7570 for _, test := range alpsMismatchTests { 7571 flags := []string{"-on-resume-expect-early-data-reason", "alps_mismatch"} 7572 if test.initialSettings != nil { 7573 flags = append(flags, "-on-initial-application-settings", "proto,"+string(test.initialSettings)) 7574 flags = append(flags, "-on-initial-expect-peer-application-settings", "runner") 7575 } 7576 if test.resumeSettings != nil { 7577 flags = append(flags, "-on-resume-application-settings", "proto,"+string(test.resumeSettings)) 7578 flags = append(flags, "-on-resume-expect-peer-application-settings", "runner") 7579 } 7580 7581 // The client should not offer early data if the session is 7582 // inconsistent with the new configuration. Note that if 7583 // the session did not negotiate ALPS (test.initialSettings 7584 // is nil), the client always offers early data. 7585 if test.initialSettings != nil { 7586 testCases = append(testCases, testCase{ 7587 protocol: protocol, 7588 testType: clientTest, 7589 name: fmt.Sprintf("ALPS-EarlyData-Mismatch-%s-Client-%s", test.name, suffix), 7590 skipQUICALPNConfig: true, 7591 config: Config{ 7592 MaxVersion: ver.version, 7593 MaxEarlyDataSize: 16384, 7594 NextProtos: []string{"proto"}, 7595 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7596 }, 7597 resumeSession: true, 7598 flags: append([]string{ 7599 "-enable-early-data", 7600 "-expect-ticket-supports-early-data", 7601 "-expect-no-offer-early-data", 7602 "-advertise-alpn", "\x05proto", 7603 "-expect-alpn", "proto", 7604 }, flags...), 7605 expectations: connectionExpectations{ 7606 peerApplicationSettings: test.initialSettings, 7607 }, 7608 resumeExpectations: &connectionExpectations{ 7609 peerApplicationSettings: test.resumeSettings, 7610 }, 7611 }) 7612 } 7613 7614 // The server should reject early data if the session is 7615 // inconsistent with the new selection. 7616 testCases = append(testCases, testCase{ 7617 protocol: protocol, 7618 testType: serverTest, 7619 name: fmt.Sprintf("ALPS-EarlyData-Mismatch-%s-Server-%s", test.name, suffix), 7620 skipQUICALPNConfig: true, 7621 config: Config{ 7622 MaxVersion: ver.version, 7623 NextProtos: []string{"proto"}, 7624 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7625 }, 7626 resumeSession: true, 7627 earlyData: true, 7628 expectEarlyDataRejected: true, 7629 flags: append([]string{ 7630 "-select-alpn", "proto", 7631 }, flags...), 7632 expectations: connectionExpectations{ 7633 peerApplicationSettings: test.initialSettings, 7634 }, 7635 resumeExpectations: &connectionExpectations{ 7636 peerApplicationSettings: test.resumeSettings, 7637 }, 7638 }) 7639 } 7640 7641 // Test that 0-RTT continues working when the shim configures 7642 // ALPS but the peer does not. 7643 testCases = append(testCases, testCase{ 7644 protocol: protocol, 7645 testType: clientTest, 7646 name: "ALPS-EarlyData-Client-ServerDecline-" + suffix, 7647 skipQUICALPNConfig: true, 7648 config: Config{ 7649 MaxVersion: ver.version, 7650 NextProtos: []string{"proto"}, 7651 }, 7652 resumeSession: true, 7653 earlyData: true, 7654 flags: []string{ 7655 "-advertise-alpn", "\x05proto", 7656 "-expect-alpn", "proto", 7657 "-application-settings", "proto,shim", 7658 }, 7659 }) 7660 testCases = append(testCases, testCase{ 7661 protocol: protocol, 7662 testType: serverTest, 7663 name: "ALPS-EarlyData-Server-ClientNoOffer-" + suffix, 7664 skipQUICALPNConfig: true, 7665 config: Config{ 7666 MaxVersion: ver.version, 7667 NextProtos: []string{"proto"}, 7668 }, 7669 resumeSession: true, 7670 earlyData: true, 7671 flags: []string{ 7672 "-select-alpn", "proto", 7673 "-application-settings", "proto,shim", 7674 }, 7675 }) 7676 } else { 7677 // Test the client rejects the ALPS extension if the server 7678 // negotiated TLS 1.2 or below. 7679 testCases = append(testCases, testCase{ 7680 protocol: protocol, 7681 testType: clientTest, 7682 name: "ALPS-Reject-Client-" + suffix, 7683 config: Config{ 7684 MaxVersion: ver.version, 7685 NextProtos: []string{"foo"}, 7686 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 7687 Bugs: ProtocolBugs{ 7688 AlwaysNegotiateApplicationSettings: true, 7689 }, 7690 }, 7691 flags: []string{ 7692 "-advertise-alpn", "\x03foo", 7693 "-expect-alpn", "foo", 7694 "-application-settings", "foo,shim", 7695 }, 7696 shouldFail: true, 7697 expectedError: ":UNEXPECTED_EXTENSION:", 7698 expectedLocalError: "remote error: unsupported extension", 7699 }) 7700 testCases = append(testCases, testCase{ 7701 protocol: protocol, 7702 testType: clientTest, 7703 name: "ALPS-Reject-Client-Resume-" + suffix, 7704 config: Config{ 7705 MaxVersion: ver.version, 7706 }, 7707 resumeConfig: &Config{ 7708 MaxVersion: ver.version, 7709 NextProtos: []string{"foo"}, 7710 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 7711 Bugs: ProtocolBugs{ 7712 AlwaysNegotiateApplicationSettings: true, 7713 }, 7714 }, 7715 resumeSession: true, 7716 flags: []string{ 7717 "-on-resume-advertise-alpn", "\x03foo", 7718 "-on-resume-expect-alpn", "foo", 7719 "-on-resume-application-settings", "foo,shim", 7720 }, 7721 shouldFail: true, 7722 expectedError: ":UNEXPECTED_EXTENSION:", 7723 expectedLocalError: "remote error: unsupported extension", 7724 }) 7725 7726 // Test the server declines ALPS if it negotiates TLS 1.2 or below. 7727 testCases = append(testCases, testCase{ 7728 protocol: protocol, 7729 testType: serverTest, 7730 name: "ALPS-Decline-Server-" + suffix, 7731 config: Config{ 7732 MaxVersion: ver.version, 7733 NextProtos: []string{"foo"}, 7734 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 7735 }, 7736 // Test both TLS 1.2 full and resumption handshakes. 7737 resumeSession: true, 7738 flags: []string{ 7739 "-select-alpn", "foo", 7740 "-application-settings", "foo,shim", 7741 }, 7742 // If not specified, runner and shim both implicitly expect ALPS 7743 // is not negotiated. 7744 }) 7745 } 7746 7747 // Test QUIC transport params 7748 if protocol == quic { 7749 // Client sends params 7750 for _, clientConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 7751 for _, serverSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 7752 useCodepointFlag := "0" 7753 if clientConfig == QUICUseCodepointLegacy { 7754 useCodepointFlag = "1" 7755 } 7756 flags := []string{ 7757 "-quic-transport-params", 7758 base64FlagValue([]byte{1, 2}), 7759 "-quic-use-legacy-codepoint", useCodepointFlag, 7760 } 7761 expectations := connectionExpectations{ 7762 quicTransportParams: []byte{1, 2}, 7763 } 7764 shouldFail := false 7765 expectedError := "" 7766 expectedLocalError := "" 7767 if clientConfig == QUICUseCodepointLegacy { 7768 expectations = connectionExpectations{ 7769 quicTransportParamsLegacy: []byte{1, 2}, 7770 } 7771 } 7772 if serverSends != clientConfig { 7773 expectations = connectionExpectations{} 7774 shouldFail = true 7775 if serverSends == QUICUseCodepointNeither { 7776 expectedError = ":MISSING_EXTENSION:" 7777 } else { 7778 expectedLocalError = "remote error: unsupported extension" 7779 } 7780 } else { 7781 flags = append(flags, 7782 "-expect-quic-transport-params", 7783 base64FlagValue([]byte{3, 4})) 7784 } 7785 testCases = append(testCases, testCase{ 7786 testType: clientTest, 7787 protocol: protocol, 7788 name: fmt.Sprintf("QUICTransportParams-Client-Client%s-Server%s-%s", clientConfig, serverSends, suffix), 7789 config: Config{ 7790 MinVersion: ver.version, 7791 MaxVersion: ver.version, 7792 QUICTransportParams: []byte{3, 4}, 7793 QUICTransportParamsUseLegacyCodepoint: serverSends, 7794 }, 7795 flags: flags, 7796 expectations: expectations, 7797 shouldFail: shouldFail, 7798 expectedError: expectedError, 7799 expectedLocalError: expectedLocalError, 7800 skipTransportParamsConfig: true, 7801 }) 7802 } 7803 } 7804 // Server sends params 7805 for _, clientSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 7806 for _, serverConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 7807 expectations := connectionExpectations{ 7808 quicTransportParams: []byte{3, 4}, 7809 } 7810 shouldFail := false 7811 expectedError := "" 7812 useCodepointFlag := "0" 7813 if serverConfig == QUICUseCodepointLegacy { 7814 useCodepointFlag = "1" 7815 expectations = connectionExpectations{ 7816 quicTransportParamsLegacy: []byte{3, 4}, 7817 } 7818 } 7819 flags := []string{ 7820 "-quic-transport-params", 7821 base64FlagValue([]byte{3, 4}), 7822 "-quic-use-legacy-codepoint", useCodepointFlag, 7823 } 7824 if clientSends != QUICUseCodepointBoth && clientSends != serverConfig { 7825 expectations = connectionExpectations{} 7826 shouldFail = true 7827 expectedError = ":MISSING_EXTENSION:" 7828 } else { 7829 flags = append(flags, 7830 "-expect-quic-transport-params", 7831 base64FlagValue([]byte{1, 2}), 7832 ) 7833 } 7834 testCases = append(testCases, testCase{ 7835 testType: serverTest, 7836 protocol: protocol, 7837 name: fmt.Sprintf("QUICTransportParams-Server-Client%s-Server%s-%s", clientSends, serverConfig, suffix), 7838 config: Config{ 7839 MinVersion: ver.version, 7840 MaxVersion: ver.version, 7841 QUICTransportParams: []byte{1, 2}, 7842 QUICTransportParamsUseLegacyCodepoint: clientSends, 7843 }, 7844 flags: flags, 7845 expectations: expectations, 7846 shouldFail: shouldFail, 7847 expectedError: expectedError, 7848 skipTransportParamsConfig: true, 7849 }) 7850 } 7851 } 7852 } else { 7853 // Ensure non-QUIC client doesn't send QUIC transport parameters. 7854 for _, clientConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 7855 useCodepointFlag := "0" 7856 if clientConfig == QUICUseCodepointLegacy { 7857 useCodepointFlag = "1" 7858 } 7859 testCases = append(testCases, testCase{ 7860 protocol: protocol, 7861 testType: clientTest, 7862 name: fmt.Sprintf("QUICTransportParams-Client-NotSentInNonQUIC-%s-%s", clientConfig, suffix), 7863 config: Config{ 7864 MinVersion: ver.version, 7865 MaxVersion: ver.version, 7866 QUICTransportParamsUseLegacyCodepoint: clientConfig, 7867 }, 7868 flags: []string{ 7869 "-max-version", 7870 strconv.Itoa(int(ver.versionWire)), 7871 "-quic-transport-params", 7872 base64FlagValue([]byte{3, 4}), 7873 "-quic-use-legacy-codepoint", useCodepointFlag, 7874 }, 7875 shouldFail: true, 7876 expectedError: ":QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED:", 7877 skipTransportParamsConfig: true, 7878 }) 7879 } 7880 // Ensure non-QUIC server rejects codepoint 57 but ignores legacy 0xffa5. 7881 for _, clientSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 7882 for _, serverConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 7883 shouldFail := false 7884 expectedLocalError := "" 7885 useCodepointFlag := "0" 7886 if serverConfig == QUICUseCodepointLegacy { 7887 useCodepointFlag = "1" 7888 } 7889 if clientSends == QUICUseCodepointStandard || clientSends == QUICUseCodepointBoth { 7890 shouldFail = true 7891 expectedLocalError = "remote error: unsupported extension" 7892 } 7893 testCases = append(testCases, testCase{ 7894 protocol: protocol, 7895 testType: serverTest, 7896 name: fmt.Sprintf("QUICTransportParams-NonQUICServer-Client%s-Server%s-%s", clientSends, serverConfig, suffix), 7897 config: Config{ 7898 MinVersion: ver.version, 7899 MaxVersion: ver.version, 7900 QUICTransportParams: []byte{1, 2}, 7901 QUICTransportParamsUseLegacyCodepoint: clientSends, 7902 }, 7903 flags: []string{ 7904 "-quic-use-legacy-codepoint", useCodepointFlag, 7905 }, 7906 shouldFail: shouldFail, 7907 expectedLocalError: expectedLocalError, 7908 skipTransportParamsConfig: true, 7909 }) 7910 } 7911 } 7912 7913 } 7914 7915 // Test ticket behavior. 7916 7917 // Resume with a corrupt ticket. 7918 testCases = append(testCases, testCase{ 7919 protocol: protocol, 7920 testType: serverTest, 7921 name: "CorruptTicket-" + suffix, 7922 config: Config{ 7923 MaxVersion: ver.version, 7924 Bugs: ProtocolBugs{ 7925 FilterTicket: func(in []byte) ([]byte, error) { 7926 in[len(in)-1] ^= 1 7927 return in, nil 7928 }, 7929 }, 7930 }, 7931 resumeSession: true, 7932 expectResumeRejected: true, 7933 }) 7934 // Test the ticket callback, with and without renewal. 7935 testCases = append(testCases, testCase{ 7936 protocol: protocol, 7937 testType: serverTest, 7938 name: "TicketCallback-" + suffix, 7939 config: Config{ 7940 MaxVersion: ver.version, 7941 }, 7942 resumeSession: true, 7943 flags: []string{"-use-ticket-callback"}, 7944 }) 7945 testCases = append(testCases, testCase{ 7946 protocol: protocol, 7947 testType: serverTest, 7948 name: "TicketCallback-Renew-" + suffix, 7949 config: Config{ 7950 MaxVersion: ver.version, 7951 Bugs: ProtocolBugs{ 7952 ExpectNewTicket: true, 7953 }, 7954 }, 7955 flags: []string{"-use-ticket-callback", "-renew-ticket"}, 7956 resumeSession: true, 7957 }) 7958 7959 // Test that the ticket callback is only called once when everything before 7960 // it in the ClientHello is asynchronous. This corrupts the ticket so 7961 // certificate selection callbacks run. 7962 testCases = append(testCases, testCase{ 7963 protocol: protocol, 7964 testType: serverTest, 7965 name: "TicketCallback-SingleCall-" + suffix, 7966 config: Config{ 7967 MaxVersion: ver.version, 7968 Bugs: ProtocolBugs{ 7969 FilterTicket: func(in []byte) ([]byte, error) { 7970 in[len(in)-1] ^= 1 7971 return in, nil 7972 }, 7973 }, 7974 }, 7975 resumeSession: true, 7976 expectResumeRejected: true, 7977 flags: []string{ 7978 "-use-ticket-callback", 7979 "-async", 7980 }, 7981 }) 7982 7983 // Resume with various lengths of ticket session id. 7984 if ver.version < VersionTLS13 { 7985 testCases = append(testCases, testCase{ 7986 protocol: protocol, 7987 testType: serverTest, 7988 name: "TicketSessionIDLength-0-" + suffix, 7989 config: Config{ 7990 MaxVersion: ver.version, 7991 Bugs: ProtocolBugs{ 7992 EmptyTicketSessionID: true, 7993 }, 7994 }, 7995 resumeSession: true, 7996 }) 7997 testCases = append(testCases, testCase{ 7998 protocol: protocol, 7999 testType: serverTest, 8000 name: "TicketSessionIDLength-16-" + suffix, 8001 config: Config{ 8002 MaxVersion: ver.version, 8003 Bugs: ProtocolBugs{ 8004 TicketSessionIDLength: 16, 8005 }, 8006 }, 8007 resumeSession: true, 8008 }) 8009 testCases = append(testCases, testCase{ 8010 protocol: protocol, 8011 testType: serverTest, 8012 name: "TicketSessionIDLength-32-" + suffix, 8013 config: Config{ 8014 MaxVersion: ver.version, 8015 Bugs: ProtocolBugs{ 8016 TicketSessionIDLength: 32, 8017 }, 8018 }, 8019 resumeSession: true, 8020 }) 8021 testCases = append(testCases, testCase{ 8022 protocol: protocol, 8023 testType: serverTest, 8024 name: "TicketSessionIDLength-33-" + suffix, 8025 config: Config{ 8026 MaxVersion: ver.version, 8027 Bugs: ProtocolBugs{ 8028 TicketSessionIDLength: 33, 8029 }, 8030 }, 8031 resumeSession: true, 8032 shouldFail: true, 8033 // The maximum session ID length is 32. 8034 expectedError: ":DECODE_ERROR:", 8035 }) 8036 } 8037 8038 // Basic DTLS-SRTP tests. Include fake profiles to ensure they 8039 // are ignored. 8040 if protocol == dtls { 8041 testCases = append(testCases, testCase{ 8042 protocol: protocol, 8043 name: "SRTP-Client-" + suffix, 8044 config: Config{ 8045 MaxVersion: ver.version, 8046 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8047 }, 8048 flags: []string{ 8049 "-srtp-profiles", 8050 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8051 }, 8052 expectations: connectionExpectations{ 8053 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8054 }, 8055 }) 8056 testCases = append(testCases, testCase{ 8057 protocol: protocol, 8058 testType: serverTest, 8059 name: "SRTP-Server-" + suffix, 8060 config: Config{ 8061 MaxVersion: ver.version, 8062 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8063 }, 8064 flags: []string{ 8065 "-srtp-profiles", 8066 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8067 }, 8068 expectations: connectionExpectations{ 8069 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8070 }, 8071 }) 8072 // Test that the MKI is ignored. 8073 testCases = append(testCases, testCase{ 8074 protocol: protocol, 8075 testType: serverTest, 8076 name: "SRTP-Server-IgnoreMKI-" + suffix, 8077 config: Config{ 8078 MaxVersion: ver.version, 8079 SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80}, 8080 Bugs: ProtocolBugs{ 8081 SRTPMasterKeyIdentifer: "bogus", 8082 }, 8083 }, 8084 flags: []string{ 8085 "-srtp-profiles", 8086 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8087 }, 8088 expectations: connectionExpectations{ 8089 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8090 }, 8091 }) 8092 // Test that SRTP isn't negotiated on the server if there were 8093 // no matching profiles. 8094 testCases = append(testCases, testCase{ 8095 protocol: protocol, 8096 testType: serverTest, 8097 name: "SRTP-Server-NoMatch-" + suffix, 8098 config: Config{ 8099 MaxVersion: ver.version, 8100 SRTPProtectionProfiles: []uint16{100, 101, 102}, 8101 }, 8102 flags: []string{ 8103 "-srtp-profiles", 8104 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8105 }, 8106 expectations: connectionExpectations{ 8107 srtpProtectionProfile: 0, 8108 }, 8109 }) 8110 // Test that the server returning an invalid SRTP profile is 8111 // flagged as an error by the client. 8112 testCases = append(testCases, testCase{ 8113 protocol: protocol, 8114 name: "SRTP-Client-NoMatch-" + suffix, 8115 config: Config{ 8116 MaxVersion: ver.version, 8117 Bugs: ProtocolBugs{ 8118 SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32, 8119 }, 8120 }, 8121 flags: []string{ 8122 "-srtp-profiles", 8123 "SRTP_AES128_CM_SHA1_80", 8124 }, 8125 shouldFail: true, 8126 expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:", 8127 }) 8128 } else { 8129 // DTLS-SRTP is not defined for other protocols. Configuring it 8130 // on the client and server should ignore the extension. 8131 testCases = append(testCases, testCase{ 8132 protocol: protocol, 8133 name: "SRTP-Client-Ignore-" + suffix, 8134 config: Config{ 8135 MaxVersion: ver.version, 8136 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8137 }, 8138 flags: []string{ 8139 "-srtp-profiles", 8140 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8141 }, 8142 expectations: connectionExpectations{ 8143 srtpProtectionProfile: 0, 8144 }, 8145 }) 8146 testCases = append(testCases, testCase{ 8147 protocol: protocol, 8148 testType: serverTest, 8149 name: "SRTP-Server-Ignore-" + suffix, 8150 config: Config{ 8151 MaxVersion: ver.version, 8152 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8153 }, 8154 flags: []string{ 8155 "-srtp-profiles", 8156 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8157 }, 8158 expectations: connectionExpectations{ 8159 srtpProtectionProfile: 0, 8160 }, 8161 }) 8162 } 8163 8164 // Test SCT list. 8165 testCases = append(testCases, testCase{ 8166 protocol: protocol, 8167 name: "SignedCertificateTimestampList-Client-" + suffix, 8168 testType: clientTest, 8169 config: Config{ 8170 MaxVersion: ver.version, 8171 }, 8172 flags: []string{ 8173 "-enable-signed-cert-timestamps", 8174 "-expect-signed-cert-timestamps", 8175 base64FlagValue(testSCTList), 8176 }, 8177 resumeSession: true, 8178 }) 8179 8180 var differentSCTList []byte 8181 differentSCTList = append(differentSCTList, testSCTList...) 8182 differentSCTList[len(differentSCTList)-1] ^= 1 8183 8184 // The SCT extension did not specify that it must only be sent on resumption as it 8185 // should have, so test that we tolerate but ignore it. 8186 testCases = append(testCases, testCase{ 8187 protocol: protocol, 8188 name: "SendSCTListOnResume-" + suffix, 8189 config: Config{ 8190 MaxVersion: ver.version, 8191 Bugs: ProtocolBugs{ 8192 SendSCTListOnResume: differentSCTList, 8193 }, 8194 }, 8195 flags: []string{ 8196 "-enable-signed-cert-timestamps", 8197 "-expect-signed-cert-timestamps", 8198 base64FlagValue(testSCTList), 8199 }, 8200 resumeSession: true, 8201 }) 8202 8203 testCases = append(testCases, testCase{ 8204 protocol: protocol, 8205 name: "SignedCertificateTimestampList-Server-" + suffix, 8206 testType: serverTest, 8207 config: Config{ 8208 MaxVersion: ver.version, 8209 }, 8210 flags: []string{ 8211 "-signed-cert-timestamps", 8212 base64FlagValue(testSCTList), 8213 }, 8214 expectations: connectionExpectations{ 8215 sctList: testSCTList, 8216 }, 8217 resumeSession: true, 8218 }) 8219 8220 emptySCTListCert := *testCerts[0].cert 8221 emptySCTListCert.SignedCertificateTimestampList = []byte{0, 0} 8222 8223 // Test empty SCT list. 8224 testCases = append(testCases, testCase{ 8225 protocol: protocol, 8226 name: "SignedCertificateTimestampListEmpty-Client-" + suffix, 8227 testType: clientTest, 8228 config: Config{ 8229 MaxVersion: ver.version, 8230 Certificates: []Certificate{emptySCTListCert}, 8231 }, 8232 flags: []string{ 8233 "-enable-signed-cert-timestamps", 8234 }, 8235 shouldFail: true, 8236 expectedError: ":ERROR_PARSING_EXTENSION:", 8237 }) 8238 8239 emptySCTCert := *testCerts[0].cert 8240 emptySCTCert.SignedCertificateTimestampList = []byte{0, 6, 0, 2, 1, 2, 0, 0} 8241 8242 // Test empty SCT in non-empty list. 8243 testCases = append(testCases, testCase{ 8244 protocol: protocol, 8245 name: "SignedCertificateTimestampListEmptySCT-Client-" + suffix, 8246 testType: clientTest, 8247 config: Config{ 8248 MaxVersion: ver.version, 8249 Certificates: []Certificate{emptySCTCert}, 8250 }, 8251 flags: []string{ 8252 "-enable-signed-cert-timestamps", 8253 }, 8254 shouldFail: true, 8255 expectedError: ":ERROR_PARSING_EXTENSION:", 8256 }) 8257 8258 // Test that certificate-related extensions are not sent unsolicited. 8259 testCases = append(testCases, testCase{ 8260 protocol: protocol, 8261 testType: serverTest, 8262 name: "UnsolicitedCertificateExtensions-" + suffix, 8263 config: Config{ 8264 MaxVersion: ver.version, 8265 Bugs: ProtocolBugs{ 8266 NoOCSPStapling: true, 8267 NoSignedCertificateTimestamps: true, 8268 }, 8269 }, 8270 flags: []string{ 8271 "-ocsp-response", 8272 base64FlagValue(testOCSPResponse), 8273 "-signed-cert-timestamps", 8274 base64FlagValue(testSCTList), 8275 }, 8276 }) 8277 8278 // Extension permutation should interact correctly with other extensions, 8279 // HelloVerifyRequest, HelloRetryRequest, and ECH. SSLTest.PermuteExtensions 8280 // in ssl_test.cc tests that the extensions are actually permuted. This 8281 // tests the handshake still works. 8282 // 8283 // This test also tests that all our extensions interact with each other. 8284 for _, ech := range []bool{false, true} { 8285 if ech && ver.version < VersionTLS13 { 8286 continue 8287 } 8288 8289 test := testCase{ 8290 protocol: protocol, 8291 name: "AllExtensions-Client-Permute", 8292 skipQUICALPNConfig: true, 8293 config: Config{ 8294 MinVersion: ver.version, 8295 MaxVersion: ver.version, 8296 NextProtos: []string{"proto"}, 8297 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 8298 Bugs: ProtocolBugs{ 8299 SendServerNameAck: true, 8300 ExpectServerName: "example.com", 8301 ExpectGREASE: true, 8302 }, 8303 }, 8304 resumeSession: true, 8305 flags: []string{ 8306 "-permute-extensions", 8307 "-enable-grease", 8308 "-enable-ocsp-stapling", 8309 "-enable-signed-cert-timestamps", 8310 "-advertise-alpn", "\x05proto", 8311 "-expect-alpn", "proto", 8312 "-host-name", "example.com", 8313 }, 8314 } 8315 8316 if ech { 8317 test.name += "-ECH" 8318 echConfig := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 8319 test.config.ServerECHConfigs = []ServerECHConfig{echConfig} 8320 test.flags = append(test.flags, 8321 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 8322 "-expect-ech-accept", 8323 ) 8324 test.expectations.echAccepted = true 8325 } 8326 8327 if ver.version >= VersionTLS13 { 8328 // Trigger a HelloRetryRequest to test both ClientHellos. Note 8329 // our DTLS tests always enable HelloVerifyRequest. 8330 test.name += "-HelloRetryRequest" 8331 8332 // ALPS is only available on TLS 1.3. 8333 test.config.ApplicationSettings = map[string][]byte{"proto": []byte("runner")} 8334 test.flags = append(test.flags, 8335 "-application-settings", "proto,shim", 8336 "-expect-peer-application-settings", "runner") 8337 test.expectations.peerApplicationSettings = []byte("shim") 8338 } 8339 8340 if protocol == dtls { 8341 test.config.SRTPProtectionProfiles = []uint16{SRTP_AES128_CM_HMAC_SHA1_80} 8342 test.flags = append(test.flags, "-srtp-profiles", "SRTP_AES128_CM_SHA1_80") 8343 test.expectations.srtpProtectionProfile = SRTP_AES128_CM_HMAC_SHA1_80 8344 } 8345 8346 test.name += "-" + suffix 8347 testCases = append(testCases, test) 8348 } 8349 } 8350 } 8351 8352 testCases = append(testCases, testCase{ 8353 testType: clientTest, 8354 name: "ClientHelloPadding", 8355 config: Config{ 8356 Bugs: ProtocolBugs{ 8357 RequireClientHelloSize: 512, 8358 }, 8359 }, 8360 // This hostname just needs to be long enough to push the 8361 // ClientHello into F5's danger zone between 256 and 511 bytes 8362 // long. 8363 flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"}, 8364 }) 8365 8366 // Test that illegal extensions in TLS 1.3 are rejected by the client if 8367 // in ServerHello. 8368 testCases = append(testCases, testCase{ 8369 name: "NPN-Forbidden-TLS13", 8370 config: Config{ 8371 MaxVersion: VersionTLS13, 8372 NextProtos: []string{"foo"}, 8373 Bugs: ProtocolBugs{ 8374 NegotiateNPNAtAllVersions: true, 8375 }, 8376 }, 8377 flags: []string{"-select-next-proto", "foo"}, 8378 shouldFail: true, 8379 expectedError: ":ERROR_PARSING_EXTENSION:", 8380 }) 8381 testCases = append(testCases, testCase{ 8382 name: "EMS-Forbidden-TLS13", 8383 config: Config{ 8384 MaxVersion: VersionTLS13, 8385 Bugs: ProtocolBugs{ 8386 NegotiateEMSAtAllVersions: true, 8387 }, 8388 }, 8389 shouldFail: true, 8390 expectedError: ":ERROR_PARSING_EXTENSION:", 8391 }) 8392 testCases = append(testCases, testCase{ 8393 name: "RenegotiationInfo-Forbidden-TLS13", 8394 config: Config{ 8395 MaxVersion: VersionTLS13, 8396 Bugs: ProtocolBugs{ 8397 NegotiateRenegotiationInfoAtAllVersions: true, 8398 }, 8399 }, 8400 shouldFail: true, 8401 expectedError: ":ERROR_PARSING_EXTENSION:", 8402 }) 8403 testCases = append(testCases, testCase{ 8404 name: "Ticket-Forbidden-TLS13", 8405 config: Config{ 8406 MaxVersion: VersionTLS12, 8407 }, 8408 resumeConfig: &Config{ 8409 MaxVersion: VersionTLS13, 8410 Bugs: ProtocolBugs{ 8411 AdvertiseTicketExtension: true, 8412 }, 8413 }, 8414 resumeSession: true, 8415 shouldFail: true, 8416 expectedError: ":ERROR_PARSING_EXTENSION:", 8417 }) 8418 8419 // Test that illegal extensions in TLS 1.3 are declined by the server if 8420 // offered in ClientHello. The runner's server will fail if this occurs, 8421 // so we exercise the offering path. (EMS and Renegotiation Info are 8422 // implicit in every test.) 8423 testCases = append(testCases, testCase{ 8424 testType: serverTest, 8425 name: "NPN-Declined-TLS13", 8426 config: Config{ 8427 MaxVersion: VersionTLS13, 8428 NextProtos: []string{"bar"}, 8429 }, 8430 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"}, 8431 }) 8432 8433 // OpenSSL sends the status_request extension on resumption in TLS 1.2. Test that this is 8434 // tolerated. 8435 testCases = append(testCases, testCase{ 8436 name: "SendOCSPResponseOnResume-TLS12", 8437 config: Config{ 8438 MaxVersion: VersionTLS12, 8439 Bugs: ProtocolBugs{ 8440 SendOCSPResponseOnResume: []byte("bogus"), 8441 }, 8442 }, 8443 flags: []string{ 8444 "-enable-ocsp-stapling", 8445 "-expect-ocsp-response", 8446 base64FlagValue(testOCSPResponse), 8447 }, 8448 resumeSession: true, 8449 }) 8450 8451 testCases = append(testCases, testCase{ 8452 name: "SendUnsolicitedOCSPOnCertificate-TLS13", 8453 config: Config{ 8454 MaxVersion: VersionTLS13, 8455 Bugs: ProtocolBugs{ 8456 SendExtensionOnCertificate: testOCSPExtension, 8457 }, 8458 }, 8459 shouldFail: true, 8460 expectedError: ":UNEXPECTED_EXTENSION:", 8461 }) 8462 8463 testCases = append(testCases, testCase{ 8464 name: "SendUnsolicitedSCTOnCertificate-TLS13", 8465 config: Config{ 8466 MaxVersion: VersionTLS13, 8467 Bugs: ProtocolBugs{ 8468 SendExtensionOnCertificate: testSCTExtension, 8469 }, 8470 }, 8471 shouldFail: true, 8472 expectedError: ":UNEXPECTED_EXTENSION:", 8473 }) 8474 8475 // Test that extensions on client certificates are never accepted. 8476 testCases = append(testCases, testCase{ 8477 name: "SendExtensionOnClientCertificate-TLS13", 8478 testType: serverTest, 8479 config: Config{ 8480 MaxVersion: VersionTLS13, 8481 Certificates: []Certificate{rsaCertificate}, 8482 Bugs: ProtocolBugs{ 8483 SendExtensionOnCertificate: testOCSPExtension, 8484 }, 8485 }, 8486 flags: []string{ 8487 "-enable-ocsp-stapling", 8488 "-require-any-client-certificate", 8489 }, 8490 shouldFail: true, 8491 expectedError: ":UNEXPECTED_EXTENSION:", 8492 }) 8493 8494 testCases = append(testCases, testCase{ 8495 name: "SendUnknownExtensionOnCertificate-TLS13", 8496 config: Config{ 8497 MaxVersion: VersionTLS13, 8498 Bugs: ProtocolBugs{ 8499 SendExtensionOnCertificate: []byte{0x00, 0x7f, 0, 0}, 8500 }, 8501 }, 8502 shouldFail: true, 8503 expectedError: ":UNEXPECTED_EXTENSION:", 8504 }) 8505 8506 // Test that extensions on intermediates are allowed but ignored. 8507 testCases = append(testCases, testCase{ 8508 name: "IgnoreExtensionsOnIntermediates-TLS13", 8509 config: Config{ 8510 MaxVersion: VersionTLS13, 8511 Certificates: []Certificate{rsaChainCertificate}, 8512 Bugs: ProtocolBugs{ 8513 // Send different values on the intermediate. This tests 8514 // the intermediate's extensions do not override the 8515 // leaf's. 8516 SendOCSPOnIntermediates: testOCSPResponse2, 8517 SendSCTOnIntermediates: testSCTList2, 8518 }, 8519 }, 8520 flags: []string{ 8521 "-enable-ocsp-stapling", 8522 "-expect-ocsp-response", 8523 base64FlagValue(testOCSPResponse), 8524 "-enable-signed-cert-timestamps", 8525 "-expect-signed-cert-timestamps", 8526 base64FlagValue(testSCTList), 8527 }, 8528 resumeSession: true, 8529 }) 8530 8531 // Test that extensions are not sent on intermediates when configured 8532 // only for a leaf. 8533 testCases = append(testCases, testCase{ 8534 testType: serverTest, 8535 name: "SendNoExtensionsOnIntermediate-TLS13", 8536 config: Config{ 8537 MaxVersion: VersionTLS13, 8538 Bugs: ProtocolBugs{ 8539 ExpectNoExtensionsOnIntermediate: true, 8540 }, 8541 }, 8542 flags: []string{ 8543 "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 8544 "-key-file", path.Join(*resourceDir, rsaChainKeyFile), 8545 "-ocsp-response", 8546 base64FlagValue(testOCSPResponse), 8547 "-signed-cert-timestamps", 8548 base64FlagValue(testSCTList), 8549 }, 8550 }) 8551 8552 // Test that extensions are not sent on client certificates. 8553 testCases = append(testCases, testCase{ 8554 name: "SendNoClientCertificateExtensions-TLS13", 8555 config: Config{ 8556 MaxVersion: VersionTLS13, 8557 ClientAuth: RequireAnyClientCert, 8558 }, 8559 flags: []string{ 8560 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 8561 "-key-file", path.Join(*resourceDir, rsaKeyFile), 8562 "-ocsp-response", 8563 base64FlagValue(testOCSPResponse), 8564 "-signed-cert-timestamps", 8565 base64FlagValue(testSCTList), 8566 }, 8567 }) 8568 8569 testCases = append(testCases, testCase{ 8570 name: "SendDuplicateExtensionsOnCerts-TLS13", 8571 config: Config{ 8572 MaxVersion: VersionTLS13, 8573 Bugs: ProtocolBugs{ 8574 SendDuplicateCertExtensions: true, 8575 }, 8576 }, 8577 flags: []string{ 8578 "-enable-ocsp-stapling", 8579 "-enable-signed-cert-timestamps", 8580 }, 8581 resumeSession: true, 8582 shouldFail: true, 8583 expectedError: ":DUPLICATE_EXTENSION:", 8584 }) 8585 8586 testCases = append(testCases, testCase{ 8587 name: "SignedCertificateTimestampListInvalid-Server", 8588 testType: serverTest, 8589 flags: []string{ 8590 "-signed-cert-timestamps", 8591 base64FlagValue([]byte{0, 0}), 8592 }, 8593 shouldFail: true, 8594 expectedError: ":INVALID_SCT_LIST:", 8595 }) 8596} 8597 8598func addResumptionVersionTests() { 8599 for _, sessionVers := range tlsVersions { 8600 for _, resumeVers := range tlsVersions { 8601 protocols := []protocol{tls} 8602 if sessionVers.hasDTLS && resumeVers.hasDTLS { 8603 protocols = append(protocols, dtls) 8604 } 8605 if sessionVers.hasQUIC && resumeVers.hasQUIC { 8606 protocols = append(protocols, quic) 8607 } 8608 for _, protocol := range protocols { 8609 suffix := "-" + sessionVers.name + "-" + resumeVers.name 8610 suffix += "-" + protocol.String() 8611 8612 if sessionVers.version == resumeVers.version { 8613 testCases = append(testCases, testCase{ 8614 protocol: protocol, 8615 name: "Resume-Client" + suffix, 8616 resumeSession: true, 8617 config: Config{ 8618 MaxVersion: sessionVers.version, 8619 Bugs: ProtocolBugs{ 8620 ExpectNoTLS13PSK: sessionVers.version < VersionTLS13, 8621 }, 8622 }, 8623 expectations: connectionExpectations{ 8624 version: sessionVers.version, 8625 }, 8626 resumeExpectations: &connectionExpectations{ 8627 version: resumeVers.version, 8628 }, 8629 }) 8630 } else { 8631 testCases = append(testCases, testCase{ 8632 protocol: protocol, 8633 name: "Resume-Client-Mismatch" + suffix, 8634 resumeSession: true, 8635 config: Config{ 8636 MaxVersion: sessionVers.version, 8637 }, 8638 expectations: connectionExpectations{ 8639 version: sessionVers.version, 8640 }, 8641 resumeConfig: &Config{ 8642 MaxVersion: resumeVers.version, 8643 Bugs: ProtocolBugs{ 8644 AcceptAnySession: true, 8645 }, 8646 }, 8647 resumeExpectations: &connectionExpectations{ 8648 version: resumeVers.version, 8649 }, 8650 shouldFail: true, 8651 expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:", 8652 }) 8653 } 8654 8655 testCases = append(testCases, testCase{ 8656 protocol: protocol, 8657 name: "Resume-Client-NoResume" + suffix, 8658 resumeSession: true, 8659 config: Config{ 8660 MaxVersion: sessionVers.version, 8661 }, 8662 expectations: connectionExpectations{ 8663 version: sessionVers.version, 8664 }, 8665 resumeConfig: &Config{ 8666 MaxVersion: resumeVers.version, 8667 }, 8668 newSessionsOnResume: true, 8669 expectResumeRejected: true, 8670 resumeExpectations: &connectionExpectations{ 8671 version: resumeVers.version, 8672 }, 8673 }) 8674 8675 testCases = append(testCases, testCase{ 8676 protocol: protocol, 8677 testType: serverTest, 8678 name: "Resume-Server" + suffix, 8679 resumeSession: true, 8680 config: Config{ 8681 MaxVersion: sessionVers.version, 8682 }, 8683 expectations: connectionExpectations{ 8684 version: sessionVers.version, 8685 }, 8686 expectResumeRejected: sessionVers != resumeVers, 8687 resumeConfig: &Config{ 8688 MaxVersion: resumeVers.version, 8689 Bugs: ProtocolBugs{ 8690 SendBothTickets: true, 8691 }, 8692 }, 8693 resumeExpectations: &connectionExpectations{ 8694 version: resumeVers.version, 8695 }, 8696 }) 8697 8698 // Repeat the test using session IDs, rather than tickets. 8699 if sessionVers.version < VersionTLS13 && resumeVers.version < VersionTLS13 { 8700 testCases = append(testCases, testCase{ 8701 protocol: protocol, 8702 testType: serverTest, 8703 name: "Resume-Server-NoTickets" + suffix, 8704 resumeSession: true, 8705 config: Config{ 8706 MaxVersion: sessionVers.version, 8707 SessionTicketsDisabled: true, 8708 }, 8709 expectations: connectionExpectations{ 8710 version: sessionVers.version, 8711 }, 8712 expectResumeRejected: sessionVers != resumeVers, 8713 resumeConfig: &Config{ 8714 MaxVersion: resumeVers.version, 8715 SessionTicketsDisabled: true, 8716 }, 8717 resumeExpectations: &connectionExpectations{ 8718 version: resumeVers.version, 8719 }, 8720 }) 8721 } 8722 } 8723 } 8724 } 8725 8726 // Make sure shim ticket mutations are functional. 8727 testCases = append(testCases, testCase{ 8728 testType: serverTest, 8729 name: "ShimTicketRewritable", 8730 resumeSession: true, 8731 config: Config{ 8732 MaxVersion: VersionTLS12, 8733 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 8734 Bugs: ProtocolBugs{ 8735 FilterTicket: func(in []byte) ([]byte, error) { 8736 in, err := SetShimTicketVersion(in, VersionTLS12) 8737 if err != nil { 8738 return nil, err 8739 } 8740 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) 8741 }, 8742 }, 8743 }, 8744 flags: []string{ 8745 "-ticket-key", 8746 base64FlagValue(TestShimTicketKey), 8747 }, 8748 }) 8749 8750 // Resumptions are declined if the version does not match. 8751 testCases = append(testCases, testCase{ 8752 testType: serverTest, 8753 name: "Resume-Server-DeclineCrossVersion", 8754 resumeSession: true, 8755 config: Config{ 8756 MaxVersion: VersionTLS12, 8757 Bugs: ProtocolBugs{ 8758 ExpectNewTicket: true, 8759 FilterTicket: func(in []byte) ([]byte, error) { 8760 return SetShimTicketVersion(in, VersionTLS13) 8761 }, 8762 }, 8763 }, 8764 flags: []string{ 8765 "-ticket-key", 8766 base64FlagValue(TestShimTicketKey), 8767 }, 8768 expectResumeRejected: true, 8769 }) 8770 8771 testCases = append(testCases, testCase{ 8772 testType: serverTest, 8773 name: "Resume-Server-DeclineCrossVersion-TLS13", 8774 resumeSession: true, 8775 config: Config{ 8776 MaxVersion: VersionTLS13, 8777 Bugs: ProtocolBugs{ 8778 FilterTicket: func(in []byte) ([]byte, error) { 8779 return SetShimTicketVersion(in, VersionTLS12) 8780 }, 8781 }, 8782 }, 8783 flags: []string{ 8784 "-ticket-key", 8785 base64FlagValue(TestShimTicketKey), 8786 }, 8787 expectResumeRejected: true, 8788 }) 8789 8790 // Resumptions are declined if the cipher is invalid or disabled. 8791 testCases = append(testCases, testCase{ 8792 testType: serverTest, 8793 name: "Resume-Server-DeclineBadCipher", 8794 resumeSession: true, 8795 config: Config{ 8796 MaxVersion: VersionTLS12, 8797 Bugs: ProtocolBugs{ 8798 ExpectNewTicket: true, 8799 FilterTicket: func(in []byte) ([]byte, error) { 8800 return SetShimTicketCipherSuite(in, TLS_AES_128_GCM_SHA256) 8801 }, 8802 }, 8803 }, 8804 flags: []string{ 8805 "-ticket-key", 8806 base64FlagValue(TestShimTicketKey), 8807 }, 8808 expectResumeRejected: true, 8809 }) 8810 8811 testCases = append(testCases, testCase{ 8812 testType: serverTest, 8813 name: "Resume-Server-DeclineBadCipher-2", 8814 resumeSession: true, 8815 config: Config{ 8816 MaxVersion: VersionTLS12, 8817 Bugs: ProtocolBugs{ 8818 ExpectNewTicket: true, 8819 FilterTicket: func(in []byte) ([]byte, error) { 8820 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) 8821 }, 8822 }, 8823 }, 8824 flags: []string{ 8825 "-cipher", "AES128", 8826 "-ticket-key", 8827 base64FlagValue(TestShimTicketKey), 8828 }, 8829 expectResumeRejected: true, 8830 }) 8831 8832 // Sessions are not resumed if they do not use the preferred cipher. 8833 testCases = append(testCases, testCase{ 8834 testType: serverTest, 8835 name: "Resume-Server-CipherNotPreferred", 8836 resumeSession: true, 8837 config: Config{ 8838 MaxVersion: VersionTLS12, 8839 Bugs: ProtocolBugs{ 8840 ExpectNewTicket: true, 8841 FilterTicket: func(in []byte) ([]byte, error) { 8842 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) 8843 }, 8844 }, 8845 }, 8846 flags: []string{ 8847 "-ticket-key", 8848 base64FlagValue(TestShimTicketKey), 8849 }, 8850 shouldFail: false, 8851 expectResumeRejected: true, 8852 }) 8853 8854 // TLS 1.3 allows sessions to be resumed at a different cipher if their 8855 // PRF hashes match, but BoringSSL will always decline such resumptions. 8856 testCases = append(testCases, testCase{ 8857 testType: serverTest, 8858 name: "Resume-Server-CipherNotPreferred-TLS13", 8859 resumeSession: true, 8860 config: Config{ 8861 MaxVersion: VersionTLS13, 8862 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_GCM_SHA256}, 8863 Bugs: ProtocolBugs{ 8864 FilterTicket: func(in []byte) ([]byte, error) { 8865 // If the client (runner) offers ChaCha20-Poly1305 first, the 8866 // server (shim) always prefers it. Switch it to AES-GCM. 8867 return SetShimTicketCipherSuite(in, TLS_AES_128_GCM_SHA256) 8868 }, 8869 }, 8870 }, 8871 flags: []string{ 8872 "-ticket-key", 8873 base64FlagValue(TestShimTicketKey), 8874 }, 8875 shouldFail: false, 8876 expectResumeRejected: true, 8877 }) 8878 8879 // Sessions may not be resumed if they contain another version's cipher. 8880 testCases = append(testCases, testCase{ 8881 testType: serverTest, 8882 name: "Resume-Server-DeclineBadCipher-TLS13", 8883 resumeSession: true, 8884 config: Config{ 8885 MaxVersion: VersionTLS13, 8886 Bugs: ProtocolBugs{ 8887 FilterTicket: func(in []byte) ([]byte, error) { 8888 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) 8889 }, 8890 }, 8891 }, 8892 flags: []string{ 8893 "-ticket-key", 8894 base64FlagValue(TestShimTicketKey), 8895 }, 8896 expectResumeRejected: true, 8897 }) 8898 8899 // If the client does not offer the cipher from the session, decline to 8900 // resume. Clients are forbidden from doing this, but BoringSSL selects 8901 // the cipher first, so we only decline. 8902 testCases = append(testCases, testCase{ 8903 testType: serverTest, 8904 name: "Resume-Server-UnofferedCipher", 8905 resumeSession: true, 8906 config: Config{ 8907 MaxVersion: VersionTLS12, 8908 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 8909 }, 8910 resumeConfig: &Config{ 8911 MaxVersion: VersionTLS12, 8912 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 8913 Bugs: ProtocolBugs{ 8914 SendCipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 8915 }, 8916 }, 8917 expectResumeRejected: true, 8918 }) 8919 8920 // In TLS 1.3, clients may advertise a cipher list which does not 8921 // include the selected cipher. Test that we tolerate this. Servers may 8922 // resume at another cipher if the PRF matches and are not doing 0-RTT, but 8923 // BoringSSL will always decline. 8924 testCases = append(testCases, testCase{ 8925 testType: serverTest, 8926 name: "Resume-Server-UnofferedCipher-TLS13", 8927 resumeSession: true, 8928 config: Config{ 8929 MaxVersion: VersionTLS13, 8930 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 8931 }, 8932 resumeConfig: &Config{ 8933 MaxVersion: VersionTLS13, 8934 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 8935 Bugs: ProtocolBugs{ 8936 SendCipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 8937 }, 8938 }, 8939 expectResumeRejected: true, 8940 }) 8941 8942 // Sessions may not be resumed at a different cipher. 8943 testCases = append(testCases, testCase{ 8944 name: "Resume-Client-CipherMismatch", 8945 resumeSession: true, 8946 config: Config{ 8947 MaxVersion: VersionTLS12, 8948 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 8949 }, 8950 resumeConfig: &Config{ 8951 MaxVersion: VersionTLS12, 8952 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 8953 Bugs: ProtocolBugs{ 8954 SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA, 8955 }, 8956 }, 8957 shouldFail: true, 8958 expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:", 8959 }) 8960 8961 // Session resumption in TLS 1.3 may change the cipher suite if the PRF 8962 // matches. 8963 testCases = append(testCases, testCase{ 8964 name: "Resume-Client-CipherMismatch-TLS13", 8965 resumeSession: true, 8966 config: Config{ 8967 MaxVersion: VersionTLS13, 8968 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 8969 }, 8970 resumeConfig: &Config{ 8971 MaxVersion: VersionTLS13, 8972 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 8973 }, 8974 }) 8975 8976 // Session resumption in TLS 1.3 is forbidden if the PRF does not match. 8977 testCases = append(testCases, testCase{ 8978 name: "Resume-Client-PRFMismatch-TLS13", 8979 resumeSession: true, 8980 config: Config{ 8981 MaxVersion: VersionTLS13, 8982 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 8983 }, 8984 resumeConfig: &Config{ 8985 MaxVersion: VersionTLS13, 8986 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 8987 Bugs: ProtocolBugs{ 8988 SendCipherSuite: TLS_AES_256_GCM_SHA384, 8989 }, 8990 }, 8991 shouldFail: true, 8992 expectedError: ":OLD_SESSION_PRF_HASH_MISMATCH:", 8993 }) 8994 8995 for _, secondBinder := range []bool{false, true} { 8996 var suffix string 8997 var defaultCurves []CurveID 8998 if secondBinder { 8999 suffix = "-SecondBinder" 9000 // Force a HelloRetryRequest by predicting an empty curve list. 9001 defaultCurves = []CurveID{} 9002 } 9003 9004 testCases = append(testCases, testCase{ 9005 testType: serverTest, 9006 name: "Resume-Server-BinderWrongLength" + suffix, 9007 resumeSession: true, 9008 config: Config{ 9009 MaxVersion: VersionTLS13, 9010 DefaultCurves: defaultCurves, 9011 Bugs: ProtocolBugs{ 9012 SendShortPSKBinder: true, 9013 OnlyCorruptSecondPSKBinder: secondBinder, 9014 }, 9015 }, 9016 shouldFail: true, 9017 expectedLocalError: "remote error: error decrypting message", 9018 expectedError: ":DIGEST_CHECK_FAILED:", 9019 }) 9020 9021 testCases = append(testCases, testCase{ 9022 testType: serverTest, 9023 name: "Resume-Server-NoPSKBinder" + suffix, 9024 resumeSession: true, 9025 config: Config{ 9026 MaxVersion: VersionTLS13, 9027 DefaultCurves: defaultCurves, 9028 Bugs: ProtocolBugs{ 9029 SendNoPSKBinder: true, 9030 OnlyCorruptSecondPSKBinder: secondBinder, 9031 }, 9032 }, 9033 shouldFail: true, 9034 expectedLocalError: "remote error: error decoding message", 9035 expectedError: ":DECODE_ERROR:", 9036 }) 9037 9038 testCases = append(testCases, testCase{ 9039 testType: serverTest, 9040 name: "Resume-Server-ExtraPSKBinder" + suffix, 9041 resumeSession: true, 9042 config: Config{ 9043 MaxVersion: VersionTLS13, 9044 DefaultCurves: defaultCurves, 9045 Bugs: ProtocolBugs{ 9046 SendExtraPSKBinder: true, 9047 OnlyCorruptSecondPSKBinder: secondBinder, 9048 }, 9049 }, 9050 shouldFail: true, 9051 expectedLocalError: "remote error: illegal parameter", 9052 expectedError: ":PSK_IDENTITY_BINDER_COUNT_MISMATCH:", 9053 }) 9054 9055 testCases = append(testCases, testCase{ 9056 testType: serverTest, 9057 name: "Resume-Server-ExtraIdentityNoBinder" + suffix, 9058 resumeSession: true, 9059 config: Config{ 9060 MaxVersion: VersionTLS13, 9061 DefaultCurves: defaultCurves, 9062 Bugs: ProtocolBugs{ 9063 ExtraPSKIdentity: true, 9064 OnlyCorruptSecondPSKBinder: secondBinder, 9065 }, 9066 }, 9067 shouldFail: true, 9068 expectedLocalError: "remote error: illegal parameter", 9069 expectedError: ":PSK_IDENTITY_BINDER_COUNT_MISMATCH:", 9070 }) 9071 9072 testCases = append(testCases, testCase{ 9073 testType: serverTest, 9074 name: "Resume-Server-InvalidPSKBinder" + suffix, 9075 resumeSession: true, 9076 config: Config{ 9077 MaxVersion: VersionTLS13, 9078 DefaultCurves: defaultCurves, 9079 Bugs: ProtocolBugs{ 9080 SendInvalidPSKBinder: true, 9081 OnlyCorruptSecondPSKBinder: secondBinder, 9082 }, 9083 }, 9084 shouldFail: true, 9085 expectedLocalError: "remote error: error decrypting message", 9086 expectedError: ":DIGEST_CHECK_FAILED:", 9087 }) 9088 9089 testCases = append(testCases, testCase{ 9090 testType: serverTest, 9091 name: "Resume-Server-PSKBinderFirstExtension" + suffix, 9092 resumeSession: true, 9093 config: Config{ 9094 MaxVersion: VersionTLS13, 9095 DefaultCurves: defaultCurves, 9096 Bugs: ProtocolBugs{ 9097 PSKBinderFirst: true, 9098 OnlyCorruptSecondPSKBinder: secondBinder, 9099 }, 9100 }, 9101 shouldFail: true, 9102 expectedLocalError: "remote error: illegal parameter", 9103 expectedError: ":PRE_SHARED_KEY_MUST_BE_LAST:", 9104 }) 9105 } 9106 9107 testCases = append(testCases, testCase{ 9108 testType: serverTest, 9109 name: "Resume-Server-OmitPSKsOnSecondClientHello", 9110 resumeSession: true, 9111 config: Config{ 9112 MaxVersion: VersionTLS13, 9113 DefaultCurves: []CurveID{}, 9114 Bugs: ProtocolBugs{ 9115 OmitPSKsOnSecondClientHello: true, 9116 }, 9117 }, 9118 shouldFail: true, 9119 expectedLocalError: "remote error: illegal parameter", 9120 expectedError: ":INCONSISTENT_CLIENT_HELLO:", 9121 }) 9122} 9123 9124func addRenegotiationTests() { 9125 // Servers cannot renegotiate. 9126 testCases = append(testCases, testCase{ 9127 testType: serverTest, 9128 name: "Renegotiate-Server-Forbidden", 9129 config: Config{ 9130 MaxVersion: VersionTLS12, 9131 }, 9132 renegotiate: 1, 9133 shouldFail: true, 9134 expectedError: ":NO_RENEGOTIATION:", 9135 expectedLocalError: "remote error: no renegotiation", 9136 }) 9137 // The server shouldn't echo the renegotiation extension unless 9138 // requested by the client. 9139 testCases = append(testCases, testCase{ 9140 testType: serverTest, 9141 name: "Renegotiate-Server-NoExt", 9142 config: Config{ 9143 MaxVersion: VersionTLS12, 9144 Bugs: ProtocolBugs{ 9145 NoRenegotiationInfo: true, 9146 RequireRenegotiationInfo: true, 9147 }, 9148 }, 9149 shouldFail: true, 9150 expectedLocalError: "renegotiation extension missing", 9151 }) 9152 // The renegotiation SCSV should be sufficient for the server to echo 9153 // the extension. 9154 testCases = append(testCases, testCase{ 9155 testType: serverTest, 9156 name: "Renegotiate-Server-NoExt-SCSV", 9157 config: Config{ 9158 MaxVersion: VersionTLS12, 9159 Bugs: ProtocolBugs{ 9160 NoRenegotiationInfo: true, 9161 SendRenegotiationSCSV: true, 9162 RequireRenegotiationInfo: true, 9163 }, 9164 }, 9165 }) 9166 testCases = append(testCases, testCase{ 9167 name: "Renegotiate-Client", 9168 config: Config{ 9169 MaxVersion: VersionTLS12, 9170 Bugs: ProtocolBugs{ 9171 FailIfResumeOnRenego: true, 9172 }, 9173 }, 9174 renegotiate: 1, 9175 // Test renegotiation after both an initial and resumption 9176 // handshake. 9177 resumeSession: true, 9178 flags: []string{ 9179 "-renegotiate-freely", 9180 "-expect-total-renegotiations", "1", 9181 "-expect-secure-renegotiation", 9182 }, 9183 }) 9184 testCases = append(testCases, testCase{ 9185 name: "Renegotiate-Client-TLS12", 9186 config: Config{ 9187 MaxVersion: VersionTLS12, 9188 Bugs: ProtocolBugs{ 9189 FailIfResumeOnRenego: true, 9190 }, 9191 }, 9192 renegotiate: 1, 9193 // Test renegotiation after both an initial and resumption 9194 // handshake. 9195 resumeSession: true, 9196 flags: []string{ 9197 "-renegotiate-freely", 9198 "-expect-total-renegotiations", "1", 9199 "-expect-secure-renegotiation", 9200 }, 9201 }) 9202 testCases = append(testCases, testCase{ 9203 name: "Renegotiate-Client-EmptyExt", 9204 renegotiate: 1, 9205 config: Config{ 9206 MaxVersion: VersionTLS12, 9207 Bugs: ProtocolBugs{ 9208 EmptyRenegotiationInfo: true, 9209 }, 9210 }, 9211 flags: []string{"-renegotiate-freely"}, 9212 shouldFail: true, 9213 expectedError: ":RENEGOTIATION_MISMATCH:", 9214 expectedLocalError: "handshake failure", 9215 }) 9216 testCases = append(testCases, testCase{ 9217 name: "Renegotiate-Client-BadExt", 9218 renegotiate: 1, 9219 config: Config{ 9220 MaxVersion: VersionTLS12, 9221 Bugs: ProtocolBugs{ 9222 BadRenegotiationInfo: true, 9223 }, 9224 }, 9225 flags: []string{"-renegotiate-freely"}, 9226 shouldFail: true, 9227 expectedError: ":RENEGOTIATION_MISMATCH:", 9228 expectedLocalError: "handshake failure", 9229 }) 9230 testCases = append(testCases, testCase{ 9231 name: "Renegotiate-Client-BadExt2", 9232 renegotiate: 1, 9233 config: Config{ 9234 MaxVersion: VersionTLS12, 9235 Bugs: ProtocolBugs{ 9236 BadRenegotiationInfoEnd: true, 9237 }, 9238 }, 9239 flags: []string{"-renegotiate-freely"}, 9240 shouldFail: true, 9241 expectedError: ":RENEGOTIATION_MISMATCH:", 9242 expectedLocalError: "handshake failure", 9243 }) 9244 testCases = append(testCases, testCase{ 9245 name: "Renegotiate-Client-Downgrade", 9246 renegotiate: 1, 9247 config: Config{ 9248 MaxVersion: VersionTLS12, 9249 Bugs: ProtocolBugs{ 9250 NoRenegotiationInfoAfterInitial: true, 9251 }, 9252 }, 9253 flags: []string{"-renegotiate-freely"}, 9254 shouldFail: true, 9255 expectedError: ":RENEGOTIATION_MISMATCH:", 9256 expectedLocalError: "handshake failure", 9257 }) 9258 testCases = append(testCases, testCase{ 9259 name: "Renegotiate-Client-Upgrade", 9260 renegotiate: 1, 9261 config: Config{ 9262 MaxVersion: VersionTLS12, 9263 Bugs: ProtocolBugs{ 9264 NoRenegotiationInfoInInitial: true, 9265 }, 9266 }, 9267 flags: []string{"-renegotiate-freely"}, 9268 shouldFail: true, 9269 expectedError: ":RENEGOTIATION_MISMATCH:", 9270 expectedLocalError: "handshake failure", 9271 }) 9272 testCases = append(testCases, testCase{ 9273 name: "Renegotiate-Client-NoExt-Allowed", 9274 renegotiate: 1, 9275 config: Config{ 9276 MaxVersion: VersionTLS12, 9277 Bugs: ProtocolBugs{ 9278 NoRenegotiationInfo: true, 9279 }, 9280 }, 9281 flags: []string{ 9282 "-renegotiate-freely", 9283 "-expect-total-renegotiations", "1", 9284 "-expect-no-secure-renegotiation", 9285 }, 9286 }) 9287 9288 // Test that the server may switch ciphers on renegotiation without 9289 // problems. 9290 testCases = append(testCases, testCase{ 9291 name: "Renegotiate-Client-SwitchCiphers", 9292 renegotiate: 1, 9293 config: Config{ 9294 MaxVersion: VersionTLS12, 9295 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 9296 }, 9297 renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9298 flags: []string{ 9299 "-renegotiate-freely", 9300 "-expect-total-renegotiations", "1", 9301 }, 9302 }) 9303 testCases = append(testCases, testCase{ 9304 name: "Renegotiate-Client-SwitchCiphers2", 9305 renegotiate: 1, 9306 config: Config{ 9307 MaxVersion: VersionTLS12, 9308 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9309 }, 9310 renegotiateCiphers: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 9311 flags: []string{ 9312 "-renegotiate-freely", 9313 "-expect-total-renegotiations", "1", 9314 }, 9315 }) 9316 9317 // Test that the server may not switch versions on renegotiation. 9318 testCases = append(testCases, testCase{ 9319 name: "Renegotiate-Client-SwitchVersion", 9320 config: Config{ 9321 MaxVersion: VersionTLS12, 9322 // Pick a cipher which exists at both versions. 9323 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 9324 Bugs: ProtocolBugs{ 9325 NegotiateVersionOnRenego: VersionTLS11, 9326 // Avoid failing early at the record layer. 9327 SendRecordVersion: VersionTLS12, 9328 }, 9329 }, 9330 renegotiate: 1, 9331 flags: []string{ 9332 "-renegotiate-freely", 9333 "-expect-total-renegotiations", "1", 9334 }, 9335 shouldFail: true, 9336 expectedError: ":WRONG_SSL_VERSION:", 9337 }) 9338 9339 testCases = append(testCases, testCase{ 9340 name: "Renegotiate-SameClientVersion", 9341 renegotiate: 1, 9342 config: Config{ 9343 MaxVersion: VersionTLS10, 9344 Bugs: ProtocolBugs{ 9345 RequireSameRenegoClientVersion: true, 9346 }, 9347 }, 9348 flags: []string{ 9349 "-renegotiate-freely", 9350 "-expect-total-renegotiations", "1", 9351 }, 9352 }) 9353 testCases = append(testCases, testCase{ 9354 name: "Renegotiate-FalseStart", 9355 renegotiate: 1, 9356 config: Config{ 9357 MaxVersion: VersionTLS12, 9358 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9359 NextProtos: []string{"foo"}, 9360 }, 9361 flags: []string{ 9362 "-false-start", 9363 "-select-next-proto", "foo", 9364 "-renegotiate-freely", 9365 "-expect-total-renegotiations", "1", 9366 }, 9367 shimWritesFirst: true, 9368 }) 9369 9370 // Client-side renegotiation controls. 9371 testCases = append(testCases, testCase{ 9372 name: "Renegotiate-Client-Forbidden-1", 9373 config: Config{ 9374 MaxVersion: VersionTLS12, 9375 }, 9376 renegotiate: 1, 9377 shouldFail: true, 9378 expectedError: ":NO_RENEGOTIATION:", 9379 expectedLocalError: "remote error: no renegotiation", 9380 }) 9381 testCases = append(testCases, testCase{ 9382 name: "Renegotiate-Client-Once-1", 9383 config: Config{ 9384 MaxVersion: VersionTLS12, 9385 }, 9386 renegotiate: 1, 9387 flags: []string{ 9388 "-renegotiate-once", 9389 "-expect-total-renegotiations", "1", 9390 }, 9391 }) 9392 testCases = append(testCases, testCase{ 9393 name: "Renegotiate-Client-Freely-1", 9394 config: Config{ 9395 MaxVersion: VersionTLS12, 9396 }, 9397 renegotiate: 1, 9398 flags: []string{ 9399 "-renegotiate-freely", 9400 "-expect-total-renegotiations", "1", 9401 }, 9402 }) 9403 testCases = append(testCases, testCase{ 9404 name: "Renegotiate-Client-Once-2", 9405 config: Config{ 9406 MaxVersion: VersionTLS12, 9407 }, 9408 renegotiate: 2, 9409 flags: []string{"-renegotiate-once"}, 9410 shouldFail: true, 9411 expectedError: ":NO_RENEGOTIATION:", 9412 expectedLocalError: "remote error: no renegotiation", 9413 }) 9414 testCases = append(testCases, testCase{ 9415 name: "Renegotiate-Client-Freely-2", 9416 config: Config{ 9417 MaxVersion: VersionTLS12, 9418 }, 9419 renegotiate: 2, 9420 flags: []string{ 9421 "-renegotiate-freely", 9422 "-expect-total-renegotiations", "2", 9423 }, 9424 }) 9425 testCases = append(testCases, testCase{ 9426 name: "Renegotiate-Client-NoIgnore", 9427 config: Config{ 9428 MaxVersion: VersionTLS12, 9429 Bugs: ProtocolBugs{ 9430 SendHelloRequestBeforeEveryAppDataRecord: true, 9431 }, 9432 }, 9433 shouldFail: true, 9434 expectedError: ":NO_RENEGOTIATION:", 9435 }) 9436 testCases = append(testCases, testCase{ 9437 name: "Renegotiate-Client-Ignore", 9438 config: Config{ 9439 MaxVersion: VersionTLS12, 9440 Bugs: ProtocolBugs{ 9441 SendHelloRequestBeforeEveryAppDataRecord: true, 9442 }, 9443 }, 9444 flags: []string{ 9445 "-renegotiate-ignore", 9446 "-expect-total-renegotiations", "0", 9447 }, 9448 }) 9449 9450 // Renegotiation may be enabled and then disabled immediately after the 9451 // handshake. 9452 testCases = append(testCases, testCase{ 9453 name: "Renegotiate-ForbidAfterHandshake", 9454 config: Config{ 9455 MaxVersion: VersionTLS12, 9456 }, 9457 renegotiate: 1, 9458 flags: []string{"-forbid-renegotiation-after-handshake"}, 9459 shouldFail: true, 9460 expectedError: ":NO_RENEGOTIATION:", 9461 expectedLocalError: "remote error: no renegotiation", 9462 }) 9463 9464 // Renegotiation is not allowed when there is an unfinished write. 9465 testCases = append(testCases, testCase{ 9466 name: "Renegotiate-Client-UnfinishedWrite", 9467 config: Config{ 9468 MaxVersion: VersionTLS12, 9469 }, 9470 renegotiate: 1, 9471 readWithUnfinishedWrite: true, 9472 flags: []string{ 9473 "-async", 9474 "-renegotiate-freely", 9475 }, 9476 shouldFail: true, 9477 expectedError: ":NO_RENEGOTIATION:", 9478 // We do not successfully send the no_renegotiation alert in 9479 // this case. https://crbug.com/boringssl/130 9480 }) 9481 9482 // We reject stray HelloRequests during the handshake in TLS 1.2. 9483 testCases = append(testCases, testCase{ 9484 name: "StrayHelloRequest", 9485 config: Config{ 9486 MaxVersion: VersionTLS12, 9487 Bugs: ProtocolBugs{ 9488 SendHelloRequestBeforeEveryHandshakeMessage: true, 9489 }, 9490 }, 9491 shouldFail: true, 9492 expectedError: ":UNEXPECTED_MESSAGE:", 9493 }) 9494 testCases = append(testCases, testCase{ 9495 name: "StrayHelloRequest-Packed", 9496 config: Config{ 9497 MaxVersion: VersionTLS12, 9498 Bugs: ProtocolBugs{ 9499 PackHandshakeFlight: true, 9500 SendHelloRequestBeforeEveryHandshakeMessage: true, 9501 }, 9502 }, 9503 shouldFail: true, 9504 expectedError: ":UNEXPECTED_MESSAGE:", 9505 }) 9506 9507 // Test that HelloRequest is rejected if it comes in the same record as the 9508 // server Finished. 9509 testCases = append(testCases, testCase{ 9510 name: "Renegotiate-Client-Packed", 9511 config: Config{ 9512 MaxVersion: VersionTLS12, 9513 Bugs: ProtocolBugs{ 9514 PackHandshakeFlight: true, 9515 PackHelloRequestWithFinished: true, 9516 }, 9517 }, 9518 renegotiate: 1, 9519 flags: []string{"-renegotiate-freely"}, 9520 shouldFail: true, 9521 expectedError: ":EXCESS_HANDSHAKE_DATA:", 9522 expectedLocalError: "remote error: unexpected message", 9523 }) 9524 9525 // Renegotiation is forbidden in TLS 1.3. 9526 testCases = append(testCases, testCase{ 9527 name: "Renegotiate-Client-TLS13", 9528 config: Config{ 9529 MaxVersion: VersionTLS13, 9530 Bugs: ProtocolBugs{ 9531 SendHelloRequestBeforeEveryAppDataRecord: true, 9532 }, 9533 }, 9534 flags: []string{ 9535 "-renegotiate-freely", 9536 }, 9537 shouldFail: true, 9538 expectedError: ":UNEXPECTED_MESSAGE:", 9539 }) 9540 9541 // Stray HelloRequests during the handshake are forbidden in TLS 1.3. 9542 testCases = append(testCases, testCase{ 9543 name: "StrayHelloRequest-TLS13", 9544 config: Config{ 9545 MaxVersion: VersionTLS13, 9546 Bugs: ProtocolBugs{ 9547 SendHelloRequestBeforeEveryHandshakeMessage: true, 9548 }, 9549 }, 9550 shouldFail: true, 9551 expectedError: ":UNEXPECTED_MESSAGE:", 9552 }) 9553 9554 // The renegotiation_info extension is not sent in TLS 1.3, but TLS 1.3 9555 // always reads as supporting it, regardless of whether it was 9556 // negotiated. 9557 testCases = append(testCases, testCase{ 9558 name: "AlwaysReportRenegotiationInfo-TLS13", 9559 config: Config{ 9560 MaxVersion: VersionTLS13, 9561 Bugs: ProtocolBugs{ 9562 NoRenegotiationInfo: true, 9563 }, 9564 }, 9565 flags: []string{ 9566 "-expect-secure-renegotiation", 9567 }, 9568 }) 9569 9570 // Certificates may not change on renegotiation. 9571 testCases = append(testCases, testCase{ 9572 name: "Renegotiation-CertificateChange", 9573 config: Config{ 9574 MaxVersion: VersionTLS12, 9575 Certificates: []Certificate{rsaCertificate}, 9576 Bugs: ProtocolBugs{ 9577 RenegotiationCertificate: &rsaChainCertificate, 9578 }, 9579 }, 9580 renegotiate: 1, 9581 flags: []string{"-renegotiate-freely"}, 9582 shouldFail: true, 9583 expectedError: ":SERVER_CERT_CHANGED:", 9584 }) 9585 testCases = append(testCases, testCase{ 9586 name: "Renegotiation-CertificateChange-2", 9587 config: Config{ 9588 MaxVersion: VersionTLS12, 9589 Certificates: []Certificate{rsaCertificate}, 9590 Bugs: ProtocolBugs{ 9591 RenegotiationCertificate: &rsa1024Certificate, 9592 }, 9593 }, 9594 renegotiate: 1, 9595 flags: []string{"-renegotiate-freely"}, 9596 shouldFail: true, 9597 expectedError: ":SERVER_CERT_CHANGED:", 9598 }) 9599 9600 // We do not negotiate ALPN after the initial handshake. This is 9601 // error-prone and only risks bugs in consumers. 9602 testCases = append(testCases, testCase{ 9603 testType: clientTest, 9604 name: "Renegotiation-ForbidALPN", 9605 config: Config{ 9606 MaxVersion: VersionTLS12, 9607 Bugs: ProtocolBugs{ 9608 // Forcibly negotiate ALPN on both initial and 9609 // renegotiation handshakes. The test stack will 9610 // internally check the client does not offer 9611 // it. 9612 SendALPN: "foo", 9613 }, 9614 }, 9615 flags: []string{ 9616 "-advertise-alpn", "\x03foo\x03bar\x03baz", 9617 "-expect-alpn", "foo", 9618 "-renegotiate-freely", 9619 }, 9620 renegotiate: 1, 9621 shouldFail: true, 9622 expectedError: ":UNEXPECTED_EXTENSION:", 9623 }) 9624 9625 // The server may send different stapled OCSP responses or SCT lists on 9626 // renegotiation, but BoringSSL ignores this and reports the old values. 9627 // Also test that non-fatal verify results are preserved. 9628 testCases = append(testCases, testCase{ 9629 testType: clientTest, 9630 name: "Renegotiation-ChangeAuthProperties", 9631 config: Config{ 9632 MaxVersion: VersionTLS12, 9633 Bugs: ProtocolBugs{ 9634 SendOCSPResponseOnRenegotiation: testOCSPResponse2, 9635 SendSCTListOnRenegotiation: testSCTList2, 9636 }, 9637 }, 9638 renegotiate: 1, 9639 flags: []string{ 9640 "-renegotiate-freely", 9641 "-expect-total-renegotiations", "1", 9642 "-enable-ocsp-stapling", 9643 "-expect-ocsp-response", 9644 base64FlagValue(testOCSPResponse), 9645 "-enable-signed-cert-timestamps", 9646 "-expect-signed-cert-timestamps", 9647 base64FlagValue(testSCTList), 9648 "-verify-fail", 9649 "-expect-verify-result", 9650 }, 9651 }) 9652} 9653 9654func addDTLSReplayTests() { 9655 // Test that sequence number replays are detected. 9656 testCases = append(testCases, testCase{ 9657 protocol: dtls, 9658 name: "DTLS-Replay", 9659 messageCount: 200, 9660 replayWrites: true, 9661 }) 9662 9663 // Test the incoming sequence number skipping by values larger 9664 // than the retransmit window. 9665 testCases = append(testCases, testCase{ 9666 protocol: dtls, 9667 name: "DTLS-Replay-LargeGaps", 9668 config: Config{ 9669 Bugs: ProtocolBugs{ 9670 SequenceNumberMapping: func(in uint64) uint64 { 9671 return in * 127 9672 }, 9673 }, 9674 }, 9675 messageCount: 200, 9676 replayWrites: true, 9677 }) 9678 9679 // Test the incoming sequence number changing non-monotonically. 9680 testCases = append(testCases, testCase{ 9681 protocol: dtls, 9682 name: "DTLS-Replay-NonMonotonic", 9683 config: Config{ 9684 Bugs: ProtocolBugs{ 9685 SequenceNumberMapping: func(in uint64) uint64 { 9686 return in ^ 31 9687 }, 9688 }, 9689 }, 9690 messageCount: 200, 9691 replayWrites: true, 9692 }) 9693} 9694 9695var testSignatureAlgorithms = []struct { 9696 name string 9697 id signatureAlgorithm 9698 cert testCert 9699}{ 9700 {"RSA_PKCS1_SHA1", signatureRSAPKCS1WithSHA1, testCertRSA}, 9701 {"RSA_PKCS1_SHA256", signatureRSAPKCS1WithSHA256, testCertRSA}, 9702 {"RSA_PKCS1_SHA384", signatureRSAPKCS1WithSHA384, testCertRSA}, 9703 {"RSA_PKCS1_SHA512", signatureRSAPKCS1WithSHA512, testCertRSA}, 9704 {"ECDSA_SHA1", signatureECDSAWithSHA1, testCertECDSAP256}, 9705 // The “P256” in the following line is not a mistake. In TLS 1.2 the 9706 // hash function doesn't have to match the curve and so the same 9707 // signature algorithm works with P-224. 9708 {"ECDSA_P224_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP224}, 9709 {"ECDSA_P256_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP256}, 9710 {"ECDSA_P384_SHA384", signatureECDSAWithP384AndSHA384, testCertECDSAP384}, 9711 {"ECDSA_P521_SHA512", signatureECDSAWithP521AndSHA512, testCertECDSAP521}, 9712 {"RSA_PSS_SHA256", signatureRSAPSSWithSHA256, testCertRSA}, 9713 {"RSA_PSS_SHA384", signatureRSAPSSWithSHA384, testCertRSA}, 9714 {"RSA_PSS_SHA512", signatureRSAPSSWithSHA512, testCertRSA}, 9715 {"Ed25519", signatureEd25519, testCertEd25519}, 9716 // Tests for key types prior to TLS 1.2. 9717 {"RSA", 0, testCertRSA}, 9718 {"ECDSA", 0, testCertECDSAP256}, 9719} 9720 9721const fakeSigAlg1 signatureAlgorithm = 0x2a01 9722const fakeSigAlg2 signatureAlgorithm = 0xff01 9723 9724func addSignatureAlgorithmTests() { 9725 // Not all ciphers involve a signature. Advertise a list which gives all 9726 // versions a signing cipher. 9727 signingCiphers := []uint16{ 9728 TLS_AES_256_GCM_SHA384, 9729 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 9730 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 9731 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 9732 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 9733 } 9734 9735 var allAlgorithms []signatureAlgorithm 9736 for _, alg := range testSignatureAlgorithms { 9737 if alg.id != 0 { 9738 allAlgorithms = append(allAlgorithms, alg.id) 9739 } 9740 } 9741 9742 // Make sure each signature algorithm works. Include some fake values in 9743 // the list and ensure they're ignored. 9744 for _, alg := range testSignatureAlgorithms { 9745 for _, ver := range tlsVersions { 9746 if (ver.version < VersionTLS12) != (alg.id == 0) { 9747 continue 9748 } 9749 9750 var shouldFail, rejectByDefault bool 9751 // ecdsa_sha1 does not exist in TLS 1.3. 9752 if ver.version >= VersionTLS13 && alg.id == signatureECDSAWithSHA1 { 9753 shouldFail = true 9754 } 9755 // RSA-PKCS1 does not exist in TLS 1.3. 9756 if ver.version >= VersionTLS13 && hasComponent(alg.name, "PKCS1") { 9757 shouldFail = true 9758 } 9759 // SHA-224 has been removed from TLS 1.3 and, in 1.3, 9760 // the curve has to match the hash size. 9761 if ver.version >= VersionTLS13 && alg.cert == testCertECDSAP224 { 9762 shouldFail = true 9763 } 9764 9765 // By default, BoringSSL does not enable ecdsa_sha1, ecdsa_secp521_sha512, and ed25519. 9766 if alg.id == signatureECDSAWithSHA1 || alg.id == signatureECDSAWithP521AndSHA512 || alg.id == signatureEd25519 { 9767 rejectByDefault = true 9768 } 9769 9770 var signError, signLocalError, verifyError, verifyLocalError, defaultError, defaultLocalError string 9771 if shouldFail { 9772 signError = ":NO_COMMON_SIGNATURE_ALGORITHMS:" 9773 signLocalError = "remote error: handshake failure" 9774 verifyError = ":WRONG_SIGNATURE_TYPE:" 9775 verifyLocalError = "remote error" 9776 rejectByDefault = true 9777 } 9778 if rejectByDefault { 9779 defaultError = ":WRONG_SIGNATURE_TYPE:" 9780 defaultLocalError = "remote error" 9781 } 9782 9783 suffix := "-" + alg.name + "-" + ver.name 9784 9785 for _, testType := range []testType{clientTest, serverTest} { 9786 prefix := "Client-" 9787 if testType == serverTest { 9788 prefix = "Server-" 9789 } 9790 9791 // Test the shim using the algorithm for signing. 9792 signTest := testCase{ 9793 testType: testType, 9794 name: prefix + "Sign" + suffix, 9795 config: Config{ 9796 MaxVersion: ver.version, 9797 VerifySignatureAlgorithms: []signatureAlgorithm{ 9798 fakeSigAlg1, 9799 alg.id, 9800 fakeSigAlg2, 9801 }, 9802 }, 9803 flags: append( 9804 []string{ 9805 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)), 9806 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)), 9807 }, 9808 flagInts("-curves", shimConfig.AllCurves)..., 9809 ), 9810 shouldFail: shouldFail, 9811 expectedError: signError, 9812 expectedLocalError: signLocalError, 9813 expectations: connectionExpectations{ 9814 peerSignatureAlgorithm: alg.id, 9815 }, 9816 } 9817 9818 // Test that the shim will select the algorithm when configured to only 9819 // support it. 9820 negotiateTest := testCase{ 9821 testType: testType, 9822 name: prefix + "Sign-Negotiate" + suffix, 9823 config: Config{ 9824 MaxVersion: ver.version, 9825 VerifySignatureAlgorithms: allAlgorithms, 9826 }, 9827 flags: append( 9828 []string{ 9829 "-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)), 9830 "-key-file", path.Join(*resourceDir, getShimKey(alg.cert)), 9831 "-signing-prefs", strconv.Itoa(int(alg.id)), 9832 }, 9833 flagInts("-curves", shimConfig.AllCurves)..., 9834 ), 9835 expectations: connectionExpectations{ 9836 peerSignatureAlgorithm: alg.id, 9837 }, 9838 } 9839 9840 if testType == serverTest { 9841 // TLS 1.2 servers only sign on some cipher suites. 9842 signTest.config.CipherSuites = signingCiphers 9843 negotiateTest.config.CipherSuites = signingCiphers 9844 } else { 9845 // TLS 1.2 clients only sign when the server requests certificates. 9846 signTest.config.ClientAuth = RequireAnyClientCert 9847 negotiateTest.config.ClientAuth = RequireAnyClientCert 9848 } 9849 testCases = append(testCases, signTest) 9850 if ver.version >= VersionTLS12 && !shouldFail { 9851 testCases = append(testCases, negotiateTest) 9852 } 9853 9854 // Test the shim using the algorithm for verifying. 9855 verifyTest := testCase{ 9856 testType: testType, 9857 name: prefix + "Verify" + suffix, 9858 config: Config{ 9859 MaxVersion: ver.version, 9860 Certificates: []Certificate{getRunnerCertificate(alg.cert)}, 9861 SignSignatureAlgorithms: []signatureAlgorithm{ 9862 alg.id, 9863 }, 9864 Bugs: ProtocolBugs{ 9865 SkipECDSACurveCheck: shouldFail, 9866 IgnoreSignatureVersionChecks: shouldFail, 9867 // Some signature algorithms may not be advertised. 9868 IgnorePeerSignatureAlgorithmPreferences: shouldFail, 9869 }, 9870 }, 9871 flags: append( 9872 []string{ 9873 "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)), 9874 // The algorithm may be disabled by default, so explicitly enable it. 9875 "-verify-prefs", strconv.Itoa(int(alg.id)), 9876 }, 9877 flagInts("-curves", shimConfig.AllCurves)..., 9878 ), 9879 // Resume the session to assert the peer signature 9880 // algorithm is reported on both handshakes. 9881 resumeSession: !shouldFail, 9882 shouldFail: shouldFail, 9883 expectedError: verifyError, 9884 expectedLocalError: verifyLocalError, 9885 } 9886 9887 // Test whether the shim expects the algorithm enabled by default. 9888 defaultTest := testCase{ 9889 testType: testType, 9890 name: prefix + "VerifyDefault" + suffix, 9891 config: Config{ 9892 MaxVersion: ver.version, 9893 Certificates: []Certificate{getRunnerCertificate(alg.cert)}, 9894 SignSignatureAlgorithms: []signatureAlgorithm{ 9895 alg.id, 9896 }, 9897 Bugs: ProtocolBugs{ 9898 SkipECDSACurveCheck: rejectByDefault, 9899 IgnoreSignatureVersionChecks: rejectByDefault, 9900 // Some signature algorithms may not be advertised. 9901 IgnorePeerSignatureAlgorithmPreferences: rejectByDefault, 9902 }, 9903 }, 9904 flags: append( 9905 []string{"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))}, 9906 flagInts("-curves", shimConfig.AllCurves)..., 9907 ), 9908 // Resume the session to assert the peer signature 9909 // algorithm is reported on both handshakes. 9910 resumeSession: !rejectByDefault, 9911 shouldFail: rejectByDefault, 9912 expectedError: defaultError, 9913 expectedLocalError: defaultLocalError, 9914 } 9915 9916 // Test whether the shim handles invalid signatures for this algorithm. 9917 invalidTest := testCase{ 9918 testType: testType, 9919 name: prefix + "InvalidSignature" + suffix, 9920 config: Config{ 9921 MaxVersion: ver.version, 9922 Certificates: []Certificate{getRunnerCertificate(alg.cert)}, 9923 SignSignatureAlgorithms: []signatureAlgorithm{ 9924 alg.id, 9925 }, 9926 Bugs: ProtocolBugs{ 9927 InvalidSignature: true, 9928 }, 9929 }, 9930 flags: append( 9931 // The algorithm may be disabled by default, so explicitly enable it. 9932 []string{"-verify-prefs", strconv.Itoa(int(alg.id))}, 9933 flagInts("-curves", shimConfig.AllCurves)..., 9934 ), 9935 shouldFail: true, 9936 expectedError: ":BAD_SIGNATURE:", 9937 } 9938 9939 if testType == serverTest { 9940 // TLS 1.2 servers only verify when they request client certificates. 9941 verifyTest.flags = append(verifyTest.flags, "-require-any-client-certificate") 9942 defaultTest.flags = append(defaultTest.flags, "-require-any-client-certificate") 9943 invalidTest.flags = append(invalidTest.flags, "-require-any-client-certificate") 9944 } else { 9945 // TLS 1.2 clients only verify on some cipher suites. 9946 verifyTest.config.CipherSuites = signingCiphers 9947 defaultTest.config.CipherSuites = signingCiphers 9948 invalidTest.config.CipherSuites = signingCiphers 9949 } 9950 testCases = append(testCases, verifyTest, defaultTest) 9951 if !shouldFail { 9952 testCases = append(testCases, invalidTest) 9953 } 9954 } 9955 } 9956 } 9957 9958 // Test the peer's verify preferences are available. 9959 for _, ver := range tlsVersions { 9960 if ver.version < VersionTLS12 { 9961 continue 9962 } 9963 testCases = append(testCases, testCase{ 9964 name: "ClientAuth-PeerVerifyPrefs-" + ver.name, 9965 config: Config{ 9966 MaxVersion: ver.version, 9967 ClientAuth: RequireAnyClientCert, 9968 VerifySignatureAlgorithms: []signatureAlgorithm{ 9969 signatureRSAPSSWithSHA256, 9970 signatureEd25519, 9971 signatureECDSAWithP256AndSHA256, 9972 }, 9973 }, 9974 flags: []string{ 9975 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 9976 "-key-file", path.Join(*resourceDir, rsaKeyFile), 9977 "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 9978 "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), 9979 "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 9980 }, 9981 }) 9982 9983 testCases = append(testCases, testCase{ 9984 testType: serverTest, 9985 name: "ServerAuth-PeerVerifyPrefs-" + ver.name, 9986 config: Config{ 9987 MaxVersion: ver.version, 9988 VerifySignatureAlgorithms: []signatureAlgorithm{ 9989 signatureRSAPSSWithSHA256, 9990 signatureEd25519, 9991 signatureECDSAWithP256AndSHA256, 9992 }, 9993 }, 9994 flags: []string{ 9995 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 9996 "-key-file", path.Join(*resourceDir, rsaKeyFile), 9997 "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 9998 "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), 9999 "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 10000 }, 10001 }) 10002 10003 } 10004 10005 // Test that algorithm selection takes the key type into account. 10006 testCases = append(testCases, testCase{ 10007 name: "ClientAuth-SignatureType", 10008 config: Config{ 10009 ClientAuth: RequireAnyClientCert, 10010 MaxVersion: VersionTLS12, 10011 VerifySignatureAlgorithms: []signatureAlgorithm{ 10012 signatureECDSAWithP521AndSHA512, 10013 signatureRSAPKCS1WithSHA384, 10014 signatureECDSAWithSHA1, 10015 }, 10016 }, 10017 flags: []string{ 10018 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10019 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10020 }, 10021 expectations: connectionExpectations{ 10022 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, 10023 }, 10024 }) 10025 10026 testCases = append(testCases, testCase{ 10027 name: "ClientAuth-SignatureType-TLS13", 10028 config: Config{ 10029 ClientAuth: RequireAnyClientCert, 10030 MaxVersion: VersionTLS13, 10031 VerifySignatureAlgorithms: []signatureAlgorithm{ 10032 signatureECDSAWithP521AndSHA512, 10033 signatureRSAPKCS1WithSHA384, 10034 signatureRSAPSSWithSHA384, 10035 signatureECDSAWithSHA1, 10036 }, 10037 }, 10038 flags: []string{ 10039 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10040 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10041 }, 10042 expectations: connectionExpectations{ 10043 peerSignatureAlgorithm: signatureRSAPSSWithSHA384, 10044 }, 10045 }) 10046 10047 testCases = append(testCases, testCase{ 10048 testType: serverTest, 10049 name: "ServerAuth-SignatureType", 10050 config: Config{ 10051 MaxVersion: VersionTLS12, 10052 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10053 VerifySignatureAlgorithms: []signatureAlgorithm{ 10054 signatureECDSAWithP521AndSHA512, 10055 signatureRSAPKCS1WithSHA384, 10056 signatureECDSAWithSHA1, 10057 }, 10058 }, 10059 expectations: connectionExpectations{ 10060 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, 10061 }, 10062 }) 10063 10064 testCases = append(testCases, testCase{ 10065 testType: serverTest, 10066 name: "ServerAuth-SignatureType-TLS13", 10067 config: Config{ 10068 MaxVersion: VersionTLS13, 10069 VerifySignatureAlgorithms: []signatureAlgorithm{ 10070 signatureECDSAWithP521AndSHA512, 10071 signatureRSAPKCS1WithSHA384, 10072 signatureRSAPSSWithSHA384, 10073 signatureECDSAWithSHA1, 10074 }, 10075 }, 10076 expectations: connectionExpectations{ 10077 peerSignatureAlgorithm: signatureRSAPSSWithSHA384, 10078 }, 10079 }) 10080 10081 // Test that signature verification takes the key type into account. 10082 testCases = append(testCases, testCase{ 10083 testType: serverTest, 10084 name: "Verify-ClientAuth-SignatureType", 10085 config: Config{ 10086 MaxVersion: VersionTLS12, 10087 Certificates: []Certificate{rsaCertificate}, 10088 SignSignatureAlgorithms: []signatureAlgorithm{ 10089 signatureRSAPKCS1WithSHA256, 10090 }, 10091 Bugs: ProtocolBugs{ 10092 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10093 }, 10094 }, 10095 flags: []string{ 10096 "-require-any-client-certificate", 10097 }, 10098 shouldFail: true, 10099 expectedError: ":WRONG_SIGNATURE_TYPE:", 10100 }) 10101 10102 testCases = append(testCases, testCase{ 10103 testType: serverTest, 10104 name: "Verify-ClientAuth-SignatureType-TLS13", 10105 config: Config{ 10106 MaxVersion: VersionTLS13, 10107 Certificates: []Certificate{rsaCertificate}, 10108 SignSignatureAlgorithms: []signatureAlgorithm{ 10109 signatureRSAPSSWithSHA256, 10110 }, 10111 Bugs: ProtocolBugs{ 10112 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10113 }, 10114 }, 10115 flags: []string{ 10116 "-require-any-client-certificate", 10117 }, 10118 shouldFail: true, 10119 expectedError: ":WRONG_SIGNATURE_TYPE:", 10120 }) 10121 10122 testCases = append(testCases, testCase{ 10123 name: "Verify-ServerAuth-SignatureType", 10124 config: Config{ 10125 MaxVersion: VersionTLS12, 10126 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10127 SignSignatureAlgorithms: []signatureAlgorithm{ 10128 signatureRSAPKCS1WithSHA256, 10129 }, 10130 Bugs: ProtocolBugs{ 10131 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10132 }, 10133 }, 10134 shouldFail: true, 10135 expectedError: ":WRONG_SIGNATURE_TYPE:", 10136 }) 10137 10138 testCases = append(testCases, testCase{ 10139 name: "Verify-ServerAuth-SignatureType-TLS13", 10140 config: Config{ 10141 MaxVersion: VersionTLS13, 10142 SignSignatureAlgorithms: []signatureAlgorithm{ 10143 signatureRSAPSSWithSHA256, 10144 }, 10145 Bugs: ProtocolBugs{ 10146 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10147 }, 10148 }, 10149 shouldFail: true, 10150 expectedError: ":WRONG_SIGNATURE_TYPE:", 10151 }) 10152 10153 // Test that, if the ClientHello list is missing, the server falls back 10154 // to SHA-1 in TLS 1.2, but not TLS 1.3. 10155 testCases = append(testCases, testCase{ 10156 testType: serverTest, 10157 name: "ServerAuth-SHA1-Fallback-RSA", 10158 config: Config{ 10159 MaxVersion: VersionTLS12, 10160 VerifySignatureAlgorithms: []signatureAlgorithm{ 10161 signatureRSAPKCS1WithSHA1, 10162 }, 10163 Bugs: ProtocolBugs{ 10164 NoSignatureAlgorithms: true, 10165 }, 10166 }, 10167 flags: []string{ 10168 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10169 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10170 }, 10171 }) 10172 10173 testCases = append(testCases, testCase{ 10174 testType: serverTest, 10175 name: "ServerAuth-SHA1-Fallback-ECDSA", 10176 config: Config{ 10177 MaxVersion: VersionTLS12, 10178 VerifySignatureAlgorithms: []signatureAlgorithm{ 10179 signatureECDSAWithSHA1, 10180 }, 10181 Bugs: ProtocolBugs{ 10182 NoSignatureAlgorithms: true, 10183 }, 10184 }, 10185 flags: []string{ 10186 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 10187 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 10188 }, 10189 }) 10190 10191 testCases = append(testCases, testCase{ 10192 testType: serverTest, 10193 name: "ServerAuth-NoFallback-TLS13", 10194 config: Config{ 10195 MaxVersion: VersionTLS13, 10196 VerifySignatureAlgorithms: []signatureAlgorithm{ 10197 signatureRSAPKCS1WithSHA1, 10198 }, 10199 Bugs: ProtocolBugs{ 10200 NoSignatureAlgorithms: true, 10201 DisableDelegatedCredentials: true, 10202 }, 10203 }, 10204 shouldFail: true, 10205 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10206 }) 10207 10208 // The CertificateRequest list, however, may never be omitted. It is a 10209 // syntax error for it to be empty. 10210 testCases = append(testCases, testCase{ 10211 name: "ClientAuth-NoFallback-RSA", 10212 config: Config{ 10213 MaxVersion: VersionTLS12, 10214 ClientAuth: RequireAnyClientCert, 10215 VerifySignatureAlgorithms: []signatureAlgorithm{ 10216 signatureRSAPKCS1WithSHA1, 10217 }, 10218 Bugs: ProtocolBugs{ 10219 NoSignatureAlgorithms: true, 10220 }, 10221 }, 10222 flags: []string{ 10223 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10224 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10225 }, 10226 shouldFail: true, 10227 expectedError: ":DECODE_ERROR:", 10228 expectedLocalError: "remote error: error decoding message", 10229 }) 10230 10231 testCases = append(testCases, testCase{ 10232 name: "ClientAuth-NoFallback-ECDSA", 10233 config: Config{ 10234 MaxVersion: VersionTLS12, 10235 ClientAuth: RequireAnyClientCert, 10236 VerifySignatureAlgorithms: []signatureAlgorithm{ 10237 signatureECDSAWithSHA1, 10238 }, 10239 Bugs: ProtocolBugs{ 10240 NoSignatureAlgorithms: true, 10241 }, 10242 }, 10243 flags: []string{ 10244 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 10245 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 10246 }, 10247 shouldFail: true, 10248 expectedError: ":DECODE_ERROR:", 10249 expectedLocalError: "remote error: error decoding message", 10250 }) 10251 10252 testCases = append(testCases, testCase{ 10253 name: "ClientAuth-NoFallback-TLS13", 10254 config: Config{ 10255 MaxVersion: VersionTLS13, 10256 ClientAuth: RequireAnyClientCert, 10257 VerifySignatureAlgorithms: []signatureAlgorithm{ 10258 signatureRSAPKCS1WithSHA1, 10259 }, 10260 Bugs: ProtocolBugs{ 10261 NoSignatureAlgorithms: true, 10262 }, 10263 }, 10264 flags: []string{ 10265 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10266 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10267 }, 10268 shouldFail: true, 10269 expectedError: ":DECODE_ERROR:", 10270 expectedLocalError: "remote error: error decoding message", 10271 }) 10272 10273 // Test that signature preferences are enforced. BoringSSL does not 10274 // implement MD5 signatures. 10275 testCases = append(testCases, testCase{ 10276 testType: serverTest, 10277 name: "ClientAuth-Enforced", 10278 config: Config{ 10279 MaxVersion: VersionTLS12, 10280 Certificates: []Certificate{rsaCertificate}, 10281 SignSignatureAlgorithms: []signatureAlgorithm{ 10282 signatureRSAPKCS1WithMD5, 10283 }, 10284 Bugs: ProtocolBugs{ 10285 IgnorePeerSignatureAlgorithmPreferences: true, 10286 }, 10287 }, 10288 flags: []string{"-require-any-client-certificate"}, 10289 shouldFail: true, 10290 expectedError: ":WRONG_SIGNATURE_TYPE:", 10291 }) 10292 10293 testCases = append(testCases, testCase{ 10294 name: "ServerAuth-Enforced", 10295 config: Config{ 10296 MaxVersion: VersionTLS12, 10297 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10298 SignSignatureAlgorithms: []signatureAlgorithm{ 10299 signatureRSAPKCS1WithMD5, 10300 }, 10301 Bugs: ProtocolBugs{ 10302 IgnorePeerSignatureAlgorithmPreferences: true, 10303 }, 10304 }, 10305 shouldFail: true, 10306 expectedError: ":WRONG_SIGNATURE_TYPE:", 10307 }) 10308 testCases = append(testCases, testCase{ 10309 testType: serverTest, 10310 name: "ClientAuth-Enforced-TLS13", 10311 config: Config{ 10312 MaxVersion: VersionTLS13, 10313 Certificates: []Certificate{rsaCertificate}, 10314 SignSignatureAlgorithms: []signatureAlgorithm{ 10315 signatureRSAPKCS1WithMD5, 10316 }, 10317 Bugs: ProtocolBugs{ 10318 IgnorePeerSignatureAlgorithmPreferences: true, 10319 IgnoreSignatureVersionChecks: true, 10320 }, 10321 }, 10322 flags: []string{"-require-any-client-certificate"}, 10323 shouldFail: true, 10324 expectedError: ":WRONG_SIGNATURE_TYPE:", 10325 }) 10326 10327 testCases = append(testCases, testCase{ 10328 name: "ServerAuth-Enforced-TLS13", 10329 config: Config{ 10330 MaxVersion: VersionTLS13, 10331 SignSignatureAlgorithms: []signatureAlgorithm{ 10332 signatureRSAPKCS1WithMD5, 10333 }, 10334 Bugs: ProtocolBugs{ 10335 IgnorePeerSignatureAlgorithmPreferences: true, 10336 IgnoreSignatureVersionChecks: true, 10337 }, 10338 }, 10339 shouldFail: true, 10340 expectedError: ":WRONG_SIGNATURE_TYPE:", 10341 }) 10342 10343 // Test that the negotiated signature algorithm respects the client and 10344 // server preferences. 10345 testCases = append(testCases, testCase{ 10346 name: "NoCommonAlgorithms", 10347 config: Config{ 10348 MaxVersion: VersionTLS12, 10349 ClientAuth: RequireAnyClientCert, 10350 VerifySignatureAlgorithms: []signatureAlgorithm{ 10351 signatureRSAPKCS1WithSHA512, 10352 signatureRSAPKCS1WithSHA1, 10353 }, 10354 }, 10355 flags: []string{ 10356 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10357 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10358 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 10359 }, 10360 shouldFail: true, 10361 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10362 }) 10363 testCases = append(testCases, testCase{ 10364 name: "NoCommonAlgorithms-TLS13", 10365 config: Config{ 10366 MaxVersion: VersionTLS13, 10367 ClientAuth: RequireAnyClientCert, 10368 VerifySignatureAlgorithms: []signatureAlgorithm{ 10369 signatureRSAPSSWithSHA512, 10370 signatureRSAPSSWithSHA384, 10371 }, 10372 }, 10373 flags: []string{ 10374 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10375 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10376 "-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 10377 }, 10378 shouldFail: true, 10379 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10380 }) 10381 testCases = append(testCases, testCase{ 10382 name: "Agree-Digest-SHA256", 10383 config: Config{ 10384 MaxVersion: VersionTLS12, 10385 ClientAuth: RequireAnyClientCert, 10386 VerifySignatureAlgorithms: []signatureAlgorithm{ 10387 signatureRSAPKCS1WithSHA1, 10388 signatureRSAPKCS1WithSHA256, 10389 }, 10390 }, 10391 flags: []string{ 10392 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10393 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10394 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 10395 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA1)), 10396 }, 10397 expectations: connectionExpectations{ 10398 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10399 }, 10400 }) 10401 testCases = append(testCases, testCase{ 10402 name: "Agree-Digest-SHA1", 10403 config: Config{ 10404 MaxVersion: VersionTLS12, 10405 ClientAuth: RequireAnyClientCert, 10406 VerifySignatureAlgorithms: []signatureAlgorithm{ 10407 signatureRSAPKCS1WithSHA1, 10408 }, 10409 }, 10410 flags: []string{ 10411 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10412 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10413 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA512)), 10414 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 10415 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA1)), 10416 }, 10417 expectations: connectionExpectations{ 10418 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA1, 10419 }, 10420 }) 10421 testCases = append(testCases, testCase{ 10422 name: "Agree-Digest-Default", 10423 config: Config{ 10424 MaxVersion: VersionTLS12, 10425 ClientAuth: RequireAnyClientCert, 10426 VerifySignatureAlgorithms: []signatureAlgorithm{ 10427 signatureRSAPKCS1WithSHA256, 10428 signatureECDSAWithP256AndSHA256, 10429 signatureRSAPKCS1WithSHA1, 10430 signatureECDSAWithSHA1, 10431 }, 10432 }, 10433 flags: []string{ 10434 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10435 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10436 }, 10437 expectations: connectionExpectations{ 10438 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10439 }, 10440 }) 10441 10442 // Test that the signing preference list may include extra algorithms 10443 // without negotiation problems. 10444 testCases = append(testCases, testCase{ 10445 testType: serverTest, 10446 name: "FilterExtraAlgorithms", 10447 config: Config{ 10448 MaxVersion: VersionTLS12, 10449 VerifySignatureAlgorithms: []signatureAlgorithm{ 10450 signatureRSAPKCS1WithSHA256, 10451 }, 10452 }, 10453 flags: []string{ 10454 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 10455 "-key-file", path.Join(*resourceDir, rsaKeyFile), 10456 "-signing-prefs", strconv.Itoa(int(fakeSigAlg1)), 10457 "-signing-prefs", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 10458 "-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 10459 "-signing-prefs", strconv.Itoa(int(fakeSigAlg2)), 10460 }, 10461 expectations: connectionExpectations{ 10462 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10463 }, 10464 }) 10465 10466 // In TLS 1.2 and below, ECDSA uses the curve list rather than the 10467 // signature algorithms. 10468 testCases = append(testCases, testCase{ 10469 name: "CheckLeafCurve", 10470 config: Config{ 10471 MaxVersion: VersionTLS12, 10472 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 10473 Certificates: []Certificate{ecdsaP256Certificate}, 10474 }, 10475 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 10476 shouldFail: true, 10477 expectedError: ":BAD_ECC_CERT:", 10478 }) 10479 10480 // In TLS 1.3, ECDSA does not use the ECDHE curve list. 10481 testCases = append(testCases, testCase{ 10482 name: "CheckLeafCurve-TLS13", 10483 config: Config{ 10484 MaxVersion: VersionTLS13, 10485 Certificates: []Certificate{ecdsaP256Certificate}, 10486 }, 10487 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 10488 }) 10489 10490 // In TLS 1.2, the ECDSA curve is not in the signature algorithm. 10491 testCases = append(testCases, testCase{ 10492 name: "ECDSACurveMismatch-Verify-TLS12", 10493 config: Config{ 10494 MaxVersion: VersionTLS12, 10495 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 10496 Certificates: []Certificate{ecdsaP256Certificate}, 10497 SignSignatureAlgorithms: []signatureAlgorithm{ 10498 signatureECDSAWithP384AndSHA384, 10499 }, 10500 }, 10501 }) 10502 10503 // In TLS 1.3, the ECDSA curve comes from the signature algorithm. 10504 testCases = append(testCases, testCase{ 10505 name: "ECDSACurveMismatch-Verify-TLS13", 10506 config: Config{ 10507 MaxVersion: VersionTLS13, 10508 Certificates: []Certificate{ecdsaP256Certificate}, 10509 SignSignatureAlgorithms: []signatureAlgorithm{ 10510 signatureECDSAWithP384AndSHA384, 10511 }, 10512 Bugs: ProtocolBugs{ 10513 SkipECDSACurveCheck: true, 10514 }, 10515 }, 10516 shouldFail: true, 10517 expectedError: ":WRONG_SIGNATURE_TYPE:", 10518 }) 10519 10520 // Signature algorithm selection in TLS 1.3 should take the curve into 10521 // account. 10522 testCases = append(testCases, testCase{ 10523 testType: serverTest, 10524 name: "ECDSACurveMismatch-Sign-TLS13", 10525 config: Config{ 10526 MaxVersion: VersionTLS13, 10527 VerifySignatureAlgorithms: []signatureAlgorithm{ 10528 signatureECDSAWithP384AndSHA384, 10529 signatureECDSAWithP256AndSHA256, 10530 }, 10531 }, 10532 flags: []string{ 10533 "-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 10534 "-key-file", path.Join(*resourceDir, ecdsaP256KeyFile), 10535 }, 10536 expectations: connectionExpectations{ 10537 peerSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10538 }, 10539 }) 10540 10541 // RSASSA-PSS with SHA-512 is too large for 1024-bit RSA. Test that the 10542 // server does not attempt to sign in that case. 10543 testCases = append(testCases, testCase{ 10544 testType: serverTest, 10545 name: "RSA-PSS-Large", 10546 config: Config{ 10547 MaxVersion: VersionTLS13, 10548 VerifySignatureAlgorithms: []signatureAlgorithm{ 10549 signatureRSAPSSWithSHA512, 10550 }, 10551 }, 10552 flags: []string{ 10553 "-cert-file", path.Join(*resourceDir, rsa1024CertificateFile), 10554 "-key-file", path.Join(*resourceDir, rsa1024KeyFile), 10555 }, 10556 shouldFail: true, 10557 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10558 }) 10559 10560 // Test that RSA-PSS is enabled by default for TLS 1.2. 10561 testCases = append(testCases, testCase{ 10562 testType: clientTest, 10563 name: "RSA-PSS-Default-Verify", 10564 config: Config{ 10565 MaxVersion: VersionTLS12, 10566 SignSignatureAlgorithms: []signatureAlgorithm{ 10567 signatureRSAPSSWithSHA256, 10568 }, 10569 }, 10570 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 10571 }) 10572 10573 testCases = append(testCases, testCase{ 10574 testType: serverTest, 10575 name: "RSA-PSS-Default-Sign", 10576 config: Config{ 10577 MaxVersion: VersionTLS12, 10578 VerifySignatureAlgorithms: []signatureAlgorithm{ 10579 signatureRSAPSSWithSHA256, 10580 }, 10581 }, 10582 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 10583 }) 10584 10585 // TLS 1.1 and below has no way to advertise support for or negotiate 10586 // Ed25519's signature algorithm. 10587 testCases = append(testCases, testCase{ 10588 testType: clientTest, 10589 name: "NoEd25519-TLS11-ServerAuth-Verify", 10590 config: Config{ 10591 MaxVersion: VersionTLS11, 10592 Certificates: []Certificate{ed25519Certificate}, 10593 Bugs: ProtocolBugs{ 10594 // Sign with Ed25519 even though it is TLS 1.1. 10595 UseLegacySigningAlgorithm: signatureEd25519, 10596 }, 10597 }, 10598 flags: []string{"-verify-prefs", strconv.Itoa(int(signatureEd25519))}, 10599 shouldFail: true, 10600 expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:", 10601 }) 10602 testCases = append(testCases, testCase{ 10603 testType: serverTest, 10604 name: "NoEd25519-TLS11-ServerAuth-Sign", 10605 config: Config{ 10606 MaxVersion: VersionTLS11, 10607 }, 10608 flags: []string{ 10609 "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), 10610 "-key-file", path.Join(*resourceDir, ed25519KeyFile), 10611 }, 10612 shouldFail: true, 10613 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10614 }) 10615 testCases = append(testCases, testCase{ 10616 testType: serverTest, 10617 name: "NoEd25519-TLS11-ClientAuth-Verify", 10618 config: Config{ 10619 MaxVersion: VersionTLS11, 10620 Certificates: []Certificate{ed25519Certificate}, 10621 Bugs: ProtocolBugs{ 10622 // Sign with Ed25519 even though it is TLS 1.1. 10623 UseLegacySigningAlgorithm: signatureEd25519, 10624 }, 10625 }, 10626 flags: []string{ 10627 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 10628 "-require-any-client-certificate", 10629 }, 10630 shouldFail: true, 10631 expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:", 10632 }) 10633 testCases = append(testCases, testCase{ 10634 testType: clientTest, 10635 name: "NoEd25519-TLS11-ClientAuth-Sign", 10636 config: Config{ 10637 MaxVersion: VersionTLS11, 10638 ClientAuth: RequireAnyClientCert, 10639 }, 10640 flags: []string{ 10641 "-cert-file", path.Join(*resourceDir, ed25519CertificateFile), 10642 "-key-file", path.Join(*resourceDir, ed25519KeyFile), 10643 }, 10644 shouldFail: true, 10645 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10646 }) 10647 10648 // Test Ed25519 is not advertised by default. 10649 testCases = append(testCases, testCase{ 10650 testType: clientTest, 10651 name: "Ed25519DefaultDisable-NoAdvertise", 10652 config: Config{ 10653 Certificates: []Certificate{ed25519Certificate}, 10654 }, 10655 shouldFail: true, 10656 expectedLocalError: "tls: no common signature algorithms", 10657 }) 10658 10659 // Test Ed25519, when disabled, is not accepted if the peer ignores our 10660 // preferences. 10661 testCases = append(testCases, testCase{ 10662 testType: clientTest, 10663 name: "Ed25519DefaultDisable-NoAccept", 10664 config: Config{ 10665 Certificates: []Certificate{ed25519Certificate}, 10666 Bugs: ProtocolBugs{ 10667 IgnorePeerSignatureAlgorithmPreferences: true, 10668 }, 10669 }, 10670 shouldFail: true, 10671 expectedLocalError: "remote error: illegal parameter", 10672 expectedError: ":WRONG_SIGNATURE_TYPE:", 10673 }) 10674 10675 // Test that configuring verify preferences changes what the client 10676 // advertises. 10677 testCases = append(testCases, testCase{ 10678 name: "VerifyPreferences-Advertised", 10679 config: Config{ 10680 Certificates: []Certificate{rsaCertificate}, 10681 SignSignatureAlgorithms: []signatureAlgorithm{ 10682 signatureRSAPSSWithSHA256, 10683 signatureRSAPSSWithSHA384, 10684 signatureRSAPSSWithSHA512, 10685 }, 10686 }, 10687 flags: []string{ 10688 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10689 "-expect-peer-signature-algorithm", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10690 }, 10691 }) 10692 10693 // Test that the client advertises a set which the runner can find 10694 // nothing in common with. 10695 testCases = append(testCases, testCase{ 10696 name: "VerifyPreferences-NoCommonAlgorithms", 10697 config: Config{ 10698 Certificates: []Certificate{rsaCertificate}, 10699 SignSignatureAlgorithms: []signatureAlgorithm{ 10700 signatureRSAPSSWithSHA256, 10701 signatureRSAPSSWithSHA512, 10702 }, 10703 }, 10704 flags: []string{ 10705 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10706 }, 10707 shouldFail: true, 10708 expectedLocalError: "tls: no common signature algorithms", 10709 }) 10710 10711 // Test that the client enforces its preferences when configured. 10712 testCases = append(testCases, testCase{ 10713 name: "VerifyPreferences-Enforced", 10714 config: Config{ 10715 Certificates: []Certificate{rsaCertificate}, 10716 SignSignatureAlgorithms: []signatureAlgorithm{ 10717 signatureRSAPSSWithSHA256, 10718 signatureRSAPSSWithSHA512, 10719 }, 10720 Bugs: ProtocolBugs{ 10721 IgnorePeerSignatureAlgorithmPreferences: true, 10722 }, 10723 }, 10724 flags: []string{ 10725 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10726 }, 10727 shouldFail: true, 10728 expectedLocalError: "remote error: illegal parameter", 10729 expectedError: ":WRONG_SIGNATURE_TYPE:", 10730 }) 10731 10732 // Test that explicitly configuring Ed25519 is as good as changing the 10733 // boolean toggle. 10734 testCases = append(testCases, testCase{ 10735 name: "VerifyPreferences-Ed25519", 10736 config: Config{ 10737 Certificates: []Certificate{ed25519Certificate}, 10738 }, 10739 flags: []string{ 10740 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 10741 }, 10742 }) 10743} 10744 10745// timeouts is the retransmit schedule for BoringSSL. It doubles and 10746// caps at 60 seconds. On the 13th timeout, it gives up. 10747var timeouts = []time.Duration{ 10748 1 * time.Second, 10749 2 * time.Second, 10750 4 * time.Second, 10751 8 * time.Second, 10752 16 * time.Second, 10753 32 * time.Second, 10754 60 * time.Second, 10755 60 * time.Second, 10756 60 * time.Second, 10757 60 * time.Second, 10758 60 * time.Second, 10759 60 * time.Second, 10760 60 * time.Second, 10761} 10762 10763// shortTimeouts is an alternate set of timeouts which would occur if the 10764// initial timeout duration was set to 250ms. 10765var shortTimeouts = []time.Duration{ 10766 250 * time.Millisecond, 10767 500 * time.Millisecond, 10768 1 * time.Second, 10769 2 * time.Second, 10770 4 * time.Second, 10771 8 * time.Second, 10772 16 * time.Second, 10773 32 * time.Second, 10774 60 * time.Second, 10775 60 * time.Second, 10776 60 * time.Second, 10777 60 * time.Second, 10778 60 * time.Second, 10779} 10780 10781func addDTLSRetransmitTests() { 10782 // These tests work by coordinating some behavior on both the shim and 10783 // the runner. 10784 // 10785 // TimeoutSchedule configures the runner to send a series of timeout 10786 // opcodes to the shim (see packetAdaptor) immediately before reading 10787 // each peer handshake flight N. The timeout opcode both simulates a 10788 // timeout in the shim and acts as a synchronization point to help the 10789 // runner bracket each handshake flight. 10790 // 10791 // We assume the shim does not read from the channel eagerly. It must 10792 // first wait until it has sent flight N and is ready to receive 10793 // handshake flight N+1. At this point, it will process the timeout 10794 // opcode. It must then immediately respond with a timeout ACK and act 10795 // as if the shim was idle for the specified amount of time. 10796 // 10797 // The runner then drops all packets received before the ACK and 10798 // continues waiting for flight N. This ordering results in one attempt 10799 // at sending flight N to be dropped. For the test to complete, the 10800 // shim must send flight N again, testing that the shim implements DTLS 10801 // retransmit on a timeout. 10802 10803 // TODO(davidben): Add DTLS 1.3 versions of these tests. There will 10804 // likely be more epochs to cross and the final message's retransmit may 10805 // be more complex. 10806 10807 // Test that this is indeed the timeout schedule. Stress all 10808 // four patterns of handshake. 10809 for i := 1; i < len(timeouts); i++ { 10810 number := strconv.Itoa(i) 10811 testCases = append(testCases, testCase{ 10812 protocol: dtls, 10813 name: "DTLS-Retransmit-Client-" + number, 10814 config: Config{ 10815 MaxVersion: VersionTLS12, 10816 Bugs: ProtocolBugs{ 10817 TimeoutSchedule: timeouts[:i], 10818 }, 10819 }, 10820 resumeSession: true, 10821 flags: []string{"-async"}, 10822 }) 10823 testCases = append(testCases, testCase{ 10824 protocol: dtls, 10825 testType: serverTest, 10826 name: "DTLS-Retransmit-Server-" + number, 10827 config: Config{ 10828 MaxVersion: VersionTLS12, 10829 Bugs: ProtocolBugs{ 10830 TimeoutSchedule: timeouts[:i], 10831 }, 10832 }, 10833 resumeSession: true, 10834 flags: []string{"-async"}, 10835 }) 10836 } 10837 10838 // Test that exceeding the timeout schedule hits a read 10839 // timeout. 10840 testCases = append(testCases, testCase{ 10841 protocol: dtls, 10842 name: "DTLS-Retransmit-Timeout", 10843 config: Config{ 10844 MaxVersion: VersionTLS12, 10845 Bugs: ProtocolBugs{ 10846 TimeoutSchedule: timeouts, 10847 }, 10848 }, 10849 resumeSession: true, 10850 flags: []string{"-async"}, 10851 shouldFail: true, 10852 expectedError: ":READ_TIMEOUT_EXPIRED:", 10853 }) 10854 10855 // Test that timeout handling has a fudge factor, due to API 10856 // problems. 10857 testCases = append(testCases, testCase{ 10858 protocol: dtls, 10859 name: "DTLS-Retransmit-Fudge", 10860 config: Config{ 10861 MaxVersion: VersionTLS12, 10862 Bugs: ProtocolBugs{ 10863 TimeoutSchedule: []time.Duration{ 10864 timeouts[0] - 10*time.Millisecond, 10865 }, 10866 }, 10867 }, 10868 resumeSession: true, 10869 flags: []string{"-async"}, 10870 }) 10871 10872 // Test that the final Finished retransmitting isn't 10873 // duplicated if the peer badly fragments everything. 10874 testCases = append(testCases, testCase{ 10875 testType: serverTest, 10876 protocol: dtls, 10877 name: "DTLS-Retransmit-Fragmented", 10878 config: Config{ 10879 MaxVersion: VersionTLS12, 10880 Bugs: ProtocolBugs{ 10881 TimeoutSchedule: []time.Duration{timeouts[0]}, 10882 MaxHandshakeRecordLength: 2, 10883 }, 10884 }, 10885 flags: []string{"-async"}, 10886 }) 10887 10888 // Test the timeout schedule when a shorter initial timeout duration is set. 10889 testCases = append(testCases, testCase{ 10890 protocol: dtls, 10891 name: "DTLS-Retransmit-Short-Client", 10892 config: Config{ 10893 MaxVersion: VersionTLS12, 10894 Bugs: ProtocolBugs{ 10895 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1], 10896 }, 10897 }, 10898 resumeSession: true, 10899 flags: []string{ 10900 "-async", 10901 "-initial-timeout-duration-ms", "250", 10902 }, 10903 }) 10904 testCases = append(testCases, testCase{ 10905 protocol: dtls, 10906 testType: serverTest, 10907 name: "DTLS-Retransmit-Short-Server", 10908 config: Config{ 10909 MaxVersion: VersionTLS12, 10910 Bugs: ProtocolBugs{ 10911 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1], 10912 }, 10913 }, 10914 resumeSession: true, 10915 flags: []string{ 10916 "-async", 10917 "-initial-timeout-duration-ms", "250", 10918 }, 10919 }) 10920 10921 // If the shim sends the last Finished (server full or client resume 10922 // handshakes), it must retransmit that Finished when it sees a 10923 // post-handshake penultimate Finished from the runner. The above tests 10924 // cover this. Conversely, if the shim sends the penultimate Finished 10925 // (client full or server resume), test that it does not retransmit. 10926 testCases = append(testCases, testCase{ 10927 protocol: dtls, 10928 testType: clientTest, 10929 name: "DTLS-StrayRetransmitFinished-ClientFull", 10930 config: Config{ 10931 MaxVersion: VersionTLS12, 10932 Bugs: ProtocolBugs{ 10933 RetransmitFinished: true, 10934 }, 10935 }, 10936 }) 10937 testCases = append(testCases, testCase{ 10938 protocol: dtls, 10939 testType: serverTest, 10940 name: "DTLS-StrayRetransmitFinished-ServerResume", 10941 config: Config{ 10942 MaxVersion: VersionTLS12, 10943 }, 10944 resumeConfig: &Config{ 10945 MaxVersion: VersionTLS12, 10946 Bugs: ProtocolBugs{ 10947 RetransmitFinished: true, 10948 }, 10949 }, 10950 resumeSession: true, 10951 }) 10952} 10953 10954func addExportKeyingMaterialTests() { 10955 for _, vers := range tlsVersions { 10956 testCases = append(testCases, testCase{ 10957 name: "ExportKeyingMaterial-" + vers.name, 10958 config: Config{ 10959 MaxVersion: vers.version, 10960 }, 10961 // Test the exporter in both initial and resumption 10962 // handshakes. 10963 resumeSession: true, 10964 exportKeyingMaterial: 1024, 10965 exportLabel: "label", 10966 exportContext: "context", 10967 useExportContext: true, 10968 }) 10969 testCases = append(testCases, testCase{ 10970 name: "ExportKeyingMaterial-NoContext-" + vers.name, 10971 config: Config{ 10972 MaxVersion: vers.version, 10973 }, 10974 exportKeyingMaterial: 1024, 10975 }) 10976 testCases = append(testCases, testCase{ 10977 name: "ExportKeyingMaterial-EmptyContext-" + vers.name, 10978 config: Config{ 10979 MaxVersion: vers.version, 10980 }, 10981 exportKeyingMaterial: 1024, 10982 useExportContext: true, 10983 }) 10984 testCases = append(testCases, testCase{ 10985 name: "ExportKeyingMaterial-Small-" + vers.name, 10986 config: Config{ 10987 MaxVersion: vers.version, 10988 }, 10989 exportKeyingMaterial: 1, 10990 exportLabel: "label", 10991 exportContext: "context", 10992 useExportContext: true, 10993 }) 10994 10995 if vers.version >= VersionTLS13 { 10996 // Test the exporters do not work while the client is 10997 // sending 0-RTT data. 10998 testCases = append(testCases, testCase{ 10999 name: "NoEarlyKeyingMaterial-Client-InEarlyData-" + vers.name, 11000 config: Config{ 11001 MaxVersion: vers.version, 11002 }, 11003 resumeSession: true, 11004 earlyData: true, 11005 flags: []string{ 11006 "-on-resume-export-keying-material", "1024", 11007 "-on-resume-export-label", "label", 11008 "-on-resume-export-context", "context", 11009 }, 11010 shouldFail: true, 11011 expectedError: ":HANDSHAKE_NOT_COMPLETE:", 11012 }) 11013 11014 // Test the normal exporter on the server in half-RTT. 11015 testCases = append(testCases, testCase{ 11016 testType: serverTest, 11017 name: "ExportKeyingMaterial-Server-HalfRTT-" + vers.name, 11018 config: Config{ 11019 MaxVersion: vers.version, 11020 Bugs: ProtocolBugs{ 11021 // The shim writes exported data immediately after 11022 // the handshake returns, so disable the built-in 11023 // early data test. 11024 SendEarlyData: [][]byte{}, 11025 ExpectHalfRTTData: [][]byte{}, 11026 }, 11027 }, 11028 resumeSession: true, 11029 earlyData: true, 11030 exportKeyingMaterial: 1024, 11031 exportLabel: "label", 11032 exportContext: "context", 11033 useExportContext: true, 11034 }) 11035 } 11036 } 11037 11038 // Exporters work during a False Start. 11039 testCases = append(testCases, testCase{ 11040 name: "ExportKeyingMaterial-FalseStart", 11041 config: Config{ 11042 MaxVersion: VersionTLS12, 11043 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11044 NextProtos: []string{"foo"}, 11045 Bugs: ProtocolBugs{ 11046 ExpectFalseStart: true, 11047 }, 11048 }, 11049 flags: []string{ 11050 "-false-start", 11051 "-advertise-alpn", "\x03foo", 11052 "-expect-alpn", "foo", 11053 }, 11054 shimWritesFirst: true, 11055 exportKeyingMaterial: 1024, 11056 exportLabel: "label", 11057 exportContext: "context", 11058 useExportContext: true, 11059 }) 11060 11061 // Exporters do not work in the middle of a renegotiation. Test this by 11062 // triggering the exporter after every SSL_read call and configuring the 11063 // shim to run asynchronously. 11064 testCases = append(testCases, testCase{ 11065 name: "ExportKeyingMaterial-Renegotiate", 11066 config: Config{ 11067 MaxVersion: VersionTLS12, 11068 }, 11069 renegotiate: 1, 11070 flags: []string{ 11071 "-async", 11072 "-use-exporter-between-reads", 11073 "-renegotiate-freely", 11074 "-expect-total-renegotiations", "1", 11075 }, 11076 shouldFail: true, 11077 expectedError: "failed to export keying material", 11078 }) 11079} 11080 11081func addExportTrafficSecretsTests() { 11082 for _, cipherSuite := range []testCipherSuite{ 11083 // Test a SHA-256 and SHA-384 based cipher suite. 11084 {"AEAD-AES128-GCM-SHA256", TLS_AES_128_GCM_SHA256}, 11085 {"AEAD-AES256-GCM-SHA384", TLS_AES_256_GCM_SHA384}, 11086 } { 11087 11088 testCases = append(testCases, testCase{ 11089 name: "ExportTrafficSecrets-" + cipherSuite.name, 11090 config: Config{ 11091 MinVersion: VersionTLS13, 11092 CipherSuites: []uint16{cipherSuite.id}, 11093 }, 11094 exportTrafficSecrets: true, 11095 }) 11096 } 11097} 11098 11099func addTLSUniqueTests() { 11100 for _, isClient := range []bool{false, true} { 11101 for _, isResumption := range []bool{false, true} { 11102 for _, hasEMS := range []bool{false, true} { 11103 var suffix string 11104 if isResumption { 11105 suffix = "Resume-" 11106 } else { 11107 suffix = "Full-" 11108 } 11109 11110 if hasEMS { 11111 suffix += "EMS-" 11112 } else { 11113 suffix += "NoEMS-" 11114 } 11115 11116 if isClient { 11117 suffix += "Client" 11118 } else { 11119 suffix += "Server" 11120 } 11121 11122 test := testCase{ 11123 name: "TLSUnique-" + suffix, 11124 testTLSUnique: true, 11125 config: Config{ 11126 MaxVersion: VersionTLS12, 11127 Bugs: ProtocolBugs{ 11128 NoExtendedMasterSecret: !hasEMS, 11129 }, 11130 }, 11131 } 11132 11133 if isResumption { 11134 test.resumeSession = true 11135 test.resumeConfig = &Config{ 11136 MaxVersion: VersionTLS12, 11137 Bugs: ProtocolBugs{ 11138 NoExtendedMasterSecret: !hasEMS, 11139 }, 11140 } 11141 } 11142 11143 if isResumption && !hasEMS { 11144 test.shouldFail = true 11145 test.expectedError = "failed to get tls-unique" 11146 } 11147 11148 testCases = append(testCases, test) 11149 } 11150 } 11151 } 11152} 11153 11154func addCustomExtensionTests() { 11155 // Test an unknown extension from the server. 11156 testCases = append(testCases, testCase{ 11157 testType: clientTest, 11158 name: "UnknownExtension-Client", 11159 config: Config{ 11160 MaxVersion: VersionTLS12, 11161 Bugs: ProtocolBugs{ 11162 CustomExtension: "custom extension", 11163 }, 11164 }, 11165 shouldFail: true, 11166 expectedError: ":UNEXPECTED_EXTENSION:", 11167 expectedLocalError: "remote error: unsupported extension", 11168 }) 11169 testCases = append(testCases, testCase{ 11170 testType: clientTest, 11171 name: "UnknownExtension-Client-TLS13", 11172 config: Config{ 11173 MaxVersion: VersionTLS13, 11174 Bugs: ProtocolBugs{ 11175 CustomExtension: "custom extension", 11176 }, 11177 }, 11178 shouldFail: true, 11179 expectedError: ":UNEXPECTED_EXTENSION:", 11180 expectedLocalError: "remote error: unsupported extension", 11181 }) 11182 testCases = append(testCases, testCase{ 11183 testType: clientTest, 11184 name: "UnknownUnencryptedExtension-Client-TLS13", 11185 config: Config{ 11186 MaxVersion: VersionTLS13, 11187 Bugs: ProtocolBugs{ 11188 CustomUnencryptedExtension: "custom extension", 11189 }, 11190 }, 11191 shouldFail: true, 11192 expectedError: ":UNEXPECTED_EXTENSION:", 11193 // The shim must send an alert, but alerts at this point do not 11194 // get successfully decrypted by the runner. 11195 expectedLocalError: "local error: bad record MAC", 11196 }) 11197 testCases = append(testCases, testCase{ 11198 testType: clientTest, 11199 name: "UnexpectedUnencryptedExtension-Client-TLS13", 11200 config: Config{ 11201 MaxVersion: VersionTLS13, 11202 Bugs: ProtocolBugs{ 11203 SendUnencryptedALPN: "foo", 11204 }, 11205 }, 11206 flags: []string{ 11207 "-advertise-alpn", "\x03foo\x03bar", 11208 }, 11209 shouldFail: true, 11210 expectedError: ":UNEXPECTED_EXTENSION:", 11211 // The shim must send an alert, but alerts at this point do not 11212 // get successfully decrypted by the runner. 11213 expectedLocalError: "local error: bad record MAC", 11214 }) 11215 11216 // Test a known but unoffered extension from the server. 11217 testCases = append(testCases, testCase{ 11218 testType: clientTest, 11219 name: "UnofferedExtension-Client", 11220 config: Config{ 11221 MaxVersion: VersionTLS12, 11222 Bugs: ProtocolBugs{ 11223 SendALPN: "alpn", 11224 }, 11225 }, 11226 shouldFail: true, 11227 expectedError: ":UNEXPECTED_EXTENSION:", 11228 expectedLocalError: "remote error: unsupported extension", 11229 }) 11230 testCases = append(testCases, testCase{ 11231 testType: clientTest, 11232 name: "UnofferedExtension-Client-TLS13", 11233 config: Config{ 11234 MaxVersion: VersionTLS13, 11235 Bugs: ProtocolBugs{ 11236 SendALPN: "alpn", 11237 }, 11238 }, 11239 shouldFail: true, 11240 expectedError: ":UNEXPECTED_EXTENSION:", 11241 expectedLocalError: "remote error: unsupported extension", 11242 }) 11243} 11244 11245func addRSAClientKeyExchangeTests() { 11246 for bad := RSABadValue(1); bad < NumRSABadValues; bad++ { 11247 testCases = append(testCases, testCase{ 11248 testType: serverTest, 11249 name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad), 11250 config: Config{ 11251 // Ensure the ClientHello version and final 11252 // version are different, to detect if the 11253 // server uses the wrong one. 11254 MaxVersion: VersionTLS11, 11255 CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 11256 Bugs: ProtocolBugs{ 11257 BadRSAClientKeyExchange: bad, 11258 }, 11259 }, 11260 shouldFail: true, 11261 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 11262 }) 11263 } 11264 11265 // The server must compare whatever was in ClientHello.version for the 11266 // RSA premaster. 11267 testCases = append(testCases, testCase{ 11268 testType: serverTest, 11269 name: "SendClientVersion-RSA", 11270 config: Config{ 11271 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 11272 Bugs: ProtocolBugs{ 11273 SendClientVersion: 0x1234, 11274 }, 11275 }, 11276 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 11277 }) 11278} 11279 11280var testCurves = []struct { 11281 name string 11282 id CurveID 11283}{ 11284 {"P-224", CurveP224}, 11285 {"P-256", CurveP256}, 11286 {"P-384", CurveP384}, 11287 {"P-521", CurveP521}, 11288 {"X25519", CurveX25519}, 11289 {"CECPQ2", CurveCECPQ2}, 11290} 11291 11292const bogusCurve = 0x1234 11293 11294func isPqGroup(r CurveID) bool { 11295 return r == CurveCECPQ2 11296} 11297 11298func addCurveTests() { 11299 for _, curve := range testCurves { 11300 for _, ver := range tlsVersions { 11301 if isPqGroup(curve.id) && ver.version < VersionTLS13 { 11302 continue 11303 } 11304 11305 suffix := curve.name + "-" + ver.name 11306 11307 testCases = append(testCases, testCase{ 11308 name: "CurveTest-Client-" + suffix, 11309 config: Config{ 11310 MaxVersion: ver.version, 11311 CipherSuites: []uint16{ 11312 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11313 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11314 TLS_AES_256_GCM_SHA384, 11315 }, 11316 CurvePreferences: []CurveID{curve.id}, 11317 }, 11318 flags: append( 11319 []string{"-expect-curve-id", strconv.Itoa(int(curve.id))}, 11320 flagInts("-curves", shimConfig.AllCurves)..., 11321 ), 11322 expectations: connectionExpectations{ 11323 curveID: curve.id, 11324 }, 11325 }) 11326 testCases = append(testCases, testCase{ 11327 testType: serverTest, 11328 name: "CurveTest-Server-" + suffix, 11329 config: Config{ 11330 MaxVersion: ver.version, 11331 CipherSuites: []uint16{ 11332 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11333 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11334 TLS_AES_256_GCM_SHA384, 11335 }, 11336 CurvePreferences: []CurveID{curve.id}, 11337 }, 11338 flags: append( 11339 []string{"-expect-curve-id", strconv.Itoa(int(curve.id))}, 11340 flagInts("-curves", shimConfig.AllCurves)..., 11341 ), 11342 expectations: connectionExpectations{ 11343 curveID: curve.id, 11344 }, 11345 }) 11346 11347 if curve.id != CurveX25519 && !isPqGroup(curve.id) { 11348 testCases = append(testCases, testCase{ 11349 name: "CurveTest-Client-Compressed-" + suffix, 11350 config: Config{ 11351 MaxVersion: ver.version, 11352 CipherSuites: []uint16{ 11353 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11354 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11355 TLS_AES_256_GCM_SHA384, 11356 }, 11357 CurvePreferences: []CurveID{curve.id}, 11358 Bugs: ProtocolBugs{ 11359 SendCompressedCoordinates: true, 11360 }, 11361 }, 11362 flags: flagInts("-curves", shimConfig.AllCurves), 11363 shouldFail: true, 11364 expectedError: ":BAD_ECPOINT:", 11365 }) 11366 testCases = append(testCases, testCase{ 11367 testType: serverTest, 11368 name: "CurveTest-Server-Compressed-" + suffix, 11369 config: Config{ 11370 MaxVersion: ver.version, 11371 CipherSuites: []uint16{ 11372 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11373 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11374 TLS_AES_256_GCM_SHA384, 11375 }, 11376 CurvePreferences: []CurveID{curve.id}, 11377 Bugs: ProtocolBugs{ 11378 SendCompressedCoordinates: true, 11379 }, 11380 }, 11381 flags: flagInts("-curves", shimConfig.AllCurves), 11382 shouldFail: true, 11383 expectedError: ":BAD_ECPOINT:", 11384 }) 11385 } 11386 } 11387 } 11388 11389 // The server must be tolerant to bogus curves. 11390 testCases = append(testCases, testCase{ 11391 testType: serverTest, 11392 name: "UnknownCurve", 11393 config: Config{ 11394 MaxVersion: VersionTLS12, 11395 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11396 CurvePreferences: []CurveID{bogusCurve, CurveP256}, 11397 }, 11398 }) 11399 11400 // The server must be tolerant to bogus curves. 11401 testCases = append(testCases, testCase{ 11402 testType: serverTest, 11403 name: "UnknownCurve-TLS13", 11404 config: Config{ 11405 MaxVersion: VersionTLS13, 11406 CurvePreferences: []CurveID{bogusCurve, CurveP256}, 11407 }, 11408 }) 11409 11410 // The server must not consider ECDHE ciphers when there are no 11411 // supported curves. 11412 testCases = append(testCases, testCase{ 11413 testType: serverTest, 11414 name: "NoSupportedCurves", 11415 config: Config{ 11416 MaxVersion: VersionTLS12, 11417 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11418 Bugs: ProtocolBugs{ 11419 NoSupportedCurves: true, 11420 }, 11421 }, 11422 shouldFail: true, 11423 expectedError: ":NO_SHARED_CIPHER:", 11424 }) 11425 testCases = append(testCases, testCase{ 11426 testType: serverTest, 11427 name: "NoSupportedCurves-TLS13", 11428 config: Config{ 11429 MaxVersion: VersionTLS13, 11430 Bugs: ProtocolBugs{ 11431 NoSupportedCurves: true, 11432 }, 11433 }, 11434 shouldFail: true, 11435 expectedError: ":NO_SHARED_GROUP:", 11436 }) 11437 11438 // The server must fall back to another cipher when there are no 11439 // supported curves. 11440 testCases = append(testCases, testCase{ 11441 testType: serverTest, 11442 name: "NoCommonCurves", 11443 config: Config{ 11444 MaxVersion: VersionTLS12, 11445 CipherSuites: []uint16{ 11446 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11447 TLS_RSA_WITH_AES_128_GCM_SHA256, 11448 }, 11449 CurvePreferences: []CurveID{CurveP224}, 11450 }, 11451 expectations: connectionExpectations{ 11452 cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, 11453 }, 11454 }) 11455 11456 // The client must reject bogus curves and disabled curves. 11457 testCases = append(testCases, testCase{ 11458 name: "BadECDHECurve", 11459 config: Config{ 11460 MaxVersion: VersionTLS12, 11461 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11462 Bugs: ProtocolBugs{ 11463 SendCurve: bogusCurve, 11464 }, 11465 }, 11466 shouldFail: true, 11467 expectedError: ":WRONG_CURVE:", 11468 }) 11469 testCases = append(testCases, testCase{ 11470 name: "BadECDHECurve-TLS13", 11471 config: Config{ 11472 MaxVersion: VersionTLS13, 11473 Bugs: ProtocolBugs{ 11474 SendCurve: bogusCurve, 11475 }, 11476 }, 11477 shouldFail: true, 11478 expectedError: ":WRONG_CURVE:", 11479 }) 11480 11481 testCases = append(testCases, testCase{ 11482 name: "UnsupportedCurve", 11483 config: Config{ 11484 MaxVersion: VersionTLS12, 11485 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11486 CurvePreferences: []CurveID{CurveP256}, 11487 Bugs: ProtocolBugs{ 11488 IgnorePeerCurvePreferences: true, 11489 }, 11490 }, 11491 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 11492 shouldFail: true, 11493 expectedError: ":WRONG_CURVE:", 11494 }) 11495 11496 testCases = append(testCases, testCase{ 11497 // TODO(davidben): Add a TLS 1.3 version where 11498 // HelloRetryRequest requests an unsupported curve. 11499 name: "UnsupportedCurve-ServerHello-TLS13", 11500 config: Config{ 11501 MaxVersion: VersionTLS13, 11502 CurvePreferences: []CurveID{CurveP384}, 11503 Bugs: ProtocolBugs{ 11504 SendCurve: CurveP256, 11505 }, 11506 }, 11507 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 11508 shouldFail: true, 11509 expectedError: ":WRONG_CURVE:", 11510 }) 11511 11512 // Test invalid curve points. 11513 testCases = append(testCases, testCase{ 11514 name: "InvalidECDHPoint-Client", 11515 config: Config{ 11516 MaxVersion: VersionTLS12, 11517 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11518 CurvePreferences: []CurveID{CurveP256}, 11519 Bugs: ProtocolBugs{ 11520 InvalidECDHPoint: true, 11521 }, 11522 }, 11523 shouldFail: true, 11524 expectedError: ":BAD_ECPOINT:", 11525 }) 11526 testCases = append(testCases, testCase{ 11527 name: "InvalidECDHPoint-Client-TLS13", 11528 config: Config{ 11529 MaxVersion: VersionTLS13, 11530 CurvePreferences: []CurveID{CurveP256}, 11531 Bugs: ProtocolBugs{ 11532 InvalidECDHPoint: true, 11533 }, 11534 }, 11535 shouldFail: true, 11536 expectedError: ":BAD_ECPOINT:", 11537 }) 11538 testCases = append(testCases, testCase{ 11539 testType: serverTest, 11540 name: "InvalidECDHPoint-Server", 11541 config: Config{ 11542 MaxVersion: VersionTLS12, 11543 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11544 CurvePreferences: []CurveID{CurveP256}, 11545 Bugs: ProtocolBugs{ 11546 InvalidECDHPoint: true, 11547 }, 11548 }, 11549 shouldFail: true, 11550 expectedError: ":BAD_ECPOINT:", 11551 }) 11552 testCases = append(testCases, testCase{ 11553 testType: serverTest, 11554 name: "InvalidECDHPoint-Server-TLS13", 11555 config: Config{ 11556 MaxVersion: VersionTLS13, 11557 CurvePreferences: []CurveID{CurveP256}, 11558 Bugs: ProtocolBugs{ 11559 InvalidECDHPoint: true, 11560 }, 11561 }, 11562 shouldFail: true, 11563 expectedError: ":BAD_ECPOINT:", 11564 }) 11565 11566 // The previous curve ID should be reported on TLS 1.2 resumption. 11567 testCases = append(testCases, testCase{ 11568 name: "CurveID-Resume-Client", 11569 config: Config{ 11570 MaxVersion: VersionTLS12, 11571 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11572 CurvePreferences: []CurveID{CurveX25519}, 11573 }, 11574 flags: []string{"-expect-curve-id", strconv.Itoa(int(CurveX25519))}, 11575 resumeSession: true, 11576 }) 11577 testCases = append(testCases, testCase{ 11578 testType: serverTest, 11579 name: "CurveID-Resume-Server", 11580 config: Config{ 11581 MaxVersion: VersionTLS12, 11582 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11583 CurvePreferences: []CurveID{CurveX25519}, 11584 }, 11585 flags: []string{"-expect-curve-id", strconv.Itoa(int(CurveX25519))}, 11586 resumeSession: true, 11587 }) 11588 11589 // TLS 1.3 allows resuming at a differet curve. If this happens, the new 11590 // one should be reported. 11591 testCases = append(testCases, testCase{ 11592 name: "CurveID-Resume-Client-TLS13", 11593 config: Config{ 11594 MaxVersion: VersionTLS13, 11595 CurvePreferences: []CurveID{CurveX25519}, 11596 }, 11597 resumeConfig: &Config{ 11598 MaxVersion: VersionTLS13, 11599 CurvePreferences: []CurveID{CurveP256}, 11600 }, 11601 flags: []string{ 11602 "-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)), 11603 "-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)), 11604 }, 11605 resumeSession: true, 11606 }) 11607 testCases = append(testCases, testCase{ 11608 testType: serverTest, 11609 name: "CurveID-Resume-Server-TLS13", 11610 config: Config{ 11611 MaxVersion: VersionTLS13, 11612 CurvePreferences: []CurveID{CurveX25519}, 11613 }, 11614 resumeConfig: &Config{ 11615 MaxVersion: VersionTLS13, 11616 CurvePreferences: []CurveID{CurveP256}, 11617 }, 11618 flags: []string{ 11619 "-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)), 11620 "-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)), 11621 }, 11622 resumeSession: true, 11623 }) 11624 11625 // Server-sent point formats are legal in TLS 1.2, but not in TLS 1.3. 11626 testCases = append(testCases, testCase{ 11627 name: "PointFormat-ServerHello-TLS12", 11628 config: Config{ 11629 MaxVersion: VersionTLS12, 11630 Bugs: ProtocolBugs{ 11631 SendSupportedPointFormats: []byte{pointFormatUncompressed}, 11632 }, 11633 }, 11634 }) 11635 testCases = append(testCases, testCase{ 11636 name: "PointFormat-EncryptedExtensions-TLS13", 11637 config: Config{ 11638 MaxVersion: VersionTLS13, 11639 Bugs: ProtocolBugs{ 11640 SendSupportedPointFormats: []byte{pointFormatUncompressed}, 11641 }, 11642 }, 11643 shouldFail: true, 11644 expectedError: ":ERROR_PARSING_EXTENSION:", 11645 }) 11646 11647 // Server-sent supported groups/curves are legal in TLS 1.3. They are 11648 // illegal in TLS 1.2, but some servers send them anyway, so we must 11649 // tolerate them. 11650 testCases = append(testCases, testCase{ 11651 name: "SupportedCurves-ServerHello-TLS12", 11652 config: Config{ 11653 MaxVersion: VersionTLS12, 11654 Bugs: ProtocolBugs{ 11655 SendServerSupportedCurves: true, 11656 }, 11657 }, 11658 }) 11659 testCases = append(testCases, testCase{ 11660 name: "SupportedCurves-EncryptedExtensions-TLS13", 11661 config: Config{ 11662 MaxVersion: VersionTLS13, 11663 Bugs: ProtocolBugs{ 11664 SendServerSupportedCurves: true, 11665 }, 11666 }, 11667 }) 11668 11669 // Test that we tolerate unknown point formats, as long as 11670 // pointFormatUncompressed is present. Limit ciphers to ECDHE ciphers to 11671 // check they are still functional. 11672 testCases = append(testCases, testCase{ 11673 name: "PointFormat-Client-Tolerance", 11674 config: Config{ 11675 MaxVersion: VersionTLS12, 11676 Bugs: ProtocolBugs{ 11677 SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime}, 11678 }, 11679 }, 11680 }) 11681 testCases = append(testCases, testCase{ 11682 testType: serverTest, 11683 name: "PointFormat-Server-Tolerance", 11684 config: Config{ 11685 MaxVersion: VersionTLS12, 11686 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 11687 Bugs: ProtocolBugs{ 11688 SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime}, 11689 }, 11690 }, 11691 }) 11692 11693 // Test TLS 1.2 does not require the point format extension to be 11694 // present. 11695 testCases = append(testCases, testCase{ 11696 name: "PointFormat-Client-Missing", 11697 config: Config{ 11698 MaxVersion: VersionTLS12, 11699 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 11700 Bugs: ProtocolBugs{ 11701 SendSupportedPointFormats: []byte{}, 11702 }, 11703 }, 11704 }) 11705 testCases = append(testCases, testCase{ 11706 testType: serverTest, 11707 name: "PointFormat-Server-Missing", 11708 config: Config{ 11709 MaxVersion: VersionTLS12, 11710 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 11711 Bugs: ProtocolBugs{ 11712 SendSupportedPointFormats: []byte{}, 11713 }, 11714 }, 11715 }) 11716 11717 // If the point format extension is present, uncompressed points must be 11718 // offered. BoringSSL requires this whether or not ECDHE is used. 11719 testCases = append(testCases, testCase{ 11720 name: "PointFormat-Client-MissingUncompressed", 11721 config: Config{ 11722 MaxVersion: VersionTLS12, 11723 Bugs: ProtocolBugs{ 11724 SendSupportedPointFormats: []byte{pointFormatCompressedPrime}, 11725 }, 11726 }, 11727 shouldFail: true, 11728 expectedError: ":ERROR_PARSING_EXTENSION:", 11729 }) 11730 testCases = append(testCases, testCase{ 11731 testType: serverTest, 11732 name: "PointFormat-Server-MissingUncompressed", 11733 config: Config{ 11734 MaxVersion: VersionTLS12, 11735 Bugs: ProtocolBugs{ 11736 SendSupportedPointFormats: []byte{pointFormatCompressedPrime}, 11737 }, 11738 }, 11739 shouldFail: true, 11740 expectedError: ":ERROR_PARSING_EXTENSION:", 11741 }) 11742 11743 // Implementations should mask off the high order bit in X25519. 11744 testCases = append(testCases, testCase{ 11745 name: "SetX25519HighBit", 11746 config: Config{ 11747 CipherSuites: []uint16{ 11748 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11749 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11750 TLS_AES_128_GCM_SHA256, 11751 }, 11752 CurvePreferences: []CurveID{CurveX25519}, 11753 Bugs: ProtocolBugs{ 11754 SetX25519HighBit: true, 11755 }, 11756 }, 11757 }) 11758 11759 // CECPQ2 should not be offered by a TLS < 1.3 client. 11760 testCases = append(testCases, testCase{ 11761 name: "CECPQ2NotInTLS12", 11762 config: Config{ 11763 Bugs: ProtocolBugs{ 11764 FailIfCECPQ2Offered: true, 11765 }, 11766 }, 11767 flags: []string{ 11768 "-max-version", strconv.Itoa(VersionTLS12), 11769 "-curves", strconv.Itoa(int(CurveCECPQ2)), 11770 "-curves", strconv.Itoa(int(CurveX25519)), 11771 }, 11772 }) 11773 11774 // CECPQ2 should not crash a TLS < 1.3 client if the server mistakenly 11775 // selects it. 11776 testCases = append(testCases, testCase{ 11777 name: "CECPQ2NotAcceptedByTLS12Client", 11778 config: Config{ 11779 Bugs: ProtocolBugs{ 11780 SendCurve: CurveCECPQ2, 11781 }, 11782 }, 11783 flags: []string{ 11784 "-max-version", strconv.Itoa(VersionTLS12), 11785 "-curves", strconv.Itoa(int(CurveCECPQ2)), 11786 "-curves", strconv.Itoa(int(CurveX25519)), 11787 }, 11788 shouldFail: true, 11789 expectedError: ":WRONG_CURVE:", 11790 }) 11791 11792 // CECPQ2 should not be offered by default as a client. 11793 testCases = append(testCases, testCase{ 11794 name: "CECPQ2NotEnabledByDefaultInClients", 11795 config: Config{ 11796 MinVersion: VersionTLS13, 11797 Bugs: ProtocolBugs{ 11798 FailIfCECPQ2Offered: true, 11799 }, 11800 }, 11801 }) 11802 11803 // If CECPQ2 is offered, both X25519 and CECPQ2 should have a key-share. 11804 testCases = append(testCases, testCase{ 11805 name: "NotJustCECPQ2KeyShare", 11806 config: Config{ 11807 MinVersion: VersionTLS13, 11808 Bugs: ProtocolBugs{ 11809 ExpectedKeyShares: []CurveID{CurveCECPQ2, CurveX25519}, 11810 }, 11811 }, 11812 flags: []string{ 11813 "-curves", strconv.Itoa(int(CurveCECPQ2)), 11814 "-curves", strconv.Itoa(int(CurveX25519)), 11815 "-expect-curve-id", strconv.Itoa(int(CurveCECPQ2)), 11816 }, 11817 }) 11818 11819 // ... but only if CECPQ2 is listed first. 11820 testCases = append(testCases, testCase{ 11821 name: "CECPQ2KeyShareNotIncludedSecond", 11822 config: Config{ 11823 MinVersion: VersionTLS13, 11824 Bugs: ProtocolBugs{ 11825 ExpectedKeyShares: []CurveID{CurveX25519}, 11826 }, 11827 }, 11828 flags: []string{ 11829 "-curves", strconv.Itoa(int(CurveX25519)), 11830 "-curves", strconv.Itoa(int(CurveCECPQ2)), 11831 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 11832 }, 11833 }) 11834 11835 // If CECPQ2 is the only configured curve, the key share is sent. 11836 testCases = append(testCases, testCase{ 11837 name: "JustConfiguringCECPQ2Works", 11838 config: Config{ 11839 MinVersion: VersionTLS13, 11840 Bugs: ProtocolBugs{ 11841 ExpectedKeyShares: []CurveID{CurveCECPQ2}, 11842 }, 11843 }, 11844 flags: []string{ 11845 "-curves", strconv.Itoa(int(CurveCECPQ2)), 11846 "-expect-curve-id", strconv.Itoa(int(CurveCECPQ2)), 11847 }, 11848 }) 11849 11850 // As a server, CECPQ2 is not yet supported by default. 11851 testCases = append(testCases, testCase{ 11852 testType: serverTest, 11853 name: "CECPQ2NotEnabledByDefaultForAServer", 11854 config: Config{ 11855 MinVersion: VersionTLS13, 11856 CurvePreferences: []CurveID{CurveCECPQ2, CurveX25519}, 11857 DefaultCurves: []CurveID{CurveCECPQ2}, 11858 }, 11859 flags: []string{ 11860 "-server-preference", 11861 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 11862 }, 11863 }) 11864} 11865 11866func addTLS13RecordTests() { 11867 testCases = append(testCases, testCase{ 11868 name: "TLS13-RecordPadding", 11869 config: Config{ 11870 MaxVersion: VersionTLS13, 11871 MinVersion: VersionTLS13, 11872 Bugs: ProtocolBugs{ 11873 RecordPadding: 10, 11874 }, 11875 }, 11876 }) 11877 11878 testCases = append(testCases, testCase{ 11879 name: "TLS13-EmptyRecords", 11880 config: Config{ 11881 MaxVersion: VersionTLS13, 11882 MinVersion: VersionTLS13, 11883 Bugs: ProtocolBugs{ 11884 OmitRecordContents: true, 11885 }, 11886 }, 11887 shouldFail: true, 11888 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 11889 }) 11890 11891 testCases = append(testCases, testCase{ 11892 name: "TLS13-OnlyPadding", 11893 config: Config{ 11894 MaxVersion: VersionTLS13, 11895 MinVersion: VersionTLS13, 11896 Bugs: ProtocolBugs{ 11897 OmitRecordContents: true, 11898 RecordPadding: 10, 11899 }, 11900 }, 11901 shouldFail: true, 11902 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 11903 }) 11904 11905 testCases = append(testCases, testCase{ 11906 name: "TLS13-WrongOuterRecord", 11907 config: Config{ 11908 MaxVersion: VersionTLS13, 11909 MinVersion: VersionTLS13, 11910 Bugs: ProtocolBugs{ 11911 OuterRecordType: recordTypeHandshake, 11912 }, 11913 }, 11914 shouldFail: true, 11915 expectedError: ":INVALID_OUTER_RECORD_TYPE:", 11916 }) 11917} 11918 11919func addSessionTicketTests() { 11920 testCases = append(testCases, testCase{ 11921 // In TLS 1.2 and below, empty NewSessionTicket messages 11922 // mean the server changed its mind on sending a ticket. 11923 name: "SendEmptySessionTicket", 11924 config: Config{ 11925 MaxVersion: VersionTLS12, 11926 Bugs: ProtocolBugs{ 11927 SendEmptySessionTicket: true, 11928 }, 11929 }, 11930 flags: []string{"-expect-no-session"}, 11931 }) 11932 11933 // Test that the server ignores unknown PSK modes. 11934 testCases = append(testCases, testCase{ 11935 testType: serverTest, 11936 name: "TLS13-SendUnknownModeSessionTicket-Server", 11937 config: Config{ 11938 MaxVersion: VersionTLS13, 11939 Bugs: ProtocolBugs{ 11940 SendPSKKeyExchangeModes: []byte{0x1a, pskDHEKEMode, 0x2a}, 11941 }, 11942 }, 11943 resumeSession: true, 11944 expectations: connectionExpectations{ 11945 version: VersionTLS13, 11946 }, 11947 }) 11948 11949 // Test that the server does not send session tickets with no matching key exchange mode. 11950 testCases = append(testCases, testCase{ 11951 testType: serverTest, 11952 name: "TLS13-ExpectNoSessionTicketOnBadKEMode-Server", 11953 config: Config{ 11954 MaxVersion: VersionTLS13, 11955 Bugs: ProtocolBugs{ 11956 SendPSKKeyExchangeModes: []byte{0x1a}, 11957 ExpectNoNewSessionTicket: true, 11958 }, 11959 }, 11960 }) 11961 11962 // Test that the server does not accept a session with no matching key exchange mode. 11963 testCases = append(testCases, testCase{ 11964 testType: serverTest, 11965 name: "TLS13-SendBadKEModeSessionTicket-Server", 11966 config: Config{ 11967 MaxVersion: VersionTLS13, 11968 }, 11969 resumeConfig: &Config{ 11970 MaxVersion: VersionTLS13, 11971 Bugs: ProtocolBugs{ 11972 SendPSKKeyExchangeModes: []byte{0x1a}, 11973 }, 11974 }, 11975 resumeSession: true, 11976 expectResumeRejected: true, 11977 }) 11978 11979 // Test that the server rejects ClientHellos with pre_shared_key but without 11980 // psk_key_exchange_modes. 11981 testCases = append(testCases, testCase{ 11982 testType: serverTest, 11983 name: "TLS13-SendNoKEMModesWithPSK-Server", 11984 config: Config{ 11985 MaxVersion: VersionTLS13, 11986 }, 11987 resumeConfig: &Config{ 11988 MaxVersion: VersionTLS13, 11989 Bugs: ProtocolBugs{ 11990 SendPSKKeyExchangeModes: []byte{}, 11991 }, 11992 }, 11993 resumeSession: true, 11994 shouldFail: true, 11995 expectedLocalError: "remote error: missing extension", 11996 expectedError: ":MISSING_EXTENSION:", 11997 }) 11998 11999 // Test that the client ticket age is sent correctly. 12000 testCases = append(testCases, testCase{ 12001 testType: clientTest, 12002 name: "TLS13-TestValidTicketAge-Client", 12003 config: Config{ 12004 MaxVersion: VersionTLS13, 12005 Bugs: ProtocolBugs{ 12006 ExpectTicketAge: 10 * time.Second, 12007 }, 12008 }, 12009 resumeSession: true, 12010 flags: []string{ 12011 "-resumption-delay", "10", 12012 }, 12013 }) 12014 12015 // Test that the client ticket age is enforced. 12016 testCases = append(testCases, testCase{ 12017 testType: clientTest, 12018 name: "TLS13-TestBadTicketAge-Client", 12019 config: Config{ 12020 MaxVersion: VersionTLS13, 12021 Bugs: ProtocolBugs{ 12022 ExpectTicketAge: 1000 * time.Second, 12023 }, 12024 }, 12025 resumeSession: true, 12026 shouldFail: true, 12027 expectedLocalError: "tls: invalid ticket age", 12028 }) 12029 12030 // Test that the server's ticket age skew reporting works. 12031 testCases = append(testCases, testCase{ 12032 testType: serverTest, 12033 name: "TLS13-TicketAgeSkew-Forward", 12034 config: Config{ 12035 MaxVersion: VersionTLS13, 12036 Bugs: ProtocolBugs{ 12037 SendTicketAge: 15 * time.Second, 12038 }, 12039 }, 12040 resumeSession: true, 12041 resumeRenewedSession: true, 12042 flags: []string{ 12043 "-resumption-delay", "10", 12044 "-expect-ticket-age-skew", "5", 12045 }, 12046 }) 12047 testCases = append(testCases, testCase{ 12048 testType: serverTest, 12049 name: "TLS13-TicketAgeSkew-Backward", 12050 config: Config{ 12051 MaxVersion: VersionTLS13, 12052 Bugs: ProtocolBugs{ 12053 SendTicketAge: 5 * time.Second, 12054 }, 12055 }, 12056 resumeSession: true, 12057 resumeRenewedSession: true, 12058 flags: []string{ 12059 "-resumption-delay", "10", 12060 "-expect-ticket-age-skew", "-5", 12061 }, 12062 }) 12063 12064 // Test that ticket age skew up to 60 seconds in either direction is accepted. 12065 testCases = append(testCases, testCase{ 12066 testType: serverTest, 12067 name: "TLS13-TicketAgeSkew-Forward-60-Accept", 12068 config: Config{ 12069 MaxVersion: VersionTLS13, 12070 Bugs: ProtocolBugs{ 12071 SendTicketAge: 70 * time.Second, 12072 }, 12073 }, 12074 resumeSession: true, 12075 earlyData: true, 12076 flags: []string{ 12077 "-resumption-delay", "10", 12078 "-expect-ticket-age-skew", "60", 12079 }, 12080 }) 12081 testCases = append(testCases, testCase{ 12082 testType: serverTest, 12083 name: "TLS13-TicketAgeSkew-Backward-60-Accept", 12084 config: Config{ 12085 MaxVersion: VersionTLS13, 12086 Bugs: ProtocolBugs{ 12087 SendTicketAge: 10 * time.Second, 12088 }, 12089 }, 12090 resumeSession: true, 12091 earlyData: true, 12092 flags: []string{ 12093 "-resumption-delay", "70", 12094 "-expect-ticket-age-skew", "-60", 12095 }, 12096 }) 12097 12098 // Test that ticket age skew beyond 60 seconds in either direction is rejected. 12099 testCases = append(testCases, testCase{ 12100 testType: serverTest, 12101 name: "TLS13-TicketAgeSkew-Forward-61-Reject", 12102 config: Config{ 12103 MaxVersion: VersionTLS13, 12104 Bugs: ProtocolBugs{ 12105 SendTicketAge: 71 * time.Second, 12106 }, 12107 }, 12108 resumeSession: true, 12109 earlyData: true, 12110 expectEarlyDataRejected: true, 12111 flags: []string{ 12112 "-resumption-delay", "10", 12113 "-expect-ticket-age-skew", "61", 12114 "-on-resume-expect-early-data-reason", "ticket_age_skew", 12115 }, 12116 }) 12117 testCases = append(testCases, testCase{ 12118 testType: serverTest, 12119 name: "TLS13-TicketAgeSkew-Backward-61-Reject", 12120 config: Config{ 12121 MaxVersion: VersionTLS13, 12122 Bugs: ProtocolBugs{ 12123 SendTicketAge: 10 * time.Second, 12124 }, 12125 }, 12126 resumeSession: true, 12127 earlyData: true, 12128 expectEarlyDataRejected: true, 12129 flags: []string{ 12130 "-resumption-delay", "71", 12131 "-expect-ticket-age-skew", "-61", 12132 "-on-resume-expect-early-data-reason", "ticket_age_skew", 12133 }, 12134 }) 12135 12136 testCases = append(testCases, testCase{ 12137 testType: clientTest, 12138 name: "TLS13-SendTicketEarlyDataSupport", 12139 config: Config{ 12140 MaxVersion: VersionTLS13, 12141 MaxEarlyDataSize: 16384, 12142 }, 12143 flags: []string{ 12144 "-enable-early-data", 12145 "-expect-ticket-supports-early-data", 12146 }, 12147 }) 12148 12149 // Test that 0-RTT tickets are still recorded as such when early data is disabled overall. 12150 testCases = append(testCases, testCase{ 12151 testType: clientTest, 12152 name: "TLS13-SendTicketEarlyDataSupport-Disabled", 12153 config: Config{ 12154 MaxVersion: VersionTLS13, 12155 MaxEarlyDataSize: 16384, 12156 }, 12157 flags: []string{ 12158 "-expect-ticket-supports-early-data", 12159 }, 12160 }) 12161 12162 testCases = append(testCases, testCase{ 12163 testType: clientTest, 12164 name: "TLS13-DuplicateTicketEarlyDataSupport", 12165 config: Config{ 12166 MaxVersion: VersionTLS13, 12167 MaxEarlyDataSize: 16384, 12168 Bugs: ProtocolBugs{ 12169 DuplicateTicketEarlyData: true, 12170 }, 12171 }, 12172 shouldFail: true, 12173 expectedError: ":DUPLICATE_EXTENSION:", 12174 expectedLocalError: "remote error: illegal parameter", 12175 }) 12176 12177 testCases = append(testCases, testCase{ 12178 testType: serverTest, 12179 name: "TLS13-ExpectTicketEarlyDataSupport", 12180 config: Config{ 12181 MaxVersion: VersionTLS13, 12182 Bugs: ProtocolBugs{ 12183 ExpectTicketEarlyData: true, 12184 }, 12185 }, 12186 flags: []string{ 12187 "-enable-early-data", 12188 }, 12189 }) 12190 12191 // Test that, in TLS 1.3, the server-offered NewSessionTicket lifetime 12192 // is honored. 12193 testCases = append(testCases, testCase{ 12194 testType: clientTest, 12195 name: "TLS13-HonorServerSessionTicketLifetime", 12196 config: Config{ 12197 MaxVersion: VersionTLS13, 12198 Bugs: ProtocolBugs{ 12199 SendTicketLifetime: 20 * time.Second, 12200 }, 12201 }, 12202 flags: []string{ 12203 "-resumption-delay", "19", 12204 }, 12205 resumeSession: true, 12206 }) 12207 testCases = append(testCases, testCase{ 12208 testType: clientTest, 12209 name: "TLS13-HonorServerSessionTicketLifetime-2", 12210 config: Config{ 12211 MaxVersion: VersionTLS13, 12212 Bugs: ProtocolBugs{ 12213 SendTicketLifetime: 20 * time.Second, 12214 // The client should not offer the expired session. 12215 ExpectNoTLS13PSK: true, 12216 }, 12217 }, 12218 flags: []string{ 12219 "-resumption-delay", "21", 12220 }, 12221 resumeSession: true, 12222 expectResumeRejected: true, 12223 }) 12224 12225 for _, ver := range tlsVersions { 12226 // Prior to TLS 1.3, disabling session tickets enables session IDs. 12227 useStatefulResumption := ver.version < VersionTLS13 12228 12229 // SSL_OP_NO_TICKET implies the server must not mint any tickets. 12230 testCases = append(testCases, testCase{ 12231 testType: serverTest, 12232 name: ver.name + "-NoTicket-NoMint", 12233 config: Config{ 12234 MinVersion: ver.version, 12235 MaxVersion: ver.version, 12236 Bugs: ProtocolBugs{ 12237 ExpectNoNewSessionTicket: true, 12238 RequireSessionIDs: useStatefulResumption, 12239 }, 12240 }, 12241 resumeSession: useStatefulResumption, 12242 flags: []string{"-no-ticket"}, 12243 }) 12244 12245 // SSL_OP_NO_TICKET implies the server must not accept any tickets. 12246 testCases = append(testCases, testCase{ 12247 testType: serverTest, 12248 name: ver.name + "-NoTicket-NoAccept", 12249 config: Config{ 12250 MinVersion: ver.version, 12251 MaxVersion: ver.version, 12252 }, 12253 resumeSession: true, 12254 expectResumeRejected: true, 12255 // Set SSL_OP_NO_TICKET on the second connection, after the first 12256 // has established tickets. 12257 flags: []string{"-on-resume-no-ticket"}, 12258 }) 12259 } 12260} 12261 12262func addChangeCipherSpecTests() { 12263 // Test missing ChangeCipherSpecs. 12264 testCases = append(testCases, testCase{ 12265 name: "SkipChangeCipherSpec-Client", 12266 config: Config{ 12267 MaxVersion: VersionTLS12, 12268 Bugs: ProtocolBugs{ 12269 SkipChangeCipherSpec: true, 12270 }, 12271 }, 12272 shouldFail: true, 12273 expectedError: ":UNEXPECTED_RECORD:", 12274 }) 12275 testCases = append(testCases, testCase{ 12276 testType: serverTest, 12277 name: "SkipChangeCipherSpec-Server", 12278 config: Config{ 12279 MaxVersion: VersionTLS12, 12280 Bugs: ProtocolBugs{ 12281 SkipChangeCipherSpec: true, 12282 }, 12283 }, 12284 shouldFail: true, 12285 expectedError: ":UNEXPECTED_RECORD:", 12286 }) 12287 testCases = append(testCases, testCase{ 12288 testType: serverTest, 12289 name: "SkipChangeCipherSpec-Server-NPN", 12290 config: Config{ 12291 MaxVersion: VersionTLS12, 12292 NextProtos: []string{"bar"}, 12293 Bugs: ProtocolBugs{ 12294 SkipChangeCipherSpec: true, 12295 }, 12296 }, 12297 flags: []string{ 12298 "-advertise-npn", "\x03foo\x03bar\x03baz", 12299 }, 12300 shouldFail: true, 12301 expectedError: ":UNEXPECTED_RECORD:", 12302 }) 12303 12304 // Test synchronization between the handshake and ChangeCipherSpec. 12305 // Partial post-CCS handshake messages before ChangeCipherSpec should be 12306 // rejected. Test both with and without handshake packing to handle both 12307 // when the partial post-CCS message is in its own record and when it is 12308 // attached to the pre-CCS message. 12309 for _, packed := range []bool{false, true} { 12310 var suffix string 12311 if packed { 12312 suffix = "-Packed" 12313 } 12314 12315 testCases = append(testCases, testCase{ 12316 name: "FragmentAcrossChangeCipherSpec-Client" + suffix, 12317 config: Config{ 12318 MaxVersion: VersionTLS12, 12319 Bugs: ProtocolBugs{ 12320 FragmentAcrossChangeCipherSpec: true, 12321 PackHandshakeFlight: packed, 12322 }, 12323 }, 12324 shouldFail: true, 12325 expectedError: ":UNEXPECTED_RECORD:", 12326 }) 12327 testCases = append(testCases, testCase{ 12328 name: "FragmentAcrossChangeCipherSpec-Client-Resume" + suffix, 12329 config: Config{ 12330 MaxVersion: VersionTLS12, 12331 }, 12332 resumeSession: true, 12333 resumeConfig: &Config{ 12334 MaxVersion: VersionTLS12, 12335 Bugs: ProtocolBugs{ 12336 FragmentAcrossChangeCipherSpec: true, 12337 PackHandshakeFlight: packed, 12338 }, 12339 }, 12340 shouldFail: true, 12341 expectedError: ":UNEXPECTED_RECORD:", 12342 }) 12343 testCases = append(testCases, testCase{ 12344 testType: serverTest, 12345 name: "FragmentAcrossChangeCipherSpec-Server" + suffix, 12346 config: Config{ 12347 MaxVersion: VersionTLS12, 12348 Bugs: ProtocolBugs{ 12349 FragmentAcrossChangeCipherSpec: true, 12350 PackHandshakeFlight: packed, 12351 }, 12352 }, 12353 shouldFail: true, 12354 expectedError: ":UNEXPECTED_RECORD:", 12355 }) 12356 testCases = append(testCases, testCase{ 12357 testType: serverTest, 12358 name: "FragmentAcrossChangeCipherSpec-Server-Resume" + suffix, 12359 config: Config{ 12360 MaxVersion: VersionTLS12, 12361 }, 12362 resumeSession: true, 12363 resumeConfig: &Config{ 12364 MaxVersion: VersionTLS12, 12365 Bugs: ProtocolBugs{ 12366 FragmentAcrossChangeCipherSpec: true, 12367 PackHandshakeFlight: packed, 12368 }, 12369 }, 12370 shouldFail: true, 12371 expectedError: ":UNEXPECTED_RECORD:", 12372 }) 12373 testCases = append(testCases, testCase{ 12374 testType: serverTest, 12375 name: "FragmentAcrossChangeCipherSpec-Server-NPN" + suffix, 12376 config: Config{ 12377 MaxVersion: VersionTLS12, 12378 NextProtos: []string{"bar"}, 12379 Bugs: ProtocolBugs{ 12380 FragmentAcrossChangeCipherSpec: true, 12381 PackHandshakeFlight: packed, 12382 }, 12383 }, 12384 flags: []string{ 12385 "-advertise-npn", "\x03foo\x03bar\x03baz", 12386 }, 12387 shouldFail: true, 12388 expectedError: ":UNEXPECTED_RECORD:", 12389 }) 12390 } 12391 12392 // In TLS 1.2 resumptions, the client sends ClientHello in the first flight 12393 // and ChangeCipherSpec + Finished in the second flight. Test the server's 12394 // behavior when the Finished message is fragmented across not only 12395 // ChangeCipherSpec but also the flight boundary. 12396 testCases = append(testCases, testCase{ 12397 testType: serverTest, 12398 name: "PartialClientFinishedWithClientHello-TLS12-Resume", 12399 config: Config{ 12400 MaxVersion: VersionTLS12, 12401 }, 12402 resumeConfig: &Config{ 12403 MaxVersion: VersionTLS12, 12404 Bugs: ProtocolBugs{ 12405 PartialClientFinishedWithClientHello: true, 12406 }, 12407 }, 12408 resumeSession: true, 12409 shouldFail: true, 12410 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12411 expectedLocalError: "remote error: unexpected message", 12412 }) 12413 12414 // In TLS 1.2 full handshakes without tickets, the server's first flight ends 12415 // with ServerHelloDone and the second flight is ChangeCipherSpec + Finished. 12416 // Test the client's behavior when the Finished message is fragmented across 12417 // not only ChangeCipherSpec but also the flight boundary. 12418 testCases = append(testCases, testCase{ 12419 testType: clientTest, 12420 name: "PartialFinishedWithServerHelloDone", 12421 config: Config{ 12422 MaxVersion: VersionTLS12, 12423 SessionTicketsDisabled: true, 12424 Bugs: ProtocolBugs{ 12425 PartialFinishedWithServerHelloDone: true, 12426 }, 12427 }, 12428 shouldFail: true, 12429 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12430 expectedLocalError: "remote error: unexpected message", 12431 }) 12432 12433 // Test that, in DTLS, ChangeCipherSpec is not allowed when there are 12434 // messages in the handshake queue. Do this by testing the server 12435 // reading the client Finished, reversing the flight so Finished comes 12436 // first. 12437 testCases = append(testCases, testCase{ 12438 protocol: dtls, 12439 testType: serverTest, 12440 name: "SendUnencryptedFinished-DTLS", 12441 config: Config{ 12442 MaxVersion: VersionTLS12, 12443 Bugs: ProtocolBugs{ 12444 SendUnencryptedFinished: true, 12445 ReverseHandshakeFragments: true, 12446 }, 12447 }, 12448 shouldFail: true, 12449 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12450 }) 12451 12452 // Test synchronization between encryption changes and the handshake in 12453 // TLS 1.3, where ChangeCipherSpec is implicit. 12454 testCases = append(testCases, testCase{ 12455 name: "PartialEncryptedExtensionsWithServerHello", 12456 config: Config{ 12457 MaxVersion: VersionTLS13, 12458 Bugs: ProtocolBugs{ 12459 PartialEncryptedExtensionsWithServerHello: true, 12460 }, 12461 }, 12462 shouldFail: true, 12463 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12464 }) 12465 testCases = append(testCases, testCase{ 12466 testType: serverTest, 12467 name: "PartialClientFinishedWithClientHello", 12468 config: Config{ 12469 MaxVersion: VersionTLS13, 12470 Bugs: ProtocolBugs{ 12471 PartialClientFinishedWithClientHello: true, 12472 }, 12473 }, 12474 shouldFail: true, 12475 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12476 }) 12477 testCases = append(testCases, testCase{ 12478 testType: serverTest, 12479 name: "PartialClientFinishedWithSecondClientHello", 12480 config: Config{ 12481 MaxVersion: VersionTLS13, 12482 // Trigger a curve-based HelloRetryRequest. 12483 DefaultCurves: []CurveID{}, 12484 Bugs: ProtocolBugs{ 12485 PartialClientFinishedWithSecondClientHello: true, 12486 }, 12487 }, 12488 shouldFail: true, 12489 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12490 }) 12491 testCases = append(testCases, testCase{ 12492 testType: serverTest, 12493 name: "PartialEndOfEarlyDataWithClientHello", 12494 config: Config{ 12495 MaxVersion: VersionTLS13, 12496 }, 12497 resumeConfig: &Config{ 12498 MaxVersion: VersionTLS13, 12499 Bugs: ProtocolBugs{ 12500 PartialEndOfEarlyDataWithClientHello: true, 12501 }, 12502 }, 12503 resumeSession: true, 12504 earlyData: true, 12505 shouldFail: true, 12506 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12507 }) 12508 12509 // Test that early ChangeCipherSpecs are handled correctly. 12510 testCases = append(testCases, testCase{ 12511 testType: serverTest, 12512 name: "EarlyChangeCipherSpec-server-1", 12513 config: Config{ 12514 MaxVersion: VersionTLS12, 12515 Bugs: ProtocolBugs{ 12516 EarlyChangeCipherSpec: 1, 12517 }, 12518 }, 12519 shouldFail: true, 12520 expectedError: ":UNEXPECTED_RECORD:", 12521 }) 12522 testCases = append(testCases, testCase{ 12523 testType: serverTest, 12524 name: "EarlyChangeCipherSpec-server-2", 12525 config: Config{ 12526 MaxVersion: VersionTLS12, 12527 Bugs: ProtocolBugs{ 12528 EarlyChangeCipherSpec: 2, 12529 }, 12530 }, 12531 shouldFail: true, 12532 expectedError: ":UNEXPECTED_RECORD:", 12533 }) 12534 testCases = append(testCases, testCase{ 12535 protocol: dtls, 12536 name: "StrayChangeCipherSpec", 12537 config: Config{ 12538 // TODO(davidben): Once DTLS 1.3 exists, test 12539 // that stray ChangeCipherSpec messages are 12540 // rejected. 12541 MaxVersion: VersionTLS12, 12542 Bugs: ProtocolBugs{ 12543 StrayChangeCipherSpec: true, 12544 }, 12545 }, 12546 }) 12547 12548 // Test that reordered ChangeCipherSpecs are tolerated. 12549 testCases = append(testCases, testCase{ 12550 protocol: dtls, 12551 name: "ReorderChangeCipherSpec-DTLS-Client", 12552 config: Config{ 12553 MaxVersion: VersionTLS12, 12554 Bugs: ProtocolBugs{ 12555 ReorderChangeCipherSpec: true, 12556 }, 12557 }, 12558 resumeSession: true, 12559 }) 12560 testCases = append(testCases, testCase{ 12561 testType: serverTest, 12562 protocol: dtls, 12563 name: "ReorderChangeCipherSpec-DTLS-Server", 12564 config: Config{ 12565 MaxVersion: VersionTLS12, 12566 Bugs: ProtocolBugs{ 12567 ReorderChangeCipherSpec: true, 12568 }, 12569 }, 12570 resumeSession: true, 12571 }) 12572 12573 // Test that the contents of ChangeCipherSpec are checked. 12574 testCases = append(testCases, testCase{ 12575 name: "BadChangeCipherSpec-1", 12576 config: Config{ 12577 MaxVersion: VersionTLS12, 12578 Bugs: ProtocolBugs{ 12579 BadChangeCipherSpec: []byte{2}, 12580 }, 12581 }, 12582 shouldFail: true, 12583 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12584 }) 12585 testCases = append(testCases, testCase{ 12586 name: "BadChangeCipherSpec-2", 12587 config: Config{ 12588 MaxVersion: VersionTLS12, 12589 Bugs: ProtocolBugs{ 12590 BadChangeCipherSpec: []byte{1, 1}, 12591 }, 12592 }, 12593 shouldFail: true, 12594 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12595 }) 12596 testCases = append(testCases, testCase{ 12597 protocol: dtls, 12598 name: "BadChangeCipherSpec-DTLS-1", 12599 config: Config{ 12600 MaxVersion: VersionTLS12, 12601 Bugs: ProtocolBugs{ 12602 BadChangeCipherSpec: []byte{2}, 12603 }, 12604 }, 12605 shouldFail: true, 12606 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12607 }) 12608 testCases = append(testCases, testCase{ 12609 protocol: dtls, 12610 name: "BadChangeCipherSpec-DTLS-2", 12611 config: Config{ 12612 MaxVersion: VersionTLS12, 12613 Bugs: ProtocolBugs{ 12614 BadChangeCipherSpec: []byte{1, 1}, 12615 }, 12616 }, 12617 shouldFail: true, 12618 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12619 }) 12620} 12621 12622// addEndOfFlightTests adds tests where the runner adds extra data in the final 12623// record of each handshake flight. Depending on the implementation strategy, 12624// this data may be carried over to the next flight (assuming no key change) or 12625// may be rejected. To avoid differences with split handshakes and generally 12626// reject misbehavior, BoringSSL treats this as an error. When possible, these 12627// tests pull the extra data from the subsequent flight to distinguish the data 12628// being carried over from a general syntax error. 12629// 12630// These tests are similar to tests in |addChangeCipherSpecTests| that send 12631// extra data at key changes. Not all key changes are at the end of a flight and 12632// not all flights end at a key change. 12633func addEndOfFlightTests() { 12634 // TLS 1.3 client handshakes. 12635 // 12636 // Data following the second TLS 1.3 ClientHello is covered by 12637 // PartialClientFinishedWithClientHello, 12638 // PartialClientFinishedWithSecondClientHello, and 12639 // PartialEndOfEarlyDataWithClientHello in |addChangeCipherSpecTests|. 12640 testCases = append(testCases, testCase{ 12641 testType: serverTest, 12642 name: "PartialSecondClientHelloAfterFirst", 12643 config: Config{ 12644 MaxVersion: VersionTLS13, 12645 // Trigger a curve-based HelloRetryRequest. 12646 DefaultCurves: []CurveID{}, 12647 Bugs: ProtocolBugs{ 12648 PartialSecondClientHelloAfterFirst: true, 12649 }, 12650 }, 12651 shouldFail: true, 12652 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12653 expectedLocalError: "remote error: unexpected message", 12654 }) 12655 12656 // TLS 1.3 server handshakes. 12657 testCases = append(testCases, testCase{ 12658 testType: clientTest, 12659 name: "PartialServerHelloWithHelloRetryRequest", 12660 config: Config{ 12661 MaxVersion: VersionTLS13, 12662 // P-384 requires HelloRetryRequest in BoringSSL. 12663 CurvePreferences: []CurveID{CurveP384}, 12664 Bugs: ProtocolBugs{ 12665 PartialServerHelloWithHelloRetryRequest: true, 12666 }, 12667 }, 12668 shouldFail: true, 12669 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12670 expectedLocalError: "remote error: unexpected message", 12671 }) 12672 12673 // TLS 1.2 client handshakes. 12674 testCases = append(testCases, testCase{ 12675 testType: serverTest, 12676 name: "PartialClientKeyExchangeWithClientHello", 12677 config: Config{ 12678 MaxVersion: VersionTLS12, 12679 Bugs: ProtocolBugs{ 12680 PartialClientKeyExchangeWithClientHello: true, 12681 }, 12682 }, 12683 shouldFail: true, 12684 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12685 expectedLocalError: "remote error: unexpected message", 12686 }) 12687 12688 // TLS 1.2 server handshakes. 12689 testCases = append(testCases, testCase{ 12690 testType: clientTest, 12691 name: "PartialNewSessionTicketWithServerHelloDone", 12692 config: Config{ 12693 MaxVersion: VersionTLS12, 12694 Bugs: ProtocolBugs{ 12695 PartialNewSessionTicketWithServerHelloDone: true, 12696 }, 12697 }, 12698 shouldFail: true, 12699 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12700 expectedLocalError: "remote error: unexpected message", 12701 }) 12702 12703 for _, vers := range tlsVersions { 12704 for _, testType := range []testType{clientTest, serverTest} { 12705 suffix := "-Client" 12706 if testType == serverTest { 12707 suffix = "-Server" 12708 } 12709 suffix += "-" + vers.name 12710 12711 testCases = append(testCases, testCase{ 12712 testType: testType, 12713 name: "TrailingDataWithFinished" + suffix, 12714 config: Config{ 12715 MaxVersion: vers.version, 12716 Bugs: ProtocolBugs{ 12717 TrailingDataWithFinished: true, 12718 }, 12719 }, 12720 shouldFail: true, 12721 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12722 expectedLocalError: "remote error: unexpected message", 12723 }) 12724 testCases = append(testCases, testCase{ 12725 testType: testType, 12726 name: "TrailingDataWithFinished-Resume" + suffix, 12727 config: Config{ 12728 MaxVersion: vers.version, 12729 }, 12730 resumeConfig: &Config{ 12731 MaxVersion: vers.version, 12732 Bugs: ProtocolBugs{ 12733 TrailingDataWithFinished: true, 12734 }, 12735 }, 12736 resumeSession: true, 12737 shouldFail: true, 12738 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12739 expectedLocalError: "remote error: unexpected message", 12740 }) 12741 } 12742 } 12743} 12744 12745type perMessageTest struct { 12746 messageType uint8 12747 test testCase 12748} 12749 12750// makePerMessageTests returns a series of test templates which cover each 12751// message in the TLS handshake. These may be used with bugs like 12752// WrongMessageType to fully test a per-message bug. 12753func makePerMessageTests() []perMessageTest { 12754 var ret []perMessageTest 12755 // The following tests are limited to TLS 1.2, so QUIC is not tested. 12756 for _, protocol := range []protocol{tls, dtls} { 12757 suffix := "-" + protocol.String() 12758 12759 ret = append(ret, perMessageTest{ 12760 messageType: typeClientHello, 12761 test: testCase{ 12762 protocol: protocol, 12763 testType: serverTest, 12764 name: "ClientHello" + suffix, 12765 config: Config{ 12766 MaxVersion: VersionTLS12, 12767 }, 12768 }, 12769 }) 12770 12771 if protocol == dtls { 12772 ret = append(ret, perMessageTest{ 12773 messageType: typeHelloVerifyRequest, 12774 test: testCase{ 12775 protocol: protocol, 12776 name: "HelloVerifyRequest" + suffix, 12777 config: Config{ 12778 MaxVersion: VersionTLS12, 12779 }, 12780 }, 12781 }) 12782 } 12783 12784 ret = append(ret, perMessageTest{ 12785 messageType: typeServerHello, 12786 test: testCase{ 12787 protocol: protocol, 12788 name: "ServerHello" + suffix, 12789 config: Config{ 12790 MaxVersion: VersionTLS12, 12791 }, 12792 }, 12793 }) 12794 12795 ret = append(ret, perMessageTest{ 12796 messageType: typeCertificate, 12797 test: testCase{ 12798 protocol: protocol, 12799 name: "ServerCertificate" + suffix, 12800 config: Config{ 12801 MaxVersion: VersionTLS12, 12802 }, 12803 }, 12804 }) 12805 12806 ret = append(ret, perMessageTest{ 12807 messageType: typeCertificateStatus, 12808 test: testCase{ 12809 protocol: protocol, 12810 name: "CertificateStatus" + suffix, 12811 config: Config{ 12812 MaxVersion: VersionTLS12, 12813 }, 12814 flags: []string{"-enable-ocsp-stapling"}, 12815 }, 12816 }) 12817 12818 ret = append(ret, perMessageTest{ 12819 messageType: typeServerKeyExchange, 12820 test: testCase{ 12821 protocol: protocol, 12822 name: "ServerKeyExchange" + suffix, 12823 config: Config{ 12824 MaxVersion: VersionTLS12, 12825 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 12826 }, 12827 }, 12828 }) 12829 12830 ret = append(ret, perMessageTest{ 12831 messageType: typeCertificateRequest, 12832 test: testCase{ 12833 protocol: protocol, 12834 name: "CertificateRequest" + suffix, 12835 config: Config{ 12836 MaxVersion: VersionTLS12, 12837 ClientAuth: RequireAnyClientCert, 12838 }, 12839 }, 12840 }) 12841 12842 ret = append(ret, perMessageTest{ 12843 messageType: typeServerHelloDone, 12844 test: testCase{ 12845 protocol: protocol, 12846 name: "ServerHelloDone" + suffix, 12847 config: Config{ 12848 MaxVersion: VersionTLS12, 12849 }, 12850 }, 12851 }) 12852 12853 ret = append(ret, perMessageTest{ 12854 messageType: typeCertificate, 12855 test: testCase{ 12856 testType: serverTest, 12857 protocol: protocol, 12858 name: "ClientCertificate" + suffix, 12859 config: Config{ 12860 Certificates: []Certificate{rsaCertificate}, 12861 MaxVersion: VersionTLS12, 12862 }, 12863 flags: []string{"-require-any-client-certificate"}, 12864 }, 12865 }) 12866 12867 ret = append(ret, perMessageTest{ 12868 messageType: typeCertificateVerify, 12869 test: testCase{ 12870 testType: serverTest, 12871 protocol: protocol, 12872 name: "CertificateVerify" + suffix, 12873 config: Config{ 12874 Certificates: []Certificate{rsaCertificate}, 12875 MaxVersion: VersionTLS12, 12876 }, 12877 flags: []string{"-require-any-client-certificate"}, 12878 }, 12879 }) 12880 12881 ret = append(ret, perMessageTest{ 12882 messageType: typeClientKeyExchange, 12883 test: testCase{ 12884 testType: serverTest, 12885 protocol: protocol, 12886 name: "ClientKeyExchange" + suffix, 12887 config: Config{ 12888 MaxVersion: VersionTLS12, 12889 }, 12890 }, 12891 }) 12892 12893 if protocol != dtls { 12894 ret = append(ret, perMessageTest{ 12895 messageType: typeNextProtocol, 12896 test: testCase{ 12897 testType: serverTest, 12898 protocol: protocol, 12899 name: "NextProtocol" + suffix, 12900 config: Config{ 12901 MaxVersion: VersionTLS12, 12902 NextProtos: []string{"bar"}, 12903 }, 12904 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"}, 12905 }, 12906 }) 12907 12908 ret = append(ret, perMessageTest{ 12909 messageType: typeChannelID, 12910 test: testCase{ 12911 testType: serverTest, 12912 protocol: protocol, 12913 name: "ChannelID" + suffix, 12914 config: Config{ 12915 MaxVersion: VersionTLS12, 12916 ChannelID: channelIDKey, 12917 }, 12918 flags: []string{ 12919 "-expect-channel-id", 12920 base64FlagValue(channelIDBytes), 12921 }, 12922 }, 12923 }) 12924 } 12925 12926 ret = append(ret, perMessageTest{ 12927 messageType: typeFinished, 12928 test: testCase{ 12929 testType: serverTest, 12930 protocol: protocol, 12931 name: "ClientFinished" + suffix, 12932 config: Config{ 12933 MaxVersion: VersionTLS12, 12934 }, 12935 }, 12936 }) 12937 12938 ret = append(ret, perMessageTest{ 12939 messageType: typeNewSessionTicket, 12940 test: testCase{ 12941 protocol: protocol, 12942 name: "NewSessionTicket" + suffix, 12943 config: Config{ 12944 MaxVersion: VersionTLS12, 12945 }, 12946 }, 12947 }) 12948 12949 ret = append(ret, perMessageTest{ 12950 messageType: typeFinished, 12951 test: testCase{ 12952 protocol: protocol, 12953 name: "ServerFinished" + suffix, 12954 config: Config{ 12955 MaxVersion: VersionTLS12, 12956 }, 12957 }, 12958 }) 12959 12960 } 12961 12962 for _, protocol := range []protocol{tls, quic} { 12963 suffix := "-" + protocol.String() 12964 ret = append(ret, perMessageTest{ 12965 messageType: typeClientHello, 12966 test: testCase{ 12967 testType: serverTest, 12968 protocol: protocol, 12969 name: "TLS13-ClientHello" + suffix, 12970 config: Config{ 12971 MaxVersion: VersionTLS13, 12972 }, 12973 }, 12974 }) 12975 12976 ret = append(ret, perMessageTest{ 12977 messageType: typeServerHello, 12978 test: testCase{ 12979 name: "TLS13-ServerHello" + suffix, 12980 protocol: protocol, 12981 config: Config{ 12982 MaxVersion: VersionTLS13, 12983 }, 12984 }, 12985 }) 12986 12987 ret = append(ret, perMessageTest{ 12988 messageType: typeEncryptedExtensions, 12989 test: testCase{ 12990 name: "TLS13-EncryptedExtensions" + suffix, 12991 protocol: protocol, 12992 config: Config{ 12993 MaxVersion: VersionTLS13, 12994 }, 12995 }, 12996 }) 12997 12998 ret = append(ret, perMessageTest{ 12999 messageType: typeCertificateRequest, 13000 test: testCase{ 13001 name: "TLS13-CertificateRequest" + suffix, 13002 protocol: protocol, 13003 config: Config{ 13004 MaxVersion: VersionTLS13, 13005 ClientAuth: RequireAnyClientCert, 13006 }, 13007 }, 13008 }) 13009 13010 ret = append(ret, perMessageTest{ 13011 messageType: typeCertificate, 13012 test: testCase{ 13013 name: "TLS13-ServerCertificate" + suffix, 13014 protocol: protocol, 13015 config: Config{ 13016 MaxVersion: VersionTLS13, 13017 }, 13018 }, 13019 }) 13020 13021 ret = append(ret, perMessageTest{ 13022 messageType: typeCertificateVerify, 13023 test: testCase{ 13024 name: "TLS13-ServerCertificateVerify" + suffix, 13025 protocol: protocol, 13026 config: Config{ 13027 MaxVersion: VersionTLS13, 13028 }, 13029 }, 13030 }) 13031 13032 ret = append(ret, perMessageTest{ 13033 messageType: typeFinished, 13034 test: testCase{ 13035 name: "TLS13-ServerFinished" + suffix, 13036 protocol: protocol, 13037 config: Config{ 13038 MaxVersion: VersionTLS13, 13039 }, 13040 }, 13041 }) 13042 13043 ret = append(ret, perMessageTest{ 13044 messageType: typeCertificate, 13045 test: testCase{ 13046 testType: serverTest, 13047 protocol: protocol, 13048 name: "TLS13-ClientCertificate" + suffix, 13049 config: Config{ 13050 Certificates: []Certificate{rsaCertificate}, 13051 MaxVersion: VersionTLS13, 13052 }, 13053 flags: []string{"-require-any-client-certificate"}, 13054 }, 13055 }) 13056 13057 ret = append(ret, perMessageTest{ 13058 messageType: typeCertificateVerify, 13059 test: testCase{ 13060 testType: serverTest, 13061 protocol: protocol, 13062 name: "TLS13-ClientCertificateVerify" + suffix, 13063 config: Config{ 13064 Certificates: []Certificate{rsaCertificate}, 13065 MaxVersion: VersionTLS13, 13066 }, 13067 flags: []string{"-require-any-client-certificate"}, 13068 }, 13069 }) 13070 13071 ret = append(ret, perMessageTest{ 13072 messageType: typeFinished, 13073 test: testCase{ 13074 testType: serverTest, 13075 protocol: protocol, 13076 name: "TLS13-ClientFinished" + suffix, 13077 config: Config{ 13078 MaxVersion: VersionTLS13, 13079 }, 13080 }, 13081 }) 13082 13083 // Only TLS uses EndOfEarlyData. 13084 if protocol == tls { 13085 ret = append(ret, perMessageTest{ 13086 messageType: typeEndOfEarlyData, 13087 test: testCase{ 13088 testType: serverTest, 13089 protocol: protocol, 13090 name: "TLS13-EndOfEarlyData" + suffix, 13091 config: Config{ 13092 MaxVersion: VersionTLS13, 13093 }, 13094 resumeSession: true, 13095 earlyData: true, 13096 }, 13097 }) 13098 } 13099 } 13100 13101 return ret 13102} 13103 13104func addWrongMessageTypeTests() { 13105 for _, t := range makePerMessageTests() { 13106 t.test.name = "WrongMessageType-" + t.test.name 13107 if t.test.resumeConfig != nil { 13108 t.test.resumeConfig.Bugs.SendWrongMessageType = t.messageType 13109 } else { 13110 t.test.config.Bugs.SendWrongMessageType = t.messageType 13111 } 13112 t.test.shouldFail = true 13113 t.test.expectedError = ":UNEXPECTED_MESSAGE:" 13114 t.test.expectedLocalError = "remote error: unexpected message" 13115 13116 if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello { 13117 // In TLS 1.3, if the server believes it has sent ServerHello, 13118 // but the client cannot process it, the client will send an 13119 // unencrypted alert while the server expects encryption. In TLS, 13120 // this is a decryption failure. In QUIC, the encryption levels 13121 // do not match. 13122 if t.test.protocol == quic { 13123 t.test.expectedLocalError = "received record at initial encryption level, but expected handshake" 13124 } else { 13125 t.test.expectedLocalError = "local error: bad record MAC" 13126 } 13127 } 13128 13129 testCases = append(testCases, t.test) 13130 } 13131} 13132 13133func addTrailingMessageDataTests() { 13134 for _, t := range makePerMessageTests() { 13135 t.test.name = "TrailingMessageData-" + t.test.name 13136 if t.test.resumeConfig != nil { 13137 t.test.resumeConfig.Bugs.SendTrailingMessageData = t.messageType 13138 } else { 13139 t.test.config.Bugs.SendTrailingMessageData = t.messageType 13140 } 13141 t.test.shouldFail = true 13142 t.test.expectedError = ":DECODE_ERROR:" 13143 t.test.expectedLocalError = "remote error: error decoding message" 13144 13145 if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello { 13146 // In TLS 1.3, if the server believes it has sent ServerHello, 13147 // but the client cannot process it, the client will send an 13148 // unencrypted alert while the server expects encryption. In TLS, 13149 // this is a decryption failure. In QUIC, the encryption levels 13150 // do not match. 13151 if t.test.protocol == quic { 13152 t.test.expectedLocalError = "received record at initial encryption level, but expected handshake" 13153 } else { 13154 t.test.expectedLocalError = "local error: bad record MAC" 13155 } 13156 } 13157 13158 if t.messageType == typeFinished { 13159 // Bad Finished messages read as the verify data having 13160 // the wrong length. 13161 t.test.expectedError = ":DIGEST_CHECK_FAILED:" 13162 t.test.expectedLocalError = "remote error: error decrypting message" 13163 } 13164 13165 testCases = append(testCases, t.test) 13166 } 13167} 13168 13169func addTLS13HandshakeTests() { 13170 testCases = append(testCases, testCase{ 13171 testType: clientTest, 13172 name: "NegotiatePSKResumption-TLS13", 13173 config: Config{ 13174 MaxVersion: VersionTLS13, 13175 Bugs: ProtocolBugs{ 13176 NegotiatePSKResumption: true, 13177 }, 13178 }, 13179 resumeSession: true, 13180 shouldFail: true, 13181 expectedError: ":MISSING_KEY_SHARE:", 13182 }) 13183 13184 testCases = append(testCases, testCase{ 13185 testType: clientTest, 13186 name: "MissingKeyShare-Client-TLS13", 13187 config: Config{ 13188 MaxVersion: VersionTLS13, 13189 Bugs: ProtocolBugs{ 13190 MissingKeyShare: true, 13191 }, 13192 }, 13193 shouldFail: true, 13194 expectedError: ":MISSING_KEY_SHARE:", 13195 }) 13196 13197 testCases = append(testCases, testCase{ 13198 testType: serverTest, 13199 name: "MissingKeyShare-Server-TLS13", 13200 config: Config{ 13201 MaxVersion: VersionTLS13, 13202 Bugs: ProtocolBugs{ 13203 MissingKeyShare: true, 13204 }, 13205 }, 13206 shouldFail: true, 13207 expectedError: ":MISSING_KEY_SHARE:", 13208 }) 13209 13210 testCases = append(testCases, testCase{ 13211 testType: serverTest, 13212 name: "DuplicateKeyShares-TLS13", 13213 config: Config{ 13214 MaxVersion: VersionTLS13, 13215 Bugs: ProtocolBugs{ 13216 DuplicateKeyShares: true, 13217 }, 13218 }, 13219 shouldFail: true, 13220 expectedError: ":DUPLICATE_KEY_SHARE:", 13221 }) 13222 13223 testCases = append(testCases, testCase{ 13224 testType: serverTest, 13225 name: "SkipEarlyData-TLS13", 13226 config: Config{ 13227 MaxVersion: VersionTLS13, 13228 Bugs: ProtocolBugs{ 13229 SendFakeEarlyDataLength: 4, 13230 }, 13231 }, 13232 }) 13233 13234 // Test that enabling TLS 1.3 does not interfere with TLS 1.2 session ID 13235 // resumption. 13236 testCases = append(testCases, testCase{ 13237 testType: clientTest, 13238 name: "ResumeTLS12SessionID-TLS13", 13239 config: Config{ 13240 MaxVersion: VersionTLS12, 13241 SessionTicketsDisabled: true, 13242 }, 13243 flags: []string{"-max-version", strconv.Itoa(VersionTLS13)}, 13244 resumeSession: true, 13245 }) 13246 13247 // Test that the client correctly handles a TLS 1.3 ServerHello which echoes 13248 // a TLS 1.2 session ID. 13249 testCases = append(testCases, testCase{ 13250 testType: clientTest, 13251 name: "TLS12SessionID-TLS13", 13252 config: Config{ 13253 MaxVersion: VersionTLS12, 13254 SessionTicketsDisabled: true, 13255 }, 13256 resumeConfig: &Config{ 13257 MaxVersion: VersionTLS13, 13258 }, 13259 resumeSession: true, 13260 expectResumeRejected: true, 13261 }) 13262 13263 // Test that the server correctly echoes back session IDs of 13264 // various lengths. The first test additionally asserts that 13265 // BoringSSL always sends the ChangeCipherSpec messages for 13266 // compatibility mode, rather than negotiating it based on the 13267 // ClientHello. 13268 testCases = append(testCases, testCase{ 13269 testType: serverTest, 13270 name: "EmptySessionID-TLS13", 13271 config: Config{ 13272 MaxVersion: VersionTLS13, 13273 Bugs: ProtocolBugs{ 13274 SendClientHelloSessionID: []byte{}, 13275 }, 13276 }, 13277 }) 13278 13279 testCases = append(testCases, testCase{ 13280 testType: serverTest, 13281 name: "Server-ShortSessionID-TLS13", 13282 config: Config{ 13283 MaxVersion: VersionTLS13, 13284 Bugs: ProtocolBugs{ 13285 SendClientHelloSessionID: make([]byte, 16), 13286 }, 13287 }, 13288 }) 13289 13290 testCases = append(testCases, testCase{ 13291 testType: serverTest, 13292 name: "Server-FullSessionID-TLS13", 13293 config: Config{ 13294 MaxVersion: VersionTLS13, 13295 Bugs: ProtocolBugs{ 13296 SendClientHelloSessionID: make([]byte, 32), 13297 }, 13298 }, 13299 }) 13300 13301 // The server should reject ClientHellos whose session IDs are too long. 13302 testCases = append(testCases, testCase{ 13303 testType: serverTest, 13304 name: "Server-TooLongSessionID-TLS13", 13305 config: Config{ 13306 MaxVersion: VersionTLS13, 13307 Bugs: ProtocolBugs{ 13308 SendClientHelloSessionID: make([]byte, 33), 13309 }, 13310 }, 13311 shouldFail: true, 13312 expectedError: ":DECODE_ERROR:", 13313 expectedLocalError: "remote error: error decoding message", 13314 }) 13315 testCases = append(testCases, testCase{ 13316 testType: serverTest, 13317 name: "Server-TooLongSessionID-TLS12", 13318 config: Config{ 13319 MaxVersion: VersionTLS12, 13320 Bugs: ProtocolBugs{ 13321 SendClientHelloSessionID: make([]byte, 33), 13322 }, 13323 }, 13324 shouldFail: true, 13325 expectedError: ":DECODE_ERROR:", 13326 expectedLocalError: "remote error: error decoding message", 13327 }) 13328 13329 // Test that the client correctly accepts or rejects short session IDs from 13330 // the server. Our tests use 32 bytes by default, so the boundary condition 13331 // is already covered. 13332 testCases = append(testCases, testCase{ 13333 name: "Client-ShortSessionID", 13334 config: Config{ 13335 MaxVersion: VersionTLS12, 13336 SessionTicketsDisabled: true, 13337 Bugs: ProtocolBugs{ 13338 NewSessionIDLength: 1, 13339 }, 13340 }, 13341 resumeSession: true, 13342 }) 13343 testCases = append(testCases, testCase{ 13344 name: "Client-TooLongSessionID", 13345 config: Config{ 13346 MaxVersion: VersionTLS12, 13347 SessionTicketsDisabled: true, 13348 Bugs: ProtocolBugs{ 13349 NewSessionIDLength: 33, 13350 }, 13351 }, 13352 shouldFail: true, 13353 expectedError: ":DECODE_ERROR:", 13354 expectedLocalError: "remote error: error decoding message", 13355 }) 13356 13357 // Test that the client sends a fake session ID in TLS 1.3. We cover both 13358 // normal and resumption handshakes to capture interactions with the 13359 // session resumption path. 13360 testCases = append(testCases, testCase{ 13361 testType: clientTest, 13362 name: "TLS13SessionID-TLS13", 13363 config: Config{ 13364 MaxVersion: VersionTLS13, 13365 Bugs: ProtocolBugs{ 13366 ExpectClientHelloSessionID: true, 13367 }, 13368 }, 13369 resumeSession: true, 13370 }) 13371 13372 // Test that the client omits the fake session ID when the max version is TLS 1.2 and below. 13373 testCases = append(testCases, testCase{ 13374 testType: clientTest, 13375 name: "TLS12NoSessionID-TLS13", 13376 config: Config{ 13377 MaxVersion: VersionTLS13, 13378 Bugs: ProtocolBugs{ 13379 ExpectNoSessionID: true, 13380 }, 13381 }, 13382 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 13383 }) 13384 13385 testCases = append(testCases, testCase{ 13386 testType: clientTest, 13387 name: "EarlyData-Client-TLS13", 13388 config: Config{ 13389 MaxVersion: VersionTLS13, 13390 MinVersion: VersionTLS13, 13391 }, 13392 resumeSession: true, 13393 earlyData: true, 13394 flags: []string{ 13395 "-on-initial-expect-early-data-reason", "no_session_offered", 13396 "-on-resume-expect-early-data-reason", "accept", 13397 }, 13398 }) 13399 13400 testCases = append(testCases, testCase{ 13401 testType: clientTest, 13402 name: "EarlyData-Reject-Client-TLS13", 13403 config: Config{ 13404 MaxVersion: VersionTLS13, 13405 }, 13406 resumeConfig: &Config{ 13407 MaxVersion: VersionTLS13, 13408 Bugs: ProtocolBugs{ 13409 AlwaysRejectEarlyData: true, 13410 }, 13411 }, 13412 resumeSession: true, 13413 earlyData: true, 13414 expectEarlyDataRejected: true, 13415 flags: []string{ 13416 "-on-retry-expect-early-data-reason", "peer_declined", 13417 }, 13418 }) 13419 13420 testCases = append(testCases, testCase{ 13421 testType: serverTest, 13422 name: "EarlyData-Server-TLS13", 13423 config: Config{ 13424 MaxVersion: VersionTLS13, 13425 MinVersion: VersionTLS13, 13426 }, 13427 messageCount: 2, 13428 resumeSession: true, 13429 earlyData: true, 13430 flags: []string{ 13431 "-on-initial-expect-early-data-reason", "no_session_offered", 13432 "-on-resume-expect-early-data-reason", "accept", 13433 }, 13434 }) 13435 13436 // The above tests the most recent ticket. Additionally test that 0-RTT 13437 // works on the first ticket issued by the server. 13438 testCases = append(testCases, testCase{ 13439 testType: serverTest, 13440 name: "EarlyData-FirstTicket-Server-TLS13", 13441 config: Config{ 13442 MaxVersion: VersionTLS13, 13443 MinVersion: VersionTLS13, 13444 Bugs: ProtocolBugs{ 13445 UseFirstSessionTicket: true, 13446 }, 13447 }, 13448 messageCount: 2, 13449 resumeSession: true, 13450 earlyData: true, 13451 flags: []string{ 13452 "-on-resume-expect-early-data-reason", "accept", 13453 }, 13454 }) 13455 13456 testCases = append(testCases, testCase{ 13457 testType: serverTest, 13458 name: "SkipEarlyData-OmitEarlyDataExtension-TLS13", 13459 config: Config{ 13460 MaxVersion: VersionTLS13, 13461 Bugs: ProtocolBugs{ 13462 SendFakeEarlyDataLength: 4, 13463 OmitEarlyDataExtension: true, 13464 }, 13465 }, 13466 shouldFail: true, 13467 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 13468 }) 13469 13470 testCases = append(testCases, testCase{ 13471 testType: serverTest, 13472 name: "SkipEarlyData-OmitEarlyDataExtension-HelloRetryRequest-TLS13", 13473 config: Config{ 13474 MaxVersion: VersionTLS13, 13475 // Require a HelloRetryRequest for every curve. 13476 DefaultCurves: []CurveID{}, 13477 Bugs: ProtocolBugs{ 13478 SendFakeEarlyDataLength: 4, 13479 OmitEarlyDataExtension: true, 13480 }, 13481 }, 13482 shouldFail: true, 13483 expectedError: ":UNEXPECTED_RECORD:", 13484 expectedLocalError: "remote error: unexpected message", 13485 }) 13486 13487 testCases = append(testCases, testCase{ 13488 testType: serverTest, 13489 name: "SkipEarlyData-TooMuchData-TLS13", 13490 config: Config{ 13491 MaxVersion: VersionTLS13, 13492 Bugs: ProtocolBugs{ 13493 SendFakeEarlyDataLength: 16384 + 1, 13494 }, 13495 }, 13496 shouldFail: true, 13497 expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:", 13498 }) 13499 13500 testCases = append(testCases, testCase{ 13501 testType: serverTest, 13502 name: "SkipEarlyData-Interleaved-TLS13", 13503 config: Config{ 13504 MaxVersion: VersionTLS13, 13505 Bugs: ProtocolBugs{ 13506 SendFakeEarlyDataLength: 4, 13507 InterleaveEarlyData: true, 13508 }, 13509 }, 13510 shouldFail: true, 13511 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 13512 }) 13513 13514 testCases = append(testCases, testCase{ 13515 testType: serverTest, 13516 name: "SkipEarlyData-EarlyDataInTLS12-TLS13", 13517 config: Config{ 13518 MaxVersion: VersionTLS13, 13519 Bugs: ProtocolBugs{ 13520 SendFakeEarlyDataLength: 4, 13521 }, 13522 }, 13523 shouldFail: true, 13524 expectedError: ":UNEXPECTED_RECORD:", 13525 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 13526 }) 13527 13528 testCases = append(testCases, testCase{ 13529 testType: serverTest, 13530 name: "SkipEarlyData-HRR-TLS13", 13531 config: Config{ 13532 MaxVersion: VersionTLS13, 13533 Bugs: ProtocolBugs{ 13534 SendFakeEarlyDataLength: 4, 13535 }, 13536 DefaultCurves: []CurveID{}, 13537 }, 13538 // Though the session is not resumed and we send HelloRetryRequest, 13539 // early data being disabled takes priority as the reject reason. 13540 flags: []string{"-expect-early-data-reason", "disabled"}, 13541 }) 13542 13543 testCases = append(testCases, testCase{ 13544 testType: serverTest, 13545 name: "SkipEarlyData-HRR-Interleaved-TLS13", 13546 config: Config{ 13547 MaxVersion: VersionTLS13, 13548 Bugs: ProtocolBugs{ 13549 SendFakeEarlyDataLength: 4, 13550 InterleaveEarlyData: true, 13551 }, 13552 DefaultCurves: []CurveID{}, 13553 }, 13554 shouldFail: true, 13555 expectedError: ":UNEXPECTED_RECORD:", 13556 }) 13557 13558 testCases = append(testCases, testCase{ 13559 testType: serverTest, 13560 name: "SkipEarlyData-HRR-TooMuchData-TLS13", 13561 config: Config{ 13562 MaxVersion: VersionTLS13, 13563 Bugs: ProtocolBugs{ 13564 SendFakeEarlyDataLength: 16384 + 1, 13565 }, 13566 DefaultCurves: []CurveID{}, 13567 }, 13568 shouldFail: true, 13569 expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:", 13570 }) 13571 13572 // Test that skipping early data looking for cleartext correctly 13573 // processes an alert record. 13574 testCases = append(testCases, testCase{ 13575 testType: serverTest, 13576 name: "SkipEarlyData-HRR-FatalAlert-TLS13", 13577 config: Config{ 13578 MaxVersion: VersionTLS13, 13579 Bugs: ProtocolBugs{ 13580 SendEarlyAlert: true, 13581 SendFakeEarlyDataLength: 4, 13582 }, 13583 DefaultCurves: []CurveID{}, 13584 }, 13585 shouldFail: true, 13586 expectedError: ":SSLV3_ALERT_HANDSHAKE_FAILURE:", 13587 }) 13588 13589 testCases = append(testCases, testCase{ 13590 testType: serverTest, 13591 name: "SkipEarlyData-SecondClientHelloEarlyData-TLS13", 13592 config: Config{ 13593 MaxVersion: VersionTLS13, 13594 Bugs: ProtocolBugs{ 13595 SendEarlyDataOnSecondClientHello: true, 13596 }, 13597 DefaultCurves: []CurveID{}, 13598 }, 13599 shouldFail: true, 13600 expectedLocalError: "remote error: bad record MAC", 13601 }) 13602 13603 testCases = append(testCases, testCase{ 13604 testType: clientTest, 13605 name: "EmptyEncryptedExtensions-TLS13", 13606 config: Config{ 13607 MaxVersion: VersionTLS13, 13608 Bugs: ProtocolBugs{ 13609 EmptyEncryptedExtensions: true, 13610 }, 13611 }, 13612 shouldFail: true, 13613 expectedLocalError: "remote error: error decoding message", 13614 }) 13615 13616 testCases = append(testCases, testCase{ 13617 testType: clientTest, 13618 name: "EncryptedExtensionsWithKeyShare-TLS13", 13619 config: Config{ 13620 MaxVersion: VersionTLS13, 13621 Bugs: ProtocolBugs{ 13622 EncryptedExtensionsWithKeyShare: true, 13623 }, 13624 }, 13625 shouldFail: true, 13626 expectedLocalError: "remote error: unsupported extension", 13627 }) 13628 13629 testCases = append(testCases, testCase{ 13630 testType: serverTest, 13631 name: "SendHelloRetryRequest-TLS13", 13632 config: Config{ 13633 MaxVersion: VersionTLS13, 13634 // Require a HelloRetryRequest for every curve. 13635 DefaultCurves: []CurveID{}, 13636 CurvePreferences: []CurveID{CurveX25519}, 13637 }, 13638 expectations: connectionExpectations{ 13639 curveID: CurveX25519, 13640 }, 13641 flags: []string{"-expect-hrr"}, 13642 }) 13643 13644 testCases = append(testCases, testCase{ 13645 testType: serverTest, 13646 name: "SendHelloRetryRequest-2-TLS13", 13647 config: Config{ 13648 MaxVersion: VersionTLS13, 13649 DefaultCurves: []CurveID{CurveP384}, 13650 CurvePreferences: []CurveID{CurveX25519, CurveP384}, 13651 }, 13652 // Although the ClientHello did not predict our preferred curve, 13653 // we always select it whether it is predicted or not. 13654 expectations: connectionExpectations{ 13655 curveID: CurveX25519, 13656 }, 13657 flags: []string{"-expect-hrr"}, 13658 }) 13659 13660 testCases = append(testCases, testCase{ 13661 name: "UnknownCurve-HelloRetryRequest-TLS13", 13662 config: Config{ 13663 MaxVersion: VersionTLS13, 13664 // P-384 requires HelloRetryRequest in BoringSSL. 13665 CurvePreferences: []CurveID{CurveP384}, 13666 Bugs: ProtocolBugs{ 13667 SendHelloRetryRequestCurve: bogusCurve, 13668 }, 13669 }, 13670 shouldFail: true, 13671 expectedError: ":WRONG_CURVE:", 13672 }) 13673 13674 testCases = append(testCases, testCase{ 13675 name: "HelloRetryRequest-CipherChange-TLS13", 13676 config: Config{ 13677 MaxVersion: VersionTLS13, 13678 // P-384 requires HelloRetryRequest in BoringSSL. 13679 CurvePreferences: []CurveID{CurveP384}, 13680 Bugs: ProtocolBugs{ 13681 SendCipherSuite: TLS_AES_128_GCM_SHA256, 13682 SendHelloRetryRequestCipherSuite: TLS_CHACHA20_POLY1305_SHA256, 13683 }, 13684 }, 13685 shouldFail: true, 13686 expectedError: ":WRONG_CIPHER_RETURNED:", 13687 }) 13688 13689 // Test that the client does not offer a PSK in the second ClientHello if the 13690 // HelloRetryRequest is incompatible with it. 13691 testCases = append(testCases, testCase{ 13692 testType: clientTest, 13693 name: "HelloRetryRequest-NonResumableCipher-TLS13", 13694 config: Config{ 13695 MaxVersion: VersionTLS13, 13696 CipherSuites: []uint16{ 13697 TLS_AES_128_GCM_SHA256, 13698 }, 13699 }, 13700 resumeConfig: &Config{ 13701 MaxVersion: VersionTLS13, 13702 // P-384 requires HelloRetryRequest in BoringSSL. 13703 CurvePreferences: []CurveID{CurveP384}, 13704 Bugs: ProtocolBugs{ 13705 ExpectNoTLS13PSKAfterHRR: true, 13706 }, 13707 CipherSuites: []uint16{ 13708 TLS_AES_256_GCM_SHA384, 13709 }, 13710 }, 13711 resumeSession: true, 13712 expectResumeRejected: true, 13713 }) 13714 13715 testCases = append(testCases, testCase{ 13716 name: "DisabledCurve-HelloRetryRequest-TLS13", 13717 config: Config{ 13718 MaxVersion: VersionTLS13, 13719 CurvePreferences: []CurveID{CurveP256}, 13720 Bugs: ProtocolBugs{ 13721 IgnorePeerCurvePreferences: true, 13722 }, 13723 }, 13724 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 13725 shouldFail: true, 13726 expectedError: ":WRONG_CURVE:", 13727 }) 13728 13729 testCases = append(testCases, testCase{ 13730 name: "UnnecessaryHelloRetryRequest-TLS13", 13731 config: Config{ 13732 MaxVersion: VersionTLS13, 13733 CurvePreferences: []CurveID{CurveX25519}, 13734 Bugs: ProtocolBugs{ 13735 SendHelloRetryRequestCurve: CurveX25519, 13736 }, 13737 }, 13738 shouldFail: true, 13739 expectedError: ":WRONG_CURVE:", 13740 }) 13741 13742 testCases = append(testCases, testCase{ 13743 name: "SecondHelloRetryRequest-TLS13", 13744 config: Config{ 13745 MaxVersion: VersionTLS13, 13746 // P-384 requires HelloRetryRequest in BoringSSL. 13747 CurvePreferences: []CurveID{CurveP384}, 13748 Bugs: ProtocolBugs{ 13749 SecondHelloRetryRequest: true, 13750 }, 13751 }, 13752 shouldFail: true, 13753 expectedError: ":UNEXPECTED_MESSAGE:", 13754 }) 13755 13756 testCases = append(testCases, testCase{ 13757 name: "HelloRetryRequest-Empty-TLS13", 13758 config: Config{ 13759 MaxVersion: VersionTLS13, 13760 Bugs: ProtocolBugs{ 13761 AlwaysSendHelloRetryRequest: true, 13762 }, 13763 }, 13764 shouldFail: true, 13765 expectedError: ":EMPTY_HELLO_RETRY_REQUEST:", 13766 expectedLocalError: "remote error: illegal parameter", 13767 }) 13768 13769 testCases = append(testCases, testCase{ 13770 name: "HelloRetryRequest-DuplicateCurve-TLS13", 13771 config: Config{ 13772 MaxVersion: VersionTLS13, 13773 // P-384 requires a HelloRetryRequest against BoringSSL's default 13774 // configuration. Assert this ExpectMissingKeyShare. 13775 CurvePreferences: []CurveID{CurveP384}, 13776 Bugs: ProtocolBugs{ 13777 ExpectMissingKeyShare: true, 13778 DuplicateHelloRetryRequestExtensions: true, 13779 }, 13780 }, 13781 shouldFail: true, 13782 expectedError: ":DUPLICATE_EXTENSION:", 13783 expectedLocalError: "remote error: illegal parameter", 13784 }) 13785 13786 testCases = append(testCases, testCase{ 13787 name: "HelloRetryRequest-Cookie-TLS13", 13788 config: Config{ 13789 MaxVersion: VersionTLS13, 13790 Bugs: ProtocolBugs{ 13791 SendHelloRetryRequestCookie: []byte("cookie"), 13792 }, 13793 }, 13794 }) 13795 13796 testCases = append(testCases, testCase{ 13797 name: "HelloRetryRequest-DuplicateCookie-TLS13", 13798 config: Config{ 13799 MaxVersion: VersionTLS13, 13800 Bugs: ProtocolBugs{ 13801 SendHelloRetryRequestCookie: []byte("cookie"), 13802 DuplicateHelloRetryRequestExtensions: true, 13803 }, 13804 }, 13805 shouldFail: true, 13806 expectedError: ":DUPLICATE_EXTENSION:", 13807 expectedLocalError: "remote error: illegal parameter", 13808 }) 13809 13810 testCases = append(testCases, testCase{ 13811 name: "HelloRetryRequest-EmptyCookie-TLS13", 13812 config: Config{ 13813 MaxVersion: VersionTLS13, 13814 Bugs: ProtocolBugs{ 13815 SendHelloRetryRequestCookie: []byte{}, 13816 }, 13817 }, 13818 shouldFail: true, 13819 expectedError: ":DECODE_ERROR:", 13820 }) 13821 13822 testCases = append(testCases, testCase{ 13823 name: "HelloRetryRequest-Cookie-Curve-TLS13", 13824 config: Config{ 13825 MaxVersion: VersionTLS13, 13826 // P-384 requires HelloRetryRequest in BoringSSL. 13827 CurvePreferences: []CurveID{CurveP384}, 13828 Bugs: ProtocolBugs{ 13829 SendHelloRetryRequestCookie: []byte("cookie"), 13830 ExpectMissingKeyShare: true, 13831 }, 13832 }, 13833 }) 13834 13835 testCases = append(testCases, testCase{ 13836 name: "HelloRetryRequest-Unknown-TLS13", 13837 config: Config{ 13838 MaxVersion: VersionTLS13, 13839 Bugs: ProtocolBugs{ 13840 CustomHelloRetryRequestExtension: "extension", 13841 }, 13842 }, 13843 shouldFail: true, 13844 expectedError: ":UNEXPECTED_EXTENSION:", 13845 expectedLocalError: "remote error: unsupported extension", 13846 }) 13847 13848 testCases = append(testCases, testCase{ 13849 testType: serverTest, 13850 name: "SecondClientHelloMissingKeyShare-TLS13", 13851 config: Config{ 13852 MaxVersion: VersionTLS13, 13853 DefaultCurves: []CurveID{}, 13854 Bugs: ProtocolBugs{ 13855 SecondClientHelloMissingKeyShare: true, 13856 }, 13857 }, 13858 shouldFail: true, 13859 expectedError: ":MISSING_KEY_SHARE:", 13860 }) 13861 13862 testCases = append(testCases, testCase{ 13863 testType: serverTest, 13864 name: "SecondClientHelloWrongCurve-TLS13", 13865 config: Config{ 13866 MaxVersion: VersionTLS13, 13867 DefaultCurves: []CurveID{}, 13868 Bugs: ProtocolBugs{ 13869 MisinterpretHelloRetryRequestCurve: CurveP521, 13870 }, 13871 }, 13872 shouldFail: true, 13873 expectedError: ":WRONG_CURVE:", 13874 }) 13875 13876 testCases = append(testCases, testCase{ 13877 name: "HelloRetryRequestVersionMismatch-TLS13", 13878 config: Config{ 13879 MaxVersion: VersionTLS13, 13880 // P-384 requires HelloRetryRequest in BoringSSL. 13881 CurvePreferences: []CurveID{CurveP384}, 13882 Bugs: ProtocolBugs{ 13883 SendServerHelloVersion: 0x0305, 13884 }, 13885 }, 13886 shouldFail: true, 13887 expectedError: ":DECODE_ERROR:", 13888 }) 13889 13890 testCases = append(testCases, testCase{ 13891 name: "HelloRetryRequestCurveMismatch-TLS13", 13892 config: Config{ 13893 MaxVersion: VersionTLS13, 13894 // P-384 requires HelloRetryRequest in BoringSSL. 13895 CurvePreferences: []CurveID{CurveP384}, 13896 Bugs: ProtocolBugs{ 13897 // Send P-384 (correct) in the HelloRetryRequest. 13898 SendHelloRetryRequestCurve: CurveP384, 13899 // But send P-256 in the ServerHello. 13900 SendCurve: CurveP256, 13901 }, 13902 }, 13903 shouldFail: true, 13904 expectedError: ":WRONG_CURVE:", 13905 }) 13906 13907 // Test the server selecting a curve that requires a HelloRetryRequest 13908 // without sending it. 13909 testCases = append(testCases, testCase{ 13910 name: "SkipHelloRetryRequest-TLS13", 13911 config: Config{ 13912 MaxVersion: VersionTLS13, 13913 // P-384 requires HelloRetryRequest in BoringSSL. 13914 CurvePreferences: []CurveID{CurveP384}, 13915 Bugs: ProtocolBugs{ 13916 SkipHelloRetryRequest: true, 13917 }, 13918 }, 13919 shouldFail: true, 13920 expectedError: ":WRONG_CURVE:", 13921 }) 13922 13923 testCases = append(testCases, testCase{ 13924 name: "SecondServerHelloNoVersion-TLS13", 13925 config: Config{ 13926 MaxVersion: VersionTLS13, 13927 // P-384 requires HelloRetryRequest in BoringSSL. 13928 CurvePreferences: []CurveID{CurveP384}, 13929 Bugs: ProtocolBugs{ 13930 OmitServerSupportedVersionExtension: true, 13931 }, 13932 }, 13933 shouldFail: true, 13934 expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:", 13935 }) 13936 testCases = append(testCases, testCase{ 13937 name: "SecondServerHelloWrongVersion-TLS13", 13938 config: Config{ 13939 MaxVersion: VersionTLS13, 13940 // P-384 requires HelloRetryRequest in BoringSSL. 13941 CurvePreferences: []CurveID{CurveP384}, 13942 Bugs: ProtocolBugs{ 13943 SendServerSupportedVersionExtension: 0x1234, 13944 }, 13945 }, 13946 shouldFail: true, 13947 expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:", 13948 }) 13949 13950 testCases = append(testCases, testCase{ 13951 name: "RequestContextInHandshake-TLS13", 13952 config: Config{ 13953 MaxVersion: VersionTLS13, 13954 MinVersion: VersionTLS13, 13955 ClientAuth: RequireAnyClientCert, 13956 Bugs: ProtocolBugs{ 13957 SendRequestContext: []byte("request context"), 13958 }, 13959 }, 13960 flags: []string{ 13961 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 13962 "-key-file", path.Join(*resourceDir, rsaKeyFile), 13963 }, 13964 shouldFail: true, 13965 expectedError: ":DECODE_ERROR:", 13966 }) 13967 13968 testCases = append(testCases, testCase{ 13969 name: "UnknownExtensionInCertificateRequest-TLS13", 13970 config: Config{ 13971 MaxVersion: VersionTLS13, 13972 MinVersion: VersionTLS13, 13973 ClientAuth: RequireAnyClientCert, 13974 Bugs: ProtocolBugs{ 13975 SendCustomCertificateRequest: 0x1212, 13976 }, 13977 }, 13978 flags: []string{ 13979 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 13980 "-key-file", path.Join(*resourceDir, rsaKeyFile), 13981 }, 13982 }) 13983 13984 testCases = append(testCases, testCase{ 13985 name: "MissingSignatureAlgorithmsInCertificateRequest-TLS13", 13986 config: Config{ 13987 MaxVersion: VersionTLS13, 13988 MinVersion: VersionTLS13, 13989 ClientAuth: RequireAnyClientCert, 13990 Bugs: ProtocolBugs{ 13991 OmitCertificateRequestAlgorithms: true, 13992 }, 13993 }, 13994 flags: []string{ 13995 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 13996 "-key-file", path.Join(*resourceDir, rsaKeyFile), 13997 }, 13998 shouldFail: true, 13999 expectedError: ":DECODE_ERROR:", 14000 }) 14001 14002 testCases = append(testCases, testCase{ 14003 testType: serverTest, 14004 name: "TrailingKeyShareData-TLS13", 14005 config: Config{ 14006 MaxVersion: VersionTLS13, 14007 Bugs: ProtocolBugs{ 14008 TrailingKeyShareData: true, 14009 }, 14010 }, 14011 shouldFail: true, 14012 expectedError: ":DECODE_ERROR:", 14013 }) 14014 14015 testCases = append(testCases, testCase{ 14016 name: "AlwaysSelectPSKIdentity-TLS13", 14017 config: Config{ 14018 MaxVersion: VersionTLS13, 14019 Bugs: ProtocolBugs{ 14020 AlwaysSelectPSKIdentity: true, 14021 }, 14022 }, 14023 shouldFail: true, 14024 expectedError: ":UNEXPECTED_EXTENSION:", 14025 }) 14026 14027 testCases = append(testCases, testCase{ 14028 name: "InvalidPSKIdentity-TLS13", 14029 config: Config{ 14030 MaxVersion: VersionTLS13, 14031 Bugs: ProtocolBugs{ 14032 SelectPSKIdentityOnResume: 1, 14033 }, 14034 }, 14035 resumeSession: true, 14036 shouldFail: true, 14037 expectedError: ":PSK_IDENTITY_NOT_FOUND:", 14038 }) 14039 14040 testCases = append(testCases, testCase{ 14041 testType: serverTest, 14042 name: "ExtraPSKIdentity-TLS13", 14043 config: Config{ 14044 MaxVersion: VersionTLS13, 14045 Bugs: ProtocolBugs{ 14046 ExtraPSKIdentity: true, 14047 SendExtraPSKBinder: true, 14048 }, 14049 }, 14050 resumeSession: true, 14051 }) 14052 14053 // Test that unknown NewSessionTicket extensions are tolerated. 14054 testCases = append(testCases, testCase{ 14055 name: "CustomTicketExtension-TLS13", 14056 config: Config{ 14057 MaxVersion: VersionTLS13, 14058 Bugs: ProtocolBugs{ 14059 CustomTicketExtension: "1234", 14060 }, 14061 }, 14062 }) 14063 14064 // Test the client handles 0-RTT being rejected by a full handshake 14065 // and correctly reports a certificate change. 14066 testCases = append(testCases, testCase{ 14067 testType: clientTest, 14068 name: "EarlyData-RejectTicket-Client-TLS13", 14069 config: Config{ 14070 MaxVersion: VersionTLS13, 14071 Certificates: []Certificate{rsaCertificate}, 14072 }, 14073 resumeConfig: &Config{ 14074 MaxVersion: VersionTLS13, 14075 Certificates: []Certificate{ecdsaP256Certificate}, 14076 SessionTicketsDisabled: true, 14077 }, 14078 resumeSession: true, 14079 expectResumeRejected: true, 14080 earlyData: true, 14081 expectEarlyDataRejected: true, 14082 flags: []string{ 14083 "-on-retry-expect-early-data-reason", "session_not_resumed", 14084 // Test the peer certificate is reported correctly in each of the 14085 // three logical connections. 14086 "-on-initial-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14087 "-on-resume-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14088 "-on-retry-expect-peer-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 14089 // Session tickets are disabled, so the runner will not send a ticket. 14090 "-on-retry-expect-no-session", 14091 }, 14092 }) 14093 14094 // Test the server rejects 0-RTT if it does not recognize the ticket. 14095 testCases = append(testCases, testCase{ 14096 testType: serverTest, 14097 name: "EarlyData-RejectTicket-Server-TLS13", 14098 config: Config{ 14099 MaxVersion: VersionTLS13, 14100 MinVersion: VersionTLS13, 14101 Bugs: ProtocolBugs{ 14102 // Corrupt the ticket. 14103 FilterTicket: func(in []byte) ([]byte, error) { 14104 in[len(in)-1] ^= 1 14105 return in, nil 14106 }, 14107 }, 14108 }, 14109 messageCount: 2, 14110 resumeSession: true, 14111 expectResumeRejected: true, 14112 earlyData: true, 14113 expectEarlyDataRejected: true, 14114 flags: []string{ 14115 "-on-resume-expect-early-data-reason", "session_not_resumed", 14116 }, 14117 }) 14118 14119 // Test the client handles 0-RTT being rejected via a HelloRetryRequest. 14120 testCases = append(testCases, testCase{ 14121 testType: clientTest, 14122 name: "EarlyData-HRR-Client-TLS13", 14123 config: Config{ 14124 MaxVersion: VersionTLS13, 14125 }, 14126 resumeConfig: &Config{ 14127 MaxVersion: VersionTLS13, 14128 Bugs: ProtocolBugs{ 14129 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14130 }, 14131 }, 14132 resumeSession: true, 14133 earlyData: true, 14134 expectEarlyDataRejected: true, 14135 flags: []string{ 14136 "-on-retry-expect-early-data-reason", "hello_retry_request", 14137 }, 14138 }) 14139 14140 // Test the server rejects 0-RTT if it needs to send a HelloRetryRequest. 14141 testCases = append(testCases, testCase{ 14142 testType: serverTest, 14143 name: "EarlyData-HRR-Server-TLS13", 14144 config: Config{ 14145 MaxVersion: VersionTLS13, 14146 MinVersion: VersionTLS13, 14147 // Require a HelloRetryRequest for every curve. 14148 DefaultCurves: []CurveID{}, 14149 }, 14150 messageCount: 2, 14151 resumeSession: true, 14152 earlyData: true, 14153 expectEarlyDataRejected: true, 14154 flags: []string{ 14155 "-on-resume-expect-early-data-reason", "hello_retry_request", 14156 }, 14157 }) 14158 14159 // Test the client handles a 0-RTT reject from both ticket rejection and 14160 // HelloRetryRequest. 14161 testCases = append(testCases, testCase{ 14162 testType: clientTest, 14163 name: "EarlyData-HRR-RejectTicket-Client-TLS13", 14164 config: Config{ 14165 MaxVersion: VersionTLS13, 14166 Certificates: []Certificate{rsaCertificate}, 14167 }, 14168 resumeConfig: &Config{ 14169 MaxVersion: VersionTLS13, 14170 Certificates: []Certificate{ecdsaP256Certificate}, 14171 SessionTicketsDisabled: true, 14172 Bugs: ProtocolBugs{ 14173 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14174 }, 14175 }, 14176 resumeSession: true, 14177 expectResumeRejected: true, 14178 earlyData: true, 14179 expectEarlyDataRejected: true, 14180 flags: []string{ 14181 // The client sees HelloRetryRequest before the resumption result, 14182 // though neither value is inherently preferable. 14183 "-on-retry-expect-early-data-reason", "hello_retry_request", 14184 // Test the peer certificate is reported correctly in each of the 14185 // three logical connections. 14186 "-on-initial-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14187 "-on-resume-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile), 14188 "-on-retry-expect-peer-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile), 14189 // Session tickets are disabled, so the runner will not send a ticket. 14190 "-on-retry-expect-no-session", 14191 }, 14192 }) 14193 14194 // Test the server rejects 0-RTT if it needs to send a HelloRetryRequest. 14195 testCases = append(testCases, testCase{ 14196 testType: serverTest, 14197 name: "EarlyData-HRR-RejectTicket-Server-TLS13", 14198 config: Config{ 14199 MaxVersion: VersionTLS13, 14200 MinVersion: VersionTLS13, 14201 // Require a HelloRetryRequest for every curve. 14202 DefaultCurves: []CurveID{}, 14203 Bugs: ProtocolBugs{ 14204 // Corrupt the ticket. 14205 FilterTicket: func(in []byte) ([]byte, error) { 14206 in[len(in)-1] ^= 1 14207 return in, nil 14208 }, 14209 }, 14210 }, 14211 messageCount: 2, 14212 resumeSession: true, 14213 expectResumeRejected: true, 14214 earlyData: true, 14215 expectEarlyDataRejected: true, 14216 flags: []string{ 14217 // The server sees the missed resumption before HelloRetryRequest, 14218 // though neither value is inherently preferable. 14219 "-on-resume-expect-early-data-reason", "session_not_resumed", 14220 }, 14221 }) 14222 14223 // The client must check the server does not send the early_data 14224 // extension while rejecting the session. 14225 testCases = append(testCases, testCase{ 14226 testType: clientTest, 14227 name: "EarlyDataWithoutResume-Client-TLS13", 14228 config: Config{ 14229 MaxVersion: VersionTLS13, 14230 MaxEarlyDataSize: 16384, 14231 }, 14232 resumeConfig: &Config{ 14233 MaxVersion: VersionTLS13, 14234 SessionTicketsDisabled: true, 14235 Bugs: ProtocolBugs{ 14236 SendEarlyDataExtension: true, 14237 }, 14238 }, 14239 resumeSession: true, 14240 earlyData: true, 14241 shouldFail: true, 14242 expectedError: ":UNEXPECTED_EXTENSION:", 14243 }) 14244 14245 // The client must fail with a dedicated error code if the server 14246 // responds with TLS 1.2 when offering 0-RTT. 14247 testCases = append(testCases, testCase{ 14248 testType: clientTest, 14249 name: "EarlyDataVersionDowngrade-Client-TLS13", 14250 config: Config{ 14251 MaxVersion: VersionTLS13, 14252 }, 14253 resumeConfig: &Config{ 14254 MaxVersion: VersionTLS12, 14255 }, 14256 resumeSession: true, 14257 earlyData: true, 14258 shouldFail: true, 14259 expectedError: ":WRONG_VERSION_ON_EARLY_DATA:", 14260 }) 14261 14262 // Test that the client rejects an (unsolicited) early_data extension if 14263 // the server sent an HRR. 14264 testCases = append(testCases, testCase{ 14265 testType: clientTest, 14266 name: "ServerAcceptsEarlyDataOnHRR-Client-TLS13", 14267 config: Config{ 14268 MaxVersion: VersionTLS13, 14269 }, 14270 resumeConfig: &Config{ 14271 MaxVersion: VersionTLS13, 14272 Bugs: ProtocolBugs{ 14273 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14274 SendEarlyDataExtension: true, 14275 }, 14276 }, 14277 resumeSession: true, 14278 earlyData: true, 14279 // The client will first process an early data reject from the HRR. 14280 expectEarlyDataRejected: true, 14281 shouldFail: true, 14282 expectedError: ":UNEXPECTED_EXTENSION:", 14283 }) 14284 14285 testCases = append(testCases, testCase{ 14286 testType: clientTest, 14287 name: "SkipChangeCipherSpec-Client-TLS13", 14288 config: Config{ 14289 MaxVersion: VersionTLS13, 14290 Bugs: ProtocolBugs{ 14291 SkipChangeCipherSpec: true, 14292 }, 14293 }, 14294 }) 14295 14296 testCases = append(testCases, testCase{ 14297 testType: serverTest, 14298 name: "SkipChangeCipherSpec-Server-TLS13", 14299 config: Config{ 14300 MaxVersion: VersionTLS13, 14301 Bugs: ProtocolBugs{ 14302 SkipChangeCipherSpec: true, 14303 }, 14304 }, 14305 }) 14306 14307 testCases = append(testCases, testCase{ 14308 testType: clientTest, 14309 name: "TooManyChangeCipherSpec-Client-TLS13", 14310 config: Config{ 14311 MaxVersion: VersionTLS13, 14312 Bugs: ProtocolBugs{ 14313 SendExtraChangeCipherSpec: 33, 14314 }, 14315 }, 14316 shouldFail: true, 14317 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 14318 }) 14319 14320 testCases = append(testCases, testCase{ 14321 testType: serverTest, 14322 name: "TooManyChangeCipherSpec-Server-TLS13", 14323 config: Config{ 14324 MaxVersion: VersionTLS13, 14325 Bugs: ProtocolBugs{ 14326 SendExtraChangeCipherSpec: 33, 14327 }, 14328 }, 14329 shouldFail: true, 14330 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 14331 }) 14332 14333 testCases = append(testCases, testCase{ 14334 name: "SendPostHandshakeChangeCipherSpec-TLS13", 14335 config: Config{ 14336 MaxVersion: VersionTLS13, 14337 Bugs: ProtocolBugs{ 14338 SendPostHandshakeChangeCipherSpec: true, 14339 }, 14340 }, 14341 shouldFail: true, 14342 expectedError: ":UNEXPECTED_RECORD:", 14343 expectedLocalError: "remote error: unexpected message", 14344 }) 14345 14346 fooString := "foo" 14347 barString := "bar" 14348 14349 // Test that the client reports the correct ALPN after a 0-RTT reject 14350 // that changed it. 14351 testCases = append(testCases, testCase{ 14352 testType: clientTest, 14353 name: "EarlyData-ALPNMismatch-Client-TLS13", 14354 config: Config{ 14355 MaxVersion: VersionTLS13, 14356 Bugs: ProtocolBugs{ 14357 ALPNProtocol: &fooString, 14358 }, 14359 }, 14360 resumeConfig: &Config{ 14361 MaxVersion: VersionTLS13, 14362 Bugs: ProtocolBugs{ 14363 ALPNProtocol: &barString, 14364 }, 14365 }, 14366 resumeSession: true, 14367 earlyData: true, 14368 expectEarlyDataRejected: true, 14369 flags: []string{ 14370 "-advertise-alpn", "\x03foo\x03bar", 14371 // The client does not learn ALPN was the cause. 14372 "-on-retry-expect-early-data-reason", "peer_declined", 14373 // In the 0-RTT state, we surface the predicted ALPN. After 14374 // processing the reject, we surface the real one. 14375 "-on-initial-expect-alpn", "foo", 14376 "-on-resume-expect-alpn", "foo", 14377 "-on-retry-expect-alpn", "bar", 14378 }, 14379 }) 14380 14381 // Test that the client reports the correct ALPN after a 0-RTT reject if 14382 // ALPN was omitted from the first connection. 14383 testCases = append(testCases, testCase{ 14384 testType: clientTest, 14385 name: "EarlyData-ALPNOmitted1-Client-TLS13", 14386 config: Config{ 14387 MaxVersion: VersionTLS13, 14388 }, 14389 resumeConfig: &Config{ 14390 MaxVersion: VersionTLS13, 14391 NextProtos: []string{"foo"}, 14392 }, 14393 resumeSession: true, 14394 earlyData: true, 14395 expectEarlyDataRejected: true, 14396 flags: []string{ 14397 "-advertise-alpn", "\x03foo\x03bar", 14398 // The client does not learn ALPN was the cause. 14399 "-on-retry-expect-early-data-reason", "peer_declined", 14400 // In the 0-RTT state, we surface the predicted ALPN. After 14401 // processing the reject, we surface the real one. 14402 "-on-initial-expect-alpn", "", 14403 "-on-resume-expect-alpn", "", 14404 "-on-retry-expect-alpn", "foo", 14405 }, 14406 }) 14407 14408 // Test that the client reports the correct ALPN after a 0-RTT reject if 14409 // ALPN was omitted from the second connection. 14410 testCases = append(testCases, testCase{ 14411 testType: clientTest, 14412 name: "EarlyData-ALPNOmitted2-Client-TLS13", 14413 config: Config{ 14414 MaxVersion: VersionTLS13, 14415 NextProtos: []string{"foo"}, 14416 }, 14417 resumeConfig: &Config{ 14418 MaxVersion: VersionTLS13, 14419 }, 14420 resumeSession: true, 14421 earlyData: true, 14422 expectEarlyDataRejected: true, 14423 flags: []string{ 14424 "-advertise-alpn", "\x03foo\x03bar", 14425 // The client does not learn ALPN was the cause. 14426 "-on-retry-expect-early-data-reason", "peer_declined", 14427 // In the 0-RTT state, we surface the predicted ALPN. After 14428 // processing the reject, we surface the real one. 14429 "-on-initial-expect-alpn", "foo", 14430 "-on-resume-expect-alpn", "foo", 14431 "-on-retry-expect-alpn", "", 14432 }, 14433 }) 14434 14435 // Test that the client enforces ALPN match on 0-RTT accept. 14436 testCases = append(testCases, testCase{ 14437 testType: clientTest, 14438 name: "EarlyData-BadALPNMismatch-Client-TLS13", 14439 config: Config{ 14440 MaxVersion: VersionTLS13, 14441 Bugs: ProtocolBugs{ 14442 ALPNProtocol: &fooString, 14443 }, 14444 }, 14445 resumeConfig: &Config{ 14446 MaxVersion: VersionTLS13, 14447 Bugs: ProtocolBugs{ 14448 AlwaysAcceptEarlyData: true, 14449 ALPNProtocol: &barString, 14450 }, 14451 }, 14452 resumeSession: true, 14453 earlyData: true, 14454 flags: []string{ 14455 "-advertise-alpn", "\x03foo\x03bar", 14456 "-on-initial-expect-alpn", "foo", 14457 "-on-resume-expect-alpn", "foo", 14458 "-on-retry-expect-alpn", "bar", 14459 }, 14460 shouldFail: true, 14461 expectedError: ":ALPN_MISMATCH_ON_EARLY_DATA:", 14462 expectedLocalError: "remote error: illegal parameter", 14463 }) 14464 14465 // Test that the client does not offer early data if it is incompatible 14466 // with ALPN preferences. 14467 testCases = append(testCases, testCase{ 14468 testType: clientTest, 14469 name: "EarlyData-ALPNPreferenceChanged-TLS13", 14470 config: Config{ 14471 MaxVersion: VersionTLS13, 14472 MaxEarlyDataSize: 16384, 14473 NextProtos: []string{"foo", "bar"}, 14474 }, 14475 resumeSession: true, 14476 flags: []string{ 14477 "-enable-early-data", 14478 "-expect-ticket-supports-early-data", 14479 "-expect-no-offer-early-data", 14480 // Offer different ALPN values in the initial and resumption. 14481 "-on-initial-advertise-alpn", "\x03foo", 14482 "-on-initial-expect-alpn", "foo", 14483 "-on-resume-advertise-alpn", "\x03bar", 14484 "-on-resume-expect-alpn", "bar", 14485 // The ALPN mismatch comes from the client, so it reports it as the 14486 // reason. 14487 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14488 }, 14489 }) 14490 14491 // Test that the client does not offer 0-RTT to servers which never 14492 // advertise it. 14493 testCases = append(testCases, testCase{ 14494 testType: clientTest, 14495 name: "EarlyData-NonZeroRTTSession-Client-TLS13", 14496 config: Config{ 14497 MaxVersion: VersionTLS13, 14498 }, 14499 resumeSession: true, 14500 flags: []string{ 14501 "-enable-early-data", 14502 "-on-resume-expect-no-offer-early-data", 14503 // The client declines to offer 0-RTT because of the session. 14504 "-on-resume-expect-early-data-reason", "unsupported_for_session", 14505 }, 14506 }) 14507 14508 // Test that the server correctly rejects 0-RTT when the previous 14509 // session did not allow early data on resumption. 14510 testCases = append(testCases, testCase{ 14511 testType: serverTest, 14512 name: "EarlyData-NonZeroRTTSession-Server-TLS13", 14513 config: Config{ 14514 MaxVersion: VersionTLS13, 14515 }, 14516 resumeConfig: &Config{ 14517 MaxVersion: VersionTLS13, 14518 Bugs: ProtocolBugs{ 14519 SendEarlyData: [][]byte{{1, 2, 3, 4}}, 14520 ExpectEarlyDataAccepted: false, 14521 }, 14522 }, 14523 resumeSession: true, 14524 // This test configures early data manually instead of the earlyData 14525 // option, to customize the -enable-early-data flag. 14526 flags: []string{ 14527 "-on-resume-enable-early-data", 14528 "-expect-reject-early-data", 14529 // The server rejects 0-RTT because of the session. 14530 "-on-resume-expect-early-data-reason", "unsupported_for_session", 14531 }, 14532 }) 14533 14534 // Test that we reject early data where ALPN is omitted from the first 14535 // connection, but negotiated in the second. 14536 testCases = append(testCases, testCase{ 14537 testType: serverTest, 14538 name: "EarlyData-ALPNOmitted1-Server-TLS13", 14539 config: Config{ 14540 MaxVersion: VersionTLS13, 14541 NextProtos: []string{}, 14542 }, 14543 resumeConfig: &Config{ 14544 MaxVersion: VersionTLS13, 14545 NextProtos: []string{"foo"}, 14546 }, 14547 resumeSession: true, 14548 earlyData: true, 14549 expectEarlyDataRejected: true, 14550 flags: []string{ 14551 "-on-initial-select-alpn", "", 14552 "-on-resume-select-alpn", "foo", 14553 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14554 }, 14555 }) 14556 14557 // Test that we reject early data where ALPN is omitted from the second 14558 // connection, but negotiated in the first. 14559 testCases = append(testCases, testCase{ 14560 testType: serverTest, 14561 name: "EarlyData-ALPNOmitted2-Server-TLS13", 14562 config: Config{ 14563 MaxVersion: VersionTLS13, 14564 NextProtos: []string{"foo"}, 14565 }, 14566 resumeConfig: &Config{ 14567 MaxVersion: VersionTLS13, 14568 NextProtos: []string{}, 14569 }, 14570 resumeSession: true, 14571 earlyData: true, 14572 expectEarlyDataRejected: true, 14573 flags: []string{ 14574 "-on-initial-select-alpn", "foo", 14575 "-on-resume-select-alpn", "", 14576 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14577 }, 14578 }) 14579 14580 // Test that we reject early data with mismatched ALPN. 14581 testCases = append(testCases, testCase{ 14582 testType: serverTest, 14583 name: "EarlyData-ALPNMismatch-Server-TLS13", 14584 config: Config{ 14585 MaxVersion: VersionTLS13, 14586 NextProtos: []string{"foo"}, 14587 }, 14588 resumeConfig: &Config{ 14589 MaxVersion: VersionTLS13, 14590 NextProtos: []string{"bar"}, 14591 }, 14592 resumeSession: true, 14593 earlyData: true, 14594 expectEarlyDataRejected: true, 14595 flags: []string{ 14596 "-on-initial-select-alpn", "foo", 14597 "-on-resume-select-alpn", "bar", 14598 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14599 }, 14600 }) 14601 14602 // Test that the client offering 0-RTT and Channel ID forbids the server 14603 // from accepting both. 14604 testCases = append(testCases, testCase{ 14605 testType: clientTest, 14606 name: "EarlyDataChannelID-AcceptBoth-Client-TLS13", 14607 config: Config{ 14608 MaxVersion: VersionTLS13, 14609 RequestChannelID: true, 14610 }, 14611 resumeSession: true, 14612 earlyData: true, 14613 expectations: connectionExpectations{ 14614 channelID: true, 14615 }, 14616 shouldFail: true, 14617 expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:", 14618 expectedLocalError: "remote error: illegal parameter", 14619 flags: []string{ 14620 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 14621 }, 14622 }) 14623 14624 // Test that the client offering Channel ID and 0-RTT allows the server 14625 // to decline 0-RTT. 14626 testCases = append(testCases, testCase{ 14627 testType: clientTest, 14628 name: "EarlyDataChannelID-AcceptChannelID-Client-TLS13", 14629 config: Config{ 14630 MaxVersion: VersionTLS13, 14631 RequestChannelID: true, 14632 Bugs: ProtocolBugs{ 14633 AlwaysRejectEarlyData: true, 14634 }, 14635 }, 14636 resumeSession: true, 14637 earlyData: true, 14638 expectEarlyDataRejected: true, 14639 expectations: connectionExpectations{ 14640 channelID: true, 14641 }, 14642 flags: []string{ 14643 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 14644 // The client never learns the reason was Channel ID. 14645 "-on-retry-expect-early-data-reason", "peer_declined", 14646 }, 14647 }) 14648 14649 // Test that the client offering Channel ID and 0-RTT allows the server 14650 // to decline Channel ID. 14651 testCases = append(testCases, testCase{ 14652 testType: clientTest, 14653 name: "EarlyDataChannelID-AcceptEarlyData-Client-TLS13", 14654 config: Config{ 14655 MaxVersion: VersionTLS13, 14656 }, 14657 resumeSession: true, 14658 earlyData: true, 14659 flags: []string{ 14660 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 14661 }, 14662 }) 14663 14664 // Test that the server supporting Channel ID and 0-RTT declines 0-RTT 14665 // if it would negotiate Channel ID. 14666 testCases = append(testCases, testCase{ 14667 testType: serverTest, 14668 name: "EarlyDataChannelID-OfferBoth-Server-TLS13", 14669 config: Config{ 14670 MaxVersion: VersionTLS13, 14671 ChannelID: channelIDKey, 14672 }, 14673 resumeSession: true, 14674 earlyData: true, 14675 expectEarlyDataRejected: true, 14676 expectations: connectionExpectations{ 14677 channelID: true, 14678 }, 14679 flags: []string{ 14680 "-expect-channel-id", 14681 base64FlagValue(channelIDBytes), 14682 "-on-resume-expect-early-data-reason", "channel_id", 14683 }, 14684 }) 14685 14686 // Test that the server supporting Channel ID and 0-RTT accepts 0-RTT 14687 // if not offered Channel ID. 14688 testCases = append(testCases, testCase{ 14689 testType: serverTest, 14690 name: "EarlyDataChannelID-OfferEarlyData-Server-TLS13", 14691 config: Config{ 14692 MaxVersion: VersionTLS13, 14693 }, 14694 resumeSession: true, 14695 earlyData: true, 14696 expectations: connectionExpectations{ 14697 channelID: false, 14698 }, 14699 flags: []string{ 14700 "-enable-channel-id", 14701 "-on-resume-expect-early-data-reason", "accept", 14702 }, 14703 }) 14704 14705 // Test that the server errors on 0-RTT streams without end_of_early_data. 14706 // The subsequent records should fail to decrypt. 14707 testCases = append(testCases, testCase{ 14708 testType: serverTest, 14709 name: "EarlyData-SkipEndOfEarlyData-TLS13", 14710 config: Config{ 14711 MaxVersion: VersionTLS13, 14712 Bugs: ProtocolBugs{ 14713 SkipEndOfEarlyData: true, 14714 }, 14715 }, 14716 resumeSession: true, 14717 earlyData: true, 14718 shouldFail: true, 14719 expectedLocalError: "remote error: bad record MAC", 14720 expectedError: ":BAD_DECRYPT:", 14721 }) 14722 14723 // Test that the server errors on 0-RTT streams with a stray handshake 14724 // message in them. 14725 testCases = append(testCases, testCase{ 14726 testType: serverTest, 14727 name: "EarlyData-UnexpectedHandshake-Server-TLS13", 14728 config: Config{ 14729 MaxVersion: VersionTLS13, 14730 }, 14731 resumeConfig: &Config{ 14732 MaxVersion: VersionTLS13, 14733 Bugs: ProtocolBugs{ 14734 SendStrayEarlyHandshake: true, 14735 }, 14736 }, 14737 resumeSession: true, 14738 earlyData: true, 14739 shouldFail: true, 14740 expectedError: ":UNEXPECTED_MESSAGE:", 14741 expectedLocalError: "remote error: unexpected message", 14742 }) 14743 14744 // Test that the client reports TLS 1.3 as the version while sending 14745 // early data. 14746 testCases = append(testCases, testCase{ 14747 testType: clientTest, 14748 name: "EarlyData-Client-VersionAPI-TLS13", 14749 config: Config{ 14750 MaxVersion: VersionTLS13, 14751 }, 14752 resumeSession: true, 14753 earlyData: true, 14754 flags: []string{ 14755 "-expect-version", strconv.Itoa(VersionTLS13), 14756 }, 14757 }) 14758 14759 // Test that client and server both notice handshake errors after data 14760 // has started flowing. 14761 testCases = append(testCases, testCase{ 14762 testType: clientTest, 14763 name: "EarlyData-Client-BadFinished-TLS13", 14764 config: Config{ 14765 MaxVersion: VersionTLS13, 14766 }, 14767 resumeConfig: &Config{ 14768 MaxVersion: VersionTLS13, 14769 Bugs: ProtocolBugs{ 14770 BadFinished: true, 14771 }, 14772 }, 14773 resumeSession: true, 14774 earlyData: true, 14775 shouldFail: true, 14776 expectedError: ":DIGEST_CHECK_FAILED:", 14777 expectedLocalError: "remote error: error decrypting message", 14778 }) 14779 testCases = append(testCases, testCase{ 14780 testType: serverTest, 14781 name: "EarlyData-Server-BadFinished-TLS13", 14782 config: Config{ 14783 MaxVersion: VersionTLS13, 14784 }, 14785 resumeConfig: &Config{ 14786 MaxVersion: VersionTLS13, 14787 Bugs: ProtocolBugs{ 14788 BadFinished: true, 14789 }, 14790 }, 14791 resumeSession: true, 14792 earlyData: true, 14793 shouldFail: true, 14794 expectedError: ":DIGEST_CHECK_FAILED:", 14795 expectedLocalError: "remote error: error decrypting message", 14796 }) 14797 14798 testCases = append(testCases, testCase{ 14799 testType: serverTest, 14800 name: "Server-NonEmptyEndOfEarlyData-TLS13", 14801 config: Config{ 14802 MaxVersion: VersionTLS13, 14803 }, 14804 resumeConfig: &Config{ 14805 MaxVersion: VersionTLS13, 14806 Bugs: ProtocolBugs{ 14807 NonEmptyEndOfEarlyData: true, 14808 }, 14809 }, 14810 resumeSession: true, 14811 earlyData: true, 14812 shouldFail: true, 14813 expectedError: ":DECODE_ERROR:", 14814 }) 14815 14816 testCases = append(testCases, testCase{ 14817 testType: serverTest, 14818 name: "ServerSkipCertificateVerify-TLS13", 14819 config: Config{ 14820 MinVersion: VersionTLS13, 14821 MaxVersion: VersionTLS13, 14822 Certificates: []Certificate{rsaChainCertificate}, 14823 Bugs: ProtocolBugs{ 14824 SkipCertificateVerify: true, 14825 }, 14826 }, 14827 expectations: connectionExpectations{ 14828 peerCertificate: &rsaChainCertificate, 14829 }, 14830 flags: []string{ 14831 "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 14832 "-key-file", path.Join(*resourceDir, rsaChainKeyFile), 14833 "-require-any-client-certificate", 14834 }, 14835 shouldFail: true, 14836 expectedError: ":UNEXPECTED_MESSAGE:", 14837 expectedLocalError: "remote error: unexpected message", 14838 }) 14839 testCases = append(testCases, testCase{ 14840 testType: clientTest, 14841 name: "ClientSkipCertificateVerify-TLS13", 14842 config: Config{ 14843 MinVersion: VersionTLS13, 14844 MaxVersion: VersionTLS13, 14845 Certificates: []Certificate{rsaChainCertificate}, 14846 Bugs: ProtocolBugs{ 14847 SkipCertificateVerify: true, 14848 }, 14849 }, 14850 expectations: connectionExpectations{ 14851 peerCertificate: &rsaChainCertificate, 14852 }, 14853 flags: []string{ 14854 "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 14855 "-key-file", path.Join(*resourceDir, rsaChainKeyFile), 14856 }, 14857 shouldFail: true, 14858 expectedError: ":UNEXPECTED_MESSAGE:", 14859 expectedLocalError: "remote error: unexpected message", 14860 }) 14861 14862 // If the client or server has 0-RTT enabled but disabled TLS 1.3, it should 14863 // report a reason of protocol_version. 14864 testCases = append(testCases, testCase{ 14865 testType: clientTest, 14866 name: "EarlyDataEnabled-Client-MaxTLS12", 14867 expectations: connectionExpectations{ 14868 version: VersionTLS12, 14869 }, 14870 flags: []string{ 14871 "-enable-early-data", 14872 "-max-version", strconv.Itoa(VersionTLS12), 14873 "-expect-early-data-reason", "protocol_version", 14874 }, 14875 }) 14876 testCases = append(testCases, testCase{ 14877 testType: serverTest, 14878 name: "EarlyDataEnabled-Server-MaxTLS12", 14879 expectations: connectionExpectations{ 14880 version: VersionTLS12, 14881 }, 14882 flags: []string{ 14883 "-enable-early-data", 14884 "-max-version", strconv.Itoa(VersionTLS12), 14885 "-expect-early-data-reason", "protocol_version", 14886 }, 14887 }) 14888 14889 // The server additionally reports protocol_version if it enabled TLS 1.3, 14890 // but the peer negotiated TLS 1.2. (The corresponding situation does not 14891 // exist on the client because negotiating TLS 1.2 with a 0-RTT ClientHello 14892 // is a fatal error.) 14893 testCases = append(testCases, testCase{ 14894 testType: serverTest, 14895 name: "EarlyDataEnabled-Server-NegotiateTLS12", 14896 config: Config{ 14897 MaxVersion: VersionTLS12, 14898 }, 14899 expectations: connectionExpectations{ 14900 version: VersionTLS12, 14901 }, 14902 flags: []string{ 14903 "-enable-early-data", 14904 "-expect-early-data-reason", "protocol_version", 14905 }, 14906 }) 14907 14908 // On 0-RTT reject, the server may end up negotiating a cipher suite with a 14909 // different PRF hash. Test that the client handles this correctly. 14910 testCases = append(testCases, testCase{ 14911 testType: clientTest, 14912 name: "EarlyData-Reject0RTT-DifferentPRF-Client", 14913 config: Config{ 14914 MaxVersion: VersionTLS13, 14915 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 14916 }, 14917 resumeConfig: &Config{ 14918 MaxVersion: VersionTLS13, 14919 CipherSuites: []uint16{TLS_AES_256_GCM_SHA384}, 14920 }, 14921 resumeSession: true, 14922 expectResumeRejected: true, 14923 earlyData: true, 14924 expectEarlyDataRejected: true, 14925 flags: []string{ 14926 "-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 14927 // The client initially reports the old cipher suite while sending 14928 // early data. After processing the 0-RTT reject, it reports the 14929 // true cipher suite. 14930 "-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 14931 "-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)), 14932 }, 14933 }) 14934 testCases = append(testCases, testCase{ 14935 testType: clientTest, 14936 name: "EarlyData-Reject0RTT-DifferentPRF-HRR-Client", 14937 config: Config{ 14938 MaxVersion: VersionTLS13, 14939 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 14940 }, 14941 resumeConfig: &Config{ 14942 MaxVersion: VersionTLS13, 14943 CipherSuites: []uint16{TLS_AES_256_GCM_SHA384}, 14944 // P-384 requires a HelloRetryRequest against BoringSSL's default 14945 // configuration. Assert this with ExpectMissingKeyShare. 14946 CurvePreferences: []CurveID{CurveP384}, 14947 Bugs: ProtocolBugs{ 14948 ExpectMissingKeyShare: true, 14949 }, 14950 }, 14951 resumeSession: true, 14952 expectResumeRejected: true, 14953 earlyData: true, 14954 expectEarlyDataRejected: true, 14955 flags: []string{ 14956 "-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 14957 // The client initially reports the old cipher suite while sending 14958 // early data. After processing the 0-RTT reject, it reports the 14959 // true cipher suite. 14960 "-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 14961 "-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)), 14962 }, 14963 }) 14964 14965 // Test that the client enforces cipher suite match on 0-RTT accept. 14966 testCases = append(testCases, testCase{ 14967 testType: clientTest, 14968 name: "EarlyData-CipherMismatch-Client-TLS13", 14969 config: Config{ 14970 MaxVersion: VersionTLS13, 14971 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 14972 }, 14973 resumeConfig: &Config{ 14974 MaxVersion: VersionTLS13, 14975 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 14976 Bugs: ProtocolBugs{ 14977 AlwaysAcceptEarlyData: true, 14978 }, 14979 }, 14980 resumeSession: true, 14981 earlyData: true, 14982 shouldFail: true, 14983 expectedError: ":CIPHER_MISMATCH_ON_EARLY_DATA:", 14984 expectedLocalError: "remote error: illegal parameter", 14985 }) 14986 14987 // Test that the client can write early data when it has received a partial 14988 // ServerHello..Finished flight. See https://crbug.com/1208784. Note the 14989 // EncryptedExtensions test assumes EncryptedExtensions and Finished are in 14990 // separate records, i.e. that PackHandshakeFlight is disabled. 14991 testCases = append(testCases, testCase{ 14992 testType: clientTest, 14993 name: "EarlyData-WriteAfterServerHello", 14994 config: Config{ 14995 MinVersion: VersionTLS13, 14996 MaxVersion: VersionTLS13, 14997 Bugs: ProtocolBugs{ 14998 // Write the server response before expecting early data. 14999 ExpectEarlyData: [][]byte{}, 15000 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 15001 }, 15002 }, 15003 resumeSession: true, 15004 earlyData: true, 15005 flags: []string{ 15006 "-async", 15007 "-on-resume-early-write-after-message", 15008 strconv.Itoa(int(typeServerHello)), 15009 }, 15010 }) 15011 testCases = append(testCases, testCase{ 15012 testType: clientTest, 15013 name: "EarlyData-WriteAfterEncryptedExtensions", 15014 config: Config{ 15015 MinVersion: VersionTLS13, 15016 MaxVersion: VersionTLS13, 15017 Bugs: ProtocolBugs{ 15018 // Write the server response before expecting early data. 15019 ExpectEarlyData: [][]byte{}, 15020 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 15021 }, 15022 }, 15023 resumeSession: true, 15024 earlyData: true, 15025 flags: []string{ 15026 "-async", 15027 "-on-resume-early-write-after-message", 15028 strconv.Itoa(int(typeEncryptedExtensions)), 15029 }, 15030 }) 15031} 15032 15033func addTLS13CipherPreferenceTests() { 15034 // Test that client preference is honored if the shim has AES hardware 15035 // and ChaCha20-Poly1305 is preferred otherwise. 15036 testCases = append(testCases, testCase{ 15037 testType: serverTest, 15038 name: "TLS13-CipherPreference-Server-ChaCha20-AES", 15039 config: Config{ 15040 MaxVersion: VersionTLS13, 15041 CipherSuites: []uint16{ 15042 TLS_CHACHA20_POLY1305_SHA256, 15043 TLS_AES_128_GCM_SHA256, 15044 }, 15045 CurvePreferences: []CurveID{CurveX25519}, 15046 }, 15047 flags: []string{ 15048 "-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15049 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15050 }, 15051 }) 15052 15053 testCases = append(testCases, testCase{ 15054 testType: serverTest, 15055 name: "TLS13-CipherPreference-Server-AES-ChaCha20", 15056 config: Config{ 15057 MaxVersion: VersionTLS13, 15058 CipherSuites: []uint16{ 15059 TLS_AES_128_GCM_SHA256, 15060 TLS_CHACHA20_POLY1305_SHA256, 15061 }, 15062 CurvePreferences: []CurveID{CurveX25519}, 15063 }, 15064 flags: []string{ 15065 "-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15066 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15067 }, 15068 }) 15069 15070 // Test that the client orders ChaCha20-Poly1305 and AES-GCM based on 15071 // whether it has AES hardware. 15072 testCases = append(testCases, testCase{ 15073 name: "TLS13-CipherPreference-Client", 15074 config: Config{ 15075 MaxVersion: VersionTLS13, 15076 // Use the client cipher order. (This is the default but 15077 // is listed to be explicit.) 15078 PreferServerCipherSuites: false, 15079 }, 15080 flags: []string{ 15081 "-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15082 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15083 }, 15084 }) 15085 15086 // CECPQ2 prefers 256-bit ciphers but will use AES-128 if there's nothing else. 15087 testCases = append(testCases, testCase{ 15088 testType: serverTest, 15089 name: "TLS13-CipherPreference-CECPQ2-AES128Only", 15090 config: Config{ 15091 MaxVersion: VersionTLS13, 15092 CipherSuites: []uint16{ 15093 TLS_AES_128_GCM_SHA256, 15094 }, 15095 }, 15096 flags: []string{ 15097 "-curves", strconv.Itoa(int(CurveCECPQ2)), 15098 }, 15099 }) 15100 15101 // When a 256-bit cipher is offered, even if not in first place, it should be 15102 // picked. 15103 testCases = append(testCases, testCase{ 15104 testType: serverTest, 15105 name: "TLS13-CipherPreference-CECPQ2-AES256Preferred", 15106 config: Config{ 15107 MaxVersion: VersionTLS13, 15108 CipherSuites: []uint16{ 15109 TLS_AES_128_GCM_SHA256, 15110 TLS_AES_256_GCM_SHA384, 15111 }, 15112 }, 15113 flags: []string{ 15114 "-curves", strconv.Itoa(int(CurveCECPQ2)), 15115 }, 15116 expectations: connectionExpectations{ 15117 cipher: TLS_AES_256_GCM_SHA384, 15118 }, 15119 }) 15120 // ... but when CECPQ2 isn't being used, the client's preference controls. 15121 testCases = append(testCases, testCase{ 15122 testType: serverTest, 15123 name: "TLS13-CipherPreference-CECPQ2-AES128PreferredOtherwise", 15124 config: Config{ 15125 MaxVersion: VersionTLS13, 15126 CipherSuites: []uint16{ 15127 TLS_AES_128_GCM_SHA256, 15128 TLS_AES_256_GCM_SHA384, 15129 }, 15130 }, 15131 flags: []string{ 15132 "-curves", strconv.Itoa(int(CurveX25519)), 15133 }, 15134 expectations: connectionExpectations{ 15135 cipher: TLS_AES_128_GCM_SHA256, 15136 }, 15137 }) 15138 15139 // Test that CECPQ2 continues to honor AES vs ChaCha20 logic. 15140 testCases = append(testCases, testCase{ 15141 testType: serverTest, 15142 name: "TLS13-CipherPreference-CECPQ2-AES128-ChaCha20-AES256", 15143 config: Config{ 15144 MaxVersion: VersionTLS13, 15145 CipherSuites: []uint16{ 15146 TLS_AES_128_GCM_SHA256, 15147 TLS_CHACHA20_POLY1305_SHA256, 15148 TLS_AES_256_GCM_SHA384, 15149 }, 15150 }, 15151 flags: []string{ 15152 "-curves", strconv.Itoa(int(CurveCECPQ2)), 15153 "-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15154 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15155 }, 15156 }) 15157 testCases = append(testCases, testCase{ 15158 testType: serverTest, 15159 name: "TLS13-CipherPreference-CECPQ2-AES128-AES256-ChaCha20", 15160 config: Config{ 15161 MaxVersion: VersionTLS13, 15162 CipherSuites: []uint16{ 15163 TLS_AES_128_GCM_SHA256, 15164 TLS_AES_256_GCM_SHA384, 15165 TLS_CHACHA20_POLY1305_SHA256, 15166 }, 15167 }, 15168 flags: []string{ 15169 "-curves", strconv.Itoa(int(CurveCECPQ2)), 15170 "-expect-cipher-aes", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)), 15171 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15172 }, 15173 }) 15174} 15175 15176func addPeekTests() { 15177 // Test SSL_peek works, including on empty records. 15178 testCases = append(testCases, testCase{ 15179 name: "Peek-Basic", 15180 sendEmptyRecords: 1, 15181 flags: []string{"-peek-then-read"}, 15182 }) 15183 15184 // Test SSL_peek can drive the initial handshake. 15185 testCases = append(testCases, testCase{ 15186 name: "Peek-ImplicitHandshake", 15187 flags: []string{ 15188 "-peek-then-read", 15189 "-implicit-handshake", 15190 }, 15191 }) 15192 15193 // Test SSL_peek can discover and drive a renegotiation. 15194 testCases = append(testCases, testCase{ 15195 name: "Peek-Renegotiate", 15196 config: Config{ 15197 MaxVersion: VersionTLS12, 15198 }, 15199 renegotiate: 1, 15200 flags: []string{ 15201 "-peek-then-read", 15202 "-renegotiate-freely", 15203 "-expect-total-renegotiations", "1", 15204 }, 15205 }) 15206 15207 // Test SSL_peek can discover a close_notify. 15208 testCases = append(testCases, testCase{ 15209 name: "Peek-Shutdown", 15210 config: Config{ 15211 Bugs: ProtocolBugs{ 15212 ExpectCloseNotify: true, 15213 }, 15214 }, 15215 flags: []string{ 15216 "-peek-then-read", 15217 "-check-close-notify", 15218 }, 15219 }) 15220 15221 // Test SSL_peek can discover an alert. 15222 testCases = append(testCases, testCase{ 15223 name: "Peek-Alert", 15224 config: Config{ 15225 Bugs: ProtocolBugs{ 15226 SendSpuriousAlert: alertRecordOverflow, 15227 }, 15228 }, 15229 flags: []string{"-peek-then-read"}, 15230 shouldFail: true, 15231 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 15232 }) 15233 15234 // Test SSL_peek can handle KeyUpdate. 15235 testCases = append(testCases, testCase{ 15236 name: "Peek-KeyUpdate", 15237 config: Config{ 15238 MaxVersion: VersionTLS13, 15239 }, 15240 sendKeyUpdates: 1, 15241 keyUpdateRequest: keyUpdateNotRequested, 15242 flags: []string{"-peek-then-read"}, 15243 }) 15244} 15245 15246func addRecordVersionTests() { 15247 for _, ver := range tlsVersions { 15248 // Test that the record version is enforced. 15249 testCases = append(testCases, testCase{ 15250 name: "CheckRecordVersion-" + ver.name, 15251 config: Config{ 15252 MinVersion: ver.version, 15253 MaxVersion: ver.version, 15254 Bugs: ProtocolBugs{ 15255 SendRecordVersion: 0x03ff, 15256 }, 15257 }, 15258 shouldFail: true, 15259 expectedError: ":WRONG_VERSION_NUMBER:", 15260 }) 15261 15262 // Test that the ClientHello may use any record version, for 15263 // compatibility reasons. 15264 testCases = append(testCases, testCase{ 15265 testType: serverTest, 15266 name: "LooseInitialRecordVersion-" + ver.name, 15267 config: Config{ 15268 MinVersion: ver.version, 15269 MaxVersion: ver.version, 15270 Bugs: ProtocolBugs{ 15271 SendInitialRecordVersion: 0x03ff, 15272 }, 15273 }, 15274 }) 15275 15276 // Test that garbage ClientHello record versions are rejected. 15277 testCases = append(testCases, testCase{ 15278 testType: serverTest, 15279 name: "GarbageInitialRecordVersion-" + ver.name, 15280 config: Config{ 15281 MinVersion: ver.version, 15282 MaxVersion: ver.version, 15283 Bugs: ProtocolBugs{ 15284 SendInitialRecordVersion: 0xffff, 15285 }, 15286 }, 15287 shouldFail: true, 15288 expectedError: ":WRONG_VERSION_NUMBER:", 15289 }) 15290 } 15291} 15292 15293func addCertificateTests() { 15294 for _, ver := range tlsVersions { 15295 // Test that a certificate chain with intermediate may be sent 15296 // and received as both client and server. 15297 testCases = append(testCases, testCase{ 15298 testType: clientTest, 15299 name: "SendReceiveIntermediate-Client-" + ver.name, 15300 config: Config{ 15301 MinVersion: ver.version, 15302 MaxVersion: ver.version, 15303 Certificates: []Certificate{rsaChainCertificate}, 15304 ClientAuth: RequireAnyClientCert, 15305 }, 15306 expectations: connectionExpectations{ 15307 peerCertificate: &rsaChainCertificate, 15308 }, 15309 flags: []string{ 15310 "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 15311 "-key-file", path.Join(*resourceDir, rsaChainKeyFile), 15312 "-expect-peer-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 15313 }, 15314 }) 15315 15316 testCases = append(testCases, testCase{ 15317 testType: serverTest, 15318 name: "SendReceiveIntermediate-Server-" + ver.name, 15319 config: Config{ 15320 MinVersion: ver.version, 15321 MaxVersion: ver.version, 15322 Certificates: []Certificate{rsaChainCertificate}, 15323 }, 15324 expectations: connectionExpectations{ 15325 peerCertificate: &rsaChainCertificate, 15326 }, 15327 flags: []string{ 15328 "-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 15329 "-key-file", path.Join(*resourceDir, rsaChainKeyFile), 15330 "-require-any-client-certificate", 15331 "-expect-peer-cert-file", path.Join(*resourceDir, rsaChainCertificateFile), 15332 }, 15333 }) 15334 15335 // Test that garbage leaf certificates are properly rejected. 15336 testCases = append(testCases, testCase{ 15337 testType: clientTest, 15338 name: "GarbageCertificate-Client-" + ver.name, 15339 config: Config{ 15340 MinVersion: ver.version, 15341 MaxVersion: ver.version, 15342 Certificates: []Certificate{garbageCertificate}, 15343 }, 15344 shouldFail: true, 15345 expectedError: ":CANNOT_PARSE_LEAF_CERT:", 15346 expectedLocalError: "remote error: error decoding message", 15347 }) 15348 15349 testCases = append(testCases, testCase{ 15350 testType: serverTest, 15351 name: "GarbageCertificate-Server-" + ver.name, 15352 config: Config{ 15353 MinVersion: ver.version, 15354 MaxVersion: ver.version, 15355 Certificates: []Certificate{garbageCertificate}, 15356 }, 15357 flags: []string{"-require-any-client-certificate"}, 15358 shouldFail: true, 15359 expectedError: ":CANNOT_PARSE_LEAF_CERT:", 15360 expectedLocalError: "remote error: error decoding message", 15361 }) 15362 } 15363} 15364 15365func addRetainOnlySHA256ClientCertTests() { 15366 for _, ver := range tlsVersions { 15367 // Test that enabling 15368 // SSL_CTX_set_retain_only_sha256_of_client_certs without 15369 // actually requesting a client certificate is a no-op. 15370 testCases = append(testCases, testCase{ 15371 testType: serverTest, 15372 name: "RetainOnlySHA256-NoCert-" + ver.name, 15373 config: Config{ 15374 MinVersion: ver.version, 15375 MaxVersion: ver.version, 15376 }, 15377 flags: []string{ 15378 "-on-initial-retain-only-sha256-client-cert", 15379 "-on-resume-retain-only-sha256-client-cert", 15380 }, 15381 resumeSession: true, 15382 }) 15383 15384 // Test that when retaining only a SHA-256 certificate is 15385 // enabled, the hash appears as expected. 15386 testCases = append(testCases, testCase{ 15387 testType: serverTest, 15388 name: "RetainOnlySHA256-Cert-" + ver.name, 15389 config: Config{ 15390 MinVersion: ver.version, 15391 MaxVersion: ver.version, 15392 Certificates: []Certificate{rsaCertificate}, 15393 }, 15394 flags: []string{ 15395 "-verify-peer", 15396 "-on-initial-retain-only-sha256-client-cert", 15397 "-on-resume-retain-only-sha256-client-cert", 15398 "-on-initial-expect-sha256-client-cert", 15399 "-on-resume-expect-sha256-client-cert", 15400 }, 15401 resumeSession: true, 15402 }) 15403 15404 // Test that when the config changes from on to off, a 15405 // resumption is rejected because the server now wants the full 15406 // certificate chain. 15407 testCases = append(testCases, testCase{ 15408 testType: serverTest, 15409 name: "RetainOnlySHA256-OnOff-" + ver.name, 15410 config: Config{ 15411 MinVersion: ver.version, 15412 MaxVersion: ver.version, 15413 Certificates: []Certificate{rsaCertificate}, 15414 }, 15415 flags: []string{ 15416 "-verify-peer", 15417 "-on-initial-retain-only-sha256-client-cert", 15418 "-on-initial-expect-sha256-client-cert", 15419 }, 15420 resumeSession: true, 15421 expectResumeRejected: true, 15422 }) 15423 15424 // Test that when the config changes from off to on, a 15425 // resumption is rejected because the server now wants just the 15426 // hash. 15427 testCases = append(testCases, testCase{ 15428 testType: serverTest, 15429 name: "RetainOnlySHA256-OffOn-" + ver.name, 15430 config: Config{ 15431 MinVersion: ver.version, 15432 MaxVersion: ver.version, 15433 Certificates: []Certificate{rsaCertificate}, 15434 }, 15435 flags: []string{ 15436 "-verify-peer", 15437 "-on-resume-retain-only-sha256-client-cert", 15438 "-on-resume-expect-sha256-client-cert", 15439 }, 15440 resumeSession: true, 15441 expectResumeRejected: true, 15442 }) 15443 } 15444} 15445 15446func addECDSAKeyUsageTests() { 15447 p256 := elliptic.P256() 15448 priv, err := ecdsa.GenerateKey(p256, rand.Reader) 15449 if err != nil { 15450 panic(err) 15451 } 15452 15453 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 15454 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 15455 if err != nil { 15456 panic(err) 15457 } 15458 15459 template := x509.Certificate{ 15460 SerialNumber: serialNumber, 15461 Subject: pkix.Name{ 15462 Organization: []string{"Acme Co"}, 15463 }, 15464 NotBefore: time.Now(), 15465 NotAfter: time.Now(), 15466 15467 // An ECC certificate with only the keyAgreement key usgae may 15468 // be used with ECDH, but not ECDSA. 15469 KeyUsage: x509.KeyUsageKeyAgreement, 15470 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 15471 BasicConstraintsValid: true, 15472 } 15473 15474 derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) 15475 if err != nil { 15476 panic(err) 15477 } 15478 15479 cert := Certificate{ 15480 Certificate: [][]byte{derBytes}, 15481 PrivateKey: priv, 15482 } 15483 15484 for _, ver := range tlsVersions { 15485 if ver.version < VersionTLS12 { 15486 continue 15487 } 15488 15489 testCases = append(testCases, testCase{ 15490 testType: clientTest, 15491 name: "ECDSAKeyUsage-Client-" + ver.name, 15492 config: Config{ 15493 MinVersion: ver.version, 15494 MaxVersion: ver.version, 15495 Certificates: []Certificate{cert}, 15496 }, 15497 shouldFail: true, 15498 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15499 }) 15500 15501 testCases = append(testCases, testCase{ 15502 testType: serverTest, 15503 name: "ECDSAKeyUsage-Server-" + ver.name, 15504 config: Config{ 15505 MinVersion: ver.version, 15506 MaxVersion: ver.version, 15507 Certificates: []Certificate{cert}, 15508 }, 15509 flags: []string{"-require-any-client-certificate"}, 15510 shouldFail: true, 15511 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15512 }) 15513 } 15514} 15515 15516func addRSAKeyUsageTests() { 15517 priv := rsaCertificate.PrivateKey.(*rsa.PrivateKey) 15518 15519 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 15520 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 15521 if err != nil { 15522 panic(err) 15523 } 15524 15525 dsTemplate := x509.Certificate{ 15526 SerialNumber: serialNumber, 15527 Subject: pkix.Name{ 15528 Organization: []string{"Acme Co"}, 15529 }, 15530 NotBefore: time.Now(), 15531 NotAfter: time.Now(), 15532 15533 KeyUsage: x509.KeyUsageDigitalSignature, 15534 BasicConstraintsValid: true, 15535 } 15536 15537 encTemplate := x509.Certificate{ 15538 SerialNumber: serialNumber, 15539 Subject: pkix.Name{ 15540 Organization: []string{"Acme Co"}, 15541 }, 15542 NotBefore: time.Now(), 15543 NotAfter: time.Now(), 15544 15545 KeyUsage: x509.KeyUsageKeyEncipherment, 15546 BasicConstraintsValid: true, 15547 } 15548 15549 dsDerBytes, err := x509.CreateCertificate(rand.Reader, &dsTemplate, &dsTemplate, &priv.PublicKey, priv) 15550 if err != nil { 15551 panic(err) 15552 } 15553 15554 encDerBytes, err := x509.CreateCertificate(rand.Reader, &encTemplate, &encTemplate, &priv.PublicKey, priv) 15555 if err != nil { 15556 panic(err) 15557 } 15558 15559 dsCert := Certificate{ 15560 Certificate: [][]byte{dsDerBytes}, 15561 PrivateKey: priv, 15562 } 15563 15564 encCert := Certificate{ 15565 Certificate: [][]byte{encDerBytes}, 15566 PrivateKey: priv, 15567 } 15568 15569 dsSuites := []uint16{ 15570 TLS_AES_128_GCM_SHA256, 15571 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 15572 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 15573 } 15574 encSuites := []uint16{ 15575 TLS_RSA_WITH_AES_128_GCM_SHA256, 15576 TLS_RSA_WITH_AES_128_CBC_SHA, 15577 } 15578 15579 for _, ver := range tlsVersions { 15580 testCases = append(testCases, testCase{ 15581 testType: clientTest, 15582 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-" + ver.name, 15583 config: Config{ 15584 MinVersion: ver.version, 15585 MaxVersion: ver.version, 15586 Certificates: []Certificate{encCert}, 15587 CipherSuites: dsSuites, 15588 }, 15589 shouldFail: true, 15590 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15591 flags: []string{ 15592 "-enforce-rsa-key-usage", 15593 }, 15594 }) 15595 15596 testCases = append(testCases, testCase{ 15597 testType: clientTest, 15598 name: "RSAKeyUsage-Client-WantSignature-GotSignature-" + ver.name, 15599 config: Config{ 15600 MinVersion: ver.version, 15601 MaxVersion: ver.version, 15602 Certificates: []Certificate{dsCert}, 15603 CipherSuites: dsSuites, 15604 }, 15605 flags: []string{ 15606 "-enforce-rsa-key-usage", 15607 }, 15608 }) 15609 15610 // TLS 1.3 removes the encipherment suites. 15611 if ver.version < VersionTLS13 { 15612 testCases = append(testCases, testCase{ 15613 testType: clientTest, 15614 name: "RSAKeyUsage-Client-WantEncipherment-GotEncipherment" + ver.name, 15615 config: Config{ 15616 MinVersion: ver.version, 15617 MaxVersion: ver.version, 15618 Certificates: []Certificate{encCert}, 15619 CipherSuites: encSuites, 15620 }, 15621 flags: []string{ 15622 "-enforce-rsa-key-usage", 15623 }, 15624 }) 15625 15626 testCases = append(testCases, testCase{ 15627 testType: clientTest, 15628 name: "RSAKeyUsage-Client-WantEncipherment-GotSignature-" + ver.name, 15629 config: Config{ 15630 MinVersion: ver.version, 15631 MaxVersion: ver.version, 15632 Certificates: []Certificate{dsCert}, 15633 CipherSuites: encSuites, 15634 }, 15635 shouldFail: true, 15636 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15637 flags: []string{ 15638 "-enforce-rsa-key-usage", 15639 }, 15640 }) 15641 15642 // In 1.2 and below, we should not enforce without the enforce-rsa-key-usage flag. 15643 testCases = append(testCases, testCase{ 15644 testType: clientTest, 15645 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-Unenforced" + ver.name, 15646 config: Config{ 15647 MinVersion: ver.version, 15648 MaxVersion: ver.version, 15649 Certificates: []Certificate{dsCert}, 15650 CipherSuites: encSuites, 15651 }, 15652 }) 15653 15654 testCases = append(testCases, testCase{ 15655 testType: clientTest, 15656 name: "RSAKeyUsage-Client-WantEncipherment-GotSignature-Unenforced" + ver.name, 15657 config: Config{ 15658 MinVersion: ver.version, 15659 MaxVersion: ver.version, 15660 Certificates: []Certificate{encCert}, 15661 CipherSuites: dsSuites, 15662 }, 15663 }) 15664 } 15665 15666 if ver.version >= VersionTLS13 { 15667 // In 1.3 and above, we enforce keyUsage even without the flag. 15668 testCases = append(testCases, testCase{ 15669 testType: clientTest, 15670 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-Enforced" + ver.name, 15671 config: Config{ 15672 MinVersion: ver.version, 15673 MaxVersion: ver.version, 15674 Certificates: []Certificate{encCert}, 15675 CipherSuites: dsSuites, 15676 }, 15677 shouldFail: true, 15678 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15679 }) 15680 } 15681 15682 // The server only uses signatures and always enforces it. 15683 testCases = append(testCases, testCase{ 15684 testType: serverTest, 15685 name: "RSAKeyUsage-Server-WantSignature-GotEncipherment-" + ver.name, 15686 config: Config{ 15687 MinVersion: ver.version, 15688 MaxVersion: ver.version, 15689 Certificates: []Certificate{encCert}, 15690 }, 15691 shouldFail: true, 15692 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15693 flags: []string{"-require-any-client-certificate"}, 15694 }) 15695 15696 testCases = append(testCases, testCase{ 15697 testType: serverTest, 15698 name: "RSAKeyUsage-Server-WantSignature-GotSignature-" + ver.name, 15699 config: Config{ 15700 MinVersion: ver.version, 15701 MaxVersion: ver.version, 15702 Certificates: []Certificate{dsCert}, 15703 }, 15704 flags: []string{"-require-any-client-certificate"}, 15705 }) 15706 15707 } 15708} 15709 15710func addExtraHandshakeTests() { 15711 // An extra SSL_do_handshake is normally a no-op. These tests use -async 15712 // to ensure there is no transport I/O. 15713 testCases = append(testCases, testCase{ 15714 testType: clientTest, 15715 name: "ExtraHandshake-Client-TLS12", 15716 config: Config{ 15717 MinVersion: VersionTLS12, 15718 MaxVersion: VersionTLS12, 15719 }, 15720 flags: []string{ 15721 "-async", 15722 "-no-op-extra-handshake", 15723 }, 15724 }) 15725 testCases = append(testCases, testCase{ 15726 testType: serverTest, 15727 name: "ExtraHandshake-Server-TLS12", 15728 config: Config{ 15729 MinVersion: VersionTLS12, 15730 MaxVersion: VersionTLS12, 15731 }, 15732 flags: []string{ 15733 "-async", 15734 "-no-op-extra-handshake", 15735 }, 15736 }) 15737 testCases = append(testCases, testCase{ 15738 testType: clientTest, 15739 name: "ExtraHandshake-Client-TLS13", 15740 config: Config{ 15741 MinVersion: VersionTLS13, 15742 MaxVersion: VersionTLS13, 15743 }, 15744 flags: []string{ 15745 "-async", 15746 "-no-op-extra-handshake", 15747 }, 15748 }) 15749 testCases = append(testCases, testCase{ 15750 testType: serverTest, 15751 name: "ExtraHandshake-Server-TLS13", 15752 config: Config{ 15753 MinVersion: VersionTLS13, 15754 MaxVersion: VersionTLS13, 15755 }, 15756 flags: []string{ 15757 "-async", 15758 "-no-op-extra-handshake", 15759 }, 15760 }) 15761 15762 // An extra SSL_do_handshake is a no-op in server 0-RTT. 15763 testCases = append(testCases, testCase{ 15764 testType: serverTest, 15765 name: "ExtraHandshake-Server-EarlyData-TLS13", 15766 config: Config{ 15767 MaxVersion: VersionTLS13, 15768 MinVersion: VersionTLS13, 15769 }, 15770 messageCount: 2, 15771 resumeSession: true, 15772 earlyData: true, 15773 flags: []string{ 15774 "-async", 15775 "-no-op-extra-handshake", 15776 }, 15777 }) 15778 15779 // An extra SSL_do_handshake drives the handshake to completion in False 15780 // Start. We test this by handshaking twice and asserting the False 15781 // Start does not appear to happen. See AlertBeforeFalseStartTest for 15782 // how the test works. 15783 testCases = append(testCases, testCase{ 15784 testType: clientTest, 15785 name: "ExtraHandshake-FalseStart", 15786 config: Config{ 15787 MaxVersion: VersionTLS12, 15788 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 15789 NextProtos: []string{"foo"}, 15790 Bugs: ProtocolBugs{ 15791 ExpectFalseStart: true, 15792 AlertBeforeFalseStartTest: alertAccessDenied, 15793 }, 15794 }, 15795 flags: []string{ 15796 "-handshake-twice", 15797 "-false-start", 15798 "-advertise-alpn", "\x03foo", 15799 "-expect-alpn", "foo", 15800 }, 15801 shimWritesFirst: true, 15802 shouldFail: true, 15803 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 15804 expectedLocalError: "tls: peer did not false start: EOF", 15805 }) 15806} 15807 15808// Test that omitted and empty extensions blocks are tolerated. 15809func addOmitExtensionsTests() { 15810 // Check the ExpectOmitExtensions setting works. 15811 testCases = append(testCases, testCase{ 15812 testType: serverTest, 15813 name: "ExpectOmitExtensions", 15814 config: Config{ 15815 MinVersion: VersionTLS12, 15816 MaxVersion: VersionTLS12, 15817 Bugs: ProtocolBugs{ 15818 ExpectOmitExtensions: true, 15819 }, 15820 }, 15821 shouldFail: true, 15822 expectedLocalError: "tls: ServerHello did not omit extensions", 15823 }) 15824 15825 for _, ver := range tlsVersions { 15826 if ver.version > VersionTLS12 { 15827 continue 15828 } 15829 15830 testCases = append(testCases, testCase{ 15831 testType: serverTest, 15832 name: "OmitExtensions-ClientHello-" + ver.name, 15833 config: Config{ 15834 MinVersion: ver.version, 15835 MaxVersion: ver.version, 15836 SessionTicketsDisabled: true, 15837 Bugs: ProtocolBugs{ 15838 OmitExtensions: true, 15839 // With no client extensions, the ServerHello must not have 15840 // extensions. It should then omit the extensions field. 15841 ExpectOmitExtensions: true, 15842 }, 15843 }, 15844 }) 15845 15846 testCases = append(testCases, testCase{ 15847 testType: serverTest, 15848 name: "EmptyExtensions-ClientHello-" + ver.name, 15849 config: Config{ 15850 MinVersion: ver.version, 15851 MaxVersion: ver.version, 15852 SessionTicketsDisabled: true, 15853 Bugs: ProtocolBugs{ 15854 EmptyExtensions: true, 15855 // With no client extensions, the ServerHello must not have 15856 // extensions. It should then omit the extensions field. 15857 ExpectOmitExtensions: true, 15858 }, 15859 }, 15860 }) 15861 15862 testCases = append(testCases, testCase{ 15863 testType: clientTest, 15864 name: "OmitExtensions-ServerHello-" + ver.name, 15865 config: Config{ 15866 MinVersion: ver.version, 15867 MaxVersion: ver.version, 15868 SessionTicketsDisabled: true, 15869 Bugs: ProtocolBugs{ 15870 OmitExtensions: true, 15871 // Disable all ServerHello extensions so 15872 // OmitExtensions works. 15873 NoExtendedMasterSecret: true, 15874 NoRenegotiationInfo: true, 15875 NoOCSPStapling: true, 15876 NoSignedCertificateTimestamps: true, 15877 }, 15878 }, 15879 }) 15880 15881 testCases = append(testCases, testCase{ 15882 testType: clientTest, 15883 name: "EmptyExtensions-ServerHello-" + ver.name, 15884 config: Config{ 15885 MinVersion: ver.version, 15886 MaxVersion: ver.version, 15887 SessionTicketsDisabled: true, 15888 Bugs: ProtocolBugs{ 15889 EmptyExtensions: true, 15890 // Disable all ServerHello extensions so 15891 // EmptyExtensions works. 15892 NoExtendedMasterSecret: true, 15893 NoRenegotiationInfo: true, 15894 NoOCSPStapling: true, 15895 NoSignedCertificateTimestamps: true, 15896 }, 15897 }, 15898 }) 15899 } 15900} 15901 15902const ( 15903 shrinkingCompressionAlgID = 0xff01 15904 expandingCompressionAlgID = 0xff02 15905 randomCompressionAlgID = 0xff03 15906) 15907 15908var ( 15909 // shrinkingPrefix is the first two bytes of a Certificate message. 15910 shrinkingPrefix = []byte{0, 0} 15911 // expandingPrefix is just some arbitrary byte string. This has to match the 15912 // value in the shim. 15913 expandingPrefix = []byte{1, 2, 3, 4} 15914) 15915 15916var shrinkingCompression = CertCompressionAlg{ 15917 Compress: func(uncompressed []byte) []byte { 15918 if !bytes.HasPrefix(uncompressed, shrinkingPrefix) { 15919 panic(fmt.Sprintf("cannot compress certificate message %x", uncompressed)) 15920 } 15921 return uncompressed[len(shrinkingPrefix):] 15922 }, 15923 Decompress: func(out []byte, compressed []byte) bool { 15924 if len(out) != len(shrinkingPrefix)+len(compressed) { 15925 return false 15926 } 15927 15928 copy(out, shrinkingPrefix) 15929 copy(out[len(shrinkingPrefix):], compressed) 15930 return true 15931 }, 15932} 15933 15934var expandingCompression = CertCompressionAlg{ 15935 Compress: func(uncompressed []byte) []byte { 15936 ret := make([]byte, 0, len(expandingPrefix)+len(uncompressed)) 15937 ret = append(ret, expandingPrefix...) 15938 return append(ret, uncompressed...) 15939 }, 15940 Decompress: func(out []byte, compressed []byte) bool { 15941 if !bytes.HasPrefix(compressed, expandingPrefix) { 15942 return false 15943 } 15944 copy(out, compressed[len(expandingPrefix):]) 15945 return true 15946 }, 15947} 15948 15949var randomCompression = CertCompressionAlg{ 15950 Compress: func(uncompressed []byte) []byte { 15951 ret := make([]byte, 1+len(uncompressed)) 15952 if _, err := rand.Read(ret[:1]); err != nil { 15953 panic(err) 15954 } 15955 copy(ret[1:], uncompressed) 15956 return ret 15957 }, 15958 Decompress: func(out []byte, compressed []byte) bool { 15959 if len(compressed) != 1+len(out) { 15960 return false 15961 } 15962 copy(out, compressed[1:]) 15963 return true 15964 }, 15965} 15966 15967func addCertCompressionTests() { 15968 for _, ver := range tlsVersions { 15969 if ver.version < VersionTLS12 { 15970 continue 15971 } 15972 15973 // Duplicate compression algorithms is an error, even if nothing is 15974 // configured. 15975 testCases = append(testCases, testCase{ 15976 testType: serverTest, 15977 name: "DuplicateCertCompressionExt-" + ver.name, 15978 config: Config{ 15979 MinVersion: ver.version, 15980 MaxVersion: ver.version, 15981 Bugs: ProtocolBugs{ 15982 DuplicateCompressedCertAlgs: true, 15983 }, 15984 }, 15985 shouldFail: true, 15986 expectedError: ":ERROR_PARSING_EXTENSION:", 15987 }) 15988 15989 // With compression algorithms configured, an duplicate values should still 15990 // be an error. 15991 testCases = append(testCases, testCase{ 15992 testType: serverTest, 15993 name: "DuplicateCertCompressionExt2-" + ver.name, 15994 flags: []string{"-install-cert-compression-algs"}, 15995 config: Config{ 15996 MinVersion: ver.version, 15997 MaxVersion: ver.version, 15998 Bugs: ProtocolBugs{ 15999 DuplicateCompressedCertAlgs: true, 16000 }, 16001 }, 16002 shouldFail: true, 16003 expectedError: ":ERROR_PARSING_EXTENSION:", 16004 }) 16005 16006 if ver.version < VersionTLS13 { 16007 testCases = append(testCases, testCase{ 16008 testType: serverTest, 16009 name: "CertCompressionIgnoredBefore13-" + ver.name, 16010 flags: []string{"-install-cert-compression-algs"}, 16011 config: Config{ 16012 MinVersion: ver.version, 16013 MaxVersion: ver.version, 16014 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16015 expandingCompressionAlgID: expandingCompression, 16016 }, 16017 }, 16018 }) 16019 16020 continue 16021 } 16022 16023 testCases = append(testCases, testCase{ 16024 testType: serverTest, 16025 name: "CertCompressionExpands-" + ver.name, 16026 flags: []string{"-install-cert-compression-algs"}, 16027 config: Config{ 16028 MinVersion: ver.version, 16029 MaxVersion: ver.version, 16030 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16031 expandingCompressionAlgID: expandingCompression, 16032 }, 16033 Bugs: ProtocolBugs{ 16034 ExpectedCompressedCert: expandingCompressionAlgID, 16035 }, 16036 }, 16037 }) 16038 16039 testCases = append(testCases, testCase{ 16040 testType: serverTest, 16041 name: "CertCompressionShrinks-" + ver.name, 16042 flags: []string{"-install-cert-compression-algs"}, 16043 config: Config{ 16044 MinVersion: ver.version, 16045 MaxVersion: ver.version, 16046 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16047 shrinkingCompressionAlgID: shrinkingCompression, 16048 }, 16049 Bugs: ProtocolBugs{ 16050 ExpectedCompressedCert: shrinkingCompressionAlgID, 16051 }, 16052 }, 16053 }) 16054 16055 // Test that the shim behaves consistently if the compression function 16056 // is non-deterministic. This is intended to model version differences 16057 // between the shim and handshaker with handshake hints, but it is also 16058 // useful in confirming we only call the callbacks once. 16059 testCases = append(testCases, testCase{ 16060 testType: serverTest, 16061 name: "CertCompressionRandom-" + ver.name, 16062 flags: []string{"-install-cert-compression-algs"}, 16063 config: Config{ 16064 MinVersion: ver.version, 16065 MaxVersion: ver.version, 16066 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16067 randomCompressionAlgID: randomCompression, 16068 }, 16069 Bugs: ProtocolBugs{ 16070 ExpectedCompressedCert: randomCompressionAlgID, 16071 }, 16072 }, 16073 }) 16074 16075 // With both algorithms configured, the server should pick its most 16076 // preferable. (Which is expandingCompressionAlgID.) 16077 testCases = append(testCases, testCase{ 16078 testType: serverTest, 16079 name: "CertCompressionPriority-" + ver.name, 16080 flags: []string{"-install-cert-compression-algs"}, 16081 config: Config{ 16082 MinVersion: ver.version, 16083 MaxVersion: ver.version, 16084 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16085 shrinkingCompressionAlgID: shrinkingCompression, 16086 expandingCompressionAlgID: expandingCompression, 16087 }, 16088 Bugs: ProtocolBugs{ 16089 ExpectedCompressedCert: expandingCompressionAlgID, 16090 }, 16091 }, 16092 }) 16093 16094 // With no common algorithms configured, the server should decline 16095 // compression. 16096 testCases = append(testCases, testCase{ 16097 testType: serverTest, 16098 name: "CertCompressionNoCommonAlgs-" + ver.name, 16099 flags: []string{"-install-one-cert-compression-alg", strconv.Itoa(shrinkingCompressionAlgID)}, 16100 config: Config{ 16101 MinVersion: ver.version, 16102 MaxVersion: ver.version, 16103 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16104 expandingCompressionAlgID: expandingCompression, 16105 }, 16106 Bugs: ProtocolBugs{ 16107 ExpectUncompressedCert: true, 16108 }, 16109 }, 16110 }) 16111 16112 testCases = append(testCases, testCase{ 16113 testType: clientTest, 16114 name: "CertCompressionExpandsClient-" + ver.name, 16115 flags: []string{"-install-cert-compression-algs"}, 16116 config: Config{ 16117 MinVersion: ver.version, 16118 MaxVersion: ver.version, 16119 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16120 expandingCompressionAlgID: expandingCompression, 16121 }, 16122 Bugs: ProtocolBugs{ 16123 ExpectedCompressedCert: expandingCompressionAlgID, 16124 }, 16125 }, 16126 }) 16127 16128 testCases = append(testCases, testCase{ 16129 testType: clientTest, 16130 name: "CertCompressionShrinksClient-" + ver.name, 16131 flags: []string{"-install-cert-compression-algs"}, 16132 config: Config{ 16133 MinVersion: ver.version, 16134 MaxVersion: ver.version, 16135 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16136 shrinkingCompressionAlgID: shrinkingCompression, 16137 }, 16138 Bugs: ProtocolBugs{ 16139 ExpectedCompressedCert: shrinkingCompressionAlgID, 16140 }, 16141 }, 16142 }) 16143 16144 testCases = append(testCases, testCase{ 16145 testType: clientTest, 16146 name: "CertCompressionBadAlgIDClient-" + ver.name, 16147 flags: []string{"-install-cert-compression-algs"}, 16148 config: Config{ 16149 MinVersion: ver.version, 16150 MaxVersion: ver.version, 16151 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16152 shrinkingCompressionAlgID: shrinkingCompression, 16153 }, 16154 Bugs: ProtocolBugs{ 16155 ExpectedCompressedCert: shrinkingCompressionAlgID, 16156 SendCertCompressionAlgID: 1234, 16157 }, 16158 }, 16159 shouldFail: true, 16160 expectedError: ":UNKNOWN_CERT_COMPRESSION_ALG:", 16161 }) 16162 16163 testCases = append(testCases, testCase{ 16164 testType: clientTest, 16165 name: "CertCompressionTooSmallClient-" + ver.name, 16166 flags: []string{"-install-cert-compression-algs"}, 16167 config: Config{ 16168 MinVersion: ver.version, 16169 MaxVersion: ver.version, 16170 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16171 shrinkingCompressionAlgID: shrinkingCompression, 16172 }, 16173 Bugs: ProtocolBugs{ 16174 ExpectedCompressedCert: shrinkingCompressionAlgID, 16175 SendCertUncompressedLength: 12, 16176 }, 16177 }, 16178 shouldFail: true, 16179 expectedError: ":CERT_DECOMPRESSION_FAILED:", 16180 }) 16181 16182 testCases = append(testCases, testCase{ 16183 testType: clientTest, 16184 name: "CertCompressionTooLargeClient-" + ver.name, 16185 flags: []string{"-install-cert-compression-algs"}, 16186 config: Config{ 16187 MinVersion: ver.version, 16188 MaxVersion: ver.version, 16189 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16190 shrinkingCompressionAlgID: shrinkingCompression, 16191 }, 16192 Bugs: ProtocolBugs{ 16193 ExpectedCompressedCert: shrinkingCompressionAlgID, 16194 SendCertUncompressedLength: 1 << 20, 16195 }, 16196 }, 16197 shouldFail: true, 16198 expectedError: ":UNCOMPRESSED_CERT_TOO_LARGE:", 16199 }) 16200 } 16201} 16202 16203func addJDK11WorkaroundTests() { 16204 // Test the client treats the JDK 11 downgrade random like the usual one. 16205 testCases = append(testCases, testCase{ 16206 testType: clientTest, 16207 name: "Client-RejectJDK11DowngradeRandom", 16208 config: Config{ 16209 MaxVersion: VersionTLS12, 16210 Bugs: ProtocolBugs{ 16211 SendJDK11DowngradeRandom: true, 16212 }, 16213 }, 16214 shouldFail: true, 16215 expectedError: ":TLS13_DOWNGRADE:", 16216 expectedLocalError: "remote error: illegal parameter", 16217 }) 16218 testCases = append(testCases, testCase{ 16219 testType: clientTest, 16220 name: "Client-AcceptJDK11DowngradeRandom", 16221 config: Config{ 16222 MaxVersion: VersionTLS12, 16223 Bugs: ProtocolBugs{ 16224 SendJDK11DowngradeRandom: true, 16225 }, 16226 }, 16227 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 16228 }) 16229 16230 var clientHelloTests = []struct { 16231 clientHello []byte 16232 isJDK11 bool 16233 }{ 16234 { 16235 // A default JDK 11 ClientHello. 16236 decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"), 16237 true, 16238 }, 16239 { 16240 // The above with supported_versions and 16241 // psk_key_exchange_modes in the wrong order. 16242 decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002d00020101002b00090803040303030203010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"), 16243 false, 16244 }, 16245 { 16246 // The above with a padding extension added at the end. 16247 decodeHexOrPanic("010001b4030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000111000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b50015000700000000000000"), 16248 false, 16249 }, 16250 { 16251 // A JDK 11 ClientHello offering a TLS 1.3 PSK. 16252 decodeHexOrPanic("0100024c0303a8d71b20f060545a398226e807d21371a7a02b7ca2f96f476c2dea7e5860c5a400005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010001c9000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104aaec585ea9e121b24710a23560571322b2cf8ab8cd14e5762ef0486d8a6d0ecd721d8f2abda2eb8ed5ab7195505660450f49bba94bbf0c3f0070a531d9a1be4f002900cb00a600a0e6f7586d9a2bf64a54c1adf55a2f76657047e8e88e26629e2e7b9d630941e06fd87792770f6834e159a70b252157a9b4b082183f24629c8ff5049088b07ce37c49de8cf752a2ed7a545aff63bdc7a1b18e1bc201f23f159ee75d4987a04e00f840824f764691ab83a20e3032646e793065874cdb46138a52f50ed71406f399f96f9309eba4e5b1966148c22a63dc4aa1364269dd41dd5cc0e848d07af0095622c52cfcfc00212009cc315259e2328d65ad17a3de7c182c7874140a9356fecdd4614657806cd659"), 16253 true, 16254 }, 16255 { 16256 // A JDK 11 ClientHello offering a TLS 1.2 session. 16257 decodeHexOrPanic("010001a903038cdec49f4836d064a75046c93f22d0b9c2cf4900917332e6f0e1f41d692d3146201a3e99047492285ec65ab4e0eeee59f8f9d1eb7687398887bcd7b81353e93923005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d0002010100330047004500170041041c83c42fcd8fc06265b9f6e4f076f7e7ee17ace915c587845c0e1bc8cd177f904befeb611b682cae4702509a5f5d0c7162a282b8152d843169b91136e7c6f3e7"), 16258 true, 16259 }, 16260 { 16261 // A JDK 11 ClientHello with EMS disabled. 16262 decodeHexOrPanic("010001a50303323a857c324a9ef57d6e2544d129073830385cb1dc75ea79f6a2ec8ae09d2e7320f85fdd081678874c67ebab235e6d6a81d947f690bc0af9be4d39854ed67d9ef9005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000102000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200110009000702000400000000002b0009080304030303020301002d0002010100330047004500170041049c904c4850b495d75522f955d79e9cabea065c90279d6037a101a4c4ee712afc93ad0df5d12d287d53e458c7075d9a3ce3969c939bb62222bda779cecf54a603"), 16263 true, 16264 }, 16265 { 16266 // A JDK 11 ClientHello with OCSP stapling disabled. 16267 decodeHexOrPanic("0100019303038a50481dc85ee4f6581670821c50f2b3d34ac3251dc6e9b751bfd2521ab47ab02069a963c5486034c37ae0577ddb4c2db28cab592380ef8e4599d1305148712112005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010000f0000000080006000003736e69000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200170000002b0009080304030303020301002d00020101003300470045001700410438a97824f842c549e3c339322d8b2dbaa85d10bd7bca9c969376cb0c60b1e929eb4d13db38dcb0082ad8c637b24f55466a9acbb0b63634c1f431ec8342cf720d"), 16268 true, 16269 }, 16270 { 16271 // A JDK 11 ClientHello configured with a smaller set of 16272 // ciphers. 16273 decodeHexOrPanic("0100015603036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16274 true, 16275 }, 16276 { 16277 // The above with TLS_CHACHA20_POLY1305_SHA256 added, 16278 // which JDK 11 does not support. 16279 decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f48118000813011303c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16280 false, 16281 }, 16282 { 16283 // The above with X25519 added, which JDK 11 does not 16284 // support. 16285 decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000109000000080006000003736e69000500050100000000000a00220020001d0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16286 false, 16287 }, 16288 { 16289 // A JDK 11 ClientHello with ALPN protocols configured. 16290 decodeHexOrPanic("010001bb0303c0e0ea707b00c5311eb09cabd58626692cebfaefaef7265637e4550811dae16220da86d6eea04e214e873675223f08a6926bcf79f16d866280bdbab85e9e09c3ff005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000118000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020010000e000c02683208687474702f312e310011000900070200040000000000170000002b0009080304030303020301002d00020101003300470045001700410416def07c1d66ddde5fc9dcc328c8e77022d321c590c0d30cb41d515b38dca34540819a216c6c053bd47b9068f4f6b960f03647de4e36e8b7ffeea78f7252e3d9"), 16291 true, 16292 }, 16293 } 16294 for i, t := range clientHelloTests { 16295 expectedVersion := uint16(VersionTLS13) 16296 if t.isJDK11 { 16297 expectedVersion = VersionTLS12 16298 } 16299 16300 // In each of these tests, we set DefaultCurves to P-256 to 16301 // match the test inputs. SendClientHelloWithFixes requires the 16302 // key_shares extension to match in type. 16303 16304 // With the workaround enabled, we should negotiate TLS 1.2 on 16305 // JDK 11 ClientHellos. 16306 testCases = append(testCases, testCase{ 16307 testType: serverTest, 16308 name: fmt.Sprintf("Server-JDK11-%d", i), 16309 config: Config{ 16310 MaxVersion: VersionTLS13, 16311 DefaultCurves: []CurveID{CurveP256}, 16312 Bugs: ProtocolBugs{ 16313 SendClientHelloWithFixes: t.clientHello, 16314 ExpectJDK11DowngradeRandom: t.isJDK11, 16315 }, 16316 }, 16317 expectations: connectionExpectations{ 16318 version: expectedVersion, 16319 }, 16320 flags: []string{"-jdk11-workaround"}, 16321 }) 16322 16323 // With the workaround disabled, we always negotiate TLS 1.3. 16324 testCases = append(testCases, testCase{ 16325 testType: serverTest, 16326 name: fmt.Sprintf("Server-JDK11-NoWorkaround-%d", i), 16327 config: Config{ 16328 MaxVersion: VersionTLS13, 16329 DefaultCurves: []CurveID{CurveP256}, 16330 Bugs: ProtocolBugs{ 16331 SendClientHelloWithFixes: t.clientHello, 16332 ExpectJDK11DowngradeRandom: false, 16333 }, 16334 }, 16335 expectations: connectionExpectations{ 16336 version: VersionTLS13, 16337 }, 16338 }) 16339 16340 // If the server does not support TLS 1.3, the workaround should 16341 // be a no-op. In particular, it should not send the downgrade 16342 // signal. 16343 testCases = append(testCases, testCase{ 16344 testType: serverTest, 16345 name: fmt.Sprintf("Server-JDK11-TLS12-%d", i), 16346 config: Config{ 16347 MaxVersion: VersionTLS13, 16348 DefaultCurves: []CurveID{CurveP256}, 16349 Bugs: ProtocolBugs{ 16350 SendClientHelloWithFixes: t.clientHello, 16351 ExpectJDK11DowngradeRandom: false, 16352 }, 16353 }, 16354 expectations: connectionExpectations{ 16355 version: VersionTLS12, 16356 }, 16357 flags: []string{ 16358 "-jdk11-workaround", 16359 "-max-version", strconv.Itoa(VersionTLS12), 16360 }, 16361 }) 16362 } 16363} 16364 16365func addDelegatedCredentialTests() { 16366 certPath := path.Join(*resourceDir, rsaCertificateFile) 16367 pemBytes, err := ioutil.ReadFile(certPath) 16368 if err != nil { 16369 panic(err) 16370 } 16371 16372 block, _ := pem.Decode(pemBytes) 16373 if block == nil { 16374 panic(fmt.Sprintf("no PEM block found in %q", certPath)) 16375 } 16376 parentDER := block.Bytes 16377 16378 rsaPriv, _, err := loadRSAPrivateKey(rsaKeyFile) 16379 if err != nil { 16380 panic(err) 16381 } 16382 16383 ecdsaDC, ecdsaPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{ 16384 algo: signatureRSAPSSWithSHA256, 16385 }, parentDER, rsaPriv) 16386 if err != nil { 16387 panic(err) 16388 } 16389 ecdsaFlagValue := fmt.Sprintf("%x,%x", ecdsaDC, ecdsaPKCS8) 16390 16391 testCases = append(testCases, testCase{ 16392 testType: serverTest, 16393 name: "DelegatedCredentials-NoClientSupport", 16394 config: Config{ 16395 MinVersion: VersionTLS13, 16396 MaxVersion: VersionTLS13, 16397 Bugs: ProtocolBugs{ 16398 DisableDelegatedCredentials: true, 16399 }, 16400 }, 16401 flags: []string{ 16402 "-delegated-credential", ecdsaFlagValue, 16403 }, 16404 }) 16405 16406 testCases = append(testCases, testCase{ 16407 testType: serverTest, 16408 name: "DelegatedCredentials-Basic", 16409 config: Config{ 16410 MinVersion: VersionTLS13, 16411 MaxVersion: VersionTLS13, 16412 Bugs: ProtocolBugs{ 16413 ExpectDelegatedCredentials: true, 16414 }, 16415 }, 16416 flags: []string{ 16417 "-delegated-credential", ecdsaFlagValue, 16418 "-expect-delegated-credential-used", 16419 }, 16420 }) 16421 16422 testCases = append(testCases, testCase{ 16423 testType: serverTest, 16424 name: "DelegatedCredentials-SigAlgoMissing", 16425 config: Config{ 16426 MinVersion: VersionTLS13, 16427 MaxVersion: VersionTLS13, 16428 Bugs: ProtocolBugs{ 16429 FailIfDelegatedCredentials: true, 16430 }, 16431 // If the client doesn't support the delegated credential signature 16432 // algorithm then the handshake should complete without using delegated 16433 // credentials. 16434 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 16435 }, 16436 flags: []string{ 16437 "-delegated-credential", ecdsaFlagValue, 16438 }, 16439 }) 16440 16441 // This flag value has mismatched public and private keys which should cause a 16442 // configuration error in the shim. 16443 _, badTLSVersionPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{ 16444 algo: signatureRSAPSSWithSHA256, 16445 tlsVersion: 0x1234, 16446 }, parentDER, rsaPriv) 16447 if err != nil { 16448 panic(err) 16449 } 16450 mismatchFlagValue := fmt.Sprintf("%x,%x", ecdsaDC, badTLSVersionPKCS8) 16451 testCases = append(testCases, testCase{ 16452 testType: serverTest, 16453 name: "DelegatedCredentials-KeyMismatch", 16454 config: Config{ 16455 MinVersion: VersionTLS13, 16456 MaxVersion: VersionTLS13, 16457 Bugs: ProtocolBugs{ 16458 FailIfDelegatedCredentials: true, 16459 }, 16460 }, 16461 flags: []string{ 16462 "-delegated-credential", mismatchFlagValue, 16463 }, 16464 shouldFail: true, 16465 expectedError: ":KEY_VALUES_MISMATCH:", 16466 }) 16467} 16468 16469type echCipher struct { 16470 name string 16471 cipher HPKECipherSuite 16472} 16473 16474var echCiphers = []echCipher{ 16475 { 16476 name: "HKDF-SHA256-AES-128-GCM", 16477 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.AES128GCM}, 16478 }, 16479 { 16480 name: "HKDF-SHA256-AES-256-GCM", 16481 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.AES256GCM}, 16482 }, { 16483 name: "HKDF-SHA256-ChaCha20-Poly1305", 16484 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.ChaCha20Poly1305}, 16485 }, 16486} 16487 16488// generateServerECHConfig constructs a ServerECHConfig with a fresh X25519 16489// keypair and using |template| as a template for the ECHConfig. If fields are 16490// omitted, defaults are used. 16491func generateServerECHConfig(template *ECHConfig) ServerECHConfig { 16492 publicKey, secretKey, err := hpke.GenerateKeyPairX25519() 16493 if err != nil { 16494 panic(err) 16495 } 16496 templateCopy := *template 16497 if templateCopy.KEM == 0 { 16498 templateCopy.KEM = hpke.X25519WithHKDFSHA256 16499 } 16500 if len(templateCopy.PublicKey) == 0 { 16501 templateCopy.PublicKey = publicKey 16502 } 16503 if len(templateCopy.CipherSuites) == 0 { 16504 templateCopy.CipherSuites = make([]HPKECipherSuite, len(echCiphers)) 16505 for i, cipher := range echCiphers { 16506 templateCopy.CipherSuites[i] = cipher.cipher 16507 } 16508 } 16509 if len(templateCopy.PublicName) == 0 { 16510 templateCopy.PublicName = "public.example" 16511 } 16512 if templateCopy.MaxNameLen == 0 { 16513 templateCopy.MaxNameLen = 64 16514 } 16515 return ServerECHConfig{ECHConfig: CreateECHConfig(&templateCopy), Key: secretKey} 16516} 16517 16518func addEncryptedClientHelloTests() { 16519 // echConfig's ConfigID should match the one used in ssl/test/fuzzer.h. 16520 echConfig := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 16521 echConfig1 := generateServerECHConfig(&ECHConfig{ConfigID: 43}) 16522 echConfig2 := generateServerECHConfig(&ECHConfig{ConfigID: 44}) 16523 echConfig3 := generateServerECHConfig(&ECHConfig{ConfigID: 45}) 16524 echConfigRepeatID := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 16525 16526 for _, protocol := range []protocol{tls, quic} { 16527 prefix := protocol.String() + "-" 16528 16529 // There are two ClientHellos, so many of our tests have 16530 // HelloRetryRequest variations. 16531 for _, hrr := range []bool{false, true} { 16532 var suffix string 16533 var defaultCurves []CurveID 16534 if hrr { 16535 suffix = "-HelloRetryRequest" 16536 // Require a HelloRetryRequest for every curve. 16537 defaultCurves = []CurveID{} 16538 } 16539 16540 // Test the server can accept ECH. 16541 testCases = append(testCases, testCase{ 16542 testType: serverTest, 16543 protocol: protocol, 16544 name: prefix + "ECH-Server" + suffix, 16545 config: Config{ 16546 ServerName: "secret.example", 16547 ClientECHConfig: echConfig.ECHConfig, 16548 DefaultCurves: defaultCurves, 16549 }, 16550 resumeSession: true, 16551 flags: []string{ 16552 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16553 "-ech-server-key", base64FlagValue(echConfig.Key), 16554 "-ech-is-retry-config", "1", 16555 "-expect-server-name", "secret.example", 16556 "-expect-ech-accept", 16557 }, 16558 expectations: connectionExpectations{ 16559 echAccepted: true, 16560 }, 16561 }) 16562 16563 // Test the server can accept ECH with a minimal ClientHelloOuter. 16564 // This confirms that the server does not unexpectedly pick up 16565 // fields from the wrong ClientHello. 16566 testCases = append(testCases, testCase{ 16567 testType: serverTest, 16568 protocol: protocol, 16569 name: prefix + "ECH-Server-MinimalClientHelloOuter" + suffix, 16570 config: Config{ 16571 ServerName: "secret.example", 16572 ClientECHConfig: echConfig.ECHConfig, 16573 DefaultCurves: defaultCurves, 16574 Bugs: ProtocolBugs{ 16575 MinimalClientHelloOuter: true, 16576 }, 16577 }, 16578 resumeSession: true, 16579 flags: []string{ 16580 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16581 "-ech-server-key", base64FlagValue(echConfig.Key), 16582 "-ech-is-retry-config", "1", 16583 "-expect-server-name", "secret.example", 16584 "-expect-ech-accept", 16585 }, 16586 expectations: connectionExpectations{ 16587 echAccepted: true, 16588 }, 16589 }) 16590 16591 // Test that the server can decline ECH. In particular, it must send 16592 // retry configs. 16593 testCases = append(testCases, testCase{ 16594 testType: serverTest, 16595 protocol: protocol, 16596 name: prefix + "ECH-Server-Decline" + suffix, 16597 config: Config{ 16598 ServerName: "secret.example", 16599 DefaultCurves: defaultCurves, 16600 // The client uses an ECHConfig that the server does not understand 16601 // so we can observe which retry configs the server sends back. 16602 ClientECHConfig: echConfig.ECHConfig, 16603 Bugs: ProtocolBugs{ 16604 OfferSessionInClientHelloOuter: true, 16605 ExpectECHRetryConfigs: CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw), 16606 }, 16607 }, 16608 resumeSession: true, 16609 flags: []string{ 16610 // Configure three ECHConfigs on the shim, only two of which 16611 // should be sent in retry configs. 16612 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 16613 "-ech-server-key", base64FlagValue(echConfig1.Key), 16614 "-ech-is-retry-config", "0", 16615 "-ech-server-config", base64FlagValue(echConfig2.ECHConfig.Raw), 16616 "-ech-server-key", base64FlagValue(echConfig2.Key), 16617 "-ech-is-retry-config", "1", 16618 "-ech-server-config", base64FlagValue(echConfig3.ECHConfig.Raw), 16619 "-ech-server-key", base64FlagValue(echConfig3.Key), 16620 "-ech-is-retry-config", "1", 16621 "-expect-server-name", "public.example", 16622 }, 16623 }) 16624 16625 // Test that the server considers a ClientHelloInner indicating TLS 16626 // 1.2 to be a fatal error. 16627 testCases = append(testCases, testCase{ 16628 testType: serverTest, 16629 protocol: protocol, 16630 name: prefix + "ECH-Server-TLS12InInner" + suffix, 16631 config: Config{ 16632 ServerName: "secret.example", 16633 DefaultCurves: defaultCurves, 16634 ClientECHConfig: echConfig.ECHConfig, 16635 Bugs: ProtocolBugs{ 16636 AllowTLS12InClientHelloInner: true, 16637 }, 16638 }, 16639 flags: []string{ 16640 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16641 "-ech-server-key", base64FlagValue(echConfig.Key), 16642 "-ech-is-retry-config", "1"}, 16643 shouldFail: true, 16644 expectedLocalError: "remote error: illegal parameter", 16645 expectedError: ":INVALID_CLIENT_HELLO_INNER:", 16646 }) 16647 16648 // When inner ECH extension is absent from the ClientHelloInner, the 16649 // server should fail the connection. 16650 testCases = append(testCases, testCase{ 16651 testType: serverTest, 16652 protocol: protocol, 16653 name: prefix + "ECH-Server-MissingECHInner" + suffix, 16654 config: Config{ 16655 ServerName: "secret.example", 16656 DefaultCurves: defaultCurves, 16657 ClientECHConfig: echConfig.ECHConfig, 16658 Bugs: ProtocolBugs{ 16659 OmitECHInner: !hrr, 16660 OmitSecondECHInner: hrr, 16661 }, 16662 }, 16663 flags: []string{ 16664 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16665 "-ech-server-key", base64FlagValue(echConfig.Key), 16666 "-ech-is-retry-config", "1", 16667 }, 16668 shouldFail: true, 16669 expectedLocalError: "remote error: illegal parameter", 16670 expectedError: ":INVALID_CLIENT_HELLO_INNER:", 16671 }) 16672 16673 // Test that the server can decode ech_outer_extensions. 16674 testCases = append(testCases, testCase{ 16675 testType: serverTest, 16676 protocol: protocol, 16677 name: prefix + "ECH-Server-OuterExtensions" + suffix, 16678 config: Config{ 16679 ServerName: "secret.example", 16680 DefaultCurves: defaultCurves, 16681 ClientECHConfig: echConfig.ECHConfig, 16682 ECHOuterExtensions: []uint16{ 16683 extensionKeyShare, 16684 extensionSupportedCurves, 16685 // Include a custom extension, to test that unrecognized 16686 // extensions are also decoded. 16687 extensionCustom, 16688 }, 16689 Bugs: ProtocolBugs{ 16690 CustomExtension: "test", 16691 OnlyCompressSecondClientHelloInner: hrr, 16692 }, 16693 }, 16694 flags: []string{ 16695 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16696 "-ech-server-key", base64FlagValue(echConfig.Key), 16697 "-ech-is-retry-config", "1", 16698 "-expect-server-name", "secret.example", 16699 "-expect-ech-accept", 16700 }, 16701 expectations: connectionExpectations{ 16702 echAccepted: true, 16703 }, 16704 }) 16705 16706 // Test that the server allows referenced ClientHelloOuter 16707 // extensions to be interleaved with other extensions. Only the 16708 // relative order must match. 16709 testCases = append(testCases, testCase{ 16710 testType: serverTest, 16711 protocol: protocol, 16712 name: prefix + "ECH-Server-OuterExtensions-Interleaved" + suffix, 16713 config: Config{ 16714 ServerName: "secret.example", 16715 DefaultCurves: defaultCurves, 16716 ClientECHConfig: echConfig.ECHConfig, 16717 ECHOuterExtensions: []uint16{ 16718 extensionKeyShare, 16719 extensionSupportedCurves, 16720 extensionCustom, 16721 }, 16722 Bugs: ProtocolBugs{ 16723 CustomExtension: "test", 16724 OnlyCompressSecondClientHelloInner: hrr, 16725 ECHOuterExtensionOrder: []uint16{ 16726 extensionServerName, 16727 extensionKeyShare, 16728 extensionSupportedVersions, 16729 extensionPSKKeyExchangeModes, 16730 extensionSupportedCurves, 16731 extensionSignatureAlgorithms, 16732 extensionCustom, 16733 }, 16734 }, 16735 }, 16736 flags: []string{ 16737 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16738 "-ech-server-key", base64FlagValue(echConfig.Key), 16739 "-ech-is-retry-config", "1", 16740 "-expect-server-name", "secret.example", 16741 "-expect-ech-accept", 16742 }, 16743 expectations: connectionExpectations{ 16744 echAccepted: true, 16745 }, 16746 }) 16747 16748 // Test that the server rejects references to extensions in the 16749 // wrong order. 16750 testCases = append(testCases, testCase{ 16751 testType: serverTest, 16752 protocol: protocol, 16753 name: prefix + "ECH-Server-OuterExtensions-WrongOrder" + suffix, 16754 config: Config{ 16755 ServerName: "secret.example", 16756 DefaultCurves: defaultCurves, 16757 ClientECHConfig: echConfig.ECHConfig, 16758 ECHOuterExtensions: []uint16{ 16759 extensionKeyShare, 16760 extensionSupportedCurves, 16761 }, 16762 Bugs: ProtocolBugs{ 16763 CustomExtension: "test", 16764 OnlyCompressSecondClientHelloInner: hrr, 16765 ECHOuterExtensionOrder: []uint16{ 16766 extensionSupportedCurves, 16767 extensionKeyShare, 16768 }, 16769 }, 16770 }, 16771 flags: []string{ 16772 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16773 "-ech-server-key", base64FlagValue(echConfig.Key), 16774 "-ech-is-retry-config", "1", 16775 "-expect-server-name", "secret.example", 16776 }, 16777 shouldFail: true, 16778 expectedLocalError: "remote error: illegal parameter", 16779 expectedError: ":INVALID_OUTER_EXTENSION:", 16780 }) 16781 16782 // Test that the server rejects duplicated values in ech_outer_extensions. 16783 // Besides causing the server to reconstruct an invalid ClientHelloInner 16784 // with duplicated extensions, this behavior would be vulnerable to DoS 16785 // attacks. 16786 testCases = append(testCases, testCase{ 16787 testType: serverTest, 16788 protocol: protocol, 16789 name: prefix + "ECH-Server-OuterExtensions-Duplicate" + suffix, 16790 config: Config{ 16791 ServerName: "secret.example", 16792 DefaultCurves: defaultCurves, 16793 ClientECHConfig: echConfig.ECHConfig, 16794 ECHOuterExtensions: []uint16{ 16795 extensionSupportedCurves, 16796 extensionSupportedCurves, 16797 }, 16798 Bugs: ProtocolBugs{ 16799 OnlyCompressSecondClientHelloInner: hrr, 16800 // Don't duplicate the extension in ClientHelloOuter. 16801 ECHOuterExtensionOrder: []uint16{ 16802 extensionSupportedCurves, 16803 }, 16804 }, 16805 }, 16806 flags: []string{ 16807 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16808 "-ech-server-key", base64FlagValue(echConfig.Key), 16809 "-ech-is-retry-config", "1", 16810 }, 16811 shouldFail: true, 16812 expectedLocalError: "remote error: illegal parameter", 16813 expectedError: ":INVALID_OUTER_EXTENSION:", 16814 }) 16815 16816 // Test that the server rejects references to missing extensions in 16817 // ech_outer_extensions. 16818 testCases = append(testCases, testCase{ 16819 testType: serverTest, 16820 protocol: protocol, 16821 name: prefix + "ECH-Server-OuterExtensions-Missing" + suffix, 16822 config: Config{ 16823 ServerName: "secret.example", 16824 DefaultCurves: defaultCurves, 16825 ClientECHConfig: echConfig.ECHConfig, 16826 ECHOuterExtensions: []uint16{ 16827 extensionCustom, 16828 }, 16829 Bugs: ProtocolBugs{ 16830 OnlyCompressSecondClientHelloInner: hrr, 16831 }, 16832 }, 16833 flags: []string{ 16834 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16835 "-ech-server-key", base64FlagValue(echConfig.Key), 16836 "-ech-is-retry-config", "1", 16837 "-expect-server-name", "secret.example", 16838 "-expect-ech-accept", 16839 }, 16840 shouldFail: true, 16841 expectedLocalError: "remote error: illegal parameter", 16842 expectedError: ":INVALID_OUTER_EXTENSION:", 16843 }) 16844 16845 // Test that the server rejects a references to the ECH extension in 16846 // ech_outer_extensions. The ECH extension is not authenticated in the 16847 // AAD and would result in an invalid ClientHelloInner. 16848 testCases = append(testCases, testCase{ 16849 testType: serverTest, 16850 protocol: protocol, 16851 name: prefix + "ECH-Server-OuterExtensions-SelfReference" + suffix, 16852 config: Config{ 16853 ServerName: "secret.example", 16854 DefaultCurves: defaultCurves, 16855 ClientECHConfig: echConfig.ECHConfig, 16856 ECHOuterExtensions: []uint16{ 16857 extensionEncryptedClientHello, 16858 }, 16859 Bugs: ProtocolBugs{ 16860 OnlyCompressSecondClientHelloInner: hrr, 16861 }, 16862 }, 16863 flags: []string{ 16864 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16865 "-ech-server-key", base64FlagValue(echConfig.Key), 16866 "-ech-is-retry-config", "1", 16867 }, 16868 shouldFail: true, 16869 expectedLocalError: "remote error: illegal parameter", 16870 expectedError: ":INVALID_OUTER_EXTENSION:", 16871 }) 16872 16873 // Test the message callback is correctly reported with ECH. 16874 clientAndServerHello := "read hs 1\nread clienthelloinner\nwrite hs 2\n" 16875 expectMsgCallback := clientAndServerHello + "write ccs\n" 16876 if hrr { 16877 expectMsgCallback += clientAndServerHello 16878 } 16879 // EncryptedExtensions onwards. 16880 expectMsgCallback += `write hs 8 16881write hs 11 16882write hs 15 16883write hs 20 16884read hs 20 16885write hs 4 16886write hs 4 16887` 16888 testCases = append(testCases, testCase{ 16889 testType: serverTest, 16890 protocol: protocol, 16891 name: prefix + "ECH-Server-MessageCallback" + suffix, 16892 config: Config{ 16893 ServerName: "secret.example", 16894 ClientECHConfig: echConfig.ECHConfig, 16895 DefaultCurves: defaultCurves, 16896 Bugs: ProtocolBugs{ 16897 NoCloseNotify: true, // Align QUIC and TCP traces. 16898 }, 16899 }, 16900 flags: []string{ 16901 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16902 "-ech-server-key", base64FlagValue(echConfig.Key), 16903 "-ech-is-retry-config", "1", 16904 "-expect-ech-accept", 16905 "-expect-msg-callback", expectMsgCallback, 16906 }, 16907 expectations: connectionExpectations{ 16908 echAccepted: true, 16909 }, 16910 }) 16911 } 16912 16913 // Test that ECH, which runs before an async early callback, interacts 16914 // correctly in the state machine. 16915 testCases = append(testCases, testCase{ 16916 testType: serverTest, 16917 protocol: protocol, 16918 name: prefix + "ECH-Server-AsyncEarlyCallback", 16919 config: Config{ 16920 ServerName: "secret.example", 16921 ClientECHConfig: echConfig.ECHConfig, 16922 }, 16923 flags: []string{ 16924 "-async", 16925 "-use-early-callback", 16926 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16927 "-ech-server-key", base64FlagValue(echConfig.Key), 16928 "-ech-is-retry-config", "1", 16929 "-expect-server-name", "secret.example", 16930 "-expect-ech-accept", 16931 }, 16932 expectations: connectionExpectations{ 16933 echAccepted: true, 16934 }, 16935 }) 16936 16937 // Test ECH-enabled server with two ECHConfigs can decrypt client's ECH when 16938 // it uses the second ECHConfig. 16939 testCases = append(testCases, testCase{ 16940 testType: serverTest, 16941 protocol: protocol, 16942 name: prefix + "ECH-Server-SecondECHConfig", 16943 config: Config{ 16944 ServerName: "secret.example", 16945 ClientECHConfig: echConfig1.ECHConfig, 16946 }, 16947 flags: []string{ 16948 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16949 "-ech-server-key", base64FlagValue(echConfig.Key), 16950 "-ech-is-retry-config", "1", 16951 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 16952 "-ech-server-key", base64FlagValue(echConfig1.Key), 16953 "-ech-is-retry-config", "1", 16954 "-expect-server-name", "secret.example", 16955 "-expect-ech-accept", 16956 }, 16957 expectations: connectionExpectations{ 16958 echAccepted: true, 16959 }, 16960 }) 16961 16962 // Test ECH-enabled server with two ECHConfigs that have the same config 16963 // ID can decrypt client's ECH when it uses the second ECHConfig. 16964 testCases = append(testCases, testCase{ 16965 testType: serverTest, 16966 protocol: protocol, 16967 name: prefix + "ECH-Server-RepeatedConfigID", 16968 config: Config{ 16969 ServerName: "secret.example", 16970 ClientECHConfig: echConfigRepeatID.ECHConfig, 16971 }, 16972 flags: []string{ 16973 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16974 "-ech-server-key", base64FlagValue(echConfig.Key), 16975 "-ech-is-retry-config", "1", 16976 "-ech-server-config", base64FlagValue(echConfigRepeatID.ECHConfig.Raw), 16977 "-ech-server-key", base64FlagValue(echConfigRepeatID.Key), 16978 "-ech-is-retry-config", "1", 16979 "-expect-server-name", "secret.example", 16980 "-expect-ech-accept", 16981 }, 16982 expectations: connectionExpectations{ 16983 echAccepted: true, 16984 }, 16985 }) 16986 16987 // Test all supported ECH cipher suites. 16988 for i, cipher := range echCiphers { 16989 otherCipher := echCiphers[(i+1)%len(echCiphers)] 16990 16991 // Test the ECH server can handle the specified cipher. 16992 testCases = append(testCases, testCase{ 16993 testType: serverTest, 16994 protocol: protocol, 16995 name: prefix + "ECH-Server-Cipher-" + cipher.name, 16996 config: Config{ 16997 ServerName: "secret.example", 16998 ClientECHConfig: echConfig.ECHConfig, 16999 ECHCipherSuites: []HPKECipherSuite{cipher.cipher}, 17000 }, 17001 flags: []string{ 17002 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17003 "-ech-server-key", base64FlagValue(echConfig.Key), 17004 "-ech-is-retry-config", "1", 17005 "-expect-server-name", "secret.example", 17006 "-expect-ech-accept", 17007 }, 17008 expectations: connectionExpectations{ 17009 echAccepted: true, 17010 }, 17011 }) 17012 17013 // Test that client can offer the specified cipher and skip over 17014 // unrecognized ones. 17015 cipherConfig := generateServerECHConfig(&ECHConfig{ 17016 ConfigID: 42, 17017 CipherSuites: []HPKECipherSuite{ 17018 {KDF: 0x1111, AEAD: 0x2222}, 17019 {KDF: cipher.cipher.KDF, AEAD: 0x2222}, 17020 {KDF: 0x1111, AEAD: cipher.cipher.AEAD}, 17021 cipher.cipher, 17022 }, 17023 }) 17024 testCases = append(testCases, testCase{ 17025 testType: clientTest, 17026 protocol: protocol, 17027 name: prefix + "ECH-Client-Cipher-" + cipher.name, 17028 config: Config{ 17029 ServerECHConfigs: []ServerECHConfig{cipherConfig}, 17030 }, 17031 flags: []string{ 17032 "-ech-config-list", base64FlagValue(CreateECHConfigList(cipherConfig.ECHConfig.Raw)), 17033 "-host-name", "secret.example", 17034 "-expect-ech-accept", 17035 }, 17036 expectations: connectionExpectations{ 17037 echAccepted: true, 17038 }, 17039 }) 17040 17041 // Test that the ECH server rejects the specified cipher if not 17042 // listed in its ECHConfig. 17043 otherCipherConfig := generateServerECHConfig(&ECHConfig{ 17044 ConfigID: 42, 17045 CipherSuites: []HPKECipherSuite{otherCipher.cipher}, 17046 }) 17047 testCases = append(testCases, testCase{ 17048 testType: serverTest, 17049 protocol: protocol, 17050 name: prefix + "ECH-Server-DisabledCipher-" + cipher.name, 17051 config: Config{ 17052 ServerName: "secret.example", 17053 ClientECHConfig: echConfig.ECHConfig, 17054 ECHCipherSuites: []HPKECipherSuite{cipher.cipher}, 17055 Bugs: ProtocolBugs{ 17056 ExpectECHRetryConfigs: CreateECHConfigList(otherCipherConfig.ECHConfig.Raw), 17057 }, 17058 }, 17059 flags: []string{ 17060 "-ech-server-config", base64FlagValue(otherCipherConfig.ECHConfig.Raw), 17061 "-ech-server-key", base64FlagValue(otherCipherConfig.Key), 17062 "-ech-is-retry-config", "1", 17063 "-expect-server-name", "public.example", 17064 }, 17065 }) 17066 } 17067 17068 // Test that the ECH server handles a short enc value by falling back to 17069 // ClientHelloOuter. 17070 testCases = append(testCases, testCase{ 17071 testType: serverTest, 17072 protocol: protocol, 17073 name: prefix + "ECH-Server-ShortEnc", 17074 config: Config{ 17075 ServerName: "secret.example", 17076 ClientECHConfig: echConfig.ECHConfig, 17077 Bugs: ProtocolBugs{ 17078 ExpectECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw), 17079 TruncateClientECHEnc: true, 17080 }, 17081 }, 17082 flags: []string{ 17083 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17084 "-ech-server-key", base64FlagValue(echConfig.Key), 17085 "-ech-is-retry-config", "1", 17086 "-expect-server-name", "public.example", 17087 }, 17088 }) 17089 17090 // Test that the server handles decryption failure by falling back to 17091 // ClientHelloOuter. 17092 testCases = append(testCases, testCase{ 17093 testType: serverTest, 17094 protocol: protocol, 17095 name: prefix + "ECH-Server-CorruptEncryptedClientHello", 17096 config: Config{ 17097 ServerName: "secret.example", 17098 ClientECHConfig: echConfig.ECHConfig, 17099 Bugs: ProtocolBugs{ 17100 ExpectECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw), 17101 CorruptEncryptedClientHello: true, 17102 }, 17103 }, 17104 flags: []string{ 17105 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17106 "-ech-server-key", base64FlagValue(echConfig.Key), 17107 "-ech-is-retry-config", "1", 17108 }, 17109 }) 17110 17111 // Test that the server treats decryption failure in the second 17112 // ClientHello as fatal. 17113 testCases = append(testCases, testCase{ 17114 testType: serverTest, 17115 protocol: protocol, 17116 name: prefix + "ECH-Server-CorruptSecondEncryptedClientHello", 17117 config: Config{ 17118 ServerName: "secret.example", 17119 ClientECHConfig: echConfig.ECHConfig, 17120 // Force a HelloRetryRequest. 17121 DefaultCurves: []CurveID{}, 17122 Bugs: ProtocolBugs{ 17123 CorruptSecondEncryptedClientHello: true, 17124 }, 17125 }, 17126 flags: []string{ 17127 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17128 "-ech-server-key", base64FlagValue(echConfig.Key), 17129 "-ech-is-retry-config", "1", 17130 }, 17131 shouldFail: true, 17132 expectedError: ":DECRYPTION_FAILED:", 17133 expectedLocalError: "remote error: error decrypting message", 17134 }) 17135 17136 // Test that the server treats a missing second ECH extension as fatal. 17137 testCases = append(testCases, testCase{ 17138 testType: serverTest, 17139 protocol: protocol, 17140 name: prefix + "ECH-Server-OmitSecondEncryptedClientHello", 17141 config: Config{ 17142 ServerName: "secret.example", 17143 ClientECHConfig: echConfig.ECHConfig, 17144 // Force a HelloRetryRequest. 17145 DefaultCurves: []CurveID{}, 17146 Bugs: ProtocolBugs{ 17147 OmitSecondEncryptedClientHello: true, 17148 }, 17149 }, 17150 flags: []string{ 17151 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17152 "-ech-server-key", base64FlagValue(echConfig.Key), 17153 "-ech-is-retry-config", "1", 17154 }, 17155 shouldFail: true, 17156 expectedError: ":MISSING_EXTENSION:", 17157 expectedLocalError: "remote error: missing extension", 17158 }) 17159 17160 // Test that the server treats a mismatched config ID in the second ClientHello as fatal. 17161 testCases = append(testCases, testCase{ 17162 testType: serverTest, 17163 protocol: protocol, 17164 name: prefix + "ECH-Server-DifferentConfigIDSecondClientHello", 17165 config: Config{ 17166 ServerName: "secret.example", 17167 ClientECHConfig: echConfig.ECHConfig, 17168 // Force a HelloRetryRequest. 17169 DefaultCurves: []CurveID{}, 17170 Bugs: ProtocolBugs{ 17171 CorruptSecondEncryptedClientHelloConfigID: true, 17172 }, 17173 }, 17174 flags: []string{ 17175 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17176 "-ech-server-key", base64FlagValue(echConfig.Key), 17177 "-ech-is-retry-config", "1", 17178 }, 17179 shouldFail: true, 17180 expectedError: ":DECODE_ERROR:", 17181 expectedLocalError: "remote error: illegal parameter", 17182 }) 17183 17184 // Test early data works with ECH, in both accept and reject cases. 17185 testCases = append(testCases, testCase{ 17186 testType: serverTest, 17187 protocol: protocol, 17188 name: prefix + "ECH-Server-EarlyData", 17189 config: Config{ 17190 ServerName: "secret.example", 17191 ClientECHConfig: echConfig.ECHConfig, 17192 }, 17193 resumeSession: true, 17194 earlyData: true, 17195 flags: []string{ 17196 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17197 "-ech-server-key", base64FlagValue(echConfig.Key), 17198 "-ech-is-retry-config", "1", 17199 "-expect-ech-accept", 17200 }, 17201 expectations: connectionExpectations{ 17202 echAccepted: true, 17203 }, 17204 }) 17205 testCases = append(testCases, testCase{ 17206 testType: serverTest, 17207 protocol: protocol, 17208 name: prefix + "ECH-Server-EarlyDataRejected", 17209 config: Config{ 17210 ServerName: "secret.example", 17211 ClientECHConfig: echConfig.ECHConfig, 17212 Bugs: ProtocolBugs{ 17213 // Cause the server to reject 0-RTT with a bad ticket age. 17214 SendTicketAge: 1 * time.Hour, 17215 }, 17216 }, 17217 resumeSession: true, 17218 earlyData: true, 17219 expectEarlyDataRejected: true, 17220 flags: []string{ 17221 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17222 "-ech-server-key", base64FlagValue(echConfig.Key), 17223 "-ech-is-retry-config", "1", 17224 "-expect-ech-accept", 17225 }, 17226 expectations: connectionExpectations{ 17227 echAccepted: true, 17228 }, 17229 }) 17230 17231 // Test servers with ECH disabled correctly ignore the extension and 17232 // handshake with the ClientHelloOuter. 17233 testCases = append(testCases, testCase{ 17234 testType: serverTest, 17235 protocol: protocol, 17236 name: prefix + "ECH-Server-Disabled", 17237 config: Config{ 17238 ServerName: "secret.example", 17239 ClientECHConfig: echConfig.ECHConfig, 17240 }, 17241 flags: []string{ 17242 "-expect-server-name", "public.example", 17243 }, 17244 }) 17245 17246 // Test that ECH can be used with client certificates. In particular, 17247 // the name override logic should not interfere with the server. 17248 // Test the server can accept ECH. 17249 testCases = append(testCases, testCase{ 17250 testType: serverTest, 17251 protocol: protocol, 17252 name: prefix + "ECH-Server-ClientAuth", 17253 config: Config{ 17254 Certificates: []Certificate{rsaCertificate}, 17255 ClientECHConfig: echConfig.ECHConfig, 17256 }, 17257 flags: []string{ 17258 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17259 "-ech-server-key", base64FlagValue(echConfig.Key), 17260 "-ech-is-retry-config", "1", 17261 "-expect-ech-accept", 17262 "-require-any-client-certificate", 17263 }, 17264 expectations: connectionExpectations{ 17265 echAccepted: true, 17266 }, 17267 }) 17268 testCases = append(testCases, testCase{ 17269 testType: serverTest, 17270 protocol: protocol, 17271 name: prefix + "ECH-Server-Decline-ClientAuth", 17272 config: Config{ 17273 Certificates: []Certificate{rsaCertificate}, 17274 ClientECHConfig: echConfig.ECHConfig, 17275 Bugs: ProtocolBugs{ 17276 ExpectECHRetryConfigs: CreateECHConfigList(echConfig1.ECHConfig.Raw), 17277 }, 17278 }, 17279 flags: []string{ 17280 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 17281 "-ech-server-key", base64FlagValue(echConfig1.Key), 17282 "-ech-is-retry-config", "1", 17283 "-require-any-client-certificate", 17284 }, 17285 }) 17286 17287 // Test that the server accepts padding. 17288 testCases = append(testCases, testCase{ 17289 testType: serverTest, 17290 protocol: protocol, 17291 name: prefix + "ECH-Server-Padding", 17292 config: Config{ 17293 ClientECHConfig: echConfig.ECHConfig, 17294 Bugs: ProtocolBugs{ 17295 ClientECHPadding: 10, 17296 }, 17297 }, 17298 flags: []string{ 17299 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17300 "-ech-server-key", base64FlagValue(echConfig.Key), 17301 "-ech-is-retry-config", "1", 17302 "-expect-ech-accept", 17303 }, 17304 expectations: connectionExpectations{ 17305 echAccepted: true, 17306 }, 17307 }) 17308 17309 // Test that the server rejects bad padding. 17310 testCases = append(testCases, testCase{ 17311 testType: serverTest, 17312 protocol: protocol, 17313 name: prefix + "ECH-Server-BadPadding", 17314 config: Config{ 17315 ClientECHConfig: echConfig.ECHConfig, 17316 Bugs: ProtocolBugs{ 17317 ClientECHPadding: 10, 17318 BadClientECHPadding: true, 17319 }, 17320 }, 17321 flags: []string{ 17322 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17323 "-ech-server-key", base64FlagValue(echConfig.Key), 17324 "-ech-is-retry-config", "1", 17325 "-expect-ech-accept", 17326 }, 17327 expectations: connectionExpectations{ 17328 echAccepted: true, 17329 }, 17330 shouldFail: true, 17331 expectedError: ":DECODE_ERROR", 17332 expectedLocalError: "remote error: illegal parameter", 17333 }) 17334 17335 // Test the client's behavior when the server ignores ECH GREASE. 17336 testCases = append(testCases, testCase{ 17337 testType: clientTest, 17338 protocol: protocol, 17339 name: prefix + "ECH-GREASE-Client-TLS13", 17340 config: Config{ 17341 MinVersion: VersionTLS13, 17342 MaxVersion: VersionTLS13, 17343 Bugs: ProtocolBugs{ 17344 ExpectClientECH: true, 17345 }, 17346 }, 17347 flags: []string{"-enable-ech-grease"}, 17348 }) 17349 17350 // Test the client's ECH GREASE behavior when responding to server's 17351 // HelloRetryRequest. This test implicitly checks that the first and second 17352 // ClientHello messages have identical ECH extensions. 17353 testCases = append(testCases, testCase{ 17354 testType: clientTest, 17355 protocol: protocol, 17356 name: prefix + "ECH-GREASE-Client-TLS13-HelloRetryRequest", 17357 config: Config{ 17358 MaxVersion: VersionTLS13, 17359 MinVersion: VersionTLS13, 17360 // P-384 requires a HelloRetryRequest against BoringSSL's default 17361 // configuration. Assert this with ExpectMissingKeyShare. 17362 CurvePreferences: []CurveID{CurveP384}, 17363 Bugs: ProtocolBugs{ 17364 ExpectMissingKeyShare: true, 17365 ExpectClientECH: true, 17366 }, 17367 }, 17368 flags: []string{"-enable-ech-grease", "-expect-hrr"}, 17369 }) 17370 17371 unsupportedVersion := []byte{ 17372 // version 17373 0xba, 0xdd, 17374 // length 17375 0x00, 0x05, 17376 // contents 17377 0x05, 0x04, 0x03, 0x02, 0x01, 17378 } 17379 17380 // Test that the client accepts a well-formed encrypted_client_hello 17381 // extension in response to ECH GREASE. The response includes one ECHConfig 17382 // with a supported version and one with an unsupported version. 17383 testCases = append(testCases, testCase{ 17384 testType: clientTest, 17385 protocol: protocol, 17386 name: prefix + "ECH-GREASE-Client-TLS13-Retry-Configs", 17387 config: Config{ 17388 MinVersion: VersionTLS13, 17389 MaxVersion: VersionTLS13, 17390 Bugs: ProtocolBugs{ 17391 ExpectClientECH: true, 17392 // Include an additional well-formed ECHConfig with an 17393 // unsupported version. This ensures the client can skip 17394 // unsupported configs. 17395 SendECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw, unsupportedVersion), 17396 }, 17397 }, 17398 flags: []string{"-enable-ech-grease"}, 17399 }) 17400 17401 // TLS 1.2 ServerHellos cannot contain retry configs. 17402 if protocol != quic { 17403 testCases = append(testCases, testCase{ 17404 testType: clientTest, 17405 protocol: protocol, 17406 name: prefix + "ECH-GREASE-Client-TLS12-RejectRetryConfigs", 17407 config: Config{ 17408 MinVersion: VersionTLS12, 17409 MaxVersion: VersionTLS12, 17410 ServerECHConfigs: []ServerECHConfig{echConfig}, 17411 Bugs: ProtocolBugs{ 17412 ExpectClientECH: true, 17413 AlwaysSendECHRetryConfigs: true, 17414 }, 17415 }, 17416 flags: []string{"-enable-ech-grease"}, 17417 shouldFail: true, 17418 expectedLocalError: "remote error: unsupported extension", 17419 expectedError: ":UNEXPECTED_EXTENSION:", 17420 }) 17421 testCases = append(testCases, testCase{ 17422 testType: clientTest, 17423 protocol: protocol, 17424 name: prefix + "ECH-Client-TLS12-RejectRetryConfigs", 17425 config: Config{ 17426 MinVersion: VersionTLS12, 17427 MaxVersion: VersionTLS12, 17428 ServerECHConfigs: []ServerECHConfig{echConfig}, 17429 Bugs: ProtocolBugs{ 17430 ExpectClientECH: true, 17431 AlwaysSendECHRetryConfigs: true, 17432 }, 17433 }, 17434 flags: []string{ 17435 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig1.ECHConfig.Raw)), 17436 }, 17437 shouldFail: true, 17438 expectedLocalError: "remote error: unsupported extension", 17439 expectedError: ":UNEXPECTED_EXTENSION:", 17440 }) 17441 } 17442 17443 // Retry configs must be rejected when ECH is accepted. 17444 testCases = append(testCases, testCase{ 17445 testType: clientTest, 17446 protocol: protocol, 17447 name: prefix + "ECH-Client-Accept-RejectRetryConfigs", 17448 config: Config{ 17449 ServerECHConfigs: []ServerECHConfig{echConfig}, 17450 Bugs: ProtocolBugs{ 17451 ExpectClientECH: true, 17452 AlwaysSendECHRetryConfigs: true, 17453 }, 17454 }, 17455 flags: []string{ 17456 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17457 }, 17458 shouldFail: true, 17459 expectedLocalError: "remote error: unsupported extension", 17460 expectedError: ":UNEXPECTED_EXTENSION:", 17461 }) 17462 17463 // Unsolicited ECH HelloRetryRequest extensions should be rejected. 17464 testCases = append(testCases, testCase{ 17465 testType: clientTest, 17466 protocol: protocol, 17467 name: prefix + "ECH-Client-UnsolictedHRRExtension", 17468 config: Config{ 17469 ServerECHConfigs: []ServerECHConfig{echConfig}, 17470 CurvePreferences: []CurveID{CurveP384}, 17471 Bugs: ProtocolBugs{ 17472 AlwaysSendECHHelloRetryRequest: true, 17473 ExpectMissingKeyShare: true, // Check we triggered HRR. 17474 }, 17475 }, 17476 shouldFail: true, 17477 expectedLocalError: "remote error: unsupported extension", 17478 expectedError: ":UNEXPECTED_EXTENSION:", 17479 }) 17480 17481 // GREASE should ignore ECH HelloRetryRequest extensions. 17482 testCases = append(testCases, testCase{ 17483 testType: clientTest, 17484 protocol: protocol, 17485 name: prefix + "ECH-Client-GREASE-IgnoreHRRExtension", 17486 config: Config{ 17487 CurvePreferences: []CurveID{CurveP384}, 17488 Bugs: ProtocolBugs{ 17489 AlwaysSendECHHelloRetryRequest: true, 17490 ExpectMissingKeyShare: true, // Check we triggered HRR. 17491 }, 17492 }, 17493 flags: []string{"-enable-ech-grease"}, 17494 }) 17495 17496 // Random ECH HelloRetryRequest extensions also signal ECH reject. 17497 testCases = append(testCases, testCase{ 17498 testType: clientTest, 17499 protocol: protocol, 17500 name: prefix + "ECH-Client-Reject-RandomHRRExtension", 17501 config: Config{ 17502 CurvePreferences: []CurveID{CurveP384}, 17503 Bugs: ProtocolBugs{ 17504 AlwaysSendECHHelloRetryRequest: true, 17505 ExpectMissingKeyShare: true, // Check we triggered HRR. 17506 }, 17507 }, 17508 flags: []string{ 17509 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17510 }, 17511 shouldFail: true, 17512 expectedLocalError: "remote error: ECH required", 17513 expectedError: ":ECH_REJECTED:", 17514 }) 17515 17516 // Test that the client aborts with a decode_error alert when it receives a 17517 // syntactically-invalid encrypted_client_hello extension from the server. 17518 testCases = append(testCases, testCase{ 17519 testType: clientTest, 17520 protocol: protocol, 17521 name: prefix + "ECH-GREASE-Client-TLS13-Invalid-Retry-Configs", 17522 config: Config{ 17523 MinVersion: VersionTLS13, 17524 MaxVersion: VersionTLS13, 17525 Bugs: ProtocolBugs{ 17526 ExpectClientECH: true, 17527 SendECHRetryConfigs: []byte{0xba, 0xdd, 0xec, 0xcc}, 17528 }, 17529 }, 17530 flags: []string{"-enable-ech-grease"}, 17531 shouldFail: true, 17532 expectedLocalError: "remote error: error decoding message", 17533 expectedError: ":ERROR_PARSING_EXTENSION:", 17534 }) 17535 17536 // Test that the server responds to an inner ECH extension with the 17537 // acceptance confirmation. 17538 testCases = append(testCases, testCase{ 17539 testType: serverTest, 17540 protocol: protocol, 17541 name: prefix + "ECH-Server-ECHInner", 17542 config: Config{ 17543 MinVersion: VersionTLS13, 17544 MaxVersion: VersionTLS13, 17545 Bugs: ProtocolBugs{ 17546 AlwaysSendECHInner: true, 17547 }, 17548 }, 17549 resumeSession: true, 17550 }) 17551 testCases = append(testCases, testCase{ 17552 testType: serverTest, 17553 protocol: protocol, 17554 name: prefix + "ECH-Server-ECHInner-HelloRetryRequest", 17555 config: Config{ 17556 MinVersion: VersionTLS13, 17557 MaxVersion: VersionTLS13, 17558 // Force a HelloRetryRequest. 17559 DefaultCurves: []CurveID{}, 17560 Bugs: ProtocolBugs{ 17561 AlwaysSendECHInner: true, 17562 }, 17563 }, 17564 resumeSession: true, 17565 }) 17566 17567 // Test that server fails the handshake when it sees a non-empty 17568 // inner ECH extension. 17569 testCases = append(testCases, testCase{ 17570 testType: serverTest, 17571 protocol: protocol, 17572 name: prefix + "ECH-Server-ECHInner-NotEmpty", 17573 config: Config{ 17574 MinVersion: VersionTLS13, 17575 MaxVersion: VersionTLS13, 17576 Bugs: ProtocolBugs{ 17577 AlwaysSendECHInner: true, 17578 SendInvalidECHInner: []byte{42, 42, 42}, 17579 }, 17580 }, 17581 shouldFail: true, 17582 expectedLocalError: "remote error: error decoding message", 17583 expectedError: ":ERROR_PARSING_EXTENSION:", 17584 }) 17585 17586 // Test that a TLS 1.3 server that receives an inner ECH extension can 17587 // negotiate TLS 1.2 without clobbering the downgrade signal. 17588 if protocol != quic { 17589 testCases = append(testCases, testCase{ 17590 testType: serverTest, 17591 protocol: protocol, 17592 name: prefix + "ECH-Server-ECHInner-Absent-TLS12", 17593 config: Config{ 17594 MinVersion: VersionTLS12, 17595 MaxVersion: VersionTLS13, 17596 Bugs: ProtocolBugs{ 17597 // Omit supported_versions extension so the server negotiates 17598 // TLS 1.2. 17599 OmitSupportedVersions: true, 17600 AlwaysSendECHInner: true, 17601 }, 17602 }, 17603 // Check that the client sees the TLS 1.3 downgrade signal in 17604 // ServerHello.random. 17605 shouldFail: true, 17606 expectedLocalError: "tls: downgrade from TLS 1.3 detected", 17607 }) 17608 } 17609 17610 // Test the client can negotiate ECH, with and without HelloRetryRequest. 17611 testCases = append(testCases, testCase{ 17612 testType: clientTest, 17613 protocol: protocol, 17614 name: prefix + "ECH-Client", 17615 config: Config{ 17616 MinVersion: VersionTLS13, 17617 MaxVersion: VersionTLS13, 17618 ServerECHConfigs: []ServerECHConfig{echConfig}, 17619 Bugs: ProtocolBugs{ 17620 ExpectServerName: "secret.example", 17621 ExpectOuterServerName: "public.example", 17622 }, 17623 }, 17624 flags: []string{ 17625 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17626 "-host-name", "secret.example", 17627 "-expect-ech-accept", 17628 }, 17629 resumeSession: true, 17630 expectations: connectionExpectations{echAccepted: true}, 17631 }) 17632 testCases = append(testCases, testCase{ 17633 testType: clientTest, 17634 protocol: protocol, 17635 name: prefix + "ECH-Client-HelloRetryRequest", 17636 config: Config{ 17637 MinVersion: VersionTLS13, 17638 MaxVersion: VersionTLS13, 17639 CurvePreferences: []CurveID{CurveP384}, 17640 ServerECHConfigs: []ServerECHConfig{echConfig}, 17641 Bugs: ProtocolBugs{ 17642 ExpectServerName: "secret.example", 17643 ExpectOuterServerName: "public.example", 17644 ExpectMissingKeyShare: true, // Check we triggered HRR. 17645 }, 17646 }, 17647 resumeSession: true, 17648 flags: []string{ 17649 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17650 "-host-name", "secret.example", 17651 "-expect-ech-accept", 17652 "-expect-hrr", // Check we triggered HRR. 17653 }, 17654 expectations: connectionExpectations{echAccepted: true}, 17655 }) 17656 17657 // Test the client can negotiate ECH with early data. 17658 testCases = append(testCases, testCase{ 17659 testType: clientTest, 17660 protocol: protocol, 17661 name: prefix + "ECH-Client-EarlyData", 17662 config: Config{ 17663 MinVersion: VersionTLS13, 17664 MaxVersion: VersionTLS13, 17665 ServerECHConfigs: []ServerECHConfig{echConfig}, 17666 Bugs: ProtocolBugs{ 17667 ExpectServerName: "secret.example", 17668 }, 17669 }, 17670 flags: []string{ 17671 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17672 "-host-name", "secret.example", 17673 "-expect-ech-accept", 17674 }, 17675 resumeSession: true, 17676 earlyData: true, 17677 expectations: connectionExpectations{echAccepted: true}, 17678 }) 17679 testCases = append(testCases, testCase{ 17680 testType: clientTest, 17681 protocol: protocol, 17682 name: prefix + "ECH-Client-EarlyDataRejected", 17683 config: Config{ 17684 MinVersion: VersionTLS13, 17685 MaxVersion: VersionTLS13, 17686 ServerECHConfigs: []ServerECHConfig{echConfig}, 17687 Bugs: ProtocolBugs{ 17688 ExpectServerName: "secret.example", 17689 AlwaysRejectEarlyData: true, 17690 }, 17691 }, 17692 flags: []string{ 17693 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17694 "-host-name", "secret.example", 17695 "-expect-ech-accept", 17696 }, 17697 resumeSession: true, 17698 earlyData: true, 17699 expectEarlyDataRejected: true, 17700 expectations: connectionExpectations{echAccepted: true}, 17701 }) 17702 17703 if protocol != quic { 17704 // Test that an ECH client does not offer a TLS 1.2 session. 17705 testCases = append(testCases, testCase{ 17706 testType: clientTest, 17707 protocol: protocol, 17708 name: prefix + "ECH-Client-TLS12SessionID", 17709 config: Config{ 17710 MaxVersion: VersionTLS12, 17711 SessionTicketsDisabled: true, 17712 }, 17713 resumeConfig: &Config{ 17714 ServerECHConfigs: []ServerECHConfig{echConfig}, 17715 Bugs: ProtocolBugs{ 17716 ExpectNoTLS12Session: true, 17717 }, 17718 }, 17719 flags: []string{ 17720 "-on-resume-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17721 "-on-resume-expect-ech-accept", 17722 }, 17723 resumeSession: true, 17724 expectResumeRejected: true, 17725 resumeExpectations: &connectionExpectations{echAccepted: true}, 17726 }) 17727 testCases = append(testCases, testCase{ 17728 testType: clientTest, 17729 protocol: protocol, 17730 name: prefix + "ECH-Client-TLS12SessionTicket", 17731 config: Config{ 17732 MaxVersion: VersionTLS12, 17733 }, 17734 resumeConfig: &Config{ 17735 ServerECHConfigs: []ServerECHConfig{echConfig}, 17736 Bugs: ProtocolBugs{ 17737 ExpectNoTLS12Session: true, 17738 }, 17739 }, 17740 flags: []string{ 17741 "-on-resume-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17742 "-on-resume-expect-ech-accept", 17743 }, 17744 resumeSession: true, 17745 expectResumeRejected: true, 17746 resumeExpectations: &connectionExpectations{echAccepted: true}, 17747 }) 17748 } 17749 17750 // ClientHelloInner should not include NPN, which is a TLS 1.2-only 17751 // extensions. The Go server will enforce this, so this test only needs 17752 // to configure the feature on the shim. Other application extensions 17753 // are sent implicitly. 17754 testCases = append(testCases, testCase{ 17755 testType: clientTest, 17756 protocol: protocol, 17757 name: prefix + "ECH-Client-NoNPN", 17758 config: Config{ 17759 ServerECHConfigs: []ServerECHConfig{echConfig}, 17760 }, 17761 flags: []string{ 17762 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17763 "-expect-ech-accept", 17764 // Enable NPN. 17765 "-select-next-proto", "foo", 17766 }, 17767 expectations: connectionExpectations{echAccepted: true}, 17768 }) 17769 17770 // Test that the client iterates over configurations in the 17771 // ECHConfigList and selects the first with supported parameters. 17772 p256Key := ecdsaP256Certificate.PrivateKey.(*ecdsa.PrivateKey) 17773 unsupportedKEM := generateServerECHConfig(&ECHConfig{ 17774 KEM: hpke.P256WithHKDFSHA256, 17775 PublicKey: elliptic.Marshal(elliptic.P256(), p256Key.X, p256Key.Y), 17776 }).ECHConfig 17777 unsupportedCipherSuites := generateServerECHConfig(&ECHConfig{ 17778 CipherSuites: []HPKECipherSuite{{0x1111, 0x2222}}, 17779 }).ECHConfig 17780 unsupportedMandatoryExtension := generateServerECHConfig(&ECHConfig{ 17781 UnsupportedMandatoryExtension: true, 17782 }).ECHConfig 17783 testCases = append(testCases, testCase{ 17784 testType: clientTest, 17785 protocol: protocol, 17786 name: prefix + "ECH-Client-SelectECHConfig", 17787 config: Config{ 17788 ServerECHConfigs: []ServerECHConfig{echConfig}, 17789 }, 17790 flags: []string{ 17791 "-ech-config-list", base64FlagValue(CreateECHConfigList( 17792 unsupportedVersion, 17793 unsupportedKEM.Raw, 17794 unsupportedCipherSuites.Raw, 17795 unsupportedMandatoryExtension.Raw, 17796 echConfig.ECHConfig.Raw, 17797 // |echConfig1| is also supported, but the client should 17798 // select the first one. 17799 echConfig1.ECHConfig.Raw, 17800 )), 17801 "-expect-ech-accept", 17802 }, 17803 expectations: connectionExpectations{ 17804 echAccepted: true, 17805 }, 17806 }) 17807 17808 // Test that the client skips sending ECH if all ECHConfigs are 17809 // unsupported. 17810 testCases = append(testCases, testCase{ 17811 testType: clientTest, 17812 protocol: protocol, 17813 name: prefix + "ECH-Client-NoSupportedConfigs", 17814 config: Config{ 17815 Bugs: ProtocolBugs{ 17816 ExpectNoClientECH: true, 17817 }, 17818 }, 17819 flags: []string{ 17820 "-ech-config-list", base64FlagValue(CreateECHConfigList( 17821 unsupportedVersion, 17822 unsupportedKEM.Raw, 17823 unsupportedCipherSuites.Raw, 17824 unsupportedMandatoryExtension.Raw, 17825 )), 17826 }, 17827 }) 17828 17829 // If ECH GREASE is enabled, the client should send ECH GREASE when no 17830 // configured ECHConfig is suitable. 17831 testCases = append(testCases, testCase{ 17832 testType: clientTest, 17833 protocol: protocol, 17834 name: prefix + "ECH-Client-NoSupportedConfigs-GREASE", 17835 config: Config{ 17836 Bugs: ProtocolBugs{ 17837 ExpectClientECH: true, 17838 }, 17839 }, 17840 flags: []string{ 17841 "-ech-config-list", base64FlagValue(CreateECHConfigList( 17842 unsupportedVersion, 17843 unsupportedKEM.Raw, 17844 unsupportedCipherSuites.Raw, 17845 unsupportedMandatoryExtension.Raw, 17846 )), 17847 "-enable-ech-grease", 17848 }, 17849 }) 17850 17851 // If both ECH GREASE and suitable ECHConfigs are available, the 17852 // client should send normal ECH. 17853 testCases = append(testCases, testCase{ 17854 testType: clientTest, 17855 protocol: protocol, 17856 name: prefix + "ECH-Client-GREASE", 17857 config: Config{ 17858 ServerECHConfigs: []ServerECHConfig{echConfig}, 17859 }, 17860 flags: []string{ 17861 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17862 "-expect-ech-accept", 17863 }, 17864 resumeSession: true, 17865 expectations: connectionExpectations{echAccepted: true}, 17866 }) 17867 17868 // Test that GREASE extensions correctly interact with ECH. Both the 17869 // inner and outer ClientHellos should include GREASE extensions. 17870 testCases = append(testCases, testCase{ 17871 testType: clientTest, 17872 protocol: protocol, 17873 name: prefix + "ECH-Client-GREASEExtensions", 17874 config: Config{ 17875 ServerECHConfigs: []ServerECHConfig{echConfig}, 17876 Bugs: ProtocolBugs{ 17877 ExpectGREASE: true, 17878 }, 17879 }, 17880 flags: []string{ 17881 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17882 "-expect-ech-accept", 17883 "-enable-grease", 17884 }, 17885 resumeSession: true, 17886 expectations: connectionExpectations{echAccepted: true}, 17887 }) 17888 17889 // Test that the client tolerates unsupported extensions if the 17890 // mandatory bit is not set. 17891 unsupportedExtension := generateServerECHConfig(&ECHConfig{UnsupportedExtension: true}) 17892 testCases = append(testCases, testCase{ 17893 testType: clientTest, 17894 protocol: protocol, 17895 name: prefix + "ECH-Client-UnsupportedExtension", 17896 config: Config{ 17897 ServerECHConfigs: []ServerECHConfig{unsupportedExtension}, 17898 }, 17899 flags: []string{ 17900 "-ech-config-list", base64FlagValue(CreateECHConfigList(unsupportedExtension.ECHConfig.Raw)), 17901 "-expect-ech-accept", 17902 }, 17903 expectations: connectionExpectations{echAccepted: true}, 17904 }) 17905 17906 // Syntax errors in the ECHConfigList should be rejected. 17907 testCases = append(testCases, testCase{ 17908 testType: clientTest, 17909 protocol: protocol, 17910 name: prefix + "ECH-Client-InvalidECHConfigList", 17911 flags: []string{ 17912 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw[1:])), 17913 }, 17914 shouldFail: true, 17915 expectedError: ":INVALID_ECH_CONFIG_LIST:", 17916 }) 17917 17918 // If the ClientHelloInner has no server_name extension, while the 17919 // ClientHelloOuter has one, the client must check for unsolicited 17920 // extensions based on the selected ClientHello. 17921 testCases = append(testCases, testCase{ 17922 testType: clientTest, 17923 protocol: protocol, 17924 name: prefix + "ECH-Client-UnsolicitedInnerServerNameAck", 17925 config: Config{ 17926 ServerECHConfigs: []ServerECHConfig{echConfig}, 17927 Bugs: ProtocolBugs{ 17928 // ClientHelloOuter should have a server name. 17929 ExpectOuterServerName: "public.example", 17930 // The server will acknowledge the server_name extension. 17931 // This option runs whether or not the client requested the 17932 // extension. 17933 SendServerNameAck: true, 17934 }, 17935 }, 17936 flags: []string{ 17937 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17938 // No -host-name flag. 17939 "-expect-ech-accept", 17940 }, 17941 shouldFail: true, 17942 expectedError: ":UNEXPECTED_EXTENSION:", 17943 expectedLocalError: "remote error: unsupported extension", 17944 expectations: connectionExpectations{echAccepted: true}, 17945 }) 17946 17947 // Most extensions are the same between ClientHelloInner and 17948 // ClientHelloOuter and can be compressed. 17949 testCases = append(testCases, testCase{ 17950 testType: clientTest, 17951 protocol: protocol, 17952 name: prefix + "ECH-Client-ExpectECHOuterExtensions", 17953 config: Config{ 17954 ServerECHConfigs: []ServerECHConfig{echConfig}, 17955 NextProtos: []string{"proto"}, 17956 Bugs: ProtocolBugs{ 17957 ExpectECHOuterExtensions: []uint16{ 17958 extensionALPN, 17959 extensionKeyShare, 17960 extensionPSKKeyExchangeModes, 17961 extensionSignatureAlgorithms, 17962 extensionSupportedCurves, 17963 }, 17964 }, 17965 }, 17966 flags: []string{ 17967 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17968 "-expect-ech-accept", 17969 "-advertise-alpn", "\x05proto", 17970 "-expect-alpn", "proto", 17971 "-host-name", "secret.example", 17972 }, 17973 expectations: connectionExpectations{ 17974 echAccepted: true, 17975 nextProto: "proto", 17976 }, 17977 skipQUICALPNConfig: true, 17978 }) 17979 17980 // If the server name happens to match the public name, it still should 17981 // not be compressed. It is not publicly known that they match. 17982 testCases = append(testCases, testCase{ 17983 testType: clientTest, 17984 protocol: protocol, 17985 name: prefix + "ECH-Client-NeverCompressServerName", 17986 config: Config{ 17987 ServerECHConfigs: []ServerECHConfig{echConfig}, 17988 NextProtos: []string{"proto"}, 17989 Bugs: ProtocolBugs{ 17990 ExpectECHUncompressedExtensions: []uint16{extensionServerName}, 17991 ExpectServerName: "public.example", 17992 ExpectOuterServerName: "public.example", 17993 }, 17994 }, 17995 flags: []string{ 17996 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17997 "-expect-ech-accept", 17998 "-host-name", "public.example", 17999 }, 18000 expectations: connectionExpectations{echAccepted: true}, 18001 }) 18002 18003 // If the ClientHelloOuter disables TLS 1.3, e.g. in QUIC, the client 18004 // should also compress supported_versions. 18005 testCases = append(testCases, testCase{ 18006 testType: clientTest, 18007 protocol: protocol, 18008 name: prefix + "ECH-Client-CompressSupportedVersions", 18009 config: Config{ 18010 ServerECHConfigs: []ServerECHConfig{echConfig}, 18011 Bugs: ProtocolBugs{ 18012 ExpectECHOuterExtensions: []uint16{ 18013 extensionSupportedVersions, 18014 }, 18015 }, 18016 }, 18017 flags: []string{ 18018 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18019 "-host-name", "secret.example", 18020 "-expect-ech-accept", 18021 "-min-version", strconv.Itoa(int(VersionTLS13)), 18022 }, 18023 expectations: connectionExpectations{echAccepted: true}, 18024 }) 18025 18026 // Test that the client can still offer server names that exceed the 18027 // maximum name length. It is only a padding hint. 18028 maxNameLen10 := generateServerECHConfig(&ECHConfig{MaxNameLen: 10}) 18029 testCases = append(testCases, testCase{ 18030 testType: clientTest, 18031 protocol: protocol, 18032 name: prefix + "ECH-Client-NameTooLong", 18033 config: Config{ 18034 ServerECHConfigs: []ServerECHConfig{maxNameLen10}, 18035 Bugs: ProtocolBugs{ 18036 ExpectServerName: "test0123456789.example", 18037 }, 18038 }, 18039 flags: []string{ 18040 "-ech-config-list", base64FlagValue(CreateECHConfigList(maxNameLen10.ECHConfig.Raw)), 18041 "-host-name", "test0123456789.example", 18042 "-expect-ech-accept", 18043 }, 18044 expectations: connectionExpectations{echAccepted: true}, 18045 }) 18046 18047 // Test the client can recognize when ECH is rejected. 18048 testCases = append(testCases, testCase{ 18049 testType: clientTest, 18050 protocol: protocol, 18051 name: prefix + "ECH-Client-Reject", 18052 config: Config{ 18053 ServerECHConfigs: []ServerECHConfig{echConfig2, echConfig3}, 18054 Bugs: ProtocolBugs{ 18055 ExpectServerName: "public.example", 18056 }, 18057 }, 18058 flags: []string{ 18059 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18060 "-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw)), 18061 }, 18062 shouldFail: true, 18063 expectedLocalError: "remote error: ECH required", 18064 expectedError: ":ECH_REJECTED:", 18065 }) 18066 testCases = append(testCases, testCase{ 18067 testType: clientTest, 18068 protocol: protocol, 18069 name: prefix + "ECH-Client-Reject-HelloRetryRequest", 18070 config: Config{ 18071 ServerECHConfigs: []ServerECHConfig{echConfig2, echConfig3}, 18072 CurvePreferences: []CurveID{CurveP384}, 18073 Bugs: ProtocolBugs{ 18074 ExpectServerName: "public.example", 18075 ExpectMissingKeyShare: true, // Check we triggered HRR. 18076 }, 18077 }, 18078 flags: []string{ 18079 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18080 "-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw)), 18081 "-expect-hrr", // Check we triggered HRR. 18082 }, 18083 shouldFail: true, 18084 expectedLocalError: "remote error: ECH required", 18085 expectedError: ":ECH_REJECTED:", 18086 }) 18087 testCases = append(testCases, testCase{ 18088 testType: clientTest, 18089 protocol: protocol, 18090 name: prefix + "ECH-Client-Reject-NoRetryConfigs", 18091 config: Config{ 18092 Bugs: ProtocolBugs{ 18093 ExpectServerName: "public.example", 18094 }, 18095 }, 18096 flags: []string{ 18097 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18098 "-expect-no-ech-retry-configs", 18099 }, 18100 shouldFail: true, 18101 expectedLocalError: "remote error: ECH required", 18102 expectedError: ":ECH_REJECTED:", 18103 }) 18104 if protocol != quic { 18105 testCases = append(testCases, testCase{ 18106 testType: clientTest, 18107 protocol: protocol, 18108 name: prefix + "ECH-Client-Reject-TLS12", 18109 config: Config{ 18110 MaxVersion: VersionTLS12, 18111 Bugs: ProtocolBugs{ 18112 ExpectServerName: "public.example", 18113 }, 18114 }, 18115 flags: []string{ 18116 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18117 // TLS 1.2 cannot provide retry configs. 18118 "-expect-no-ech-retry-configs", 18119 }, 18120 shouldFail: true, 18121 expectedLocalError: "remote error: ECH required", 18122 expectedError: ":ECH_REJECTED:", 18123 }) 18124 18125 // Test that the client disables False Start when ECH is rejected. 18126 testCases = append(testCases, testCase{ 18127 name: prefix + "ECH-Client-Reject-TLS12-NoFalseStart", 18128 config: Config{ 18129 MaxVersion: VersionTLS12, 18130 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 18131 NextProtos: []string{"foo"}, 18132 Bugs: ProtocolBugs{ 18133 // The options below cause the server to, immediately 18134 // after client Finished, send an alert and try to read 18135 // application data without sending server Finished. 18136 ExpectFalseStart: true, 18137 AlertBeforeFalseStartTest: alertAccessDenied, 18138 }, 18139 }, 18140 flags: []string{ 18141 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18142 "-false-start", 18143 "-advertise-alpn", "\x03foo", 18144 "-expect-alpn", "foo", 18145 }, 18146 shimWritesFirst: true, 18147 shouldFail: true, 18148 // Ensure the client does not send application data at the False 18149 // Start point. EOF comes from the client closing the connection 18150 // in response ot the alert. 18151 expectedLocalError: "tls: peer did not false start: EOF", 18152 // Ensures the client picks up the alert before reporting an 18153 // authenticated |SSL_R_ECH_REJECTED|. 18154 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 18155 }) 18156 } 18157 18158 // Test that unsupported retry configs in a valid ECHConfigList are 18159 // allowed. They will be skipped when configured in the retry. 18160 retryConfigs := CreateECHConfigList( 18161 unsupportedVersion, 18162 unsupportedKEM.Raw, 18163 unsupportedCipherSuites.Raw, 18164 unsupportedMandatoryExtension.Raw, 18165 echConfig2.ECHConfig.Raw) 18166 testCases = append(testCases, testCase{ 18167 testType: clientTest, 18168 protocol: protocol, 18169 name: prefix + "ECH-Client-Reject-UnsupportedRetryConfigs", 18170 config: Config{ 18171 Bugs: ProtocolBugs{ 18172 SendECHRetryConfigs: retryConfigs, 18173 ExpectServerName: "public.example", 18174 }, 18175 }, 18176 flags: []string{ 18177 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18178 "-expect-ech-retry-configs", base64FlagValue(retryConfigs), 18179 }, 18180 shouldFail: true, 18181 expectedLocalError: "remote error: ECH required", 18182 expectedError: ":ECH_REJECTED:", 18183 }) 18184 18185 // Test that the client rejects ClientHelloOuter handshakes that attempt 18186 // to resume the ClientHelloInner's ticket, at TLS 1.2 and TLS 1.3. 18187 testCases = append(testCases, testCase{ 18188 testType: clientTest, 18189 protocol: protocol, 18190 name: prefix + "ECH-Client-Reject-ResumeInnerSession-TLS13", 18191 config: Config{ 18192 ServerECHConfigs: []ServerECHConfig{echConfig}, 18193 Bugs: ProtocolBugs{ 18194 ExpectServerName: "secret.example", 18195 }, 18196 }, 18197 resumeConfig: &Config{ 18198 MaxVersion: VersionTLS13, 18199 ServerECHConfigs: []ServerECHConfig{echConfig}, 18200 Bugs: ProtocolBugs{ 18201 ExpectServerName: "public.example", 18202 UseInnerSessionWithClientHelloOuter: true, 18203 }, 18204 }, 18205 resumeSession: true, 18206 flags: []string{ 18207 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18208 "-host-name", "secret.example", 18209 "-on-initial-expect-ech-accept", 18210 }, 18211 shouldFail: true, 18212 expectedError: ":UNEXPECTED_EXTENSION:", 18213 expectations: connectionExpectations{echAccepted: true}, 18214 resumeExpectations: &connectionExpectations{echAccepted: false}, 18215 }) 18216 if protocol != quic { 18217 testCases = append(testCases, testCase{ 18218 testType: clientTest, 18219 protocol: protocol, 18220 name: prefix + "ECH-Client-Reject-ResumeInnerSession-TLS12", 18221 config: Config{ 18222 ServerECHConfigs: []ServerECHConfig{echConfig}, 18223 Bugs: ProtocolBugs{ 18224 ExpectServerName: "secret.example", 18225 }, 18226 }, 18227 resumeConfig: &Config{ 18228 MinVersion: VersionTLS12, 18229 MaxVersion: VersionTLS12, 18230 ServerECHConfigs: []ServerECHConfig{echConfig}, 18231 Bugs: ProtocolBugs{ 18232 ExpectServerName: "public.example", 18233 UseInnerSessionWithClientHelloOuter: true, 18234 // The client only ever offers TLS 1.3 sessions in 18235 // ClientHelloInner. AcceptAnySession allows them to be 18236 // resumed at TLS 1.2. 18237 AcceptAnySession: true, 18238 }, 18239 }, 18240 resumeSession: true, 18241 flags: []string{ 18242 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18243 "-host-name", "secret.example", 18244 "-on-initial-expect-ech-accept", 18245 }, 18246 // From the client's perspective, the server echoed a session ID to 18247 // signal resumption, but the selected ClientHello had nothing to 18248 // resume. 18249 shouldFail: true, 18250 expectedError: ":SERVER_ECHOED_INVALID_SESSION_ID:", 18251 expectedLocalError: "remote error: illegal parameter", 18252 expectations: connectionExpectations{echAccepted: true}, 18253 resumeExpectations: &connectionExpectations{echAccepted: false}, 18254 }) 18255 } 18256 18257 // Test that the client can process ECH rejects after an early data reject. 18258 testCases = append(testCases, testCase{ 18259 testType: clientTest, 18260 protocol: protocol, 18261 name: prefix + "ECH-Client-Reject-EarlyDataRejected", 18262 config: Config{ 18263 ServerECHConfigs: []ServerECHConfig{echConfig}, 18264 Bugs: ProtocolBugs{ 18265 ExpectServerName: "secret.example", 18266 }, 18267 }, 18268 resumeConfig: &Config{ 18269 ServerECHConfigs: []ServerECHConfig{echConfig2}, 18270 Bugs: ProtocolBugs{ 18271 ExpectServerName: "public.example", 18272 }, 18273 }, 18274 flags: []string{ 18275 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18276 "-host-name", "secret.example", 18277 // Although the resumption connection does not accept ECH, the 18278 // API will report ECH was accepted at the 0-RTT point. 18279 "-expect-ech-accept", 18280 // -on-retry refers to the retried handshake after 0-RTT reject, 18281 // while ech-retry-configs refers to the ECHConfigs to use in 18282 // the next connection attempt. 18283 "-on-retry-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw)), 18284 }, 18285 resumeSession: true, 18286 expectResumeRejected: true, 18287 earlyData: true, 18288 expectEarlyDataRejected: true, 18289 expectations: connectionExpectations{echAccepted: true}, 18290 resumeExpectations: &connectionExpectations{echAccepted: false}, 18291 shouldFail: true, 18292 expectedLocalError: "remote error: ECH required", 18293 expectedError: ":ECH_REJECTED:", 18294 }) 18295 if protocol != quic { 18296 testCases = append(testCases, testCase{ 18297 testType: clientTest, 18298 protocol: protocol, 18299 name: prefix + "ECH-Client-Reject-EarlyDataRejected-TLS12", 18300 config: Config{ 18301 ServerECHConfigs: []ServerECHConfig{echConfig}, 18302 Bugs: ProtocolBugs{ 18303 ExpectServerName: "secret.example", 18304 }, 18305 }, 18306 resumeConfig: &Config{ 18307 MaxVersion: VersionTLS12, 18308 Bugs: ProtocolBugs{ 18309 ExpectServerName: "public.example", 18310 }, 18311 }, 18312 flags: []string{ 18313 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18314 "-host-name", "secret.example", 18315 // Although the resumption connection does not accept ECH, the 18316 // API will report ECH was accepted at the 0-RTT point. 18317 "-expect-ech-accept", 18318 }, 18319 resumeSession: true, 18320 expectResumeRejected: true, 18321 earlyData: true, 18322 expectEarlyDataRejected: true, 18323 expectations: connectionExpectations{echAccepted: true}, 18324 resumeExpectations: &connectionExpectations{echAccepted: false}, 18325 // ClientHellos with early data cannot negotiate TLS 1.2, with 18326 // or without ECH. The shim should first report 18327 // |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. The caller will then 18328 // repair the first error by retrying without early data. That 18329 // will look like ECH-Client-Reject-TLS12 and select TLS 1.2 18330 // and ClientHelloOuter. The caller will then trigger a third 18331 // attempt, which will succeed. 18332 shouldFail: true, 18333 expectedError: ":WRONG_VERSION_ON_EARLY_DATA:", 18334 }) 18335 } 18336 18337 // Test that the client ignores ECHConfigs with invalid public names. 18338 invalidPublicName := generateServerECHConfig(&ECHConfig{PublicName: "dns_names_have_no_underscores.example"}) 18339 testCases = append(testCases, testCase{ 18340 testType: clientTest, 18341 protocol: protocol, 18342 name: prefix + "ECH-Client-SkipInvalidPublicName", 18343 config: Config{ 18344 Bugs: ProtocolBugs{ 18345 // No ECHConfigs are supported, so the client should fall 18346 // back to cleartext. 18347 ExpectNoClientECH: true, 18348 ExpectServerName: "secret.example", 18349 }, 18350 }, 18351 flags: []string{ 18352 "-ech-config-list", base64FlagValue(CreateECHConfigList(invalidPublicName.ECHConfig.Raw)), 18353 "-host-name", "secret.example", 18354 }, 18355 }) 18356 testCases = append(testCases, testCase{ 18357 testType: clientTest, 18358 protocol: protocol, 18359 name: prefix + "ECH-Client-SkipInvalidPublicName-2", 18360 config: Config{ 18361 // The client should skip |invalidPublicName| and use |echConfig|. 18362 ServerECHConfigs: []ServerECHConfig{echConfig}, 18363 Bugs: ProtocolBugs{ 18364 ExpectOuterServerName: "public.example", 18365 ExpectServerName: "secret.example", 18366 }, 18367 }, 18368 flags: []string{ 18369 "-ech-config-list", base64FlagValue(CreateECHConfigList(invalidPublicName.ECHConfig.Raw, echConfig.ECHConfig.Raw)), 18370 "-host-name", "secret.example", 18371 "-expect-ech-accept", 18372 }, 18373 expectations: connectionExpectations{echAccepted: true}, 18374 }) 18375 18376 // Test both sync and async mode, to test both with and without the 18377 // client certificate callback. 18378 for _, async := range []bool{false, true} { 18379 var flags []string 18380 var suffix string 18381 if async { 18382 flags = []string{"-async"} 18383 suffix = "-Async" 18384 } 18385 18386 // Test that ECH and client certificates can be used together. 18387 testCases = append(testCases, testCase{ 18388 testType: clientTest, 18389 protocol: protocol, 18390 name: prefix + "ECH-Client-ClientCertificate" + suffix, 18391 config: Config{ 18392 ServerECHConfigs: []ServerECHConfig{echConfig}, 18393 ClientAuth: RequireAnyClientCert, 18394 }, 18395 flags: append([]string{ 18396 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 18397 "-key-file", path.Join(*resourceDir, rsaKeyFile), 18398 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18399 "-expect-ech-accept", 18400 }, flags...), 18401 expectations: connectionExpectations{echAccepted: true}, 18402 }) 18403 18404 // Test that, when ECH is rejected, the client does not send a client 18405 // certificate. 18406 testCases = append(testCases, testCase{ 18407 testType: clientTest, 18408 protocol: protocol, 18409 name: prefix + "ECH-Client-Reject-NoClientCertificate-TLS13" + suffix, 18410 config: Config{ 18411 MinVersion: VersionTLS13, 18412 MaxVersion: VersionTLS13, 18413 ClientAuth: RequireAnyClientCert, 18414 }, 18415 flags: append([]string{ 18416 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 18417 "-key-file", path.Join(*resourceDir, rsaKeyFile), 18418 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18419 }, flags...), 18420 shouldFail: true, 18421 expectedLocalError: "tls: client didn't provide a certificate", 18422 }) 18423 if protocol != quic { 18424 testCases = append(testCases, testCase{ 18425 testType: clientTest, 18426 protocol: protocol, 18427 name: prefix + "ECH-Client-Reject-NoClientCertificate-TLS12" + suffix, 18428 config: Config{ 18429 MinVersion: VersionTLS12, 18430 MaxVersion: VersionTLS12, 18431 ClientAuth: RequireAnyClientCert, 18432 }, 18433 flags: append([]string{ 18434 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 18435 "-key-file", path.Join(*resourceDir, rsaKeyFile), 18436 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18437 }, flags...), 18438 shouldFail: true, 18439 expectedLocalError: "tls: client didn't provide a certificate", 18440 }) 18441 } 18442 } 18443 18444 // Test that ECH and Channel ID can be used together. 18445 testCases = append(testCases, testCase{ 18446 testType: clientTest, 18447 protocol: protocol, 18448 name: prefix + "ECH-Client-ChannelID", 18449 config: Config{ 18450 ServerECHConfigs: []ServerECHConfig{echConfig}, 18451 RequestChannelID: true, 18452 }, 18453 flags: []string{ 18454 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 18455 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18456 "-expect-ech-accept", 18457 }, 18458 resumeSession: true, 18459 expectations: connectionExpectations{ 18460 channelID: true, 18461 echAccepted: true, 18462 }, 18463 }) 18464 18465 // Handshakes where ECH is rejected do not offer or accept Channel ID. 18466 testCases = append(testCases, testCase{ 18467 testType: clientTest, 18468 protocol: protocol, 18469 name: prefix + "ECH-Client-Reject-NoChannelID-TLS13", 18470 config: Config{ 18471 MinVersion: VersionTLS13, 18472 MaxVersion: VersionTLS13, 18473 Bugs: ProtocolBugs{ 18474 AlwaysNegotiateChannelID: true, 18475 }, 18476 }, 18477 flags: []string{ 18478 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 18479 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18480 }, 18481 shouldFail: true, 18482 expectedLocalError: "remote error: unsupported extension", 18483 expectedError: ":UNEXPECTED_EXTENSION:", 18484 }) 18485 if protocol != quic { 18486 testCases = append(testCases, testCase{ 18487 testType: clientTest, 18488 protocol: protocol, 18489 name: prefix + "ECH-Client-Reject-NoChannelID-TLS12", 18490 config: Config{ 18491 MinVersion: VersionTLS12, 18492 MaxVersion: VersionTLS12, 18493 Bugs: ProtocolBugs{ 18494 AlwaysNegotiateChannelID: true, 18495 }, 18496 }, 18497 flags: []string{ 18498 "-send-channel-id", path.Join(*resourceDir, channelIDKeyFile), 18499 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18500 }, 18501 shouldFail: true, 18502 expectedLocalError: "remote error: unsupported extension", 18503 expectedError: ":UNEXPECTED_EXTENSION:", 18504 }) 18505 } 18506 18507 // Test that ECH correctly overrides the host name for certificate 18508 // verification. 18509 testCases = append(testCases, testCase{ 18510 testType: clientTest, 18511 protocol: protocol, 18512 name: prefix + "ECH-Client-NotOffered-NoOverrideName", 18513 flags: []string{ 18514 "-verify-peer", 18515 "-use-custom-verify-callback", 18516 // When not offering ECH, verify the usual name in both full 18517 // and resumption handshakes. 18518 "-reverify-on-resume", 18519 "-expect-no-ech-name-override", 18520 }, 18521 resumeSession: true, 18522 }) 18523 testCases = append(testCases, testCase{ 18524 testType: clientTest, 18525 protocol: protocol, 18526 name: prefix + "ECH-Client-GREASE-NoOverrideName", 18527 flags: []string{ 18528 "-verify-peer", 18529 "-use-custom-verify-callback", 18530 "-enable-ech-grease", 18531 // When offering ECH GREASE, verify the usual name in both full 18532 // and resumption handshakes. 18533 "-reverify-on-resume", 18534 "-expect-no-ech-name-override", 18535 }, 18536 resumeSession: true, 18537 }) 18538 if protocol != quic { 18539 testCases = append(testCases, testCase{ 18540 testType: clientTest, 18541 protocol: protocol, 18542 name: prefix + "ECH-Client-Rejected-OverrideName-TLS12", 18543 config: Config{ 18544 MinVersion: VersionTLS12, 18545 MaxVersion: VersionTLS12, 18546 }, 18547 flags: []string{ 18548 "-verify-peer", 18549 "-use-custom-verify-callback", 18550 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18551 // When ECH is rejected, verify the public name. This can 18552 // only happen in full handshakes. 18553 "-expect-ech-name-override", "public.example", 18554 }, 18555 shouldFail: true, 18556 expectedError: ":ECH_REJECTED:", 18557 expectedLocalError: "remote error: ECH required", 18558 }) 18559 } 18560 testCases = append(testCases, testCase{ 18561 testType: clientTest, 18562 protocol: protocol, 18563 name: prefix + "ECH-Client-Reject-OverrideName-TLS13", 18564 config: Config{ 18565 MinVersion: VersionTLS13, 18566 MaxVersion: VersionTLS13, 18567 }, 18568 flags: []string{ 18569 "-verify-peer", 18570 "-use-custom-verify-callback", 18571 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18572 // When ECH is rejected, verify the public name. This can 18573 // only happen in full handshakes. 18574 "-expect-ech-name-override", "public.example", 18575 }, 18576 shouldFail: true, 18577 expectedError: ":ECH_REJECTED:", 18578 expectedLocalError: "remote error: ECH required", 18579 }) 18580 testCases = append(testCases, testCase{ 18581 testType: clientTest, 18582 protocol: protocol, 18583 name: prefix + "ECH-Client-Accept-NoOverrideName", 18584 config: Config{ 18585 ServerECHConfigs: []ServerECHConfig{echConfig}, 18586 }, 18587 flags: []string{ 18588 "-verify-peer", 18589 "-use-custom-verify-callback", 18590 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18591 "-expect-ech-accept", 18592 // When ECH is accepted, verify the usual name in both full and 18593 // resumption handshakes. 18594 "-reverify-on-resume", 18595 "-expect-no-ech-name-override", 18596 }, 18597 resumeSession: true, 18598 expectations: connectionExpectations{echAccepted: true}, 18599 }) 18600 testCases = append(testCases, testCase{ 18601 testType: clientTest, 18602 protocol: protocol, 18603 name: prefix + "ECH-Client-Reject-EarlyDataRejected-OverrideNameOnRetry", 18604 config: Config{ 18605 ServerECHConfigs: []ServerECHConfig{echConfig}, 18606 }, 18607 resumeConfig: &Config{}, 18608 flags: []string{ 18609 "-verify-peer", 18610 "-use-custom-verify-callback", 18611 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18612 // Although the resumption connection does not accept ECH, the 18613 // API will report ECH was accepted at the 0-RTT point. 18614 "-expect-ech-accept", 18615 // The resumption connection verifies certificates twice. First, 18616 // if reverification is enabled, we verify the 0-RTT certificate 18617 // as if ECH as accepted. There should be no name override. 18618 // Next, on the post-0-RTT-rejection retry, we verify the new 18619 // server certificate. This picks up the ECH reject, so it 18620 // should use public.example. 18621 "-reverify-on-resume", 18622 "-on-resume-expect-no-ech-name-override", 18623 "-on-retry-expect-ech-name-override", "public.example", 18624 }, 18625 resumeSession: true, 18626 expectResumeRejected: true, 18627 earlyData: true, 18628 expectEarlyDataRejected: true, 18629 expectations: connectionExpectations{echAccepted: true}, 18630 resumeExpectations: &connectionExpectations{echAccepted: false}, 18631 shouldFail: true, 18632 expectedError: ":ECH_REJECTED:", 18633 expectedLocalError: "remote error: ECH required", 18634 }) 18635 18636 // Test that the client checks both HelloRetryRequest and ServerHello 18637 // for a confirmation signal. 18638 testCases = append(testCases, testCase{ 18639 testType: clientTest, 18640 protocol: protocol, 18641 name: prefix + "ECH-Client-HelloRetryRequest-MissingServerHelloConfirmation", 18642 config: Config{ 18643 MinVersion: VersionTLS13, 18644 MaxVersion: VersionTLS13, 18645 CurvePreferences: []CurveID{CurveP384}, 18646 ServerECHConfigs: []ServerECHConfig{echConfig}, 18647 Bugs: ProtocolBugs{ 18648 ExpectMissingKeyShare: true, // Check we triggered HRR. 18649 OmitServerHelloECHConfirmation: true, 18650 }, 18651 }, 18652 resumeSession: true, 18653 flags: []string{ 18654 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18655 "-expect-hrr", // Check we triggered HRR. 18656 }, 18657 shouldFail: true, 18658 expectedError: ":INCONSISTENT_ECH_NEGOTIATION:", 18659 }) 18660 18661 // Test the message callback is correctly reported, with and without 18662 // HelloRetryRequest. 18663 clientAndServerHello := "write clienthelloinner\nwrite hs 1\nread hs 2\n" 18664 // EncryptedExtensions onwards. 18665 finishHandshake := `read hs 8 18666read hs 11 18667read hs 15 18668read hs 20 18669write hs 20 18670read hs 4 18671read hs 4 18672` 18673 testCases = append(testCases, testCase{ 18674 testType: clientTest, 18675 protocol: protocol, 18676 name: prefix + "ECH-Client-MessageCallback", 18677 config: Config{ 18678 MinVersion: VersionTLS13, 18679 MaxVersion: VersionTLS13, 18680 ServerECHConfigs: []ServerECHConfig{echConfig}, 18681 Bugs: ProtocolBugs{ 18682 NoCloseNotify: true, // Align QUIC and TCP traces. 18683 }, 18684 }, 18685 flags: []string{ 18686 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18687 "-expect-ech-accept", 18688 "-expect-msg-callback", clientAndServerHello + "write ccs\n" + finishHandshake, 18689 }, 18690 expectations: connectionExpectations{echAccepted: true}, 18691 }) 18692 testCases = append(testCases, testCase{ 18693 testType: clientTest, 18694 protocol: protocol, 18695 name: prefix + "ECH-Client-MessageCallback-HelloRetryRequest", 18696 config: Config{ 18697 MinVersion: VersionTLS13, 18698 MaxVersion: VersionTLS13, 18699 CurvePreferences: []CurveID{CurveP384}, 18700 ServerECHConfigs: []ServerECHConfig{echConfig}, 18701 Bugs: ProtocolBugs{ 18702 ExpectMissingKeyShare: true, // Check we triggered HRR. 18703 NoCloseNotify: true, // Align QUIC and TCP traces. 18704 }, 18705 }, 18706 flags: []string{ 18707 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18708 "-expect-ech-accept", 18709 "-expect-hrr", // Check we triggered HRR. 18710 "-expect-msg-callback", clientAndServerHello + "write ccs\n" + clientAndServerHello + finishHandshake, 18711 }, 18712 expectations: connectionExpectations{echAccepted: true}, 18713 }) 18714 } 18715} 18716 18717func addHintMismatchTests() { 18718 // Each of these tests skips split handshakes because split handshakes does 18719 // not handle a mismatch between shim and handshaker. Handshake hints, 18720 // however, are designed to tolerate the mismatch. 18721 // 18722 // Note also these tests do not specify -handshake-hints directly. Instead, 18723 // we define normal tests, that run even without a handshaker, and rely on 18724 // convertToSplitHandshakeTests to generate a handshaker hints variant. This 18725 // avoids repeating the -is-handshaker-supported and -handshaker-path logic. 18726 // (While not useful, the tests will still pass without a handshaker.) 18727 for _, protocol := range []protocol{tls, quic} { 18728 // If the signing payload is different, the handshake still completes 18729 // successfully. Different ALPN preferences will trigger a mismatch. 18730 testCases = append(testCases, testCase{ 18731 name: protocol.String() + "-HintMismatch-SignatureInput", 18732 testType: serverTest, 18733 protocol: protocol, 18734 skipSplitHandshake: true, 18735 config: Config{ 18736 MinVersion: VersionTLS13, 18737 MaxVersion: VersionTLS13, 18738 NextProtos: []string{"foo", "bar"}, 18739 }, 18740 flags: []string{ 18741 "-allow-hint-mismatch", 18742 "-on-shim-select-alpn", "foo", 18743 "-on-handshaker-select-alpn", "bar", 18744 }, 18745 expectations: connectionExpectations{ 18746 nextProto: "foo", 18747 nextProtoType: alpn, 18748 }, 18749 }) 18750 18751 // The shim and handshaker may have different curve preferences. 18752 testCases = append(testCases, testCase{ 18753 name: protocol.String() + "-HintMismatch-KeyShare", 18754 testType: serverTest, 18755 protocol: protocol, 18756 skipSplitHandshake: true, 18757 config: Config{ 18758 MinVersion: VersionTLS13, 18759 MaxVersion: VersionTLS13, 18760 // Send both curves in the key share list, to avoid getting 18761 // mixed up with HelloRetryRequest. 18762 DefaultCurves: []CurveID{CurveX25519, CurveP256}, 18763 }, 18764 flags: []string{ 18765 "-allow-hint-mismatch", 18766 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 18767 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 18768 }, 18769 expectations: connectionExpectations{ 18770 curveID: CurveX25519, 18771 }, 18772 }) 18773 18774 // If the handshaker does HelloRetryRequest, it will omit most hints. 18775 // The shim should still work. 18776 testCases = append(testCases, testCase{ 18777 name: protocol.String() + "-HintMismatch-HandshakerHelloRetryRequest", 18778 testType: serverTest, 18779 protocol: protocol, 18780 skipSplitHandshake: true, 18781 config: Config{ 18782 MinVersion: VersionTLS13, 18783 MaxVersion: VersionTLS13, 18784 DefaultCurves: []CurveID{CurveX25519}, 18785 }, 18786 flags: []string{ 18787 "-allow-hint-mismatch", 18788 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 18789 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 18790 }, 18791 expectations: connectionExpectations{ 18792 curveID: CurveX25519, 18793 }, 18794 }) 18795 18796 // If the shim does HelloRetryRequest, the hints from the handshaker 18797 // will be ignored. This is not reported as a mismatch because hints 18798 // would not have helped the shim anyway. 18799 testCases = append(testCases, testCase{ 18800 name: protocol.String() + "-HintMismatch-ShimHelloRetryRequest", 18801 testType: serverTest, 18802 protocol: protocol, 18803 skipSplitHandshake: true, 18804 config: Config{ 18805 MinVersion: VersionTLS13, 18806 MaxVersion: VersionTLS13, 18807 DefaultCurves: []CurveID{CurveX25519}, 18808 }, 18809 flags: []string{ 18810 "-on-shim-curves", strconv.Itoa(int(CurveP256)), 18811 "-on-handshaker-curves", strconv.Itoa(int(CurveX25519)), 18812 }, 18813 expectations: connectionExpectations{ 18814 curveID: CurveP256, 18815 }, 18816 }) 18817 18818 // The shim and handshaker may have different signature algorithm 18819 // preferences. 18820 testCases = append(testCases, testCase{ 18821 name: protocol.String() + "-HintMismatch-SignatureAlgorithm", 18822 testType: serverTest, 18823 protocol: protocol, 18824 skipSplitHandshake: true, 18825 config: Config{ 18826 MinVersion: VersionTLS13, 18827 MaxVersion: VersionTLS13, 18828 VerifySignatureAlgorithms: []signatureAlgorithm{ 18829 signatureRSAPSSWithSHA256, 18830 signatureRSAPSSWithSHA384, 18831 }, 18832 }, 18833 flags: []string{ 18834 "-allow-hint-mismatch", 18835 "-cert-file", path.Join(*resourceDir, rsaCertificateFile), 18836 "-key-file", path.Join(*resourceDir, rsaKeyFile), 18837 "-on-shim-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 18838 "-on-handshaker-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 18839 }, 18840 expectations: connectionExpectations{ 18841 peerSignatureAlgorithm: signatureRSAPSSWithSHA256, 18842 }, 18843 }) 18844 18845 // The shim and handshaker may disagree on whether resumption is allowed. 18846 // We run the first connection with tickets enabled, so the client is 18847 // issued a ticket, then disable tickets on the second connection. 18848 testCases = append(testCases, testCase{ 18849 name: protocol.String() + "-HintMismatch-NoTickets1", 18850 testType: serverTest, 18851 protocol: protocol, 18852 skipSplitHandshake: true, 18853 config: Config{ 18854 MinVersion: VersionTLS13, 18855 MaxVersion: VersionTLS13, 18856 }, 18857 flags: []string{ 18858 "-on-resume-allow-hint-mismatch", 18859 "-on-shim-on-resume-no-ticket", 18860 }, 18861 resumeSession: true, 18862 expectResumeRejected: true, 18863 }) 18864 testCases = append(testCases, testCase{ 18865 name: protocol.String() + "-HintMismatch-NoTickets2", 18866 testType: serverTest, 18867 protocol: protocol, 18868 skipSplitHandshake: true, 18869 config: Config{ 18870 MinVersion: VersionTLS13, 18871 MaxVersion: VersionTLS13, 18872 }, 18873 flags: []string{ 18874 "-on-resume-allow-hint-mismatch", 18875 "-on-handshaker-on-resume-no-ticket", 18876 }, 18877 resumeSession: true, 18878 }) 18879 18880 // The shim and handshaker may disagree on whether to request a client 18881 // certificate. 18882 testCases = append(testCases, testCase{ 18883 name: protocol.String() + "-HintMismatch-CertificateRequest", 18884 testType: serverTest, 18885 protocol: protocol, 18886 skipSplitHandshake: true, 18887 config: Config{ 18888 MinVersion: VersionTLS13, 18889 MaxVersion: VersionTLS13, 18890 Certificates: []Certificate{rsaCertificate}, 18891 }, 18892 flags: []string{ 18893 "-allow-hint-mismatch", 18894 "-on-shim-require-any-client-certificate", 18895 }, 18896 }) 18897 18898 // The shim and handshaker may negotiate different versions altogether. 18899 if protocol != quic { 18900 testCases = append(testCases, testCase{ 18901 name: protocol.String() + "-HintMismatch-Version1", 18902 testType: serverTest, 18903 protocol: protocol, 18904 skipSplitHandshake: true, 18905 config: Config{ 18906 MinVersion: VersionTLS12, 18907 MaxVersion: VersionTLS13, 18908 }, 18909 flags: []string{ 18910 "-allow-hint-mismatch", 18911 "-on-shim-max-version", strconv.Itoa(VersionTLS12), 18912 "-on-handshaker-max-version", strconv.Itoa(VersionTLS13), 18913 }, 18914 expectations: connectionExpectations{ 18915 version: VersionTLS12, 18916 }, 18917 }) 18918 testCases = append(testCases, testCase{ 18919 name: protocol.String() + "-HintMismatch-Version2", 18920 testType: serverTest, 18921 protocol: protocol, 18922 skipSplitHandshake: true, 18923 config: Config{ 18924 MinVersion: VersionTLS12, 18925 MaxVersion: VersionTLS13, 18926 }, 18927 flags: []string{ 18928 "-allow-hint-mismatch", 18929 "-on-shim-max-version", strconv.Itoa(VersionTLS13), 18930 "-on-handshaker-max-version", strconv.Itoa(VersionTLS12), 18931 }, 18932 expectations: connectionExpectations{ 18933 version: VersionTLS13, 18934 }, 18935 }) 18936 } 18937 18938 // The shim and handshaker may disagree on the certificate compression 18939 // algorithm, whether to enable certificate compression, or certificate 18940 // compression inputs. 18941 testCases = append(testCases, testCase{ 18942 name: protocol.String() + "-HintMismatch-CertificateCompression-ShimOnly", 18943 testType: serverTest, 18944 protocol: protocol, 18945 skipSplitHandshake: true, 18946 config: Config{ 18947 MinVersion: VersionTLS13, 18948 MaxVersion: VersionTLS13, 18949 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 18950 shrinkingCompressionAlgID: shrinkingCompression, 18951 }, 18952 Bugs: ProtocolBugs{ 18953 ExpectedCompressedCert: shrinkingCompressionAlgID, 18954 }, 18955 }, 18956 flags: []string{ 18957 "-allow-hint-mismatch", 18958 "-on-shim-install-cert-compression-algs", 18959 }, 18960 }) 18961 testCases = append(testCases, testCase{ 18962 name: protocol.String() + "-HintMismatch-CertificateCompression-HandshakerOnly", 18963 testType: serverTest, 18964 protocol: protocol, 18965 skipSplitHandshake: true, 18966 config: Config{ 18967 MinVersion: VersionTLS13, 18968 MaxVersion: VersionTLS13, 18969 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 18970 shrinkingCompressionAlgID: shrinkingCompression, 18971 }, 18972 Bugs: ProtocolBugs{ 18973 ExpectUncompressedCert: true, 18974 }, 18975 }, 18976 flags: []string{ 18977 "-allow-hint-mismatch", 18978 "-on-handshaker-install-cert-compression-algs", 18979 }, 18980 }) 18981 testCases = append(testCases, testCase{ 18982 testType: serverTest, 18983 name: protocol.String() + "-HintMismatch-CertificateCompression-AlgorithmMismatch", 18984 protocol: protocol, 18985 skipSplitHandshake: true, 18986 config: Config{ 18987 MinVersion: VersionTLS13, 18988 MaxVersion: VersionTLS13, 18989 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 18990 shrinkingCompressionAlgID: shrinkingCompression, 18991 expandingCompressionAlgID: expandingCompression, 18992 }, 18993 Bugs: ProtocolBugs{ 18994 // The shim's preferences should take effect. 18995 ExpectedCompressedCert: shrinkingCompressionAlgID, 18996 }, 18997 }, 18998 flags: []string{ 18999 "-allow-hint-mismatch", 19000 "-on-shim-install-one-cert-compression-alg", strconv.Itoa(shrinkingCompressionAlgID), 19001 "-on-handshaker-install-one-cert-compression-alg", strconv.Itoa(expandingCompressionAlgID), 19002 }, 19003 }) 19004 testCases = append(testCases, testCase{ 19005 testType: serverTest, 19006 name: protocol.String() + "-HintMismatch-CertificateCompression-InputMismatch", 19007 protocol: protocol, 19008 skipSplitHandshake: true, 19009 config: Config{ 19010 MinVersion: VersionTLS13, 19011 MaxVersion: VersionTLS13, 19012 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19013 shrinkingCompressionAlgID: shrinkingCompression, 19014 }, 19015 Bugs: ProtocolBugs{ 19016 ExpectedCompressedCert: shrinkingCompressionAlgID, 19017 }, 19018 }, 19019 flags: []string{ 19020 "-allow-hint-mismatch", 19021 "-install-cert-compression-algs", 19022 // Configure the shim and handshaker with different OCSP 19023 // responses, so the compression inputs do not match. 19024 "-on-shim-ocsp-response", base64FlagValue(testOCSPResponse), 19025 "-on-handshaker-ocsp-response", base64FlagValue(testOCSPResponse2), 19026 }, 19027 expectations: connectionExpectations{ 19028 // The shim's configuration should take precendence. 19029 ocspResponse: testOCSPResponse, 19030 }, 19031 }) 19032 } 19033} 19034 19035func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { 19036 defer wg.Done() 19037 19038 for test := range c { 19039 var err error 19040 19041 if *mallocTest >= 0 { 19042 for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ { 19043 statusChan <- statusMsg{test: test, statusType: statusStarted} 19044 if err = runTest(statusChan, test, shimPath, mallocNumToFail); err != errMoreMallocs { 19045 if err != nil { 19046 fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err) 19047 } 19048 break 19049 } 19050 } 19051 } else if *repeatUntilFailure { 19052 for err == nil { 19053 statusChan <- statusMsg{test: test, statusType: statusStarted} 19054 err = runTest(statusChan, test, shimPath, -1) 19055 } 19056 } else { 19057 statusChan <- statusMsg{test: test, statusType: statusStarted} 19058 err = runTest(statusChan, test, shimPath, -1) 19059 } 19060 statusChan <- statusMsg{test: test, statusType: statusDone, err: err} 19061 } 19062} 19063 19064type statusType int 19065 19066const ( 19067 statusStarted statusType = iota 19068 statusShimStarted 19069 statusDone 19070) 19071 19072type statusMsg struct { 19073 test *testCase 19074 statusType statusType 19075 pid int 19076 err error 19077} 19078 19079func statusPrinter(doneChan chan *testresult.Results, statusChan chan statusMsg, total int) { 19080 var started, done, failed, unimplemented, lineLen int 19081 19082 testOutput := testresult.NewResults() 19083 for msg := range statusChan { 19084 if !*pipe { 19085 // Erase the previous status line. 19086 var erase string 19087 for i := 0; i < lineLen; i++ { 19088 erase += "\b \b" 19089 } 19090 fmt.Print(erase) 19091 } 19092 19093 if msg.statusType == statusStarted { 19094 started++ 19095 } else if msg.statusType == statusDone { 19096 done++ 19097 19098 if msg.err != nil { 19099 if msg.err == errUnimplemented { 19100 if *pipe { 19101 // Print each test instead of a status line. 19102 fmt.Printf("UNIMPLEMENTED (%s)\n", msg.test.name) 19103 } 19104 unimplemented++ 19105 if *allowUnimplemented { 19106 testOutput.AddSkip(msg.test.name) 19107 } else { 19108 testOutput.AddResult(msg.test.name, "SKIP") 19109 } 19110 } else { 19111 fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err) 19112 failed++ 19113 testOutput.AddResult(msg.test.name, "FAIL") 19114 } 19115 } else { 19116 if *pipe { 19117 // Print each test instead of a status line. 19118 fmt.Printf("PASSED (%s)\n", msg.test.name) 19119 } 19120 testOutput.AddResult(msg.test.name, "PASS") 19121 } 19122 } 19123 19124 if !*pipe { 19125 // Print a new status line. 19126 line := fmt.Sprintf("%d/%d/%d/%d/%d", failed, unimplemented, done, started, total) 19127 if msg.statusType == statusShimStarted && *waitForDebugger { 19128 // Note -wait-for-debugger limits the test to one worker, 19129 // otherwise some output would be skipped. 19130 line += fmt.Sprintf(" (%s: attach to process %d to continue)", msg.test.name, msg.pid) 19131 } 19132 lineLen = len(line) 19133 os.Stdout.WriteString(line) 19134 } 19135 } 19136 19137 doneChan <- testOutput 19138} 19139 19140func match(oneOfPatternIfAny []string, noneOfPattern []string, candidate string) (matched bool, err error) { 19141 matched = len(oneOfPatternIfAny) == 0 19142 19143 var didMatch bool 19144 for _, pattern := range oneOfPatternIfAny { 19145 didMatch, err = filepath.Match(pattern, candidate) 19146 if err != nil { 19147 return false, err 19148 } 19149 19150 matched = didMatch || matched 19151 } 19152 19153 for _, pattern := range noneOfPattern { 19154 didMatch, err = filepath.Match(pattern, candidate) 19155 if err != nil { 19156 return false, err 19157 } 19158 19159 matched = !didMatch && matched 19160 } 19161 19162 return matched, nil 19163} 19164 19165func checkTests() { 19166 for _, test := range testCases { 19167 if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) { 19168 panic("Error expected without shouldFail in " + test.name) 19169 } 19170 19171 if test.expectResumeRejected && !test.resumeSession { 19172 panic("expectResumeRejected without resumeSession in " + test.name) 19173 } 19174 19175 if !test.skipVersionNameCheck { 19176 for _, ver := range tlsVersions { 19177 if !strings.Contains("-"+test.name+"-", "-"+ver.name+"-") { 19178 continue 19179 } 19180 19181 found := test.config.MaxVersion == ver.version || test.config.MinVersion == ver.version || test.expectations.version == ver.version 19182 if test.resumeConfig != nil { 19183 found = found || test.resumeConfig.MaxVersion == ver.version || test.resumeConfig.MinVersion == ver.version 19184 } 19185 if test.resumeExpectations != nil { 19186 found = found || test.resumeExpectations.version == ver.version 19187 } 19188 shimFlag := ver.shimFlag(test.protocol) 19189 for _, flag := range test.flags { 19190 if flag == shimFlag { 19191 found = true 19192 break 19193 } 19194 } 19195 if !found { 19196 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)) 19197 } 19198 } 19199 } 19200 19201 for _, protocol := range []protocol{tls, dtls, quic} { 19202 if strings.Contains("-"+test.name+"-", "-"+protocol.String()+"-") && test.protocol != protocol { 19203 panic(fmt.Sprintf("The name of test %q suggests that it tests %q, but the test does not reference it", test.name, protocol)) 19204 } 19205 } 19206 } 19207} 19208 19209func main() { 19210 flag.Parse() 19211 *resourceDir = path.Clean(*resourceDir) 19212 initCertificates() 19213 19214 if len(*shimConfigFile) != 0 { 19215 encoded, err := ioutil.ReadFile(*shimConfigFile) 19216 if err != nil { 19217 fmt.Fprintf(os.Stderr, "Couldn't read config file %q: %s\n", *shimConfigFile, err) 19218 os.Exit(1) 19219 } 19220 19221 if err := json.Unmarshal(encoded, &shimConfig); err != nil { 19222 fmt.Fprintf(os.Stderr, "Couldn't decode config file %q: %s\n", *shimConfigFile, err) 19223 os.Exit(1) 19224 } 19225 } 19226 19227 if shimConfig.AllCurves == nil { 19228 for _, curve := range testCurves { 19229 shimConfig.AllCurves = append(shimConfig.AllCurves, int(curve.id)) 19230 } 19231 } 19232 19233 addBasicTests() 19234 addCipherSuiteTests() 19235 addBadECDSASignatureTests() 19236 addCBCPaddingTests() 19237 addCBCSplittingTests() 19238 addClientAuthTests() 19239 addDDoSCallbackTests() 19240 addVersionNegotiationTests() 19241 addMinimumVersionTests() 19242 addExtensionTests() 19243 addResumptionVersionTests() 19244 addExtendedMasterSecretTests() 19245 addRenegotiationTests() 19246 addDTLSReplayTests() 19247 addSignatureAlgorithmTests() 19248 addDTLSRetransmitTests() 19249 addExportKeyingMaterialTests() 19250 addExportTrafficSecretsTests() 19251 addTLSUniqueTests() 19252 addCustomExtensionTests() 19253 addRSAClientKeyExchangeTests() 19254 addCurveTests() 19255 addSessionTicketTests() 19256 addTLS13RecordTests() 19257 addAllStateMachineCoverageTests() 19258 addChangeCipherSpecTests() 19259 addEndOfFlightTests() 19260 addWrongMessageTypeTests() 19261 addTrailingMessageDataTests() 19262 addTLS13HandshakeTests() 19263 addTLS13CipherPreferenceTests() 19264 addPeekTests() 19265 addRecordVersionTests() 19266 addCertificateTests() 19267 addRetainOnlySHA256ClientCertTests() 19268 addECDSAKeyUsageTests() 19269 addRSAKeyUsageTests() 19270 addExtraHandshakeTests() 19271 addOmitExtensionsTests() 19272 addCertCompressionTests() 19273 addJDK11WorkaroundTests() 19274 addDelegatedCredentialTests() 19275 addEncryptedClientHelloTests() 19276 addHintMismatchTests() 19277 19278 toAppend, err := convertToSplitHandshakeTests(testCases) 19279 if err != nil { 19280 fmt.Fprintf(os.Stderr, "Error making split handshake tests: %s", err) 19281 os.Exit(1) 19282 } 19283 testCases = append(testCases, toAppend...) 19284 19285 checkTests() 19286 19287 numWorkers := *numWorkersFlag 19288 if useDebugger() { 19289 numWorkers = 1 19290 } 19291 19292 statusChan := make(chan statusMsg, numWorkers) 19293 testChan := make(chan *testCase, numWorkers) 19294 doneChan := make(chan *testresult.Results) 19295 19296 go statusPrinter(doneChan, statusChan, len(testCases)) 19297 19298 var wg sync.WaitGroup 19299 for i := 0; i < numWorkers; i++ { 19300 wg.Add(1) 19301 go worker(statusChan, testChan, *shimPath, &wg) 19302 } 19303 19304 var oneOfPatternIfAny, noneOfPattern []string 19305 if len(*testToRun) > 0 { 19306 oneOfPatternIfAny = strings.Split(*testToRun, ";") 19307 } 19308 if len(*skipTest) > 0 { 19309 noneOfPattern = strings.Split(*skipTest, ";") 19310 } 19311 19312 shardIndex, shardTotal, err := getSharding() 19313 if err != nil { 19314 fmt.Fprintln(os.Stderr, err) 19315 os.Exit(1) 19316 } 19317 19318 if shardTotal > 0 { 19319 fmt.Printf("This is shard %d of 0..%d (inclusive)\n", shardIndex, shardTotal-1) 19320 } 19321 19322 var foundTest bool 19323 for i := range testCases { 19324 if shardTotal > 0 && i%shardTotal != shardIndex { 19325 continue 19326 } 19327 19328 matched, err := match(oneOfPatternIfAny, noneOfPattern, testCases[i].name) 19329 if err != nil { 19330 fmt.Fprintf(os.Stderr, "Error matching pattern: %s\n", err) 19331 os.Exit(1) 19332 } 19333 19334 if !*includeDisabled { 19335 for pattern := range shimConfig.DisabledTests { 19336 isDisabled, err := filepath.Match(pattern, testCases[i].name) 19337 if err != nil { 19338 fmt.Fprintf(os.Stderr, "Error matching pattern %q from config file: %s\n", pattern, err) 19339 os.Exit(1) 19340 } 19341 19342 if isDisabled { 19343 matched = false 19344 break 19345 } 19346 } 19347 } 19348 19349 if matched { 19350 if foundTest && *useRR { 19351 fmt.Fprintf(os.Stderr, "Too many matching tests. Only one test can run when RR is enabled.\n") 19352 os.Exit(1) 19353 } 19354 19355 foundTest = true 19356 testChan <- &testCases[i] 19357 19358 // Only run one test if repeating until failure. 19359 if *repeatUntilFailure { 19360 break 19361 } 19362 } 19363 } 19364 19365 if !foundTest && shardTotal == 0 { 19366 fmt.Fprintf(os.Stderr, "No tests run\n") 19367 os.Exit(1) 19368 } 19369 19370 close(testChan) 19371 wg.Wait() 19372 close(statusChan) 19373 testOutput := <-doneChan 19374 19375 fmt.Printf("\n") 19376 19377 if *jsonOutput != "" { 19378 if err := testOutput.WriteToFile(*jsonOutput); err != nil { 19379 fmt.Fprintf(os.Stderr, "Error: %s\n", err) 19380 } 19381 } 19382 19383 if *useRR { 19384 fmt.Println("RR trace recorded. Replay with `rr replay`.") 19385 } 19386 19387 if !testOutput.HasUnexpectedResults() { 19388 os.Exit(1) 19389 } 19390} 19391