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/ed25519" 22 "crypto/elliptic" 23 "crypto/rand" 24 "crypto/rsa" 25 "crypto/x509" 26 "crypto/x509/pkix" 27 _ "embed" 28 "encoding/base64" 29 "encoding/binary" 30 "encoding/hex" 31 "encoding/json" 32 "encoding/pem" 33 "errors" 34 "flag" 35 "fmt" 36 "io" 37 "math/big" 38 "net" 39 "os" 40 "os/exec" 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 "golang.org/x/crypto/cryptobyte" 52) 53 54var ( 55 useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind") 56 useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb") 57 useLLDB = flag.Bool("lldb", false, "If true, run BoringSSL code under lldb") 58 useRR = flag.Bool("rr-record", false, "If true, run BoringSSL code under `rr record`.") 59 waitForDebugger = flag.Bool("wait-for-debugger", false, "If true, jobs will run one at a time and pause for a debugger to attach") 60 flagDebug = flag.Bool("debug", false, "Hexdump the contents of the connection") 61 mallocTest = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.") 62 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.") 63 jsonOutput = flag.String("json-output", "", "The file to output JSON results to.") 64 pipe = flag.Bool("pipe", false, "If true, print status output suitable for piping into another program.") 65 testToRun = flag.String("test", "", "Semicolon-separated patterns of tests to run, or empty to run all tests") 66 skipTest = flag.String("skip", "", "Semicolon-separated patterns of tests to skip") 67 allowHintMismatch = flag.String("allow-hint-mismatch", "", "Semicolon-separated patterns of tests where hints may mismatch") 68 numWorkersFlag = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.") 69 shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.") 70 shimExtraFlags = flag.String("shim-extra-flags", "", "Semicolon-separated extra flags to pass to the shim binary on each invocation.") 71 handshakerPath = flag.String("handshaker-path", "../../../build/ssl/test/handshaker", "The location of the handshaker binary.") 72 fuzzer = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.") 73 transcriptDir = flag.String("transcript-dir", "", "The directory in which to write transcripts.") 74 idleTimeout = flag.Duration("idle-timeout", 15*time.Second, "The number of seconds to wait for a read or write to bssl_shim.") 75 deterministic = flag.Bool("deterministic", false, "If true, uses a deterministic PRNG in the runner.") 76 allowUnimplemented = flag.Bool("allow-unimplemented", false, "If true, report pass even if some tests are unimplemented.") 77 looseErrors = flag.Bool("loose-errors", false, "If true, allow shims to report an untranslated error code.") 78 shimConfigFile = flag.String("shim-config", "", "A config file to use to configure the tests for this shim.") 79 includeDisabled = flag.Bool("include-disabled", false, "If true, also runs disabled tests.") 80 repeatUntilFailure = flag.Bool("repeat-until-failure", false, "If true, the first selected test will be run repeatedly until failure.") 81) 82 83// ShimConfigurations is used with the “json” package and represents a shim 84// config file. 85type ShimConfiguration struct { 86 // DisabledTests maps from a glob-based pattern to a freeform string. 87 // The glob pattern is used to exclude tests from being run and the 88 // freeform string is unparsed but expected to explain why the test is 89 // disabled. 90 DisabledTests map[string]string 91 92 // ErrorMap maps from expected error strings to the correct error 93 // string for the shim in question. For example, it might map 94 // “:NO_SHARED_CIPHER:” (a BoringSSL error string) to something 95 // like “SSL_ERROR_NO_CYPHER_OVERLAP”. 96 ErrorMap map[string]string 97 98 // HalfRTTTickets is the number of half-RTT tickets the client should 99 // expect before half-RTT data when testing 0-RTT. 100 HalfRTTTickets int 101 102 // AllCurves is the list of all curve code points supported by the shim. 103 // This is currently used to control tests that enable all curves but may 104 // automatically disable tests in the future. 105 AllCurves []int 106} 107 108// Setup shimConfig defaults aligning with BoringSSL. 109var shimConfig ShimConfiguration = ShimConfiguration{ 110 HalfRTTTickets: 2, 111} 112 113//go:embed rsa_2048_key.pem 114var rsa2048KeyPEM []byte 115 116//go:embed rsa_1024_key.pem 117var rsa1024KeyPEM []byte 118 119//go:embed ecdsa_p224_key.pem 120var ecdsaP224KeyPEM []byte 121 122//go:embed ecdsa_p256_key.pem 123var ecdsaP256KeyPEM []byte 124 125//go:embed ecdsa_p384_key.pem 126var ecdsaP384KeyPEM []byte 127 128//go:embed ecdsa_p521_key.pem 129var ecdsaP521KeyPEM []byte 130 131//go:embed ed25519_key.pem 132var ed25519KeyPEM []byte 133 134//go:embed channel_id_key.pem 135var channelIDKeyPEM []byte 136 137var ( 138 rsa1024Key rsa.PrivateKey 139 rsa2048Key rsa.PrivateKey 140 141 ecdsaP224Key ecdsa.PrivateKey 142 ecdsaP256Key ecdsa.PrivateKey 143 ecdsaP384Key ecdsa.PrivateKey 144 ecdsaP521Key ecdsa.PrivateKey 145 146 ed25519Key ed25519.PrivateKey 147 148 channelIDKey ecdsa.PrivateKey 149) 150 151var channelIDKeyPath string 152 153func initKeys() { 154 // Since key generation is not particularly cheap (especially RSA), and the 155 // runner is intended to run on systems which may be resouece constrained, 156 // we load keys from disk instead of dynamically generating them. We treat 157 // key files the same as dynamically generated certificates, writing them 158 // out to temporary files before passing them to the shim. 159 160 for _, k := range []struct { 161 pemBytes []byte 162 key *rsa.PrivateKey 163 }{ 164 {rsa1024KeyPEM, &rsa1024Key}, 165 {rsa2048KeyPEM, &rsa2048Key}, 166 } { 167 key, err := loadPEMKey(k.pemBytes) 168 if err != nil { 169 panic(fmt.Sprintf("failed to load RSA test key: %s", err)) 170 } 171 *k.key = *(key.(*rsa.PrivateKey)) 172 } 173 174 for _, k := range []struct { 175 pemBytes []byte 176 key *ecdsa.PrivateKey 177 }{ 178 {ecdsaP224KeyPEM, &ecdsaP224Key}, 179 {ecdsaP256KeyPEM, &ecdsaP256Key}, 180 {ecdsaP384KeyPEM, &ecdsaP384Key}, 181 {ecdsaP521KeyPEM, &ecdsaP521Key}, 182 {channelIDKeyPEM, &channelIDKey}, 183 } { 184 key, err := loadPEMKey(k.pemBytes) 185 if err != nil { 186 panic(fmt.Sprintf("failed to load ECDSA test key: %s", err)) 187 } 188 *k.key = *(key.(*ecdsa.PrivateKey)) 189 } 190 191 k, err := loadPEMKey(ed25519KeyPEM) 192 if err != nil { 193 panic(fmt.Sprintf("failed to load Ed25519 test key: %s", err)) 194 } 195 ed25519Key = k.(ed25519.PrivateKey) 196 197 channelIDKeyPath = writeTempKeyFile(&channelIDKey) 198} 199 200var channelIDBytes []byte 201 202var testOCSPResponse = []byte{1, 2, 3, 4} 203var testOCSPResponse2 = []byte{5, 6, 7, 8} 204var testSCTList = []byte{0, 6, 0, 4, 5, 6, 7, 8} 205var testSCTList2 = []byte{0, 6, 0, 4, 1, 2, 3, 4} 206 207var testOCSPExtension = append([]byte{byte(extensionStatusRequest) >> 8, byte(extensionStatusRequest), 0, 8, statusTypeOCSP, 0, 0, 4}, testOCSPResponse...) 208var testSCTExtension = append([]byte{byte(extensionSignedCertificateTimestamp) >> 8, byte(extensionSignedCertificateTimestamp), 0, byte(len(testSCTList))}, testSCTList...) 209 210var ( 211 rsaCertificate Credential 212 rsaChainCertificate Credential 213 rsa1024Certificate Credential 214 ecdsaP224Certificate Credential 215 ecdsaP256Certificate Credential 216 ecdsaP384Certificate Credential 217 ecdsaP521Certificate Credential 218 ed25519Certificate Credential 219 garbageCertificate Credential 220) 221 222func initCertificates() { 223 for _, def := range []struct { 224 key crypto.Signer 225 out *Credential 226 }{ 227 {&rsa1024Key, &rsa1024Certificate}, 228 {&rsa2048Key, &rsaCertificate}, 229 {&ecdsaP224Key, &ecdsaP224Certificate}, 230 {&ecdsaP256Key, &ecdsaP256Certificate}, 231 {&ecdsaP384Key, &ecdsaP384Certificate}, 232 {&ecdsaP521Key, &ecdsaP521Certificate}, 233 {ed25519Key, &ed25519Certificate}, 234 } { 235 *def.out = generateSingleCertChain(nil, def.key) 236 } 237 238 channelIDBytes = make([]byte, 64) 239 writeIntPadded(channelIDBytes[:32], channelIDKey.X) 240 writeIntPadded(channelIDBytes[32:], channelIDKey.Y) 241 242 garbageCertificate.Certificate = [][]byte{[]byte("GARBAGE")} 243 garbageCertificate.PrivateKey = rsaCertificate.PrivateKey 244 245 // Build a basic three cert chain for testing chain specific things. 246 rootTmpl := *baseCertTemplate 247 rootTmpl.Subject.CommonName = "test root" 248 rootCert := generateTestCert(&rootTmpl, nil, &rsa2048Key) 249 intermediateTmpl := *baseCertTemplate 250 intermediateTmpl.Subject.CommonName = "test inter" 251 intermediateCert := generateTestCert(&intermediateTmpl, rootCert, &rsa2048Key) 252 leafTmpl := *baseCertTemplate 253 leafTmpl.IsCA, leafTmpl.BasicConstraintsValid = false, false 254 leafCert := generateTestCert(nil, intermediateCert, &rsa2048Key) 255 256 keyPath := writeTempKeyFile(&rsa2048Key) 257 rootCertPath, chainPath := writeTempCertFile([]*x509.Certificate{rootCert}), writeTempCertFile([]*x509.Certificate{leafCert, intermediateCert}) 258 259 rsaChainCertificate = Credential{ 260 Certificate: [][]byte{leafCert.Raw, intermediateCert.Raw}, 261 PrivateKey: &rsa2048Key, 262 Leaf: leafCert, 263 ChainPath: chainPath, 264 KeyPath: keyPath, 265 RootPath: rootCertPath, 266 } 267} 268 269func flagInts(flagName string, vals []int) []string { 270 ret := make([]string, 0, 2*len(vals)) 271 for _, val := range vals { 272 ret = append(ret, flagName, strconv.Itoa(val)) 273 } 274 return ret 275} 276 277func base64FlagValue(in []byte) string { 278 return base64.StdEncoding.EncodeToString(in) 279} 280 281func useDebugger() bool { 282 return *useGDB || *useLLDB || *useRR || *waitForDebugger 283} 284 285// delegatedCredentialConfig specifies the shape of a delegated credential, not 286// including the keys themselves. 287type delegatedCredentialConfig struct { 288 // lifetime is the amount of time, from the notBefore of the parent 289 // certificate, that the delegated credential is valid for. If zero, then 24 290 // hours is assumed. 291 lifetime time.Duration 292 // dcAlgo is the signature scheme that should be used with this delegated 293 // credential. If zero, ECDSA with P-256 is assumed. 294 dcAlgo signatureAlgorithm 295 // algo is the signature algorithm that the delegated credential itself is 296 // signed with. Cannot be zero. 297 algo signatureAlgorithm 298} 299 300func loadPEMKey(pemBytes []byte) (crypto.PrivateKey, error) { 301 block, _ := pem.Decode(pemBytes) 302 if block == nil { 303 return nil, fmt.Errorf("no PEM block found") 304 } 305 306 if block.Type != "PRIVATE KEY" { 307 return nil, fmt.Errorf("unexpected PEM type (expected \"PRIVATE KEY\"): %s", block.Type) 308 } 309 310 k, err := x509.ParsePKCS8PrivateKey(block.Bytes) 311 if err != nil { 312 return nil, fmt.Errorf("failed to parse PKCS#8 key: %s", err) 313 } 314 315 return k, nil 316} 317 318func createDelegatedCredential(parent *Credential, config delegatedCredentialConfig) *Credential { 319 if parent.Type != CredentialTypeX509 { 320 panic("delegated credentials must be issued by X.509 credentials") 321 } 322 323 dcAlgo := config.dcAlgo 324 if dcAlgo == 0 { 325 dcAlgo = signatureECDSAWithP256AndSHA256 326 } 327 328 var dcPriv crypto.Signer 329 switch dcAlgo { 330 case signatureRSAPKCS1WithMD5, signatureRSAPKCS1WithSHA1, signatureRSAPKCS1WithSHA256, signatureRSAPKCS1WithSHA384, signatureRSAPKCS1WithSHA512, signatureRSAPSSWithSHA256, signatureRSAPSSWithSHA384, signatureRSAPSSWithSHA512: 331 dcPriv = &rsa2048Key 332 333 case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256, signatureECDSAWithP384AndSHA384, signatureECDSAWithP521AndSHA512: 334 var curve elliptic.Curve 335 switch dcAlgo { 336 case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256: 337 curve = elliptic.P256() 338 case signatureECDSAWithP384AndSHA384: 339 curve = elliptic.P384() 340 case signatureECDSAWithP521AndSHA512: 341 curve = elliptic.P521() 342 default: 343 panic("internal error") 344 } 345 346 priv, err := ecdsa.GenerateKey(curve, rand.Reader) 347 if err != nil { 348 panic(err) 349 } 350 dcPriv = priv 351 352 default: 353 panic(fmt.Errorf("unsupported DC signature algorithm: %x", dcAlgo)) 354 } 355 356 lifetime := config.lifetime 357 if lifetime == 0 { 358 lifetime = 24 * time.Hour 359 } 360 lifetimeSecs := int64(lifetime.Seconds()) 361 if lifetimeSecs < 0 || lifetimeSecs > 1<<32 { 362 panic(fmt.Errorf("lifetime %s is too long to be expressed", lifetime)) 363 } 364 365 // https://www.rfc-editor.org/rfc/rfc9345.html#section-4 366 dc := cryptobyte.NewBuilder(nil) 367 dc.AddUint32(uint32(lifetimeSecs)) 368 dc.AddUint16(uint16(dcAlgo)) 369 370 pubBytes, err := x509.MarshalPKIXPublicKey(dcPriv.Public()) 371 if err != nil { 372 panic(err) 373 } 374 addUint24LengthPrefixedBytes(dc, pubBytes) 375 376 var dummyConfig Config 377 parentSignature, err := signMessage(false /* server */, VersionTLS13, parent.PrivateKey, &dummyConfig, config.algo, delegatedCredentialSignedMessage(dc.BytesOrPanic(), config.algo, parent.Leaf.Raw)) 378 if err != nil { 379 panic(err) 380 } 381 382 dc.AddUint16(uint16(config.algo)) 383 addUint16LengthPrefixedBytes(dc, parentSignature) 384 385 dcCred := *parent 386 dcCred.Type = CredentialTypeDelegated 387 dcCred.DelegatedCredential = dc.BytesOrPanic() 388 dcCred.PrivateKey = dcPriv 389 dcCred.KeyPath = writeTempKeyFile(dcPriv) 390 return &dcCred 391} 392 393// recordVersionToWire maps a record-layer protocol version to its wire 394// representation. 395func recordVersionToWire(vers uint16, protocol protocol) uint16 { 396 if protocol == dtls { 397 switch vers { 398 case VersionTLS12: 399 return VersionDTLS12 400 case VersionTLS10: 401 return VersionDTLS10 402 } 403 } else { 404 switch vers { 405 case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12: 406 return vers 407 } 408 } 409 410 panic("unknown version") 411} 412 413// encodeDERValues encodes a series of bytestrings in comma-separated-hex form. 414func encodeDERValues(values [][]byte) string { 415 var ret string 416 for i, v := range values { 417 if i > 0 { 418 ret += "," 419 } 420 ret += hex.EncodeToString(v) 421 } 422 423 return ret 424} 425 426func decodeHexOrPanic(in string) []byte { 427 ret, err := hex.DecodeString(in) 428 if err != nil { 429 panic(err) 430 } 431 return ret 432} 433 434type testType int 435 436const ( 437 clientTest testType = iota 438 serverTest 439) 440 441type protocol int 442 443const ( 444 tls protocol = iota 445 dtls 446 quic 447) 448 449func (p protocol) String() string { 450 switch p { 451 case tls: 452 return "TLS" 453 case dtls: 454 return "DTLS" 455 case quic: 456 return "QUIC" 457 } 458 return "unknown protocol" 459} 460 461const ( 462 alpn = 1 463 npn = 2 464) 465 466// connectionExpectations contains connection-level test expectations to check 467// on the runner side. 468type connectionExpectations struct { 469 // version, if non-zero, specifies the TLS version that must be negotiated. 470 version uint16 471 // cipher, if non-zero, specifies the TLS cipher suite that should be 472 // negotiated. 473 cipher uint16 474 // channelID controls whether the connection should have negotiated a 475 // Channel ID with channelIDKey. 476 channelID bool 477 // nextProto controls whether the connection should negotiate a next 478 // protocol via NPN or ALPN. 479 nextProto string 480 // noNextProto, if true, means that no next protocol should be negotiated. 481 noNextProto bool 482 // nextProtoType, if non-zero, is the next protocol negotiation mechanism. 483 nextProtoType int 484 // srtpProtectionProfile is the DTLS-SRTP profile that should be negotiated. 485 // If zero, none should be negotiated. 486 srtpProtectionProfile uint16 487 // peerSignatureAlgorithm, if not zero, is the signature algorithm that the 488 // peer should have used in the handshake. 489 peerSignatureAlgorithm signatureAlgorithm 490 // curveID, if not zero, is the curve that the handshake should have used. 491 curveID CurveID 492 // peerCertificate, if not nil, is the credential the peer is expected to 493 // send. 494 peerCertificate *Credential 495 // quicTransportParams contains the QUIC transport parameters that are to be 496 // sent by the peer using codepoint 57. 497 quicTransportParams []byte 498 // quicTransportParamsLegacy contains the QUIC transport parameters that are 499 // to be sent by the peer using legacy codepoint 0xffa5. 500 quicTransportParamsLegacy []byte 501 // peerApplicationSettings are the expected application settings for the 502 // connection. If nil, no application settings are expected. 503 peerApplicationSettings []byte 504 // peerApplicationSettingsOld are the expected application settings for 505 // the connection that are to be sent by the peer using old codepoint. 506 // If nil, no application settings are expected. 507 peerApplicationSettingsOld []byte 508 // echAccepted is whether ECH should have been accepted on this connection. 509 echAccepted bool 510} 511 512type testCase struct { 513 testType testType 514 protocol protocol 515 name string 516 config Config 517 shouldFail bool 518 expectedError string 519 // expectedLocalError, if not empty, contains a substring that must be 520 // found in the local error. 521 expectedLocalError string 522 // expectations contains test expectations for the initial 523 // connection. 524 expectations connectionExpectations 525 // resumeExpectations, if non-nil, contains test expectations for the 526 // resumption connection. If nil, |expectations| is used. 527 resumeExpectations *connectionExpectations 528 // messageLen is the length, in bytes, of the test message that will be 529 // sent. 530 messageLen int 531 // messageCount is the number of test messages that will be sent. 532 messageCount int 533 // resumeSession controls whether a second connection should be tested 534 // which attempts to resume the first session. 535 resumeSession bool 536 // resumeRenewedSession controls whether a third connection should be 537 // tested which attempts to resume the second connection's session. 538 resumeRenewedSession bool 539 // expectResumeRejected, if true, specifies that the attempted 540 // resumption must be rejected by the client. This is only valid for a 541 // serverTest. 542 expectResumeRejected bool 543 // resumeConfig, if not nil, points to a Config to be used on 544 // resumption. Unless newSessionsOnResume is set, 545 // SessionTicketKey, ServerSessionCache, and 546 // ClientSessionCache are copied from the initial connection's 547 // config. If nil, the initial connection's config is used. 548 resumeConfig *Config 549 // newSessionsOnResume, if true, will cause resumeConfig to 550 // use a different session resumption context. 551 newSessionsOnResume bool 552 // noSessionCache, if true, will cause the server to run without a 553 // session cache. 554 noSessionCache bool 555 // sendPrefix sends a prefix on the socket before actually performing a 556 // handshake. 557 sendPrefix string 558 // shimWritesFirst controls whether the shim sends an initial "hello" 559 // message before doing a roundtrip with the runner. 560 shimWritesFirst bool 561 // readWithUnfinishedWrite behaves like shimWritesFirst, but the shim 562 // does not complete the write until responding to the first runner 563 // message. 564 readWithUnfinishedWrite bool 565 // shimShutsDown, if true, runs a test where the shim shuts down the 566 // connection immediately after the handshake rather than echoing 567 // messages from the runner. The runner will default to not sending 568 // application data. 569 shimShutsDown bool 570 // renegotiate indicates the number of times the connection should be 571 // renegotiated during the exchange. 572 renegotiate int 573 // sendHalfHelloRequest, if true, causes the server to send half a 574 // HelloRequest when the handshake completes. 575 sendHalfHelloRequest bool 576 // renegotiateCiphers is a list of ciphersuite ids that will be 577 // switched in just before renegotiation. 578 renegotiateCiphers []uint16 579 // replayWrites, if true, configures the underlying transport 580 // to replay every write it makes in DTLS tests. 581 replayWrites bool 582 // damageFirstWrite, if true, configures the underlying transport to 583 // damage the final byte of the first application data write. 584 damageFirstWrite bool 585 // exportKeyingMaterial, if non-zero, configures the test to exchange 586 // keying material and verify they match. 587 exportKeyingMaterial int 588 exportLabel string 589 exportContext string 590 useExportContext bool 591 // flags, if not empty, contains a list of command-line flags that will 592 // be passed to the shim program. 593 flags []string 594 // testTLSUnique, if true, causes the shim to send the tls-unique value 595 // which will be compared against the expected value. 596 testTLSUnique bool 597 // sendEmptyRecords is the number of consecutive empty records to send 598 // before each test message. 599 sendEmptyRecords int 600 // sendWarningAlerts is the number of consecutive warning alerts to send 601 // before each test message. 602 sendWarningAlerts int 603 // sendUserCanceledAlerts is the number of consecutive user_canceled alerts to 604 // send before each test message. 605 sendUserCanceledAlerts int 606 // sendBogusAlertType, if true, causes a bogus alert of invalid type to 607 // be sent before each test message. 608 sendBogusAlertType bool 609 // sendKeyUpdates is the number of consecutive key updates to send 610 // before and after the test message. 611 sendKeyUpdates int 612 // keyUpdateRequest is the KeyUpdateRequest value to send in KeyUpdate messages. 613 keyUpdateRequest byte 614 // expectUnsolicitedKeyUpdate makes the test expect a one or more KeyUpdate 615 // messages while reading data from the shim. Don't use this in combination 616 // with any of the fields that send a KeyUpdate otherwise any received 617 // KeyUpdate might not be as unsolicited as expected. 618 expectUnsolicitedKeyUpdate bool 619 // expectMessageDropped, if true, means the test message is expected to 620 // be dropped by the client rather than echoed back. 621 expectMessageDropped bool 622 // shimPrefix is the prefix that the shim will send to the server. 623 shimPrefix string 624 // resumeShimPrefix is the prefix that the shim will send to the server on a 625 // resumption. 626 resumeShimPrefix string 627 // exportTrafficSecrets, if true, configures the test to export the TLS 1.3 628 // traffic secrets and confirms that they match. 629 exportTrafficSecrets bool 630 // skipTransportParamsConfig, if true, will skip automatic configuration of 631 // sending QUIC transport parameters when protocol == quic. 632 skipTransportParamsConfig bool 633 // skipQUICALPNConfig, if true, will skip automatic configuration of 634 // sending a fake ALPN when protocol == quic. 635 skipQUICALPNConfig bool 636 // earlyData, if true, configures default settings for an early data test. 637 // expectEarlyDataRejected controls whether the test is for early data 638 // accept or reject. In a client test, the shim will be configured to send 639 // an initial write in early data which, on accept, the runner will enforce. 640 // In a server test, the runner will send some default message in early 641 // data, which the shim is expected to echo in half-RTT. 642 earlyData bool 643 // expectEarlyDataRejected, if earlyData is true, is whether early data is 644 // expected to be rejected. In a client test, this controls whether the shim 645 // should retry for early rejection. In a server test, this is whether the 646 // test expects the shim to reject early data. 647 expectEarlyDataRejected bool 648 // skipSplitHandshake, if true, will skip the generation of a split 649 // handshake copy of the test. 650 skipSplitHandshake bool 651 // skipHints, if true, will skip the generation of a handshake hints copy of 652 // the test. 653 skipHints bool 654 // skipVersionNameCheck, if true, will skip the consistency check between 655 // test name and the versions. 656 skipVersionNameCheck bool 657 // shimCertificate, if not nil, is the default credential which should be 658 // configured at the shim. If set, it must be an X.509 credential. 659 shimCertificate *Credential 660 // handshakerCertificate, if not nil, overrides the default credential which 661 // on the handshaker. 662 handshakerCertificate *Credential 663 // shimCredentials is a list of credentials which should be configured at 664 // the shim. It differs from shimCertificate only in whether the old or 665 // new APIs are used. 666 shimCredentials []*Credential 667} 668 669var testCases []testCase 670 671func appendTranscript(path string, data []byte) error { 672 if len(data) == 0 { 673 return nil 674 } 675 676 settings, err := os.ReadFile(path) 677 if err != nil { 678 if !os.IsNotExist(err) { 679 return err 680 } 681 // If the shim aborted before writing a file, use a default 682 // settings block, so the transcript is still somewhat valid. 683 settings = []byte{0, 0} // kDataTag 684 } 685 686 settings = append(settings, data...) 687 return os.WriteFile(path, settings, 0644) 688} 689 690// A timeoutConn implements an idle timeout on each Read and Write operation. 691type timeoutConn struct { 692 net.Conn 693 timeout time.Duration 694} 695 696func (t *timeoutConn) Read(b []byte) (int, error) { 697 if !*useGDB { 698 if err := t.SetReadDeadline(time.Now().Add(t.timeout)); err != nil { 699 return 0, err 700 } 701 } 702 return t.Conn.Read(b) 703} 704 705func (t *timeoutConn) Write(b []byte) (int, error) { 706 if !*useGDB { 707 if err := t.SetWriteDeadline(time.Now().Add(t.timeout)); err != nil { 708 return 0, err 709 } 710 } 711 return t.Conn.Write(b) 712} 713 714func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool, transcripts *[][]byte, num int) error { 715 if !test.noSessionCache { 716 if config.ClientSessionCache == nil { 717 config.ClientSessionCache = NewLRUClientSessionCache(1) 718 } 719 if config.ServerSessionCache == nil { 720 config.ServerSessionCache = NewLRUServerSessionCache(1) 721 } 722 } 723 if test.testType != clientTest { 724 // Supply a ServerName to ensure a constant session cache key, 725 // rather than falling back to net.Conn.RemoteAddr. 726 if len(config.ServerName) == 0 { 727 config.ServerName = "test" 728 } 729 } 730 731 if *fuzzer { 732 config.Bugs.NullAllCiphers = true 733 } 734 if *deterministic { 735 config.Time = func() time.Time { return time.Unix(1234, 1234) } 736 } 737 738 if !useDebugger() { 739 conn = &timeoutConn{conn, *idleTimeout} 740 } 741 742 if test.protocol == dtls { 743 config.Bugs.PacketAdaptor = newPacketAdaptor(conn) 744 conn = config.Bugs.PacketAdaptor 745 } 746 747 if *flagDebug || len(*transcriptDir) != 0 { 748 local, peer := "client", "server" 749 if test.testType == clientTest { 750 local, peer = peer, local 751 } 752 connDebug := &recordingConn{ 753 Conn: conn, 754 isDatagram: test.protocol == dtls, 755 local: local, 756 peer: peer, 757 } 758 conn = connDebug 759 if *flagDebug { 760 defer connDebug.WriteTo(os.Stdout) 761 } 762 if len(*transcriptDir) != 0 { 763 defer func() { 764 if num == len(*transcripts) { 765 *transcripts = append(*transcripts, connDebug.Transcript()) 766 } else { 767 panic("transcripts are out of sync") 768 } 769 }() 770 771 // Record ClientHellos for the decode_client_hello_inner fuzzer. 772 var clientHelloCount int 773 config.Bugs.RecordClientHelloInner = func(encodedInner, outer []byte) error { 774 name := fmt.Sprintf("%s-%d-%d", test.name, num, clientHelloCount) 775 clientHelloCount++ 776 dir := filepath.Join(*transcriptDir, "decode_client_hello_inner") 777 if err := os.MkdirAll(dir, 0755); err != nil { 778 return err 779 } 780 bb := cryptobyte.NewBuilder(nil) 781 addUint24LengthPrefixedBytes(bb, encodedInner) 782 bb.AddBytes(outer) 783 return os.WriteFile(filepath.Join(dir, name), bb.BytesOrPanic(), 0644) 784 } 785 } 786 787 if config.Bugs.PacketAdaptor != nil { 788 config.Bugs.PacketAdaptor.debug = connDebug 789 } 790 } 791 if test.protocol == quic { 792 config.Bugs.MockQUICTransport = newMockQUICTransport(conn) 793 // The MockQUICTransport will panic if Read or Write is 794 // called. When a MockQUICTransport is set, separate 795 // methods should be used to actually read and write 796 // records. By setting the conn to it here, it ensures 797 // Read or Write aren't accidentally used instead of the 798 // methods provided by MockQUICTransport. 799 conn = config.Bugs.MockQUICTransport 800 } 801 802 if test.replayWrites { 803 conn = newReplayAdaptor(conn) 804 } 805 806 var connDamage *damageAdaptor 807 if test.damageFirstWrite { 808 connDamage = newDamageAdaptor(conn) 809 conn = connDamage 810 } 811 812 if test.sendPrefix != "" { 813 if _, err := conn.Write([]byte(test.sendPrefix)); err != nil { 814 return err 815 } 816 } 817 818 var tlsConn *Conn 819 if test.testType == clientTest { 820 if test.protocol == dtls { 821 tlsConn = DTLSServer(conn, config) 822 } else { 823 tlsConn = Server(conn, config) 824 } 825 } else { 826 config.InsecureSkipVerify = true 827 if test.protocol == dtls { 828 tlsConn = DTLSClient(conn, config) 829 } else { 830 tlsConn = Client(conn, config) 831 } 832 } 833 defer tlsConn.Close() 834 835 if err := tlsConn.Handshake(); err != nil { 836 return err 837 } 838 839 expectations := &test.expectations 840 if isResume && test.resumeExpectations != nil { 841 expectations = test.resumeExpectations 842 } 843 connState := tlsConn.ConnectionState() 844 if vers := connState.Version; expectations.version != 0 && vers != expectations.version { 845 return fmt.Errorf("got version %x, expected %x", vers, expectations.version) 846 } 847 848 if cipher := connState.CipherSuite; expectations.cipher != 0 && cipher != expectations.cipher { 849 return fmt.Errorf("got cipher %x, expected %x", cipher, expectations.cipher) 850 } 851 if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected { 852 return fmt.Errorf("didResume is %t, but we expected the opposite", didResume) 853 } 854 855 if expectations.channelID { 856 channelID := connState.ChannelID 857 if channelID == nil { 858 return fmt.Errorf("no channel ID negotiated") 859 } 860 if channelID.Curve != channelIDKey.Curve || 861 channelIDKey.X.Cmp(channelIDKey.X) != 0 || 862 channelIDKey.Y.Cmp(channelIDKey.Y) != 0 { 863 return fmt.Errorf("incorrect channel ID") 864 } 865 } else if connState.ChannelID != nil { 866 return fmt.Errorf("channel ID unexpectedly negotiated") 867 } 868 869 if expected := expectations.nextProto; expected != "" { 870 if actual := connState.NegotiatedProtocol; actual != expected { 871 return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected) 872 } 873 } 874 875 if expectations.noNextProto { 876 if actual := connState.NegotiatedProtocol; actual != "" { 877 return fmt.Errorf("got unexpected next proto %s", actual) 878 } 879 } 880 881 if expectations.nextProtoType != 0 { 882 if (expectations.nextProtoType == alpn) != connState.NegotiatedProtocolFromALPN { 883 return fmt.Errorf("next proto type mismatch") 884 } 885 } 886 887 if expectations.peerApplicationSettings != nil { 888 if !connState.HasApplicationSettings { 889 return errors.New("application settings should have been negotiated") 890 } 891 if !bytes.Equal(connState.PeerApplicationSettings, expectations.peerApplicationSettings) { 892 return fmt.Errorf("peer application settings mismatch: got %q, wanted %q", connState.PeerApplicationSettings, expectations.peerApplicationSettings) 893 } 894 } else if connState.HasApplicationSettings { 895 return errors.New("application settings unexpectedly negotiated") 896 } 897 898 if expectations.peerApplicationSettingsOld != nil { 899 if !connState.HasApplicationSettingsOld { 900 return errors.New("old application settings should have been negotiated") 901 } 902 if !bytes.Equal(connState.PeerApplicationSettingsOld, expectations.peerApplicationSettingsOld) { 903 return fmt.Errorf("old peer application settings mismatch: got %q, wanted %q", connState.PeerApplicationSettingsOld, expectations.peerApplicationSettingsOld) 904 } 905 } else if connState.HasApplicationSettingsOld { 906 return errors.New("old application settings unexpectedly negotiated") 907 } 908 909 if p := connState.SRTPProtectionProfile; p != expectations.srtpProtectionProfile { 910 return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, expectations.srtpProtectionProfile) 911 } 912 913 if expected := expectations.peerSignatureAlgorithm; expected != 0 && expected != connState.PeerSignatureAlgorithm { 914 return fmt.Errorf("expected peer to use signature algorithm %04x, but got %04x", expected, connState.PeerSignatureAlgorithm) 915 } 916 917 if expected := expectations.curveID; expected != 0 && expected != connState.CurveID { 918 return fmt.Errorf("expected peer to use curve %04x, but got %04x", expected, connState.CurveID) 919 } 920 921 if expected := expectations.peerCertificate; expected != nil { 922 if len(connState.PeerCertificates) != len(expected.Certificate) { 923 return fmt.Errorf("expected peer to send %d certificates, but got %d", len(connState.PeerCertificates), len(expected.Certificate)) 924 } 925 for i, cert := range connState.PeerCertificates { 926 if !bytes.Equal(cert.Raw, expected.Certificate[i]) { 927 return fmt.Errorf("peer certificate %d did not match", i+1) 928 } 929 } 930 931 if !bytes.Equal(connState.OCSPResponse, expected.OCSPStaple) { 932 return fmt.Errorf("peer OCSP response did not match") 933 } 934 935 if !bytes.Equal(connState.SCTList, expected.SignedCertificateTimestampList) { 936 return fmt.Errorf("peer SCT list did not match") 937 } 938 939 if expected.Type == CredentialTypeDelegated { 940 if connState.PeerDelegatedCredential == nil { 941 return fmt.Errorf("peer unexpectedly did not use delegated credentials") 942 } 943 if !bytes.Equal(expected.DelegatedCredential, connState.PeerDelegatedCredential) { 944 return fmt.Errorf("peer delegated credential did not match") 945 } 946 } else if connState.PeerDelegatedCredential != nil { 947 return fmt.Errorf("peer unexpectedly used delegated credentials") 948 } 949 } 950 951 if len(expectations.quicTransportParams) > 0 { 952 if !bytes.Equal(expectations.quicTransportParams, connState.QUICTransportParams) { 953 return errors.New("Peer did not send expected QUIC transport params") 954 } 955 } 956 957 if len(expectations.quicTransportParamsLegacy) > 0 { 958 if !bytes.Equal(expectations.quicTransportParamsLegacy, connState.QUICTransportParamsLegacy) { 959 return errors.New("Peer did not send expected legacy QUIC transport params") 960 } 961 } 962 963 if expectations.echAccepted { 964 if !connState.ECHAccepted { 965 return errors.New("tls: server did not accept ECH") 966 } 967 } else { 968 if connState.ECHAccepted { 969 return errors.New("tls: server unexpectedly accepted ECH") 970 } 971 } 972 973 if test.exportKeyingMaterial > 0 { 974 actual := make([]byte, test.exportKeyingMaterial) 975 if _, err := io.ReadFull(tlsConn, actual); err != nil { 976 return err 977 } 978 expected, err := tlsConn.ExportKeyingMaterial(test.exportKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext), test.useExportContext) 979 if err != nil { 980 return err 981 } 982 if !bytes.Equal(actual, expected) { 983 return fmt.Errorf("keying material mismatch; got %x, wanted %x", actual, expected) 984 } 985 } 986 987 if test.exportTrafficSecrets { 988 secretLenBytes := make([]byte, 2) 989 if _, err := io.ReadFull(tlsConn, secretLenBytes); err != nil { 990 return err 991 } 992 secretLen := binary.LittleEndian.Uint16(secretLenBytes) 993 994 theirReadSecret := make([]byte, secretLen) 995 theirWriteSecret := make([]byte, secretLen) 996 if _, err := io.ReadFull(tlsConn, theirReadSecret); err != nil { 997 return err 998 } 999 if _, err := io.ReadFull(tlsConn, theirWriteSecret); err != nil { 1000 return err 1001 } 1002 1003 myReadSecret := tlsConn.in.trafficSecret 1004 myWriteSecret := tlsConn.out.trafficSecret 1005 if !bytes.Equal(myWriteSecret, theirReadSecret) { 1006 return fmt.Errorf("read traffic-secret mismatch; got %x, wanted %x", theirReadSecret, myWriteSecret) 1007 } 1008 if !bytes.Equal(myReadSecret, theirWriteSecret) { 1009 return fmt.Errorf("write traffic-secret mismatch; got %x, wanted %x", theirWriteSecret, myReadSecret) 1010 } 1011 } 1012 1013 if test.testTLSUnique { 1014 var peersValue [12]byte 1015 if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil { 1016 return err 1017 } 1018 expected := tlsConn.ConnectionState().TLSUnique 1019 if !bytes.Equal(peersValue[:], expected) { 1020 return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected) 1021 } 1022 } 1023 1024 if test.sendHalfHelloRequest { 1025 tlsConn.SendHalfHelloRequest() 1026 } 1027 1028 shimPrefix := test.shimPrefix 1029 if isResume { 1030 shimPrefix = test.resumeShimPrefix 1031 } 1032 if test.shimWritesFirst || test.readWithUnfinishedWrite { 1033 shimPrefix = shimInitialWrite 1034 } 1035 if test.renegotiate > 0 { 1036 // If readWithUnfinishedWrite is set, the shim prefix will be 1037 // available later. 1038 if shimPrefix != "" && !test.readWithUnfinishedWrite { 1039 var buf = make([]byte, len(shimPrefix)) 1040 _, err := io.ReadFull(tlsConn, buf) 1041 if err != nil { 1042 return err 1043 } 1044 if string(buf) != shimPrefix { 1045 return fmt.Errorf("bad initial message %v vs %v", string(buf), shimPrefix) 1046 } 1047 shimPrefix = "" 1048 } 1049 1050 if test.renegotiateCiphers != nil { 1051 config.CipherSuites = test.renegotiateCiphers 1052 } 1053 for i := 0; i < test.renegotiate; i++ { 1054 if err := tlsConn.Renegotiate(); err != nil { 1055 return err 1056 } 1057 } 1058 } else if test.renegotiateCiphers != nil { 1059 panic("renegotiateCiphers without renegotiate") 1060 } 1061 1062 if test.damageFirstWrite { 1063 connDamage.setDamage(true) 1064 tlsConn.Write([]byte("DAMAGED WRITE")) 1065 connDamage.setDamage(false) 1066 } 1067 1068 messageLen := test.messageLen 1069 if messageLen < 0 { 1070 if test.protocol == dtls { 1071 return fmt.Errorf("messageLen < 0 not supported for DTLS tests") 1072 } 1073 // Read until EOF. 1074 _, err := io.Copy(io.Discard, tlsConn) 1075 return err 1076 } 1077 if messageLen == 0 { 1078 messageLen = 32 1079 } 1080 1081 messageCount := test.messageCount 1082 // shimShutsDown sets the default message count to zero. 1083 if messageCount == 0 && !test.shimShutsDown { 1084 messageCount = 1 1085 } 1086 1087 for j := 0; j < messageCount; j++ { 1088 for i := 0; i < test.sendKeyUpdates; i++ { 1089 tlsConn.SendKeyUpdate(test.keyUpdateRequest) 1090 } 1091 1092 for i := 0; i < test.sendEmptyRecords; i++ { 1093 tlsConn.Write(nil) 1094 } 1095 1096 for i := 0; i < test.sendWarningAlerts; i++ { 1097 tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage) 1098 } 1099 1100 for i := 0; i < test.sendUserCanceledAlerts; i++ { 1101 tlsConn.SendAlert(alertLevelWarning, alertUserCanceled) 1102 } 1103 1104 if test.sendBogusAlertType { 1105 tlsConn.SendAlert(0x42, alertUnexpectedMessage) 1106 } 1107 1108 testMessage := make([]byte, messageLen) 1109 for i := range testMessage { 1110 testMessage[i] = 0x42 ^ byte(j) 1111 } 1112 tlsConn.Write(testMessage) 1113 1114 // Consume the shim prefix if needed. 1115 if shimPrefix != "" { 1116 var buf = make([]byte, len(shimPrefix)) 1117 _, err := io.ReadFull(tlsConn, buf) 1118 if err != nil { 1119 return err 1120 } 1121 if string(buf) != shimPrefix { 1122 return fmt.Errorf("bad initial message %v vs %v", string(buf), shimPrefix) 1123 } 1124 shimPrefix = "" 1125 } 1126 1127 if test.shimShutsDown || test.expectMessageDropped { 1128 // The shim will not respond. 1129 continue 1130 } 1131 1132 // Process the KeyUpdate ACK. However many KeyUpdates the runner 1133 // sends, the shim should respond only once. 1134 if test.sendKeyUpdates > 0 && test.keyUpdateRequest == keyUpdateRequested { 1135 if err := tlsConn.ReadKeyUpdateACK(); err != nil { 1136 return err 1137 } 1138 } 1139 1140 buf := make([]byte, len(testMessage)) 1141 if test.protocol == dtls { 1142 bufTmp := make([]byte, len(buf)+1) 1143 n, err := tlsConn.Read(bufTmp) 1144 if err != nil { 1145 return err 1146 } 1147 if config.Bugs.SplitAndPackAppData { 1148 m, err := tlsConn.Read(bufTmp[n:]) 1149 if err != nil { 1150 return err 1151 } 1152 n += m 1153 } 1154 if n != len(buf) { 1155 return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf)) 1156 } 1157 copy(buf, bufTmp) 1158 } else { 1159 _, err := io.ReadFull(tlsConn, buf) 1160 if err != nil { 1161 return err 1162 } 1163 } 1164 1165 for i, v := range buf { 1166 if v != testMessage[i]^0xff { 1167 return fmt.Errorf("bad reply contents at byte %d; got %q and wanted %q", i, buf, testMessage) 1168 } 1169 } 1170 1171 if seen := tlsConn.keyUpdateSeen; seen != test.expectUnsolicitedKeyUpdate { 1172 return fmt.Errorf("keyUpdateSeen (%t) != expectUnsolicitedKeyUpdate", seen) 1173 } 1174 } 1175 1176 return nil 1177} 1178 1179const xtermSize = "140x50" 1180 1181func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd { 1182 valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full", "--quiet"} 1183 if dbAttach { 1184 valgrindArgs = append(valgrindArgs, "--db-attach=yes", "--db-command=xterm -geometry "+xtermSize+" -e gdb -nw %f %p") 1185 } 1186 valgrindArgs = append(valgrindArgs, path) 1187 valgrindArgs = append(valgrindArgs, args...) 1188 1189 return exec.Command("valgrind", valgrindArgs...) 1190} 1191 1192func gdbOf(path string, args ...string) *exec.Cmd { 1193 xtermArgs := []string{"-geometry", xtermSize, "-e", "gdb", "--args"} 1194 xtermArgs = append(xtermArgs, path) 1195 xtermArgs = append(xtermArgs, args...) 1196 1197 return exec.Command("xterm", xtermArgs...) 1198} 1199 1200func lldbOf(path string, args ...string) *exec.Cmd { 1201 xtermArgs := []string{"-geometry", xtermSize, "-e", "lldb", "--"} 1202 xtermArgs = append(xtermArgs, path) 1203 xtermArgs = append(xtermArgs, args...) 1204 1205 return exec.Command("xterm", xtermArgs...) 1206} 1207 1208func rrOf(path string, args ...string) *exec.Cmd { 1209 rrArgs := []string{"record", path} 1210 rrArgs = append(rrArgs, args...) 1211 return exec.Command("rr", rrArgs...) 1212} 1213 1214func removeFirstLineIfSuffix(s, suffix string) string { 1215 idx := strings.IndexByte(s, '\n') 1216 if idx < 0 { 1217 return s 1218 } 1219 if strings.HasSuffix(s[:idx], suffix) { 1220 return s[idx+1:] 1221 } 1222 return s 1223} 1224 1225var ( 1226 errMoreMallocs = errors.New("child process did not exhaust all allocation calls") 1227 errUnimplemented = errors.New("child process does not implement needed flags") 1228) 1229 1230type shimProcess struct { 1231 cmd *exec.Cmd 1232 // done is closed when the process has exited. At that point, childErr may be 1233 // read for the result. 1234 done chan struct{} 1235 childErr error 1236 listener *shimListener 1237 stdout, stderr bytes.Buffer 1238} 1239 1240// newShimProcess starts a new shim with the specified executable, flags, and 1241// environment. It internally creates a TCP listener and adds the the -port 1242// flag. 1243func newShimProcess(dispatcher *shimDispatcher, shimPath string, flags []string, env []string) (*shimProcess, error) { 1244 listener, err := dispatcher.NewShim() 1245 if err != nil { 1246 return nil, err 1247 } 1248 1249 shim := &shimProcess{listener: listener} 1250 cmdFlags := []string{ 1251 "-port", strconv.Itoa(listener.Port()), 1252 "-shim-id", strconv.FormatUint(listener.ShimID(), 10), 1253 } 1254 if listener.IsIPv6() { 1255 cmdFlags = append(cmdFlags, "-ipv6") 1256 } 1257 cmdFlags = append(cmdFlags, flags...) 1258 1259 if *useValgrind { 1260 shim.cmd = valgrindOf(false, shimPath, cmdFlags...) 1261 } else if *useGDB { 1262 shim.cmd = gdbOf(shimPath, cmdFlags...) 1263 } else if *useLLDB { 1264 shim.cmd = lldbOf(shimPath, cmdFlags...) 1265 } else if *useRR { 1266 shim.cmd = rrOf(shimPath, cmdFlags...) 1267 } else { 1268 shim.cmd = exec.Command(shimPath, cmdFlags...) 1269 } 1270 shim.cmd.Stdin = os.Stdin 1271 shim.cmd.Stdout = &shim.stdout 1272 shim.cmd.Stderr = &shim.stderr 1273 shim.cmd.Env = env 1274 1275 if err := shim.cmd.Start(); err != nil { 1276 shim.listener.Close() 1277 return nil, err 1278 } 1279 1280 shim.done = make(chan struct{}) 1281 go func() { 1282 shim.childErr = shim.cmd.Wait() 1283 shim.listener.Close() 1284 close(shim.done) 1285 }() 1286 return shim, nil 1287} 1288 1289// accept returns a new TCP connection with the shim process, or returns an 1290// error on timeout or shim exit. 1291func (s *shimProcess) accept() (net.Conn, error) { 1292 var deadline time.Time 1293 if !useDebugger() { 1294 deadline = time.Now().Add(*idleTimeout) 1295 } 1296 return s.listener.Accept(deadline) 1297} 1298 1299// wait finishes the test and waits for the shim process to exit. 1300func (s *shimProcess) wait() error { 1301 // Close the listener now. This is to avoid hangs if the shim tries to open 1302 // more connections than expected. 1303 s.listener.Close() 1304 1305 if !useDebugger() { 1306 waitTimeout := time.AfterFunc(*idleTimeout, func() { 1307 s.cmd.Process.Kill() 1308 }) 1309 defer waitTimeout.Stop() 1310 } 1311 1312 <-s.done 1313 return s.childErr 1314} 1315 1316// close releases resources associated with the shimProcess. This is safe to 1317// call before or after |wait|. 1318func (s *shimProcess) close() { 1319 s.listener.Close() 1320 s.cmd.Process.Kill() 1321} 1322 1323func doExchanges(test *testCase, shim *shimProcess, resumeCount int, transcripts *[][]byte) error { 1324 config := test.config 1325 if *deterministic { 1326 config.Rand = &deterministicRand{} 1327 } 1328 1329 conn, err := shim.accept() 1330 if err != nil { 1331 return err 1332 } 1333 err = doExchange(test, &config, conn, false /* not a resumption */, transcripts, 0) 1334 conn.Close() 1335 if err != nil { 1336 return err 1337 } 1338 1339 nextTicketKey := config.SessionTicketKey 1340 for i := 0; i < resumeCount; i++ { 1341 var resumeConfig Config 1342 if test.resumeConfig != nil { 1343 resumeConfig = *test.resumeConfig 1344 resumeConfig.Rand = config.Rand 1345 if resumeConfig.Credential == nil { 1346 resumeConfig.Credential = config.Credential 1347 } 1348 } else { 1349 resumeConfig = config 1350 } 1351 1352 if test.newSessionsOnResume { 1353 resumeConfig.ClientSessionCache = nil 1354 resumeConfig.ServerSessionCache = nil 1355 if _, err := resumeConfig.rand().Read(resumeConfig.SessionTicketKey[:]); err != nil { 1356 return err 1357 } 1358 } else { 1359 resumeConfig.ClientSessionCache = config.ClientSessionCache 1360 resumeConfig.ServerSessionCache = config.ServerSessionCache 1361 // Rotate the ticket keys between each connection, with each connection 1362 // encrypting with next connection's keys. This ensures that we test 1363 // the renewed sessions. 1364 resumeConfig.SessionTicketKey = nextTicketKey 1365 if _, err := resumeConfig.rand().Read(nextTicketKey[:]); err != nil { 1366 return err 1367 } 1368 resumeConfig.Bugs.EncryptSessionTicketKey = &nextTicketKey 1369 } 1370 1371 var connResume net.Conn 1372 connResume, err = shim.accept() 1373 if err != nil { 1374 return err 1375 } 1376 err = doExchange(test, &resumeConfig, connResume, true /* resumption */, transcripts, i+1) 1377 connResume.Close() 1378 if err != nil { 1379 return err 1380 } 1381 } 1382 1383 return nil 1384} 1385 1386func translateExpectedError(errorStr string) string { 1387 if translated, ok := shimConfig.ErrorMap[errorStr]; ok { 1388 return translated 1389 } 1390 1391 if *looseErrors { 1392 return "" 1393 } 1394 1395 return errorStr 1396} 1397 1398// shimInitialWrite is the data we expect from the shim when the 1399// -shim-writes-first flag is used. 1400const shimInitialWrite = "hello" 1401 1402func appendCredentialFlags(flags []string, cred *Credential, prefix string, newCredential bool) []string { 1403 if newCredential { 1404 switch cred.Type { 1405 case CredentialTypeX509: 1406 flags = append(flags, prefix+"-new-x509-credential") 1407 case CredentialTypeDelegated: 1408 flags = append(flags, prefix+"-new-delegated-credential") 1409 default: 1410 panic(fmt.Errorf("unknown credential type %d", cred.Type)) 1411 } 1412 } else if cred.Type != CredentialTypeX509 { 1413 panic("default credential must be X.509") 1414 } 1415 1416 if len(cred.ChainPath) != 0 { 1417 flags = append(flags, prefix+"-cert-file", cred.ChainPath) 1418 } 1419 if len(cred.KeyPath) != 0 { 1420 flags = append(flags, prefix+"-key-file", cred.KeyPath) 1421 } 1422 if len(cred.OCSPStaple) != 0 { 1423 flags = append(flags, prefix+"-ocsp-response", base64FlagValue(cred.OCSPStaple)) 1424 } 1425 if len(cred.SignedCertificateTimestampList) != 0 { 1426 flags = append(flags, prefix+"-signed-cert-timestamps", base64FlagValue(cred.SignedCertificateTimestampList)) 1427 } 1428 for _, sigAlg := range cred.SignatureAlgorithms { 1429 flags = append(flags, prefix+"-signing-prefs", strconv.Itoa(int(sigAlg))) 1430 } 1431 if len(cred.DelegatedCredential) != 0 { 1432 flags = append(flags, prefix+"-delegated-credential", base64FlagValue(cred.DelegatedCredential)) 1433 } 1434 return flags 1435} 1436 1437func runTest(dispatcher *shimDispatcher, statusChan chan statusMsg, test *testCase, shimPath string, mallocNumToFail int64) error { 1438 // Help debugging panics on the Go side. 1439 defer func() { 1440 if r := recover(); r != nil { 1441 fmt.Fprintf(os.Stderr, "Test '%s' panicked.\n", test.name) 1442 panic(r) 1443 } 1444 }() 1445 1446 var flags []string 1447 if len(*shimExtraFlags) > 0 { 1448 flags = strings.Split(*shimExtraFlags, ";") 1449 } 1450 if test.testType == serverTest { 1451 flags = append(flags, "-server") 1452 } 1453 1454 // Configure the default credential. 1455 shimCertificate := test.shimCertificate 1456 if shimCertificate == nil && len(test.shimCredentials) == 0 && test.testType == serverTest && len(test.config.PreSharedKey) == 0 { 1457 shimCertificate = &rsaCertificate 1458 } 1459 if shimCertificate != nil { 1460 var shimPrefix string 1461 if test.handshakerCertificate != nil { 1462 shimPrefix = "-on-shim" 1463 } 1464 flags = appendCredentialFlags(flags, shimCertificate, shimPrefix, false) 1465 } 1466 if test.handshakerCertificate != nil { 1467 flags = appendCredentialFlags(flags, test.handshakerCertificate, "-on-handshaker", false) 1468 } 1469 1470 // Configure any additional credentials. 1471 for _, cred := range test.shimCredentials { 1472 flags = appendCredentialFlags(flags, cred, "", true) 1473 } 1474 1475 if test.protocol == dtls { 1476 flags = append(flags, "-dtls") 1477 } else if test.protocol == quic { 1478 flags = append(flags, "-quic") 1479 if !test.skipTransportParamsConfig { 1480 test.config.QUICTransportParams = []byte{1, 2} 1481 test.config.QUICTransportParamsUseLegacyCodepoint = QUICUseCodepointStandard 1482 if test.resumeConfig != nil { 1483 test.resumeConfig.QUICTransportParams = []byte{1, 2} 1484 test.resumeConfig.QUICTransportParamsUseLegacyCodepoint = QUICUseCodepointStandard 1485 } 1486 test.expectations.quicTransportParams = []byte{3, 4} 1487 if test.resumeExpectations != nil { 1488 test.resumeExpectations.quicTransportParams = []byte{3, 4} 1489 } 1490 useCodepointFlag := "0" 1491 if test.config.QUICTransportParamsUseLegacyCodepoint == QUICUseCodepointLegacy { 1492 useCodepointFlag = "1" 1493 } 1494 flags = append(flags, 1495 "-quic-transport-params", 1496 base64FlagValue([]byte{3, 4}), 1497 "-expect-quic-transport-params", 1498 base64FlagValue([]byte{1, 2}), 1499 "-quic-use-legacy-codepoint", useCodepointFlag) 1500 } 1501 if !test.skipQUICALPNConfig { 1502 flags = append(flags, 1503 []string{ 1504 "-advertise-alpn", "\x03foo", 1505 "-select-alpn", "foo", 1506 "-expect-alpn", "foo", 1507 }...) 1508 test.config.NextProtos = []string{"foo"} 1509 if test.resumeConfig != nil { 1510 test.resumeConfig.NextProtos = []string{"foo"} 1511 } 1512 test.expectations.nextProto = "foo" 1513 test.expectations.nextProtoType = alpn 1514 if test.resumeExpectations != nil { 1515 test.resumeExpectations.nextProto = "foo" 1516 test.resumeExpectations.nextProtoType = alpn 1517 } 1518 } 1519 } 1520 1521 if test.earlyData { 1522 if !test.resumeSession { 1523 panic("earlyData set without resumeSession in " + test.name) 1524 } 1525 1526 resumeConfig := test.resumeConfig 1527 if resumeConfig == nil { 1528 resumeConfig = &test.config 1529 } 1530 if test.expectEarlyDataRejected { 1531 flags = append(flags, "-on-resume-expect-reject-early-data") 1532 } else { 1533 flags = append(flags, "-on-resume-expect-accept-early-data") 1534 } 1535 1536 if test.protocol == quic { 1537 // QUIC requires an early data context string. 1538 flags = append(flags, "-quic-early-data-context", "context") 1539 } 1540 1541 flags = append(flags, "-enable-early-data") 1542 if test.testType == clientTest { 1543 // Configure the runner with default maximum early data. 1544 flags = append(flags, "-expect-ticket-supports-early-data") 1545 if test.config.MaxEarlyDataSize == 0 { 1546 test.config.MaxEarlyDataSize = 16384 1547 } 1548 if resumeConfig.MaxEarlyDataSize == 0 { 1549 resumeConfig.MaxEarlyDataSize = 16384 1550 } 1551 1552 // Configure the shim to send some data in early data. 1553 flags = append(flags, "-on-resume-shim-writes-first") 1554 if resumeConfig.Bugs.ExpectEarlyData == nil { 1555 resumeConfig.Bugs.ExpectEarlyData = [][]byte{[]byte(shimInitialWrite)} 1556 } 1557 } else { 1558 // By default, send some early data and expect half-RTT data response. 1559 if resumeConfig.Bugs.SendEarlyData == nil { 1560 resumeConfig.Bugs.SendEarlyData = [][]byte{{1, 2, 3, 4}} 1561 } 1562 if resumeConfig.Bugs.ExpectHalfRTTData == nil { 1563 resumeConfig.Bugs.ExpectHalfRTTData = [][]byte{{254, 253, 252, 251}} 1564 } 1565 resumeConfig.Bugs.ExpectEarlyDataAccepted = !test.expectEarlyDataRejected 1566 } 1567 } 1568 1569 var resumeCount int 1570 if test.resumeSession { 1571 resumeCount++ 1572 if test.resumeRenewedSession { 1573 resumeCount++ 1574 } 1575 } 1576 1577 if resumeCount > 0 { 1578 flags = append(flags, "-resume-count", strconv.Itoa(resumeCount)) 1579 } 1580 1581 if test.shimWritesFirst { 1582 flags = append(flags, "-shim-writes-first") 1583 } 1584 1585 if test.readWithUnfinishedWrite { 1586 flags = append(flags, "-read-with-unfinished-write") 1587 } 1588 1589 if test.shimShutsDown { 1590 flags = append(flags, "-shim-shuts-down") 1591 } 1592 1593 if test.exportKeyingMaterial > 0 { 1594 flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial)) 1595 if test.useExportContext { 1596 flags = append(flags, "-use-export-context") 1597 } 1598 } 1599 if test.exportKeyingMaterial > 0 { 1600 flags = append(flags, "-export-label", test.exportLabel) 1601 flags = append(flags, "-export-context", test.exportContext) 1602 } 1603 1604 if test.exportTrafficSecrets { 1605 flags = append(flags, "-export-traffic-secrets") 1606 } 1607 1608 if test.expectResumeRejected { 1609 flags = append(flags, "-expect-session-miss") 1610 } 1611 1612 if test.testTLSUnique { 1613 flags = append(flags, "-tls-unique") 1614 } 1615 1616 if *waitForDebugger { 1617 flags = append(flags, "-wait-for-debugger") 1618 } 1619 1620 var transcriptPrefix string 1621 var transcripts [][]byte 1622 if len(*transcriptDir) != 0 { 1623 protocol := "tls" 1624 if test.protocol == dtls { 1625 protocol = "dtls" 1626 } else if test.protocol == quic { 1627 protocol = "quic" 1628 } 1629 1630 side := "client" 1631 if test.testType == serverTest { 1632 side = "server" 1633 } 1634 1635 dir := filepath.Join(*transcriptDir, protocol, side) 1636 if err := os.MkdirAll(dir, 0755); err != nil { 1637 return err 1638 } 1639 transcriptPrefix = filepath.Join(dir, test.name+"-") 1640 flags = append(flags, "-write-settings", transcriptPrefix) 1641 } 1642 1643 if test.testType == clientTest && test.config.Credential == nil { 1644 test.config.Credential = &rsaCertificate 1645 } 1646 if test.config.Credential != nil { 1647 flags = append(flags, "-trust-cert", test.config.Credential.RootPath) 1648 } 1649 1650 flags = append(flags, test.flags...) 1651 1652 var env []string 1653 if mallocNumToFail >= 0 { 1654 env = os.Environ() 1655 env = append(env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10)) 1656 if *mallocTestDebug { 1657 env = append(env, "MALLOC_BREAK_ON_FAIL=1") 1658 } 1659 env = append(env, "_MALLOC_CHECK=1") 1660 } 1661 1662 shim, err := newShimProcess(dispatcher, shimPath, flags, env) 1663 if err != nil { 1664 return err 1665 } 1666 statusChan <- statusMsg{test: test, statusType: statusShimStarted, pid: shim.cmd.Process.Pid} 1667 defer shim.close() 1668 1669 localErr := doExchanges(test, shim, resumeCount, &transcripts) 1670 childErr := shim.wait() 1671 1672 // Now that the shim has exited, all the settings files have been 1673 // written. Append the saved transcripts. 1674 for i, transcript := range transcripts { 1675 if err := appendTranscript(transcriptPrefix+strconv.Itoa(i), transcript); err != nil { 1676 return err 1677 } 1678 } 1679 1680 var isValgrindError, mustFail bool 1681 if exitError, ok := childErr.(*exec.ExitError); ok { 1682 switch exitError.Sys().(syscall.WaitStatus).ExitStatus() { 1683 case 88: 1684 return errMoreMallocs 1685 case 89: 1686 return errUnimplemented 1687 case 90: 1688 mustFail = true 1689 case 99: 1690 isValgrindError = true 1691 } 1692 } 1693 1694 // Account for Windows line endings. 1695 stdout := strings.Replace(shim.stdout.String(), "\r\n", "\n", -1) 1696 stderr := strings.Replace(shim.stderr.String(), "\r\n", "\n", -1) 1697 1698 // Work around an NDK / Android bug. The NDK r16 sometimes generates 1699 // binaries with the DF_1_PIE, which the runtime linker on Android N 1700 // complains about. The next NDK revision should work around this but, 1701 // in the meantime, strip its error out. 1702 // 1703 // https://github.com/android-ndk/ndk/issues/602 1704 // https://android-review.googlesource.com/c/platform/bionic/+/259790 1705 // https://android-review.googlesource.com/c/toolchain/binutils/+/571550 1706 // 1707 // Remove this after switching to the r17 NDK. 1708 stderr = removeFirstLineIfSuffix(stderr, ": unsupported flags DT_FLAGS_1=0x8000001") 1709 1710 // Separate the errors from the shim and those from tools like 1711 // AddressSanitizer. 1712 var extraStderr string 1713 if stderrParts := strings.SplitN(stderr, "--- DONE ---\n", 2); len(stderrParts) == 2 { 1714 stderr = stderrParts[0] 1715 extraStderr = stderrParts[1] 1716 } 1717 1718 failed := localErr != nil || childErr != nil 1719 expectedError := translateExpectedError(test.expectedError) 1720 correctFailure := len(expectedError) == 0 || strings.Contains(stderr, expectedError) 1721 1722 localErrString := "none" 1723 if localErr != nil { 1724 localErrString = localErr.Error() 1725 } 1726 if len(test.expectedLocalError) != 0 { 1727 correctFailure = correctFailure && strings.Contains(localErrString, test.expectedLocalError) 1728 } 1729 1730 if failed != test.shouldFail || failed && !correctFailure || mustFail { 1731 childErrString := "none" 1732 if childErr != nil { 1733 childErrString = childErr.Error() 1734 } 1735 1736 var msg string 1737 switch { 1738 case failed && !test.shouldFail: 1739 msg = "unexpected failure" 1740 case !failed && test.shouldFail: 1741 msg = fmt.Sprintf("unexpected success (wanted failure with %q / %q)", expectedError, test.expectedLocalError) 1742 case failed && !correctFailure: 1743 msg = fmt.Sprintf("bad error (wanted %q / %q)", expectedError, test.expectedLocalError) 1744 case mustFail: 1745 msg = "test failure" 1746 default: 1747 panic("internal error") 1748 } 1749 1750 return fmt.Errorf("%s: local error %q, child error %q, stdout:\n%s\nstderr:\n%s\n%s", msg, localErrString, childErrString, stdout, stderr, extraStderr) 1751 } 1752 1753 if len(extraStderr) > 0 || (!failed && len(stderr) > 0) { 1754 return fmt.Errorf("unexpected error output:\n%s\n%s", stderr, extraStderr) 1755 } 1756 1757 if *useValgrind && isValgrindError { 1758 return fmt.Errorf("valgrind error:\n%s\n%s", stderr, extraStderr) 1759 } 1760 1761 return nil 1762} 1763 1764type tlsVersion struct { 1765 name string 1766 // version is the protocol version. 1767 version uint16 1768 // excludeFlag is the legacy shim flag to disable the version. 1769 excludeFlag string 1770 hasDTLS bool 1771 hasQUIC bool 1772 // versionDTLS, if non-zero, is the DTLS-specific representation of the version. 1773 versionDTLS uint16 1774 // versionWire, if non-zero, is the wire representation of the 1775 // version. Otherwise the wire version is the protocol version or 1776 // versionDTLS. 1777 versionWire uint16 1778} 1779 1780func (vers tlsVersion) String() string { 1781 return vers.name 1782} 1783 1784func (vers tlsVersion) shimFlag(protocol protocol) string { 1785 // The shim uses the protocol version in its public API, but uses the 1786 // DTLS-specific version if it exists. 1787 if protocol == dtls && vers.versionDTLS != 0 { 1788 return strconv.Itoa(int(vers.versionDTLS)) 1789 } 1790 return strconv.Itoa(int(vers.version)) 1791} 1792 1793func (vers tlsVersion) wire(protocol protocol) uint16 { 1794 if protocol == dtls && vers.versionDTLS != 0 { 1795 return vers.versionDTLS 1796 } 1797 if vers.versionWire != 0 { 1798 return vers.versionWire 1799 } 1800 return vers.version 1801} 1802 1803func (vers tlsVersion) supportsProtocol(protocol protocol) bool { 1804 if protocol == dtls { 1805 return vers.hasDTLS 1806 } 1807 if protocol == quic { 1808 return vers.hasQUIC 1809 } 1810 return true 1811} 1812 1813var tlsVersions = []tlsVersion{ 1814 { 1815 name: "TLS1", 1816 version: VersionTLS10, 1817 excludeFlag: "-no-tls1", 1818 hasDTLS: true, 1819 versionDTLS: VersionDTLS10, 1820 }, 1821 { 1822 name: "TLS11", 1823 version: VersionTLS11, 1824 excludeFlag: "-no-tls11", 1825 }, 1826 { 1827 name: "TLS12", 1828 version: VersionTLS12, 1829 excludeFlag: "-no-tls12", 1830 hasDTLS: true, 1831 versionDTLS: VersionDTLS12, 1832 }, 1833 { 1834 name: "TLS13", 1835 version: VersionTLS13, 1836 excludeFlag: "-no-tls13", 1837 hasQUIC: true, 1838 versionWire: VersionTLS13, 1839 }, 1840} 1841 1842func allVersions(protocol protocol) []tlsVersion { 1843 if protocol == tls { 1844 return tlsVersions 1845 } 1846 1847 var ret []tlsVersion 1848 for _, vers := range tlsVersions { 1849 if vers.supportsProtocol(protocol) { 1850 ret = append(ret, vers) 1851 } 1852 } 1853 return ret 1854} 1855 1856type testCipherSuite struct { 1857 name string 1858 id uint16 1859} 1860 1861var testCipherSuites = []testCipherSuite{ 1862 {"RSA_WITH_3DES_EDE_CBC_SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 1863 {"RSA_WITH_AES_128_GCM_SHA256", TLS_RSA_WITH_AES_128_GCM_SHA256}, 1864 {"RSA_WITH_AES_128_CBC_SHA", TLS_RSA_WITH_AES_128_CBC_SHA}, 1865 {"RSA_WITH_AES_256_GCM_SHA384", TLS_RSA_WITH_AES_256_GCM_SHA384}, 1866 {"RSA_WITH_AES_256_CBC_SHA", TLS_RSA_WITH_AES_256_CBC_SHA}, 1867 {"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 1868 {"ECDHE_ECDSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA}, 1869 {"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}, 1870 {"ECDHE_ECDSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}, 1871 {"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256}, 1872 {"ECDHE_RSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 1873 {"ECDHE_RSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 1874 {"ECDHE_RSA_WITH_AES_128_CBC_SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256}, 1875 {"ECDHE_RSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, 1876 {"ECDHE_RSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, 1877 {"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 1878 {"PSK_WITH_AES_128_CBC_SHA", TLS_PSK_WITH_AES_128_CBC_SHA}, 1879 {"PSK_WITH_AES_256_CBC_SHA", TLS_PSK_WITH_AES_256_CBC_SHA}, 1880 {"ECDHE_PSK_WITH_AES_128_CBC_SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 1881 {"ECDHE_PSK_WITH_AES_256_CBC_SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA}, 1882 {"ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256}, 1883 {"CHACHA20_POLY1305_SHA256", TLS_CHACHA20_POLY1305_SHA256}, 1884 {"AES_128_GCM_SHA256", TLS_AES_128_GCM_SHA256}, 1885 {"AES_256_GCM_SHA384", TLS_AES_256_GCM_SHA384}, 1886} 1887 1888func hasComponent(suiteName, component string) bool { 1889 return strings.Contains("_"+suiteName+"_", "_"+component+"_") 1890} 1891 1892func isTLS12Only(suiteName string) bool { 1893 return hasComponent(suiteName, "GCM") || 1894 hasComponent(suiteName, "SHA256") || 1895 hasComponent(suiteName, "SHA384") || 1896 hasComponent(suiteName, "POLY1305") 1897} 1898 1899func isTLS13Suite(suiteName string) bool { 1900 return !hasComponent(suiteName, "WITH") 1901} 1902 1903func bigFromHex(hex string) *big.Int { 1904 ret, ok := new(big.Int).SetString(hex, 16) 1905 if !ok { 1906 panic("failed to parse hex number 0x" + hex) 1907 } 1908 return ret 1909} 1910 1911func convertToSplitHandshakeTests(tests []testCase) (splitHandshakeTests []testCase, err error) { 1912 var stdout bytes.Buffer 1913 var flags []string 1914 if len(*shimExtraFlags) > 0 { 1915 flags = strings.Split(*shimExtraFlags, ";") 1916 } 1917 flags = append(flags, "-is-handshaker-supported") 1918 shim := exec.Command(*shimPath, flags...) 1919 shim.Stdout = &stdout 1920 if err := shim.Run(); err != nil { 1921 return nil, err 1922 } 1923 1924 switch strings.TrimSpace(string(stdout.Bytes())) { 1925 case "No": 1926 return 1927 case "Yes": 1928 break 1929 default: 1930 return nil, fmt.Errorf("unknown output from shim: %q", stdout.Bytes()) 1931 } 1932 1933 var allowHintMismatchPattern []string 1934 if len(*allowHintMismatch) > 0 { 1935 allowHintMismatchPattern = strings.Split(*allowHintMismatch, ";") 1936 } 1937 1938NextTest: 1939 for _, test := range tests { 1940 if test.protocol != tls || 1941 test.testType != serverTest || 1942 len(test.shimCredentials) != 0 || 1943 strings.Contains(test.name, "ECH-Server") || 1944 test.skipSplitHandshake { 1945 continue 1946 } 1947 1948 for _, flag := range test.flags { 1949 if flag == "-implicit-handshake" { 1950 continue NextTest 1951 } 1952 } 1953 1954 shTest := test 1955 shTest.name += "-Split" 1956 shTest.flags = make([]string, len(test.flags), len(test.flags)+3) 1957 copy(shTest.flags, test.flags) 1958 shTest.flags = append(shTest.flags, "-handoff", "-handshaker-path", *handshakerPath) 1959 1960 splitHandshakeTests = append(splitHandshakeTests, shTest) 1961 } 1962 1963 for _, test := range tests { 1964 if test.protocol == dtls || 1965 test.testType != serverTest || 1966 test.skipHints { 1967 continue 1968 } 1969 1970 var matched bool 1971 if len(allowHintMismatchPattern) > 0 { 1972 matched, err = match(allowHintMismatchPattern, nil, test.name) 1973 if err != nil { 1974 return nil, fmt.Errorf("error matching pattern: %s", err) 1975 } 1976 } 1977 1978 shTest := test 1979 shTest.name += "-Hints" 1980 shTest.flags = make([]string, len(test.flags), len(test.flags)+3) 1981 copy(shTest.flags, test.flags) 1982 shTest.flags = append(shTest.flags, "-handshake-hints", "-handshaker-path", *handshakerPath) 1983 if matched { 1984 shTest.flags = append(shTest.flags, "-allow-hint-mismatch") 1985 } 1986 1987 splitHandshakeTests = append(splitHandshakeTests, shTest) 1988 } 1989 1990 return splitHandshakeTests, nil 1991} 1992 1993func addBasicTests() { 1994 basicTests := []testCase{ 1995 { 1996 name: "NoFallbackSCSV", 1997 config: Config{ 1998 Bugs: ProtocolBugs{ 1999 FailIfNotFallbackSCSV: true, 2000 }, 2001 }, 2002 shouldFail: true, 2003 expectedLocalError: "no fallback SCSV found", 2004 }, 2005 { 2006 name: "SendFallbackSCSV", 2007 config: Config{ 2008 Bugs: ProtocolBugs{ 2009 FailIfNotFallbackSCSV: true, 2010 }, 2011 }, 2012 flags: []string{"-fallback-scsv"}, 2013 }, 2014 { 2015 name: "ClientCertificateTypes", 2016 config: Config{ 2017 MaxVersion: VersionTLS12, 2018 ClientAuth: RequestClientCert, 2019 ClientCertificateTypes: []byte{ 2020 CertTypeDSSSign, 2021 CertTypeRSASign, 2022 CertTypeECDSASign, 2023 }, 2024 }, 2025 flags: []string{ 2026 "-expect-certificate-types", 2027 base64FlagValue([]byte{ 2028 CertTypeDSSSign, 2029 CertTypeRSASign, 2030 CertTypeECDSASign, 2031 }), 2032 }, 2033 }, 2034 { 2035 name: "CheckClientCertificateTypes", 2036 config: Config{ 2037 MaxVersion: VersionTLS12, 2038 ClientAuth: RequestClientCert, 2039 ClientCertificateTypes: []byte{CertTypeECDSASign}, 2040 }, 2041 shimCertificate: &rsaCertificate, 2042 shouldFail: true, 2043 expectedError: ":UNKNOWN_CERTIFICATE_TYPE:", 2044 }, 2045 { 2046 name: "NoCheckClientCertificateTypes", 2047 config: Config{ 2048 MaxVersion: VersionTLS12, 2049 ClientAuth: RequestClientCert, 2050 ClientCertificateTypes: []byte{CertTypeECDSASign}, 2051 }, 2052 shimCertificate: &rsaCertificate, 2053 flags: []string{"-no-check-client-certificate-type"}, 2054 }, 2055 { 2056 name: "UnauthenticatedECDH", 2057 config: Config{ 2058 MaxVersion: VersionTLS12, 2059 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2060 Bugs: ProtocolBugs{ 2061 UnauthenticatedECDH: true, 2062 }, 2063 }, 2064 shouldFail: true, 2065 expectedError: ":UNEXPECTED_MESSAGE:", 2066 }, 2067 { 2068 name: "SkipCertificateStatus", 2069 config: Config{ 2070 MaxVersion: VersionTLS12, 2071 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 2072 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2073 Bugs: ProtocolBugs{ 2074 SkipCertificateStatus: true, 2075 }, 2076 }, 2077 flags: []string{ 2078 "-enable-ocsp-stapling", 2079 // This test involves an optional message. Test the message callback 2080 // trace to ensure we do not miss or double-report any. 2081 "-expect-msg-callback", 2082 `write hs 1 2083read hs 2 2084read hs 11 2085read hs 12 2086read hs 14 2087write hs 16 2088write ccs 2089write hs 20 2090read hs 4 2091read ccs 2092read hs 20 2093read alert 1 0 2094`, 2095 }, 2096 }, 2097 { 2098 protocol: dtls, 2099 name: "SkipCertificateStatus-DTLS", 2100 config: Config{ 2101 MaxVersion: VersionTLS12, 2102 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 2103 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2104 Bugs: ProtocolBugs{ 2105 SkipCertificateStatus: true, 2106 }, 2107 }, 2108 flags: []string{ 2109 "-enable-ocsp-stapling", 2110 // This test involves an optional message. Test the message callback 2111 // trace to ensure we do not miss or double-report any. 2112 "-expect-msg-callback", 2113 `write hs 1 2114read hs 3 2115write hs 1 2116read hs 2 2117read hs 11 2118read hs 12 2119read hs 14 2120write hs 16 2121write ccs 2122write hs 20 2123read hs 4 2124read ccs 2125read hs 20 2126read alert 1 0 2127`, 2128 }, 2129 }, 2130 { 2131 name: "SkipServerKeyExchange", 2132 config: Config{ 2133 MaxVersion: VersionTLS12, 2134 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2135 Bugs: ProtocolBugs{ 2136 SkipServerKeyExchange: true, 2137 }, 2138 }, 2139 shouldFail: true, 2140 expectedError: ":UNEXPECTED_MESSAGE:", 2141 }, 2142 { 2143 testType: serverTest, 2144 name: "ServerSkipCertificateVerify", 2145 config: Config{ 2146 MaxVersion: VersionTLS12, 2147 Credential: &rsaCertificate, 2148 Bugs: ProtocolBugs{ 2149 SkipCertificateVerify: true, 2150 }, 2151 }, 2152 expectations: connectionExpectations{ 2153 peerCertificate: &rsaCertificate, 2154 }, 2155 flags: []string{ 2156 "-require-any-client-certificate", 2157 }, 2158 shouldFail: true, 2159 expectedError: ":UNEXPECTED_RECORD:", 2160 expectedLocalError: "remote error: unexpected message", 2161 }, 2162 { 2163 testType: serverTest, 2164 name: "Alert", 2165 config: Config{ 2166 Bugs: ProtocolBugs{ 2167 SendSpuriousAlert: alertRecordOverflow, 2168 }, 2169 }, 2170 shouldFail: true, 2171 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2172 }, 2173 { 2174 protocol: dtls, 2175 testType: serverTest, 2176 name: "Alert-DTLS", 2177 config: Config{ 2178 Bugs: ProtocolBugs{ 2179 SendSpuriousAlert: alertRecordOverflow, 2180 }, 2181 }, 2182 shouldFail: true, 2183 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2184 }, 2185 { 2186 testType: serverTest, 2187 name: "FragmentAlert", 2188 config: Config{ 2189 Bugs: ProtocolBugs{ 2190 FragmentAlert: true, 2191 SendSpuriousAlert: alertRecordOverflow, 2192 }, 2193 }, 2194 shouldFail: true, 2195 expectedError: ":BAD_ALERT:", 2196 }, 2197 { 2198 protocol: dtls, 2199 testType: serverTest, 2200 name: "FragmentAlert-DTLS", 2201 config: Config{ 2202 Bugs: ProtocolBugs{ 2203 FragmentAlert: true, 2204 SendSpuriousAlert: alertRecordOverflow, 2205 }, 2206 }, 2207 shouldFail: true, 2208 expectedError: ":BAD_ALERT:", 2209 }, 2210 { 2211 testType: serverTest, 2212 name: "DoubleAlert", 2213 config: Config{ 2214 Bugs: ProtocolBugs{ 2215 DoubleAlert: true, 2216 SendSpuriousAlert: alertRecordOverflow, 2217 }, 2218 }, 2219 shouldFail: true, 2220 expectedError: ":BAD_ALERT:", 2221 }, 2222 { 2223 protocol: dtls, 2224 testType: serverTest, 2225 name: "DoubleAlert-DTLS", 2226 config: Config{ 2227 Bugs: ProtocolBugs{ 2228 DoubleAlert: true, 2229 SendSpuriousAlert: alertRecordOverflow, 2230 }, 2231 }, 2232 shouldFail: true, 2233 expectedError: ":BAD_ALERT:", 2234 }, 2235 { 2236 name: "SkipNewSessionTicket", 2237 config: Config{ 2238 MaxVersion: VersionTLS12, 2239 Bugs: ProtocolBugs{ 2240 SkipNewSessionTicket: true, 2241 }, 2242 }, 2243 shouldFail: true, 2244 expectedError: ":UNEXPECTED_RECORD:", 2245 }, 2246 { 2247 testType: serverTest, 2248 name: "FallbackSCSV", 2249 config: Config{ 2250 MaxVersion: VersionTLS11, 2251 Bugs: ProtocolBugs{ 2252 SendFallbackSCSV: true, 2253 }, 2254 }, 2255 shouldFail: true, 2256 expectedError: ":INAPPROPRIATE_FALLBACK:", 2257 expectedLocalError: "remote error: inappropriate fallback", 2258 }, 2259 { 2260 testType: serverTest, 2261 name: "FallbackSCSV-VersionMatch-TLS13", 2262 config: Config{ 2263 MaxVersion: VersionTLS13, 2264 Bugs: ProtocolBugs{ 2265 SendFallbackSCSV: true, 2266 }, 2267 }, 2268 }, 2269 { 2270 testType: serverTest, 2271 name: "FallbackSCSV-VersionMatch-TLS12", 2272 config: Config{ 2273 MaxVersion: VersionTLS12, 2274 Bugs: ProtocolBugs{ 2275 SendFallbackSCSV: true, 2276 }, 2277 }, 2278 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 2279 }, 2280 { 2281 testType: serverTest, 2282 name: "FragmentedClientVersion", 2283 config: Config{ 2284 Bugs: ProtocolBugs{ 2285 MaxHandshakeRecordLength: 1, 2286 FragmentClientVersion: true, 2287 }, 2288 }, 2289 expectations: connectionExpectations{ 2290 version: VersionTLS13, 2291 }, 2292 }, 2293 { 2294 testType: serverTest, 2295 name: "HttpGET", 2296 sendPrefix: "GET / HTTP/1.0\n", 2297 shouldFail: true, 2298 expectedError: ":HTTP_REQUEST:", 2299 }, 2300 { 2301 testType: serverTest, 2302 name: "HttpPOST", 2303 sendPrefix: "POST / HTTP/1.0\n", 2304 shouldFail: true, 2305 expectedError: ":HTTP_REQUEST:", 2306 }, 2307 { 2308 testType: serverTest, 2309 name: "HttpHEAD", 2310 sendPrefix: "HEAD / HTTP/1.0\n", 2311 shouldFail: true, 2312 expectedError: ":HTTP_REQUEST:", 2313 }, 2314 { 2315 testType: serverTest, 2316 name: "HttpPUT", 2317 sendPrefix: "PUT / HTTP/1.0\n", 2318 shouldFail: true, 2319 expectedError: ":HTTP_REQUEST:", 2320 }, 2321 { 2322 testType: serverTest, 2323 name: "HttpCONNECT", 2324 sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n", 2325 shouldFail: true, 2326 expectedError: ":HTTPS_PROXY_REQUEST:", 2327 }, 2328 { 2329 testType: serverTest, 2330 name: "Garbage", 2331 sendPrefix: "blah", 2332 shouldFail: true, 2333 expectedError: ":WRONG_VERSION_NUMBER:", 2334 }, 2335 { 2336 name: "RSAEphemeralKey", 2337 config: Config{ 2338 MaxVersion: VersionTLS12, 2339 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 2340 Bugs: ProtocolBugs{ 2341 RSAEphemeralKey: true, 2342 }, 2343 }, 2344 shouldFail: true, 2345 expectedError: ":UNEXPECTED_MESSAGE:", 2346 }, 2347 { 2348 name: "DisableEverything", 2349 flags: []string{"-no-tls13", "-no-tls12", "-no-tls11", "-no-tls1"}, 2350 shouldFail: true, 2351 expectedError: ":NO_SUPPORTED_VERSIONS_ENABLED:", 2352 }, 2353 { 2354 protocol: dtls, 2355 name: "DisableEverything-DTLS", 2356 flags: []string{"-no-tls12", "-no-tls1"}, 2357 shouldFail: true, 2358 expectedError: ":NO_SUPPORTED_VERSIONS_ENABLED:", 2359 }, 2360 { 2361 protocol: dtls, 2362 testType: serverTest, 2363 name: "MTU", 2364 config: Config{ 2365 Bugs: ProtocolBugs{ 2366 MaxPacketLength: 256, 2367 }, 2368 }, 2369 flags: []string{"-mtu", "256"}, 2370 }, 2371 { 2372 protocol: dtls, 2373 testType: serverTest, 2374 name: "MTUExceeded", 2375 config: Config{ 2376 Bugs: ProtocolBugs{ 2377 MaxPacketLength: 255, 2378 }, 2379 }, 2380 flags: []string{"-mtu", "256"}, 2381 shouldFail: true, 2382 expectedLocalError: "dtls: exceeded maximum packet length", 2383 }, 2384 { 2385 name: "EmptyCertificateList", 2386 config: Config{ 2387 MaxVersion: VersionTLS12, 2388 Bugs: ProtocolBugs{ 2389 EmptyCertificateList: true, 2390 }, 2391 }, 2392 shouldFail: true, 2393 expectedError: ":DECODE_ERROR:", 2394 }, 2395 { 2396 name: "EmptyCertificateList-TLS13", 2397 config: Config{ 2398 MaxVersion: VersionTLS13, 2399 Bugs: ProtocolBugs{ 2400 EmptyCertificateList: true, 2401 }, 2402 }, 2403 shouldFail: true, 2404 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 2405 }, 2406 { 2407 name: "TLSFatalBadPackets", 2408 damageFirstWrite: true, 2409 shouldFail: true, 2410 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 2411 }, 2412 { 2413 protocol: dtls, 2414 name: "DTLSIgnoreBadPackets", 2415 damageFirstWrite: true, 2416 }, 2417 { 2418 protocol: dtls, 2419 name: "DTLSIgnoreBadPackets-Async", 2420 damageFirstWrite: true, 2421 flags: []string{"-async"}, 2422 }, 2423 { 2424 name: "AppDataBeforeHandshake", 2425 config: Config{ 2426 Bugs: ProtocolBugs{ 2427 AppDataBeforeHandshake: []byte("TEST MESSAGE"), 2428 }, 2429 }, 2430 shouldFail: true, 2431 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2432 }, 2433 { 2434 name: "AppDataBeforeHandshake-Empty", 2435 config: Config{ 2436 Bugs: ProtocolBugs{ 2437 AppDataBeforeHandshake: []byte{}, 2438 }, 2439 }, 2440 shouldFail: true, 2441 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2442 }, 2443 { 2444 protocol: dtls, 2445 name: "AppDataBeforeHandshake-DTLS", 2446 config: Config{ 2447 Bugs: ProtocolBugs{ 2448 AppDataBeforeHandshake: []byte("TEST MESSAGE"), 2449 }, 2450 }, 2451 shouldFail: true, 2452 expectedError: ":UNEXPECTED_RECORD:", 2453 }, 2454 { 2455 protocol: dtls, 2456 name: "AppDataBeforeHandshake-DTLS-Empty", 2457 config: Config{ 2458 Bugs: ProtocolBugs{ 2459 AppDataBeforeHandshake: []byte{}, 2460 }, 2461 }, 2462 shouldFail: true, 2463 expectedError: ":UNEXPECTED_RECORD:", 2464 }, 2465 { 2466 name: "AppDataAfterChangeCipherSpec", 2467 config: Config{ 2468 MaxVersion: VersionTLS12, 2469 Bugs: ProtocolBugs{ 2470 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"), 2471 }, 2472 }, 2473 shouldFail: true, 2474 expectedError: ":UNEXPECTED_RECORD:", 2475 }, 2476 { 2477 name: "AppDataAfterChangeCipherSpec-Empty", 2478 config: Config{ 2479 MaxVersion: VersionTLS12, 2480 Bugs: ProtocolBugs{ 2481 AppDataAfterChangeCipherSpec: []byte{}, 2482 }, 2483 }, 2484 shouldFail: true, 2485 expectedError: ":UNEXPECTED_RECORD:", 2486 }, 2487 { 2488 protocol: dtls, 2489 name: "AppDataAfterChangeCipherSpec-DTLS", 2490 config: Config{ 2491 MaxVersion: VersionTLS12, 2492 Bugs: ProtocolBugs{ 2493 AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"), 2494 }, 2495 }, 2496 // BoringSSL's DTLS implementation will drop the out-of-order 2497 // application data. 2498 }, 2499 { 2500 protocol: dtls, 2501 name: "AppDataAfterChangeCipherSpec-DTLS-Empty", 2502 config: Config{ 2503 MaxVersion: VersionTLS12, 2504 Bugs: ProtocolBugs{ 2505 AppDataAfterChangeCipherSpec: []byte{}, 2506 }, 2507 }, 2508 // BoringSSL's DTLS implementation will drop the out-of-order 2509 // application data. 2510 }, 2511 { 2512 name: "AlertAfterChangeCipherSpec", 2513 config: Config{ 2514 MaxVersion: VersionTLS12, 2515 Bugs: ProtocolBugs{ 2516 AlertAfterChangeCipherSpec: alertRecordOverflow, 2517 }, 2518 }, 2519 shouldFail: true, 2520 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2521 }, 2522 { 2523 protocol: dtls, 2524 name: "AlertAfterChangeCipherSpec-DTLS", 2525 config: Config{ 2526 MaxVersion: VersionTLS12, 2527 Bugs: ProtocolBugs{ 2528 AlertAfterChangeCipherSpec: alertRecordOverflow, 2529 }, 2530 }, 2531 shouldFail: true, 2532 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 2533 }, 2534 { 2535 protocol: dtls, 2536 name: "ReorderHandshakeFragments-Small-DTLS", 2537 config: Config{ 2538 Bugs: ProtocolBugs{ 2539 ReorderHandshakeFragments: true, 2540 // Small enough that every handshake message is 2541 // fragmented. 2542 MaxHandshakeRecordLength: 2, 2543 }, 2544 }, 2545 }, 2546 { 2547 protocol: dtls, 2548 name: "ReorderHandshakeFragments-Large-DTLS", 2549 config: Config{ 2550 Bugs: ProtocolBugs{ 2551 ReorderHandshakeFragments: true, 2552 // Large enough that no handshake message is 2553 // fragmented. 2554 MaxHandshakeRecordLength: 2048, 2555 }, 2556 }, 2557 }, 2558 { 2559 protocol: dtls, 2560 name: "MixCompleteMessageWithFragments-DTLS", 2561 config: Config{ 2562 Bugs: ProtocolBugs{ 2563 ReorderHandshakeFragments: true, 2564 MixCompleteMessageWithFragments: true, 2565 MaxHandshakeRecordLength: 2, 2566 }, 2567 }, 2568 }, 2569 { 2570 name: "SendInvalidRecordType", 2571 config: Config{ 2572 Bugs: ProtocolBugs{ 2573 SendInvalidRecordType: true, 2574 }, 2575 }, 2576 shouldFail: true, 2577 expectedError: ":UNEXPECTED_RECORD:", 2578 }, 2579 { 2580 protocol: dtls, 2581 name: "SendInvalidRecordType-DTLS", 2582 config: Config{ 2583 Bugs: ProtocolBugs{ 2584 SendInvalidRecordType: true, 2585 }, 2586 }, 2587 shouldFail: true, 2588 expectedError: ":UNEXPECTED_RECORD:", 2589 }, 2590 { 2591 name: "FalseStart-SkipServerSecondLeg", 2592 config: Config{ 2593 MaxVersion: VersionTLS12, 2594 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2595 NextProtos: []string{"foo"}, 2596 Bugs: ProtocolBugs{ 2597 SkipNewSessionTicket: true, 2598 SkipChangeCipherSpec: true, 2599 SkipFinished: true, 2600 ExpectFalseStart: true, 2601 }, 2602 }, 2603 flags: []string{ 2604 "-false-start", 2605 "-handshake-never-done", 2606 "-advertise-alpn", "\x03foo", 2607 "-expect-alpn", "foo", 2608 }, 2609 shimWritesFirst: true, 2610 shouldFail: true, 2611 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2612 }, 2613 { 2614 name: "FalseStart-SkipServerSecondLeg-Implicit", 2615 config: Config{ 2616 MaxVersion: VersionTLS12, 2617 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2618 NextProtos: []string{"foo"}, 2619 Bugs: ProtocolBugs{ 2620 SkipNewSessionTicket: true, 2621 SkipChangeCipherSpec: true, 2622 SkipFinished: true, 2623 }, 2624 }, 2625 flags: []string{ 2626 "-implicit-handshake", 2627 "-false-start", 2628 "-handshake-never-done", 2629 "-advertise-alpn", "\x03foo", 2630 }, 2631 shouldFail: true, 2632 expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:", 2633 }, 2634 { 2635 testType: serverTest, 2636 name: "FailEarlyCallback", 2637 flags: []string{"-fail-early-callback"}, 2638 shouldFail: true, 2639 expectedError: ":CONNECTION_REJECTED:", 2640 expectedLocalError: "remote error: handshake failure", 2641 }, 2642 { 2643 name: "FailCertCallback-Client-TLS12", 2644 config: Config{ 2645 MaxVersion: VersionTLS12, 2646 ClientAuth: RequestClientCert, 2647 }, 2648 flags: []string{"-fail-cert-callback"}, 2649 shouldFail: true, 2650 expectedError: ":CERT_CB_ERROR:", 2651 expectedLocalError: "remote error: internal error", 2652 }, 2653 { 2654 testType: serverTest, 2655 name: "FailCertCallback-Server-TLS12", 2656 config: Config{ 2657 MaxVersion: VersionTLS12, 2658 }, 2659 flags: []string{"-fail-cert-callback"}, 2660 shouldFail: true, 2661 expectedError: ":CERT_CB_ERROR:", 2662 expectedLocalError: "remote error: internal error", 2663 }, 2664 { 2665 name: "FailCertCallback-Client-TLS13", 2666 config: Config{ 2667 MaxVersion: VersionTLS13, 2668 ClientAuth: RequestClientCert, 2669 }, 2670 flags: []string{"-fail-cert-callback"}, 2671 shouldFail: true, 2672 expectedError: ":CERT_CB_ERROR:", 2673 expectedLocalError: "remote error: internal error", 2674 }, 2675 { 2676 testType: serverTest, 2677 name: "FailCertCallback-Server-TLS13", 2678 config: Config{ 2679 MaxVersion: VersionTLS13, 2680 }, 2681 flags: []string{"-fail-cert-callback"}, 2682 shouldFail: true, 2683 expectedError: ":CERT_CB_ERROR:", 2684 expectedLocalError: "remote error: internal error", 2685 }, 2686 { 2687 protocol: dtls, 2688 name: "FragmentMessageTypeMismatch-DTLS", 2689 config: Config{ 2690 Bugs: ProtocolBugs{ 2691 MaxHandshakeRecordLength: 2, 2692 FragmentMessageTypeMismatch: true, 2693 }, 2694 }, 2695 shouldFail: true, 2696 expectedError: ":FRAGMENT_MISMATCH:", 2697 }, 2698 { 2699 protocol: dtls, 2700 name: "FragmentMessageLengthMismatch-DTLS", 2701 config: Config{ 2702 Bugs: ProtocolBugs{ 2703 MaxHandshakeRecordLength: 2, 2704 FragmentMessageLengthMismatch: true, 2705 }, 2706 }, 2707 shouldFail: true, 2708 expectedError: ":FRAGMENT_MISMATCH:", 2709 }, 2710 { 2711 protocol: dtls, 2712 name: "SplitFragments-Header-DTLS", 2713 config: Config{ 2714 Bugs: ProtocolBugs{ 2715 SplitFragments: 2, 2716 }, 2717 }, 2718 shouldFail: true, 2719 expectedError: ":BAD_HANDSHAKE_RECORD:", 2720 }, 2721 { 2722 protocol: dtls, 2723 name: "SplitFragments-Boundary-DTLS", 2724 config: Config{ 2725 Bugs: ProtocolBugs{ 2726 SplitFragments: dtlsRecordHeaderLen, 2727 }, 2728 }, 2729 shouldFail: true, 2730 expectedError: ":BAD_HANDSHAKE_RECORD:", 2731 }, 2732 { 2733 protocol: dtls, 2734 name: "SplitFragments-Body-DTLS", 2735 config: Config{ 2736 Bugs: ProtocolBugs{ 2737 SplitFragments: dtlsRecordHeaderLen + 1, 2738 }, 2739 }, 2740 shouldFail: true, 2741 expectedError: ":BAD_HANDSHAKE_RECORD:", 2742 }, 2743 { 2744 protocol: dtls, 2745 name: "SendEmptyFragments-DTLS", 2746 config: Config{ 2747 Bugs: ProtocolBugs{ 2748 SendEmptyFragments: true, 2749 }, 2750 }, 2751 }, 2752 { 2753 testType: serverTest, 2754 protocol: dtls, 2755 name: "SendEmptyFragments-Padded-DTLS", 2756 config: Config{ 2757 Bugs: ProtocolBugs{ 2758 // Test empty fragments for a message with a 2759 // nice power-of-two length. 2760 PadClientHello: 64, 2761 SendEmptyFragments: true, 2762 }, 2763 }, 2764 }, 2765 { 2766 name: "BadFinished-Client", 2767 config: Config{ 2768 MaxVersion: VersionTLS12, 2769 Bugs: ProtocolBugs{ 2770 BadFinished: true, 2771 }, 2772 }, 2773 shouldFail: true, 2774 expectedError: ":DIGEST_CHECK_FAILED:", 2775 }, 2776 { 2777 name: "BadFinished-Client-TLS13", 2778 config: Config{ 2779 MaxVersion: VersionTLS13, 2780 Bugs: ProtocolBugs{ 2781 BadFinished: true, 2782 }, 2783 }, 2784 shouldFail: true, 2785 expectedError: ":DIGEST_CHECK_FAILED:", 2786 }, 2787 { 2788 testType: serverTest, 2789 name: "BadFinished-Server", 2790 config: Config{ 2791 MaxVersion: VersionTLS12, 2792 Bugs: ProtocolBugs{ 2793 BadFinished: true, 2794 }, 2795 }, 2796 shouldFail: true, 2797 expectedError: ":DIGEST_CHECK_FAILED:", 2798 }, 2799 { 2800 testType: serverTest, 2801 name: "BadFinished-Server-TLS13", 2802 config: Config{ 2803 MaxVersion: VersionTLS13, 2804 Bugs: ProtocolBugs{ 2805 BadFinished: true, 2806 }, 2807 }, 2808 shouldFail: true, 2809 expectedError: ":DIGEST_CHECK_FAILED:", 2810 }, 2811 { 2812 name: "FalseStart-BadFinished", 2813 config: Config{ 2814 MaxVersion: VersionTLS12, 2815 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2816 NextProtos: []string{"foo"}, 2817 Bugs: ProtocolBugs{ 2818 BadFinished: true, 2819 ExpectFalseStart: true, 2820 }, 2821 }, 2822 flags: []string{ 2823 "-false-start", 2824 "-handshake-never-done", 2825 "-advertise-alpn", "\x03foo", 2826 "-expect-alpn", "foo", 2827 }, 2828 shimWritesFirst: true, 2829 shouldFail: true, 2830 expectedError: ":DIGEST_CHECK_FAILED:", 2831 }, 2832 { 2833 name: "NoFalseStart-NoALPN", 2834 config: Config{ 2835 MaxVersion: VersionTLS12, 2836 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2837 Bugs: ProtocolBugs{ 2838 ExpectFalseStart: true, 2839 AlertBeforeFalseStartTest: alertAccessDenied, 2840 }, 2841 }, 2842 flags: []string{ 2843 "-false-start", 2844 }, 2845 shimWritesFirst: true, 2846 shouldFail: true, 2847 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 2848 expectedLocalError: "tls: peer did not false start: EOF", 2849 }, 2850 { 2851 name: "FalseStart-NoALPNAllowed", 2852 config: Config{ 2853 MaxVersion: VersionTLS12, 2854 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 2855 Bugs: ProtocolBugs{ 2856 ExpectFalseStart: true, 2857 }, 2858 }, 2859 flags: []string{ 2860 "-false-start", 2861 "-allow-false-start-without-alpn", 2862 }, 2863 shimWritesFirst: true, 2864 }, 2865 { 2866 name: "NoFalseStart-NoAEAD", 2867 config: Config{ 2868 MaxVersion: VersionTLS12, 2869 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 2870 NextProtos: []string{"foo"}, 2871 Bugs: ProtocolBugs{ 2872 ExpectFalseStart: true, 2873 AlertBeforeFalseStartTest: alertAccessDenied, 2874 }, 2875 }, 2876 flags: []string{ 2877 "-false-start", 2878 "-advertise-alpn", "\x03foo", 2879 }, 2880 shimWritesFirst: true, 2881 shouldFail: true, 2882 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 2883 expectedLocalError: "tls: peer did not false start: EOF", 2884 }, 2885 { 2886 name: "NoFalseStart-RSA", 2887 config: Config{ 2888 MaxVersion: VersionTLS12, 2889 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 2890 NextProtos: []string{"foo"}, 2891 Bugs: ProtocolBugs{ 2892 ExpectFalseStart: true, 2893 AlertBeforeFalseStartTest: alertAccessDenied, 2894 }, 2895 }, 2896 flags: []string{ 2897 "-false-start", 2898 "-advertise-alpn", "\x03foo", 2899 }, 2900 shimWritesFirst: true, 2901 shouldFail: true, 2902 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 2903 expectedLocalError: "tls: peer did not false start: EOF", 2904 }, 2905 { 2906 protocol: dtls, 2907 name: "SendSplitAlert-Sync", 2908 config: Config{ 2909 Bugs: ProtocolBugs{ 2910 SendSplitAlert: true, 2911 }, 2912 }, 2913 }, 2914 { 2915 protocol: dtls, 2916 name: "SendSplitAlert-Async", 2917 config: Config{ 2918 Bugs: ProtocolBugs{ 2919 SendSplitAlert: true, 2920 }, 2921 }, 2922 flags: []string{"-async"}, 2923 }, 2924 { 2925 name: "SendEmptyRecords-Pass", 2926 sendEmptyRecords: 32, 2927 }, 2928 { 2929 name: "SendEmptyRecords", 2930 sendEmptyRecords: 33, 2931 shouldFail: true, 2932 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 2933 }, 2934 { 2935 name: "SendEmptyRecords-Async", 2936 sendEmptyRecords: 33, 2937 flags: []string{"-async"}, 2938 shouldFail: true, 2939 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 2940 }, 2941 { 2942 name: "SendWarningAlerts-Pass", 2943 config: Config{ 2944 MaxVersion: VersionTLS12, 2945 }, 2946 sendWarningAlerts: 4, 2947 }, 2948 { 2949 protocol: dtls, 2950 name: "SendWarningAlerts-DTLS-Pass", 2951 config: Config{ 2952 MaxVersion: VersionTLS12, 2953 }, 2954 sendWarningAlerts: 4, 2955 }, 2956 { 2957 name: "SendWarningAlerts-TLS13", 2958 config: Config{ 2959 MaxVersion: VersionTLS13, 2960 }, 2961 sendWarningAlerts: 4, 2962 shouldFail: true, 2963 expectedError: ":BAD_ALERT:", 2964 expectedLocalError: "remote error: error decoding message", 2965 }, 2966 // Although TLS 1.3 intended to remove warning alerts, it left in 2967 // user_canceled. JDK11 misuses this alert as a post-handshake 2968 // full-duplex signal. As a workaround, skip user_canceled as in 2969 // TLS 1.2, which is consistent with NSS and OpenSSL. 2970 { 2971 name: "SendUserCanceledAlerts-TLS13", 2972 config: Config{ 2973 MaxVersion: VersionTLS13, 2974 }, 2975 sendUserCanceledAlerts: 4, 2976 }, 2977 { 2978 name: "SendUserCanceledAlerts-TooMany-TLS13", 2979 config: Config{ 2980 MaxVersion: VersionTLS13, 2981 }, 2982 sendUserCanceledAlerts: 5, 2983 shouldFail: true, 2984 expectedError: ":TOO_MANY_WARNING_ALERTS:", 2985 }, 2986 { 2987 name: "SendWarningAlerts-TooMany", 2988 config: Config{ 2989 MaxVersion: VersionTLS12, 2990 }, 2991 sendWarningAlerts: 5, 2992 shouldFail: true, 2993 expectedError: ":TOO_MANY_WARNING_ALERTS:", 2994 }, 2995 { 2996 name: "SendWarningAlerts-TooMany-Async", 2997 config: Config{ 2998 MaxVersion: VersionTLS12, 2999 }, 3000 sendWarningAlerts: 5, 3001 flags: []string{"-async"}, 3002 shouldFail: true, 3003 expectedError: ":TOO_MANY_WARNING_ALERTS:", 3004 }, 3005 { 3006 name: "SendBogusAlertType", 3007 sendBogusAlertType: true, 3008 shouldFail: true, 3009 expectedError: ":UNKNOWN_ALERT_TYPE:", 3010 expectedLocalError: "remote error: illegal parameter", 3011 }, 3012 { 3013 protocol: dtls, 3014 name: "SendBogusAlertType-DTLS", 3015 sendBogusAlertType: true, 3016 shouldFail: true, 3017 expectedError: ":UNKNOWN_ALERT_TYPE:", 3018 expectedLocalError: "remote error: illegal parameter", 3019 }, 3020 { 3021 name: "TooManyKeyUpdates", 3022 config: Config{ 3023 MaxVersion: VersionTLS13, 3024 }, 3025 sendKeyUpdates: 33, 3026 keyUpdateRequest: keyUpdateNotRequested, 3027 shouldFail: true, 3028 expectedError: ":TOO_MANY_KEY_UPDATES:", 3029 }, 3030 { 3031 name: "EmptySessionID", 3032 config: Config{ 3033 MaxVersion: VersionTLS12, 3034 SessionTicketsDisabled: true, 3035 }, 3036 noSessionCache: true, 3037 flags: []string{"-expect-no-session"}, 3038 }, 3039 { 3040 name: "Unclean-Shutdown", 3041 config: Config{ 3042 Bugs: ProtocolBugs{ 3043 NoCloseNotify: true, 3044 ExpectCloseNotify: true, 3045 }, 3046 }, 3047 shimShutsDown: true, 3048 flags: []string{"-check-close-notify"}, 3049 shouldFail: true, 3050 expectedError: "Unexpected SSL_shutdown result: -1 != 1", 3051 }, 3052 { 3053 name: "Unclean-Shutdown-Ignored", 3054 config: Config{ 3055 Bugs: ProtocolBugs{ 3056 NoCloseNotify: true, 3057 }, 3058 }, 3059 shimShutsDown: true, 3060 }, 3061 { 3062 name: "Unclean-Shutdown-Alert", 3063 config: Config{ 3064 Bugs: ProtocolBugs{ 3065 SendAlertOnShutdown: alertDecompressionFailure, 3066 ExpectCloseNotify: true, 3067 }, 3068 }, 3069 shimShutsDown: true, 3070 flags: []string{"-check-close-notify"}, 3071 shouldFail: true, 3072 expectedError: ":SSLV3_ALERT_DECOMPRESSION_FAILURE:", 3073 }, 3074 { 3075 name: "LargePlaintext", 3076 config: Config{ 3077 Bugs: ProtocolBugs{ 3078 SendLargeRecords: true, 3079 }, 3080 }, 3081 messageLen: maxPlaintext + 1, 3082 shouldFail: true, 3083 expectedError: ":DATA_LENGTH_TOO_LONG:", 3084 expectedLocalError: "remote error: record overflow", 3085 }, 3086 { 3087 protocol: dtls, 3088 name: "LargePlaintext-DTLS", 3089 config: Config{ 3090 Bugs: ProtocolBugs{ 3091 SendLargeRecords: true, 3092 }, 3093 }, 3094 messageLen: maxPlaintext + 1, 3095 shouldFail: true, 3096 expectedError: ":DATA_LENGTH_TOO_LONG:", 3097 expectedLocalError: "remote error: record overflow", 3098 }, 3099 { 3100 name: "LargePlaintext-TLS13-Padded-8192-8192", 3101 config: Config{ 3102 MinVersion: VersionTLS13, 3103 MaxVersion: VersionTLS13, 3104 Bugs: ProtocolBugs{ 3105 RecordPadding: 8192, 3106 SendLargeRecords: true, 3107 }, 3108 }, 3109 messageLen: 8192, 3110 }, 3111 { 3112 name: "LargePlaintext-TLS13-Padded-8193-8192", 3113 config: Config{ 3114 MinVersion: VersionTLS13, 3115 MaxVersion: VersionTLS13, 3116 Bugs: ProtocolBugs{ 3117 RecordPadding: 8193, 3118 SendLargeRecords: true, 3119 }, 3120 }, 3121 messageLen: 8192, 3122 shouldFail: true, 3123 expectedError: ":DATA_LENGTH_TOO_LONG:", 3124 expectedLocalError: "remote error: record overflow", 3125 }, 3126 { 3127 name: "LargePlaintext-TLS13-Padded-16383-1", 3128 config: Config{ 3129 MinVersion: VersionTLS13, 3130 MaxVersion: VersionTLS13, 3131 Bugs: ProtocolBugs{ 3132 RecordPadding: 1, 3133 SendLargeRecords: true, 3134 }, 3135 }, 3136 messageLen: 16383, 3137 }, 3138 { 3139 name: "LargePlaintext-TLS13-Padded-16384-1", 3140 config: Config{ 3141 MinVersion: VersionTLS13, 3142 MaxVersion: VersionTLS13, 3143 Bugs: ProtocolBugs{ 3144 RecordPadding: 1, 3145 SendLargeRecords: true, 3146 }, 3147 }, 3148 messageLen: 16384, 3149 shouldFail: true, 3150 expectedError: ":DATA_LENGTH_TOO_LONG:", 3151 expectedLocalError: "remote error: record overflow", 3152 }, 3153 { 3154 name: "LargeCiphertext", 3155 config: Config{ 3156 Bugs: ProtocolBugs{ 3157 SendLargeRecords: true, 3158 }, 3159 }, 3160 messageLen: maxPlaintext * 2, 3161 shouldFail: true, 3162 expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:", 3163 }, 3164 { 3165 protocol: dtls, 3166 name: "LargeCiphertext-DTLS", 3167 config: Config{ 3168 Bugs: ProtocolBugs{ 3169 SendLargeRecords: true, 3170 }, 3171 }, 3172 messageLen: maxPlaintext * 2, 3173 // Unlike the other four cases, DTLS drops records which 3174 // are invalid before authentication, so the connection 3175 // does not fail. 3176 expectMessageDropped: true, 3177 }, 3178 { 3179 name: "BadHelloRequest-1", 3180 renegotiate: 1, 3181 config: Config{ 3182 MaxVersion: VersionTLS12, 3183 Bugs: ProtocolBugs{ 3184 BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1}, 3185 }, 3186 }, 3187 flags: []string{ 3188 "-renegotiate-freely", 3189 "-expect-total-renegotiations", "1", 3190 }, 3191 shouldFail: true, 3192 expectedError: ":BAD_HELLO_REQUEST:", 3193 }, 3194 { 3195 name: "BadHelloRequest-2", 3196 renegotiate: 1, 3197 config: Config{ 3198 MaxVersion: VersionTLS12, 3199 Bugs: ProtocolBugs{ 3200 BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0}, 3201 }, 3202 }, 3203 flags: []string{ 3204 "-renegotiate-freely", 3205 "-expect-total-renegotiations", "1", 3206 }, 3207 shouldFail: true, 3208 expectedError: ":BAD_HELLO_REQUEST:", 3209 }, 3210 { 3211 testType: serverTest, 3212 name: "SupportTicketsWithSessionID", 3213 config: Config{ 3214 MaxVersion: VersionTLS12, 3215 SessionTicketsDisabled: true, 3216 }, 3217 resumeConfig: &Config{ 3218 MaxVersion: VersionTLS12, 3219 }, 3220 resumeSession: true, 3221 }, 3222 { 3223 protocol: dtls, 3224 name: "DTLS-SendExtraFinished", 3225 config: Config{ 3226 Bugs: ProtocolBugs{ 3227 SendExtraFinished: true, 3228 }, 3229 }, 3230 shouldFail: true, 3231 expectedError: ":UNEXPECTED_RECORD:", 3232 }, 3233 { 3234 protocol: dtls, 3235 name: "DTLS-SendExtraFinished-Reordered", 3236 config: Config{ 3237 Bugs: ProtocolBugs{ 3238 MaxHandshakeRecordLength: 2, 3239 ReorderHandshakeFragments: true, 3240 SendExtraFinished: true, 3241 }, 3242 }, 3243 shouldFail: true, 3244 expectedError: ":UNEXPECTED_RECORD:", 3245 }, 3246 { 3247 testType: serverTest, 3248 name: "V2ClientHello-EmptyRecordPrefix", 3249 config: Config{ 3250 // Choose a cipher suite that does not involve 3251 // elliptic curves, so no extensions are 3252 // involved. 3253 MaxVersion: VersionTLS12, 3254 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 3255 Bugs: ProtocolBugs{ 3256 SendV2ClientHello: true, 3257 }, 3258 }, 3259 sendPrefix: string([]byte{ 3260 byte(recordTypeHandshake), 3261 3, 1, // version 3262 0, 0, // length 3263 }), 3264 // A no-op empty record may not be sent before V2ClientHello. 3265 shouldFail: true, 3266 expectedError: ":WRONG_VERSION_NUMBER:", 3267 }, 3268 { 3269 testType: serverTest, 3270 name: "V2ClientHello-WarningAlertPrefix", 3271 config: Config{ 3272 // Choose a cipher suite that does not involve 3273 // elliptic curves, so no extensions are 3274 // involved. 3275 MaxVersion: VersionTLS12, 3276 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 3277 Bugs: ProtocolBugs{ 3278 SendV2ClientHello: true, 3279 }, 3280 }, 3281 sendPrefix: string([]byte{ 3282 byte(recordTypeAlert), 3283 3, 1, // version 3284 0, 2, // length 3285 alertLevelWarning, byte(alertDecompressionFailure), 3286 }), 3287 // A no-op warning alert may not be sent before V2ClientHello. 3288 shouldFail: true, 3289 expectedError: ":WRONG_VERSION_NUMBER:", 3290 }, 3291 { 3292 name: "KeyUpdate-ToClient", 3293 config: Config{ 3294 MaxVersion: VersionTLS13, 3295 }, 3296 sendKeyUpdates: 1, 3297 keyUpdateRequest: keyUpdateNotRequested, 3298 }, 3299 { 3300 testType: serverTest, 3301 name: "KeyUpdate-ToServer", 3302 config: Config{ 3303 MaxVersion: VersionTLS13, 3304 }, 3305 sendKeyUpdates: 1, 3306 keyUpdateRequest: keyUpdateNotRequested, 3307 }, 3308 { 3309 name: "KeyUpdate-FromClient", 3310 config: Config{ 3311 MaxVersion: VersionTLS13, 3312 }, 3313 expectUnsolicitedKeyUpdate: true, 3314 flags: []string{"-key-update"}, 3315 }, 3316 { 3317 testType: serverTest, 3318 name: "KeyUpdate-FromServer", 3319 config: Config{ 3320 MaxVersion: VersionTLS13, 3321 }, 3322 expectUnsolicitedKeyUpdate: true, 3323 flags: []string{"-key-update"}, 3324 }, 3325 { 3326 name: "KeyUpdate-InvalidRequestMode", 3327 config: Config{ 3328 MaxVersion: VersionTLS13, 3329 }, 3330 sendKeyUpdates: 1, 3331 keyUpdateRequest: 42, 3332 shouldFail: true, 3333 expectedError: ":DECODE_ERROR:", 3334 }, 3335 { 3336 // Test that KeyUpdates are acknowledged properly. 3337 name: "KeyUpdate-RequestACK", 3338 config: Config{ 3339 MaxVersion: VersionTLS13, 3340 Bugs: ProtocolBugs{ 3341 RejectUnsolicitedKeyUpdate: true, 3342 }, 3343 }, 3344 // Test the shim receiving many KeyUpdates in a row. 3345 sendKeyUpdates: 5, 3346 messageCount: 5, 3347 keyUpdateRequest: keyUpdateRequested, 3348 }, 3349 { 3350 // Test that KeyUpdates are acknowledged properly if the 3351 // peer's KeyUpdate is discovered while a write is 3352 // pending. 3353 name: "KeyUpdate-RequestACK-UnfinishedWrite", 3354 config: Config{ 3355 MaxVersion: VersionTLS13, 3356 Bugs: ProtocolBugs{ 3357 RejectUnsolicitedKeyUpdate: true, 3358 }, 3359 }, 3360 // Test the shim receiving many KeyUpdates in a row. 3361 sendKeyUpdates: 5, 3362 messageCount: 5, 3363 keyUpdateRequest: keyUpdateRequested, 3364 readWithUnfinishedWrite: true, 3365 flags: []string{"-async"}, 3366 }, 3367 { 3368 name: "SendSNIWarningAlert", 3369 config: Config{ 3370 MaxVersion: VersionTLS12, 3371 Bugs: ProtocolBugs{ 3372 SendSNIWarningAlert: true, 3373 }, 3374 }, 3375 }, 3376 { 3377 testType: serverTest, 3378 name: "ExtraCompressionMethods-TLS12", 3379 config: Config{ 3380 MaxVersion: VersionTLS12, 3381 Bugs: ProtocolBugs{ 3382 SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6}, 3383 }, 3384 }, 3385 }, 3386 { 3387 testType: serverTest, 3388 name: "ExtraCompressionMethods-TLS13", 3389 config: Config{ 3390 MaxVersion: VersionTLS13, 3391 Bugs: ProtocolBugs{ 3392 SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6}, 3393 }, 3394 }, 3395 shouldFail: true, 3396 expectedError: ":INVALID_COMPRESSION_LIST:", 3397 expectedLocalError: "remote error: illegal parameter", 3398 }, 3399 { 3400 testType: serverTest, 3401 name: "NoNullCompression-TLS12", 3402 config: Config{ 3403 MaxVersion: VersionTLS12, 3404 Bugs: ProtocolBugs{ 3405 SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6}, 3406 }, 3407 }, 3408 shouldFail: true, 3409 expectedError: ":INVALID_COMPRESSION_LIST:", 3410 expectedLocalError: "remote error: illegal parameter", 3411 }, 3412 { 3413 testType: serverTest, 3414 name: "NoNullCompression-TLS13", 3415 config: Config{ 3416 MaxVersion: VersionTLS13, 3417 Bugs: ProtocolBugs{ 3418 SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6}, 3419 }, 3420 }, 3421 shouldFail: true, 3422 expectedError: ":INVALID_COMPRESSION_LIST:", 3423 expectedLocalError: "remote error: illegal parameter", 3424 }, 3425 // Test that the client rejects invalid compression methods 3426 // from the server. 3427 { 3428 testType: clientTest, 3429 name: "InvalidCompressionMethod", 3430 config: Config{ 3431 MaxVersion: VersionTLS12, 3432 Bugs: ProtocolBugs{ 3433 SendCompressionMethod: 1, 3434 }, 3435 }, 3436 shouldFail: true, 3437 expectedError: ":UNSUPPORTED_COMPRESSION_ALGORITHM:", 3438 expectedLocalError: "remote error: illegal parameter", 3439 }, 3440 { 3441 testType: clientTest, 3442 name: "TLS13-InvalidCompressionMethod", 3443 config: Config{ 3444 MaxVersion: VersionTLS13, 3445 Bugs: ProtocolBugs{ 3446 SendCompressionMethod: 1, 3447 }, 3448 }, 3449 shouldFail: true, 3450 expectedError: ":DECODE_ERROR:", 3451 }, 3452 { 3453 testType: clientTest, 3454 name: "TLS13-HRR-InvalidCompressionMethod", 3455 config: Config{ 3456 MaxVersion: VersionTLS13, 3457 CurvePreferences: []CurveID{CurveP384}, 3458 Bugs: ProtocolBugs{ 3459 SendCompressionMethod: 1, 3460 }, 3461 }, 3462 shouldFail: true, 3463 expectedError: ":DECODE_ERROR:", 3464 expectedLocalError: "remote error: error decoding message", 3465 }, 3466 { 3467 name: "GREASE-Client-TLS12", 3468 config: Config{ 3469 MaxVersion: VersionTLS12, 3470 Bugs: ProtocolBugs{ 3471 ExpectGREASE: true, 3472 }, 3473 }, 3474 flags: []string{"-enable-grease"}, 3475 }, 3476 { 3477 name: "GREASE-Client-TLS13", 3478 config: Config{ 3479 MaxVersion: VersionTLS13, 3480 Bugs: ProtocolBugs{ 3481 ExpectGREASE: true, 3482 }, 3483 }, 3484 flags: []string{"-enable-grease"}, 3485 }, 3486 { 3487 testType: serverTest, 3488 name: "GREASE-Server-TLS13", 3489 config: Config{ 3490 MaxVersion: VersionTLS13, 3491 Bugs: ProtocolBugs{ 3492 // TLS 1.3 servers are expected to 3493 // always enable GREASE. TLS 1.3 is new, 3494 // so there is no existing ecosystem to 3495 // worry about. 3496 ExpectGREASE: true, 3497 }, 3498 }, 3499 }, 3500 { 3501 // Test the TLS 1.2 server so there is a large 3502 // unencrypted certificate as well as application data. 3503 testType: serverTest, 3504 name: "MaxSendFragment-TLS12", 3505 config: Config{ 3506 MaxVersion: VersionTLS12, 3507 Bugs: ProtocolBugs{ 3508 MaxReceivePlaintext: 512, 3509 }, 3510 }, 3511 messageLen: 1024, 3512 flags: []string{ 3513 "-max-send-fragment", "512", 3514 "-read-size", "1024", 3515 }, 3516 }, 3517 { 3518 // Test the TLS 1.2 server so there is a large 3519 // unencrypted certificate as well as application data. 3520 testType: serverTest, 3521 name: "MaxSendFragment-TLS12-TooLarge", 3522 config: Config{ 3523 MaxVersion: VersionTLS12, 3524 Bugs: ProtocolBugs{ 3525 // Ensure that some of the records are 3526 // 512. 3527 MaxReceivePlaintext: 511, 3528 }, 3529 }, 3530 messageLen: 1024, 3531 flags: []string{ 3532 "-max-send-fragment", "512", 3533 "-read-size", "1024", 3534 }, 3535 shouldFail: true, 3536 expectedLocalError: "local error: record overflow", 3537 }, 3538 { 3539 // Test the TLS 1.3 server so there is a large encrypted 3540 // certificate as well as application data. 3541 testType: serverTest, 3542 name: "MaxSendFragment-TLS13", 3543 config: Config{ 3544 MaxVersion: VersionTLS13, 3545 Bugs: ProtocolBugs{ 3546 MaxReceivePlaintext: 512, 3547 ExpectPackedEncryptedHandshake: 512, 3548 }, 3549 }, 3550 messageLen: 1024, 3551 flags: []string{ 3552 "-max-send-fragment", "512", 3553 "-read-size", "1024", 3554 }, 3555 }, 3556 { 3557 // Test the TLS 1.3 server so there is a large encrypted 3558 // certificate as well as application data. 3559 testType: serverTest, 3560 name: "MaxSendFragment-TLS13-TooLarge", 3561 config: Config{ 3562 MaxVersion: VersionTLS13, 3563 Bugs: ProtocolBugs{ 3564 // Ensure that some of the records are 3565 // 512. 3566 MaxReceivePlaintext: 511, 3567 }, 3568 }, 3569 messageLen: 1024, 3570 flags: []string{ 3571 "-max-send-fragment", "512", 3572 "-read-size", "1024", 3573 }, 3574 shouldFail: true, 3575 expectedLocalError: "local error: record overflow", 3576 }, 3577 { 3578 // Test that handshake data is tightly packed in TLS 1.3. 3579 testType: serverTest, 3580 name: "PackedEncryptedHandshake-TLS13", 3581 config: Config{ 3582 MaxVersion: VersionTLS13, 3583 Bugs: ProtocolBugs{ 3584 ExpectPackedEncryptedHandshake: 16384, 3585 }, 3586 }, 3587 }, 3588 { 3589 // Test that DTLS can handle multiple application data 3590 // records in a single packet. 3591 protocol: dtls, 3592 name: "SplitAndPackAppData-DTLS", 3593 config: Config{ 3594 Bugs: ProtocolBugs{ 3595 SplitAndPackAppData: true, 3596 }, 3597 }, 3598 }, 3599 { 3600 protocol: dtls, 3601 name: "SplitAndPackAppData-DTLS-Async", 3602 config: Config{ 3603 Bugs: ProtocolBugs{ 3604 SplitAndPackAppData: true, 3605 }, 3606 }, 3607 flags: []string{"-async"}, 3608 }, 3609 { 3610 // DTLS 1.2 allows up to a 255-byte HelloVerifyRequest cookie, which 3611 // is the largest encodable value. 3612 protocol: dtls, 3613 name: "DTLS-HelloVerifyRequest-255", 3614 config: Config{ 3615 MaxVersion: VersionTLS12, 3616 Bugs: ProtocolBugs{ 3617 HelloVerifyRequestCookieLength: 255, 3618 }, 3619 }, 3620 }, 3621 { 3622 // DTLS 1.2 allows up to a 0-byte HelloVerifyRequest cookie, which 3623 // was probably a mistake in the spec but test that it works 3624 // nonetheless. 3625 protocol: dtls, 3626 name: "DTLS-HelloVerifyRequest-0", 3627 config: Config{ 3628 MaxVersion: VersionTLS12, 3629 Bugs: ProtocolBugs{ 3630 EmptyHelloVerifyRequestCookie: true, 3631 }, 3632 }, 3633 }, 3634 } 3635 testCases = append(testCases, basicTests...) 3636 3637 // Test that very large messages can be received. 3638 cert := rsaCertificate 3639 for i := 0; i < 50; i++ { 3640 cert.Certificate = append(cert.Certificate, cert.Certificate[0]) 3641 } 3642 testCases = append(testCases, testCase{ 3643 name: "LargeMessage", 3644 config: Config{ 3645 Credential: &cert, 3646 }, 3647 }) 3648 testCases = append(testCases, testCase{ 3649 protocol: dtls, 3650 name: "LargeMessage-DTLS", 3651 config: Config{ 3652 Credential: &cert, 3653 }, 3654 }) 3655 3656 // They are rejected if the maximum certificate chain length is capped. 3657 testCases = append(testCases, testCase{ 3658 name: "LargeMessage-Reject", 3659 config: Config{ 3660 Credential: &cert, 3661 }, 3662 flags: []string{"-max-cert-list", "16384"}, 3663 shouldFail: true, 3664 expectedError: ":EXCESSIVE_MESSAGE_SIZE:", 3665 }) 3666 testCases = append(testCases, testCase{ 3667 protocol: dtls, 3668 name: "LargeMessage-Reject-DTLS", 3669 config: Config{ 3670 Credential: &cert, 3671 }, 3672 flags: []string{"-max-cert-list", "16384"}, 3673 shouldFail: true, 3674 expectedError: ":EXCESSIVE_MESSAGE_SIZE:", 3675 }) 3676 3677 // Servers echoing the TLS 1.3 compatibility mode session ID should be 3678 // rejected. 3679 testCases = append(testCases, testCase{ 3680 name: "EchoTLS13CompatibilitySessionID", 3681 config: Config{ 3682 MaxVersion: VersionTLS12, 3683 Bugs: ProtocolBugs{ 3684 EchoSessionIDInFullHandshake: true, 3685 }, 3686 }, 3687 shouldFail: true, 3688 expectedError: ":SERVER_ECHOED_INVALID_SESSION_ID:", 3689 expectedLocalError: "remote error: illegal parameter", 3690 }) 3691 3692 // Servers should reject QUIC client hellos that have a legacy 3693 // session ID. 3694 testCases = append(testCases, testCase{ 3695 name: "QUICCompatibilityMode", 3696 testType: serverTest, 3697 protocol: quic, 3698 config: Config{ 3699 MinVersion: VersionTLS13, 3700 Bugs: ProtocolBugs{ 3701 CompatModeWithQUIC: true, 3702 }, 3703 }, 3704 shouldFail: true, 3705 expectedError: ":UNEXPECTED_COMPATIBILITY_MODE:", 3706 }) 3707} 3708 3709func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol protocol) { 3710 const psk = "12345" 3711 const pskIdentity = "luggage combo" 3712 3713 if !ver.supportsProtocol(protocol) { 3714 return 3715 } 3716 prefix := protocol.String() + "-" 3717 3718 var cert *Credential 3719 if isTLS13Suite(suite.name) { 3720 cert = &rsaCertificate 3721 } else if hasComponent(suite.name, "ECDSA") { 3722 cert = &ecdsaP256Certificate 3723 } else if hasComponent(suite.name, "RSA") { 3724 cert = &rsaCertificate 3725 } 3726 3727 var flags []string 3728 if hasComponent(suite.name, "PSK") { 3729 flags = append(flags, 3730 "-psk", psk, 3731 "-psk-identity", pskIdentity) 3732 } 3733 3734 if hasComponent(suite.name, "3DES") { 3735 // BoringSSL disables 3DES ciphers by default. 3736 flags = append(flags, "-cipher", "3DES") 3737 } 3738 3739 var shouldFail bool 3740 if isTLS12Only(suite.name) && ver.version < VersionTLS12 { 3741 shouldFail = true 3742 } 3743 if !isTLS13Suite(suite.name) && ver.version >= VersionTLS13 { 3744 shouldFail = true 3745 } 3746 if isTLS13Suite(suite.name) && ver.version < VersionTLS13 { 3747 shouldFail = true 3748 } 3749 3750 var sendCipherSuite uint16 3751 var expectedServerError, expectedClientError string 3752 serverCipherSuites := []uint16{suite.id} 3753 if shouldFail { 3754 expectedServerError = ":NO_SHARED_CIPHER:" 3755 if ver.version >= VersionTLS13 && cert == nil { 3756 // TLS 1.2 PSK ciphers won't configure a server certificate, but we 3757 // require one in TLS 1.3. 3758 expectedServerError = ":NO_CERTIFICATE_SET:" 3759 } 3760 expectedClientError = ":WRONG_CIPHER_RETURNED:" 3761 // Configure the server to select ciphers as normal but 3762 // select an incompatible cipher in ServerHello. 3763 serverCipherSuites = nil 3764 sendCipherSuite = suite.id 3765 } 3766 3767 // Verify exporters interoperate. 3768 exportKeyingMaterial := 1024 3769 3770 testCases = append(testCases, testCase{ 3771 testType: serverTest, 3772 protocol: protocol, 3773 name: prefix + ver.name + "-" + suite.name + "-server", 3774 config: Config{ 3775 MinVersion: ver.version, 3776 MaxVersion: ver.version, 3777 CipherSuites: []uint16{suite.id}, 3778 Credential: cert, 3779 PreSharedKey: []byte(psk), 3780 PreSharedKeyIdentity: pskIdentity, 3781 Bugs: ProtocolBugs{ 3782 AdvertiseAllConfiguredCiphers: true, 3783 }, 3784 }, 3785 shimCertificate: cert, 3786 flags: flags, 3787 resumeSession: true, 3788 shouldFail: shouldFail, 3789 expectedError: expectedServerError, 3790 exportKeyingMaterial: exportKeyingMaterial, 3791 }) 3792 3793 testCases = append(testCases, testCase{ 3794 testType: clientTest, 3795 protocol: protocol, 3796 name: prefix + ver.name + "-" + suite.name + "-client", 3797 config: Config{ 3798 MinVersion: ver.version, 3799 MaxVersion: ver.version, 3800 CipherSuites: serverCipherSuites, 3801 Credential: cert, 3802 PreSharedKey: []byte(psk), 3803 PreSharedKeyIdentity: pskIdentity, 3804 Bugs: ProtocolBugs{ 3805 IgnorePeerCipherPreferences: shouldFail, 3806 SendCipherSuite: sendCipherSuite, 3807 }, 3808 }, 3809 flags: flags, 3810 resumeSession: true, 3811 shouldFail: shouldFail, 3812 expectedError: expectedClientError, 3813 exportKeyingMaterial: exportKeyingMaterial, 3814 }) 3815 3816 if shouldFail { 3817 return 3818 } 3819 3820 // Ensure the maximum record size is accepted. 3821 testCases = append(testCases, testCase{ 3822 protocol: protocol, 3823 name: prefix + ver.name + "-" + suite.name + "-LargeRecord", 3824 config: Config{ 3825 MinVersion: ver.version, 3826 MaxVersion: ver.version, 3827 CipherSuites: []uint16{suite.id}, 3828 Credential: cert, 3829 PreSharedKey: []byte(psk), 3830 PreSharedKeyIdentity: pskIdentity, 3831 }, 3832 flags: flags, 3833 messageLen: maxPlaintext, 3834 }) 3835 3836 // Test bad records for all ciphers. Bad records are fatal in TLS 3837 // and ignored in DTLS. 3838 shouldFail = protocol == tls 3839 var expectedError string 3840 if shouldFail { 3841 expectedError = ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:" 3842 } 3843 3844 // When QUIC is used, the QUIC stack handles record encryption/decryption. 3845 // Thus it is not possible for the TLS stack in QUIC mode to receive a 3846 // bad record (i.e. one that fails to decrypt). 3847 if protocol != quic { 3848 testCases = append(testCases, testCase{ 3849 protocol: protocol, 3850 name: prefix + ver.name + "-" + suite.name + "-BadRecord", 3851 config: Config{ 3852 MinVersion: ver.version, 3853 MaxVersion: ver.version, 3854 CipherSuites: []uint16{suite.id}, 3855 Credential: cert, 3856 PreSharedKey: []byte(psk), 3857 PreSharedKeyIdentity: pskIdentity, 3858 }, 3859 flags: flags, 3860 damageFirstWrite: true, 3861 messageLen: maxPlaintext, 3862 shouldFail: shouldFail, 3863 expectedError: expectedError, 3864 }) 3865 } 3866} 3867 3868func addCipherSuiteTests() { 3869 const bogusCipher = 0xfe00 3870 3871 for _, suite := range testCipherSuites { 3872 for _, ver := range tlsVersions { 3873 for _, protocol := range []protocol{tls, dtls, quic} { 3874 addTestForCipherSuite(suite, ver, protocol) 3875 } 3876 } 3877 } 3878 3879 testCases = append(testCases, testCase{ 3880 name: "NoSharedCipher", 3881 config: Config{ 3882 MaxVersion: VersionTLS12, 3883 CipherSuites: []uint16{}, 3884 }, 3885 shouldFail: true, 3886 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:", 3887 }) 3888 3889 testCases = append(testCases, testCase{ 3890 name: "NoSharedCipher-TLS13", 3891 config: Config{ 3892 MaxVersion: VersionTLS13, 3893 CipherSuites: []uint16{}, 3894 }, 3895 shouldFail: true, 3896 expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:", 3897 }) 3898 3899 testCases = append(testCases, testCase{ 3900 name: "UnsupportedCipherSuite", 3901 config: Config{ 3902 MaxVersion: VersionTLS12, 3903 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 3904 Bugs: ProtocolBugs{ 3905 IgnorePeerCipherPreferences: true, 3906 }, 3907 }, 3908 flags: []string{"-cipher", "DEFAULT:!AES"}, 3909 shouldFail: true, 3910 expectedError: ":WRONG_CIPHER_RETURNED:", 3911 }) 3912 3913 testCases = append(testCases, testCase{ 3914 name: "ServerHelloBogusCipher", 3915 config: Config{ 3916 MaxVersion: VersionTLS12, 3917 Bugs: ProtocolBugs{ 3918 SendCipherSuite: bogusCipher, 3919 }, 3920 }, 3921 shouldFail: true, 3922 expectedError: ":WRONG_CIPHER_RETURNED:", 3923 }) 3924 testCases = append(testCases, testCase{ 3925 name: "ServerHelloBogusCipher-TLS13", 3926 config: Config{ 3927 MaxVersion: VersionTLS13, 3928 Bugs: ProtocolBugs{ 3929 SendCipherSuite: bogusCipher, 3930 }, 3931 }, 3932 shouldFail: true, 3933 expectedError: ":WRONG_CIPHER_RETURNED:", 3934 }) 3935 3936 // The server must be tolerant to bogus ciphers. 3937 testCases = append(testCases, testCase{ 3938 testType: serverTest, 3939 name: "UnknownCipher", 3940 config: Config{ 3941 MaxVersion: VersionTLS12, 3942 CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3943 Bugs: ProtocolBugs{ 3944 AdvertiseAllConfiguredCiphers: true, 3945 }, 3946 }, 3947 }) 3948 3949 // The server must be tolerant to bogus ciphers. 3950 testCases = append(testCases, testCase{ 3951 testType: serverTest, 3952 name: "UnknownCipher-TLS13", 3953 config: Config{ 3954 MaxVersion: VersionTLS13, 3955 CipherSuites: []uint16{bogusCipher, TLS_AES_128_GCM_SHA256}, 3956 Bugs: ProtocolBugs{ 3957 AdvertiseAllConfiguredCiphers: true, 3958 }, 3959 }, 3960 }) 3961 3962 // Test empty ECDHE_PSK identity hints work as expected. 3963 testCases = append(testCases, testCase{ 3964 name: "EmptyECDHEPSKHint", 3965 config: Config{ 3966 MaxVersion: VersionTLS12, 3967 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 3968 PreSharedKey: []byte("secret"), 3969 }, 3970 flags: []string{"-psk", "secret"}, 3971 }) 3972 3973 // Test empty PSK identity hints work as expected, even if an explicit 3974 // ServerKeyExchange is sent. 3975 testCases = append(testCases, testCase{ 3976 name: "ExplicitEmptyPSKHint", 3977 config: Config{ 3978 MaxVersion: VersionTLS12, 3979 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 3980 PreSharedKey: []byte("secret"), 3981 Bugs: ProtocolBugs{ 3982 AlwaysSendPreSharedKeyIdentityHint: true, 3983 }, 3984 }, 3985 flags: []string{"-psk", "secret"}, 3986 }) 3987 3988 // Test that clients enforce that the server-sent certificate and cipher 3989 // suite match in TLS 1.2. 3990 testCases = append(testCases, testCase{ 3991 name: "CertificateCipherMismatch-RSA", 3992 config: Config{ 3993 MaxVersion: VersionTLS12, 3994 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 3995 Credential: &rsaCertificate, 3996 Bugs: ProtocolBugs{ 3997 SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 3998 }, 3999 }, 4000 shouldFail: true, 4001 expectedError: ":WRONG_CERTIFICATE_TYPE:", 4002 }) 4003 testCases = append(testCases, testCase{ 4004 name: "CertificateCipherMismatch-ECDSA", 4005 config: Config{ 4006 MaxVersion: VersionTLS12, 4007 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 4008 Credential: &ecdsaP256Certificate, 4009 Bugs: ProtocolBugs{ 4010 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 4011 }, 4012 }, 4013 shouldFail: true, 4014 expectedError: ":WRONG_CERTIFICATE_TYPE:", 4015 }) 4016 testCases = append(testCases, testCase{ 4017 name: "CertificateCipherMismatch-Ed25519", 4018 config: Config{ 4019 MaxVersion: VersionTLS12, 4020 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 4021 Credential: &ed25519Certificate, 4022 Bugs: ProtocolBugs{ 4023 SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 4024 }, 4025 }, 4026 shouldFail: true, 4027 expectedError: ":WRONG_CERTIFICATE_TYPE:", 4028 }) 4029 4030 // Test that servers decline to select a cipher suite which is 4031 // inconsistent with their configured certificate. 4032 testCases = append(testCases, testCase{ 4033 testType: serverTest, 4034 name: "ServerCipherFilter-RSA", 4035 config: Config{ 4036 MaxVersion: VersionTLS12, 4037 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 4038 }, 4039 shimCertificate: &rsaCertificate, 4040 shouldFail: true, 4041 expectedError: ":NO_SHARED_CIPHER:", 4042 }) 4043 testCases = append(testCases, testCase{ 4044 testType: serverTest, 4045 name: "ServerCipherFilter-ECDSA", 4046 config: Config{ 4047 MaxVersion: VersionTLS12, 4048 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4049 }, 4050 shimCertificate: &ecdsaP256Certificate, 4051 shouldFail: true, 4052 expectedError: ":NO_SHARED_CIPHER:", 4053 }) 4054 testCases = append(testCases, testCase{ 4055 testType: serverTest, 4056 name: "ServerCipherFilter-Ed25519", 4057 config: Config{ 4058 MaxVersion: VersionTLS12, 4059 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 4060 }, 4061 shimCertificate: &ed25519Certificate, 4062 shouldFail: true, 4063 expectedError: ":NO_SHARED_CIPHER:", 4064 }) 4065 4066 // Test cipher suite negotiation works as expected. Configure a 4067 // complicated cipher suite configuration. 4068 const negotiationTestCiphers = "" + 4069 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:" + 4070 "[TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384|TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256|TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]:" + 4071 "TLS_RSA_WITH_AES_128_GCM_SHA256:" + 4072 "TLS_RSA_WITH_AES_128_CBC_SHA:" + 4073 "[TLS_RSA_WITH_AES_256_GCM_SHA384|TLS_RSA_WITH_AES_256_CBC_SHA]" 4074 negotiationTests := []struct { 4075 ciphers []uint16 4076 expected uint16 4077 }{ 4078 // Server preferences are honored, including when 4079 // equipreference groups are involved. 4080 { 4081 []uint16{ 4082 TLS_RSA_WITH_AES_256_GCM_SHA384, 4083 TLS_RSA_WITH_AES_128_CBC_SHA, 4084 TLS_RSA_WITH_AES_128_GCM_SHA256, 4085 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4086 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 4087 }, 4088 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 4089 }, 4090 { 4091 []uint16{ 4092 TLS_RSA_WITH_AES_256_GCM_SHA384, 4093 TLS_RSA_WITH_AES_128_CBC_SHA, 4094 TLS_RSA_WITH_AES_128_GCM_SHA256, 4095 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4096 }, 4097 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4098 }, 4099 { 4100 []uint16{ 4101 TLS_RSA_WITH_AES_256_GCM_SHA384, 4102 TLS_RSA_WITH_AES_128_CBC_SHA, 4103 TLS_RSA_WITH_AES_128_GCM_SHA256, 4104 }, 4105 TLS_RSA_WITH_AES_128_GCM_SHA256, 4106 }, 4107 { 4108 []uint16{ 4109 TLS_RSA_WITH_AES_256_GCM_SHA384, 4110 TLS_RSA_WITH_AES_128_CBC_SHA, 4111 }, 4112 TLS_RSA_WITH_AES_128_CBC_SHA, 4113 }, 4114 // Equipreference groups use the client preference. 4115 { 4116 []uint16{ 4117 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4118 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4119 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4120 }, 4121 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 4122 }, 4123 { 4124 []uint16{ 4125 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4126 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4127 }, 4128 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4129 }, 4130 { 4131 []uint16{ 4132 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4133 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4134 }, 4135 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4136 }, 4137 { 4138 []uint16{ 4139 TLS_RSA_WITH_AES_256_GCM_SHA384, 4140 TLS_RSA_WITH_AES_256_CBC_SHA, 4141 }, 4142 TLS_RSA_WITH_AES_256_GCM_SHA384, 4143 }, 4144 { 4145 []uint16{ 4146 TLS_RSA_WITH_AES_256_CBC_SHA, 4147 TLS_RSA_WITH_AES_256_GCM_SHA384, 4148 }, 4149 TLS_RSA_WITH_AES_256_CBC_SHA, 4150 }, 4151 // If there are two equipreference groups, the preferred one 4152 // takes precedence. 4153 { 4154 []uint16{ 4155 TLS_RSA_WITH_AES_256_GCM_SHA384, 4156 TLS_RSA_WITH_AES_256_CBC_SHA, 4157 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4158 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 4159 }, 4160 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 4161 }, 4162 } 4163 for i, t := range negotiationTests { 4164 testCases = append(testCases, testCase{ 4165 testType: serverTest, 4166 name: "CipherNegotiation-" + strconv.Itoa(i), 4167 config: Config{ 4168 MaxVersion: VersionTLS12, 4169 CipherSuites: t.ciphers, 4170 }, 4171 flags: []string{"-cipher", negotiationTestCiphers}, 4172 expectations: connectionExpectations{ 4173 cipher: t.expected, 4174 }, 4175 }) 4176 } 4177} 4178 4179func addBadECDSASignatureTests() { 4180 for badR := BadValue(1); badR < NumBadValues; badR++ { 4181 for badS := BadValue(1); badS < NumBadValues; badS++ { 4182 testCases = append(testCases, testCase{ 4183 name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS), 4184 config: Config{ 4185 MaxVersion: VersionTLS12, 4186 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 4187 Credential: &ecdsaP256Certificate, 4188 Bugs: ProtocolBugs{ 4189 BadECDSAR: badR, 4190 BadECDSAS: badS, 4191 }, 4192 }, 4193 shouldFail: true, 4194 expectedError: ":BAD_SIGNATURE:", 4195 }) 4196 testCases = append(testCases, testCase{ 4197 name: fmt.Sprintf("BadECDSA-%d-%d-TLS13", badR, badS), 4198 config: Config{ 4199 MaxVersion: VersionTLS13, 4200 Credential: &ecdsaP256Certificate, 4201 Bugs: ProtocolBugs{ 4202 BadECDSAR: badR, 4203 BadECDSAS: badS, 4204 }, 4205 }, 4206 shouldFail: true, 4207 expectedError: ":BAD_SIGNATURE:", 4208 }) 4209 } 4210 } 4211} 4212 4213func addCBCPaddingTests() { 4214 testCases = append(testCases, testCase{ 4215 name: "MaxCBCPadding", 4216 config: Config{ 4217 MaxVersion: VersionTLS12, 4218 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4219 Bugs: ProtocolBugs{ 4220 MaxPadding: true, 4221 }, 4222 }, 4223 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size 4224 }) 4225 testCases = append(testCases, testCase{ 4226 name: "BadCBCPadding", 4227 config: Config{ 4228 MaxVersion: VersionTLS12, 4229 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4230 Bugs: ProtocolBugs{ 4231 PaddingFirstByteBad: true, 4232 }, 4233 }, 4234 shouldFail: true, 4235 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 4236 }) 4237 // OpenSSL previously had an issue where the first byte of padding in 4238 // 255 bytes of padding wasn't checked. 4239 testCases = append(testCases, testCase{ 4240 name: "BadCBCPadding255", 4241 config: Config{ 4242 MaxVersion: VersionTLS12, 4243 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4244 Bugs: ProtocolBugs{ 4245 MaxPadding: true, 4246 PaddingFirstByteBadIf255: true, 4247 }, 4248 }, 4249 messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size 4250 shouldFail: true, 4251 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 4252 }) 4253} 4254 4255func addCBCSplittingTests() { 4256 var cbcCiphers = []struct { 4257 name string 4258 cipher uint16 4259 }{ 4260 {"3DES", TLS_RSA_WITH_3DES_EDE_CBC_SHA}, 4261 {"AES128", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 4262 {"AES256", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, 4263 } 4264 for _, t := range cbcCiphers { 4265 testCases = append(testCases, testCase{ 4266 name: "CBCRecordSplitting-" + t.name, 4267 config: Config{ 4268 MaxVersion: VersionTLS10, 4269 MinVersion: VersionTLS10, 4270 CipherSuites: []uint16{t.cipher}, 4271 Bugs: ProtocolBugs{ 4272 ExpectRecordSplitting: true, 4273 }, 4274 }, 4275 messageLen: -1, // read until EOF 4276 resumeSession: true, 4277 flags: []string{ 4278 "-async", 4279 "-write-different-record-sizes", 4280 "-cbc-record-splitting", 4281 // BoringSSL disables 3DES by default. 4282 "-cipher", "ALL:3DES", 4283 }, 4284 }) 4285 testCases = append(testCases, testCase{ 4286 name: "CBCRecordSplittingPartialWrite-" + t.name, 4287 config: Config{ 4288 MaxVersion: VersionTLS10, 4289 MinVersion: VersionTLS10, 4290 CipherSuites: []uint16{t.cipher}, 4291 Bugs: ProtocolBugs{ 4292 ExpectRecordSplitting: true, 4293 }, 4294 }, 4295 messageLen: -1, // read until EOF 4296 flags: []string{ 4297 "-async", 4298 "-write-different-record-sizes", 4299 "-cbc-record-splitting", 4300 "-partial-write", 4301 // BoringSSL disables 3DES by default. 4302 "-cipher", "ALL:3DES", 4303 }, 4304 }) 4305 } 4306} 4307 4308func addClientAuthTests() { 4309 // Add a dummy cert pool to stress certificate authority parsing. 4310 certPool := x509.NewCertPool() 4311 for _, cert := range []Credential{rsaCertificate, rsa1024Certificate} { 4312 cert, err := x509.ParseCertificate(cert.Certificate[0]) 4313 if err != nil { 4314 panic(err) 4315 } 4316 certPool.AddCert(cert) 4317 } 4318 caNames := certPool.Subjects() 4319 4320 for _, ver := range tlsVersions { 4321 testCases = append(testCases, testCase{ 4322 testType: clientTest, 4323 name: ver.name + "-Client-ClientAuth-RSA", 4324 config: Config{ 4325 MinVersion: ver.version, 4326 MaxVersion: ver.version, 4327 ClientAuth: RequireAnyClientCert, 4328 ClientCAs: certPool, 4329 }, 4330 shimCertificate: &rsaCertificate, 4331 }) 4332 testCases = append(testCases, testCase{ 4333 testType: serverTest, 4334 name: ver.name + "-Server-ClientAuth-RSA", 4335 config: Config{ 4336 MinVersion: ver.version, 4337 MaxVersion: ver.version, 4338 Credential: &rsaCertificate, 4339 }, 4340 flags: []string{"-require-any-client-certificate"}, 4341 }) 4342 testCases = append(testCases, testCase{ 4343 testType: serverTest, 4344 name: ver.name + "-Server-ClientAuth-ECDSA", 4345 config: Config{ 4346 MinVersion: ver.version, 4347 MaxVersion: ver.version, 4348 Credential: &ecdsaP256Certificate, 4349 }, 4350 flags: []string{"-require-any-client-certificate"}, 4351 }) 4352 testCases = append(testCases, testCase{ 4353 testType: clientTest, 4354 name: ver.name + "-Client-ClientAuth-ECDSA", 4355 config: Config{ 4356 MinVersion: ver.version, 4357 MaxVersion: ver.version, 4358 ClientAuth: RequireAnyClientCert, 4359 ClientCAs: certPool, 4360 }, 4361 shimCertificate: &ecdsaP256Certificate, 4362 }) 4363 4364 testCases = append(testCases, testCase{ 4365 name: "NoClientCertificate-" + ver.name, 4366 config: Config{ 4367 MinVersion: ver.version, 4368 MaxVersion: ver.version, 4369 ClientAuth: RequireAnyClientCert, 4370 }, 4371 shouldFail: true, 4372 expectedLocalError: "client didn't provide a certificate", 4373 }) 4374 4375 testCases = append(testCases, testCase{ 4376 // Even if not configured to expect a certificate, OpenSSL will 4377 // return X509_V_OK as the verify_result. 4378 testType: serverTest, 4379 name: "NoClientCertificateRequested-Server-" + ver.name, 4380 config: Config{ 4381 MinVersion: ver.version, 4382 MaxVersion: ver.version, 4383 }, 4384 flags: []string{ 4385 "-expect-verify-result", 4386 }, 4387 resumeSession: true, 4388 }) 4389 4390 testCases = append(testCases, testCase{ 4391 // If a client certificate is not provided, OpenSSL will still 4392 // return X509_V_OK as the verify_result. 4393 testType: serverTest, 4394 name: "NoClientCertificate-Server-" + ver.name, 4395 config: Config{ 4396 MinVersion: ver.version, 4397 MaxVersion: ver.version, 4398 }, 4399 flags: []string{ 4400 "-expect-verify-result", 4401 "-verify-peer", 4402 }, 4403 resumeSession: true, 4404 }) 4405 4406 certificateRequired := "remote error: certificate required" 4407 if ver.version < VersionTLS13 { 4408 // Prior to TLS 1.3, the generic handshake_failure alert 4409 // was used. 4410 certificateRequired = "remote error: handshake failure" 4411 } 4412 testCases = append(testCases, testCase{ 4413 testType: serverTest, 4414 name: "RequireAnyClientCertificate-" + ver.name, 4415 config: Config{ 4416 MinVersion: ver.version, 4417 MaxVersion: ver.version, 4418 }, 4419 flags: []string{"-require-any-client-certificate"}, 4420 shouldFail: true, 4421 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 4422 expectedLocalError: certificateRequired, 4423 }) 4424 4425 testCases = append(testCases, testCase{ 4426 testType: serverTest, 4427 name: "SkipClientCertificate-" + ver.name, 4428 config: Config{ 4429 MinVersion: ver.version, 4430 MaxVersion: ver.version, 4431 Bugs: ProtocolBugs{ 4432 SkipClientCertificate: true, 4433 }, 4434 }, 4435 // Setting SSL_VERIFY_PEER allows anonymous clients. 4436 flags: []string{"-verify-peer"}, 4437 shouldFail: true, 4438 expectedError: ":UNEXPECTED_MESSAGE:", 4439 }) 4440 4441 testCases = append(testCases, testCase{ 4442 testType: serverTest, 4443 name: "VerifyPeerIfNoOBC-NoChannelID-" + ver.name, 4444 config: Config{ 4445 MinVersion: ver.version, 4446 MaxVersion: ver.version, 4447 }, 4448 flags: []string{ 4449 "-enable-channel-id", 4450 "-verify-peer-if-no-obc", 4451 }, 4452 shouldFail: true, 4453 expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", 4454 expectedLocalError: certificateRequired, 4455 }) 4456 4457 testCases = append(testCases, testCase{ 4458 testType: serverTest, 4459 name: "VerifyPeerIfNoOBC-ChannelID-" + ver.name, 4460 config: Config{ 4461 MinVersion: ver.version, 4462 MaxVersion: ver.version, 4463 ChannelID: &channelIDKey, 4464 }, 4465 expectations: connectionExpectations{ 4466 channelID: true, 4467 }, 4468 flags: []string{ 4469 "-enable-channel-id", 4470 "-verify-peer-if-no-obc", 4471 }, 4472 }) 4473 4474 testCases = append(testCases, testCase{ 4475 testType: serverTest, 4476 name: ver.name + "-Server-CertReq-CA-List", 4477 config: Config{ 4478 MinVersion: ver.version, 4479 MaxVersion: ver.version, 4480 Credential: &rsaCertificate, 4481 Bugs: ProtocolBugs{ 4482 ExpectCertificateReqNames: caNames, 4483 }, 4484 }, 4485 flags: []string{ 4486 "-require-any-client-certificate", 4487 "-use-client-ca-list", encodeDERValues(caNames), 4488 }, 4489 }) 4490 4491 testCases = append(testCases, testCase{ 4492 testType: clientTest, 4493 name: ver.name + "-Client-CertReq-CA-List", 4494 config: Config{ 4495 MinVersion: ver.version, 4496 MaxVersion: ver.version, 4497 Credential: &rsaCertificate, 4498 ClientAuth: RequireAnyClientCert, 4499 ClientCAs: certPool, 4500 }, 4501 shimCertificate: &rsaCertificate, 4502 flags: []string{ 4503 "-expect-client-ca-list", encodeDERValues(caNames), 4504 }, 4505 }) 4506 } 4507 4508 // Client auth is only legal in certificate-based ciphers. 4509 testCases = append(testCases, testCase{ 4510 testType: clientTest, 4511 name: "ClientAuth-PSK", 4512 config: Config{ 4513 MaxVersion: VersionTLS12, 4514 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 4515 PreSharedKey: []byte("secret"), 4516 ClientAuth: RequireAnyClientCert, 4517 }, 4518 shimCertificate: &rsaCertificate, 4519 flags: []string{ 4520 "-psk", "secret", 4521 }, 4522 shouldFail: true, 4523 expectedError: ":UNEXPECTED_MESSAGE:", 4524 }) 4525 testCases = append(testCases, testCase{ 4526 testType: clientTest, 4527 name: "ClientAuth-ECDHE_PSK", 4528 config: Config{ 4529 MaxVersion: VersionTLS12, 4530 CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA}, 4531 PreSharedKey: []byte("secret"), 4532 ClientAuth: RequireAnyClientCert, 4533 }, 4534 shimCertificate: &rsaCertificate, 4535 flags: []string{ 4536 "-psk", "secret", 4537 }, 4538 shouldFail: true, 4539 expectedError: ":UNEXPECTED_MESSAGE:", 4540 }) 4541 4542 // Regression test for a bug where the client CA list, if explicitly 4543 // set to NULL, was mis-encoded. 4544 testCases = append(testCases, testCase{ 4545 testType: serverTest, 4546 name: "Null-Client-CA-List", 4547 config: Config{ 4548 MaxVersion: VersionTLS12, 4549 Credential: &rsaCertificate, 4550 Bugs: ProtocolBugs{ 4551 ExpectCertificateReqNames: [][]byte{}, 4552 }, 4553 }, 4554 flags: []string{ 4555 "-require-any-client-certificate", 4556 "-use-client-ca-list", "<NULL>", 4557 }, 4558 }) 4559 4560 // Test that an empty client CA list doesn't send a CA extension. 4561 testCases = append(testCases, testCase{ 4562 testType: serverTest, 4563 name: "TLS13-Empty-Client-CA-List", 4564 config: Config{ 4565 MaxVersion: VersionTLS13, 4566 Credential: &rsaCertificate, 4567 Bugs: ProtocolBugs{ 4568 ExpectNoCertificateAuthoritiesExtension: true, 4569 }, 4570 }, 4571 flags: []string{ 4572 "-require-any-client-certificate", 4573 "-use-client-ca-list", "<EMPTY>", 4574 }, 4575 }) 4576 4577} 4578 4579func addExtendedMasterSecretTests() { 4580 const expectEMSFlag = "-expect-extended-master-secret" 4581 4582 for _, with := range []bool{false, true} { 4583 prefix := "No" 4584 if with { 4585 prefix = "" 4586 } 4587 4588 for _, isClient := range []bool{false, true} { 4589 suffix := "-Server" 4590 testType := serverTest 4591 if isClient { 4592 suffix = "-Client" 4593 testType = clientTest 4594 } 4595 4596 for _, ver := range tlsVersions { 4597 // In TLS 1.3, the extension is irrelevant and 4598 // always reports as enabled. 4599 var flags []string 4600 if with || ver.version >= VersionTLS13 { 4601 flags = []string{expectEMSFlag} 4602 } 4603 4604 testCases = append(testCases, testCase{ 4605 testType: testType, 4606 name: prefix + "ExtendedMasterSecret-" + ver.name + suffix, 4607 config: Config{ 4608 MinVersion: ver.version, 4609 MaxVersion: ver.version, 4610 Bugs: ProtocolBugs{ 4611 NoExtendedMasterSecret: !with, 4612 RequireExtendedMasterSecret: with, 4613 }, 4614 }, 4615 flags: flags, 4616 }) 4617 } 4618 } 4619 } 4620 4621 for _, isClient := range []bool{false, true} { 4622 for _, supportedInFirstConnection := range []bool{false, true} { 4623 for _, supportedInResumeConnection := range []bool{false, true} { 4624 boolToWord := func(b bool) string { 4625 if b { 4626 return "Yes" 4627 } 4628 return "No" 4629 } 4630 suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-" 4631 if isClient { 4632 suffix += "Client" 4633 } else { 4634 suffix += "Server" 4635 } 4636 4637 supportedConfig := Config{ 4638 MaxVersion: VersionTLS12, 4639 Bugs: ProtocolBugs{ 4640 RequireExtendedMasterSecret: true, 4641 }, 4642 } 4643 4644 noSupportConfig := Config{ 4645 MaxVersion: VersionTLS12, 4646 Bugs: ProtocolBugs{ 4647 NoExtendedMasterSecret: true, 4648 }, 4649 } 4650 4651 test := testCase{ 4652 name: "ExtendedMasterSecret-" + suffix, 4653 resumeSession: true, 4654 } 4655 4656 if !isClient { 4657 test.testType = serverTest 4658 } 4659 4660 if supportedInFirstConnection { 4661 test.config = supportedConfig 4662 } else { 4663 test.config = noSupportConfig 4664 } 4665 4666 if supportedInResumeConnection { 4667 test.resumeConfig = &supportedConfig 4668 } else { 4669 test.resumeConfig = &noSupportConfig 4670 } 4671 4672 switch suffix { 4673 case "YesToYes-Client", "YesToYes-Server": 4674 // When a session is resumed, it should 4675 // still be aware that its master 4676 // secret was generated via EMS and 4677 // thus it's safe to use tls-unique. 4678 test.flags = []string{expectEMSFlag} 4679 case "NoToYes-Server": 4680 // If an original connection did not 4681 // contain EMS, but a resumption 4682 // handshake does, then a server should 4683 // not resume the session. 4684 test.expectResumeRejected = true 4685 case "YesToNo-Server": 4686 // Resuming an EMS session without the 4687 // EMS extension should cause the 4688 // server to abort the connection. 4689 test.shouldFail = true 4690 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" 4691 case "NoToYes-Client": 4692 // A client should abort a connection 4693 // where the server resumed a non-EMS 4694 // session but echoed the EMS 4695 // extension. 4696 test.shouldFail = true 4697 test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:" 4698 case "YesToNo-Client": 4699 // A client should abort a connection 4700 // where the server didn't echo EMS 4701 // when the session used it. 4702 test.shouldFail = true 4703 test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:" 4704 } 4705 4706 testCases = append(testCases, test) 4707 } 4708 } 4709 } 4710 4711 // Switching EMS on renegotiation is forbidden. 4712 testCases = append(testCases, testCase{ 4713 name: "ExtendedMasterSecret-Renego-NoEMS", 4714 config: Config{ 4715 MaxVersion: VersionTLS12, 4716 Bugs: ProtocolBugs{ 4717 NoExtendedMasterSecret: true, 4718 NoExtendedMasterSecretOnRenegotiation: true, 4719 }, 4720 }, 4721 renegotiate: 1, 4722 flags: []string{ 4723 "-renegotiate-freely", 4724 "-expect-total-renegotiations", "1", 4725 }, 4726 }) 4727 4728 testCases = append(testCases, testCase{ 4729 name: "ExtendedMasterSecret-Renego-Upgrade", 4730 config: Config{ 4731 MaxVersion: VersionTLS12, 4732 Bugs: ProtocolBugs{ 4733 NoExtendedMasterSecret: true, 4734 }, 4735 }, 4736 renegotiate: 1, 4737 flags: []string{ 4738 "-renegotiate-freely", 4739 "-expect-total-renegotiations", "1", 4740 }, 4741 shouldFail: true, 4742 expectedError: ":RENEGOTIATION_EMS_MISMATCH:", 4743 }) 4744 4745 testCases = append(testCases, testCase{ 4746 name: "ExtendedMasterSecret-Renego-Downgrade", 4747 config: Config{ 4748 MaxVersion: VersionTLS12, 4749 Bugs: ProtocolBugs{ 4750 NoExtendedMasterSecretOnRenegotiation: true, 4751 }, 4752 }, 4753 renegotiate: 1, 4754 flags: []string{ 4755 "-renegotiate-freely", 4756 "-expect-total-renegotiations", "1", 4757 }, 4758 shouldFail: true, 4759 expectedError: ":RENEGOTIATION_EMS_MISMATCH:", 4760 }) 4761} 4762 4763type stateMachineTestConfig struct { 4764 protocol protocol 4765 async bool 4766 splitHandshake bool 4767 packHandshake bool 4768 implicitHandshake bool 4769} 4770 4771// Adds tests that try to cover the range of the handshake state machine, under 4772// various conditions. Some of these are redundant with other tests, but they 4773// only cover the synchronous case. 4774func addAllStateMachineCoverageTests() { 4775 for _, async := range []bool{false, true} { 4776 for _, protocol := range []protocol{tls, dtls, quic} { 4777 addStateMachineCoverageTests(stateMachineTestConfig{ 4778 protocol: protocol, 4779 async: async, 4780 }) 4781 // QUIC doesn't work with the implicit handshake API. Additionally, 4782 // splitting or packing handshake records is meaningless in QUIC. 4783 if protocol != quic { 4784 addStateMachineCoverageTests(stateMachineTestConfig{ 4785 protocol: protocol, 4786 async: async, 4787 implicitHandshake: true, 4788 }) 4789 addStateMachineCoverageTests(stateMachineTestConfig{ 4790 protocol: protocol, 4791 async: async, 4792 splitHandshake: true, 4793 }) 4794 addStateMachineCoverageTests(stateMachineTestConfig{ 4795 protocol: protocol, 4796 async: async, 4797 packHandshake: true, 4798 }) 4799 } 4800 } 4801 } 4802} 4803 4804func addStateMachineCoverageTests(config stateMachineTestConfig) { 4805 var tests []testCase 4806 4807 // Basic handshake, with resumption. Client and server, 4808 // session ID and session ticket. 4809 // The following tests have a max version of 1.2, so they are not suitable 4810 // for use with QUIC. 4811 if config.protocol != quic { 4812 tests = append(tests, testCase{ 4813 name: "Basic-Client", 4814 config: Config{ 4815 MaxVersion: VersionTLS12, 4816 }, 4817 resumeSession: true, 4818 // Ensure session tickets are used, not session IDs. 4819 noSessionCache: true, 4820 flags: []string{"-expect-no-hrr"}, 4821 }) 4822 tests = append(tests, testCase{ 4823 name: "Basic-Client-RenewTicket", 4824 config: Config{ 4825 MaxVersion: VersionTLS12, 4826 Bugs: ProtocolBugs{ 4827 RenewTicketOnResume: true, 4828 }, 4829 }, 4830 flags: []string{"-expect-ticket-renewal"}, 4831 resumeSession: true, 4832 resumeRenewedSession: true, 4833 }) 4834 tests = append(tests, testCase{ 4835 name: "Basic-Client-NoTicket", 4836 config: Config{ 4837 MaxVersion: VersionTLS12, 4838 SessionTicketsDisabled: true, 4839 }, 4840 resumeSession: true, 4841 }) 4842 tests = append(tests, testCase{ 4843 testType: serverTest, 4844 name: "Basic-Server", 4845 config: Config{ 4846 MaxVersion: VersionTLS12, 4847 Bugs: ProtocolBugs{ 4848 RequireSessionTickets: true, 4849 }, 4850 }, 4851 resumeSession: true, 4852 flags: []string{ 4853 "-expect-no-session-id", 4854 "-expect-no-hrr", 4855 }, 4856 }) 4857 tests = append(tests, testCase{ 4858 testType: serverTest, 4859 name: "Basic-Server-NoTickets", 4860 config: Config{ 4861 MaxVersion: VersionTLS12, 4862 SessionTicketsDisabled: true, 4863 }, 4864 resumeSession: true, 4865 flags: []string{"-expect-session-id"}, 4866 }) 4867 tests = append(tests, testCase{ 4868 testType: serverTest, 4869 name: "Basic-Server-EarlyCallback", 4870 config: Config{ 4871 MaxVersion: VersionTLS12, 4872 }, 4873 flags: []string{"-use-early-callback"}, 4874 resumeSession: true, 4875 }) 4876 } 4877 4878 // TLS 1.3 basic handshake shapes. DTLS 1.3 isn't supported yet. 4879 if config.protocol != dtls { 4880 tests = append(tests, testCase{ 4881 name: "TLS13-1RTT-Client", 4882 config: Config{ 4883 MaxVersion: VersionTLS13, 4884 MinVersion: VersionTLS13, 4885 }, 4886 resumeSession: true, 4887 resumeRenewedSession: true, 4888 // 0-RTT being disabled overrides all other 0-RTT reasons. 4889 flags: []string{"-expect-early-data-reason", "disabled"}, 4890 }) 4891 4892 tests = append(tests, testCase{ 4893 testType: serverTest, 4894 name: "TLS13-1RTT-Server", 4895 config: Config{ 4896 MaxVersion: VersionTLS13, 4897 MinVersion: VersionTLS13, 4898 }, 4899 resumeSession: true, 4900 resumeRenewedSession: true, 4901 flags: []string{ 4902 // TLS 1.3 uses tickets, so the session should not be 4903 // cached statefully. 4904 "-expect-no-session-id", 4905 // 0-RTT being disabled overrides all other 0-RTT reasons. 4906 "-expect-early-data-reason", "disabled", 4907 }, 4908 }) 4909 4910 tests = append(tests, testCase{ 4911 name: "TLS13-HelloRetryRequest-Client", 4912 config: Config{ 4913 MaxVersion: VersionTLS13, 4914 MinVersion: VersionTLS13, 4915 // P-384 requires a HelloRetryRequest against BoringSSL's default 4916 // configuration. Assert this with ExpectMissingKeyShare. 4917 CurvePreferences: []CurveID{CurveP384}, 4918 Bugs: ProtocolBugs{ 4919 ExpectMissingKeyShare: true, 4920 }, 4921 }, 4922 // Cover HelloRetryRequest during an ECDHE-PSK resumption. 4923 resumeSession: true, 4924 flags: []string{"-expect-hrr"}, 4925 }) 4926 4927 tests = append(tests, testCase{ 4928 testType: serverTest, 4929 name: "TLS13-HelloRetryRequest-Server", 4930 config: Config{ 4931 MaxVersion: VersionTLS13, 4932 MinVersion: VersionTLS13, 4933 // Require a HelloRetryRequest for every curve. 4934 DefaultCurves: []CurveID{}, 4935 }, 4936 // Cover HelloRetryRequest during an ECDHE-PSK resumption. 4937 resumeSession: true, 4938 flags: []string{"-expect-hrr"}, 4939 }) 4940 4941 // Tests that specify a MaxEarlyDataSize don't work with QUIC. 4942 if config.protocol != quic { 4943 tests = append(tests, testCase{ 4944 testType: clientTest, 4945 name: "TLS13-EarlyData-TooMuchData-Client", 4946 config: Config{ 4947 MaxVersion: VersionTLS13, 4948 MinVersion: VersionTLS13, 4949 MaxEarlyDataSize: 2, 4950 }, 4951 resumeConfig: &Config{ 4952 MaxVersion: VersionTLS13, 4953 MinVersion: VersionTLS13, 4954 MaxEarlyDataSize: 2, 4955 Bugs: ProtocolBugs{ 4956 ExpectEarlyData: [][]byte{[]byte(shimInitialWrite[:2])}, 4957 }, 4958 }, 4959 resumeShimPrefix: shimInitialWrite[2:], 4960 resumeSession: true, 4961 earlyData: true, 4962 }) 4963 } 4964 4965 // Unfinished writes can only be tested when operations are async. EarlyData 4966 // can't be tested as part of an ImplicitHandshake in this case since 4967 // otherwise the early data will be sent as normal data. 4968 // 4969 // Note application data is external in QUIC, so unfinished writes do not 4970 // apply. 4971 if config.async && !config.implicitHandshake && config.protocol != quic { 4972 tests = append(tests, testCase{ 4973 testType: clientTest, 4974 name: "TLS13-EarlyData-UnfinishedWrite-Client", 4975 config: Config{ 4976 MaxVersion: VersionTLS13, 4977 MinVersion: VersionTLS13, 4978 Bugs: ProtocolBugs{ 4979 // Write the server response before expecting early data. 4980 ExpectEarlyData: [][]byte{}, 4981 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 4982 }, 4983 }, 4984 resumeSession: true, 4985 earlyData: true, 4986 flags: []string{"-on-resume-read-with-unfinished-write"}, 4987 }) 4988 4989 // Rejected unfinished writes are discarded (from the 4990 // perspective of the calling application) on 0-RTT 4991 // reject. 4992 tests = append(tests, testCase{ 4993 testType: clientTest, 4994 name: "TLS13-EarlyData-RejectUnfinishedWrite-Client", 4995 config: Config{ 4996 MaxVersion: VersionTLS13, 4997 MinVersion: VersionTLS13, 4998 Bugs: ProtocolBugs{ 4999 AlwaysRejectEarlyData: true, 5000 }, 5001 }, 5002 resumeSession: true, 5003 earlyData: true, 5004 expectEarlyDataRejected: true, 5005 flags: []string{"-on-resume-read-with-unfinished-write"}, 5006 }) 5007 } 5008 5009 // Early data has no size limit in QUIC. 5010 if config.protocol != quic { 5011 tests = append(tests, testCase{ 5012 testType: serverTest, 5013 name: "TLS13-MaxEarlyData-Server", 5014 config: Config{ 5015 MaxVersion: VersionTLS13, 5016 MinVersion: VersionTLS13, 5017 Bugs: ProtocolBugs{ 5018 SendEarlyData: [][]byte{bytes.Repeat([]byte{1}, 14336+1)}, 5019 ExpectEarlyDataAccepted: true, 5020 }, 5021 }, 5022 messageCount: 2, 5023 resumeSession: true, 5024 earlyData: true, 5025 shouldFail: true, 5026 expectedError: ":TOO_MUCH_READ_EARLY_DATA:", 5027 }) 5028 } 5029 } 5030 5031 // TLS client auth. 5032 // The following tests have a max version of 1.2, so they are not suitable 5033 // for use with QUIC. 5034 if config.protocol != quic { 5035 tests = append(tests, testCase{ 5036 testType: clientTest, 5037 name: "ClientAuth-NoCertificate-Client", 5038 config: Config{ 5039 MaxVersion: VersionTLS12, 5040 ClientAuth: RequestClientCert, 5041 }, 5042 }) 5043 tests = append(tests, testCase{ 5044 testType: serverTest, 5045 name: "ClientAuth-NoCertificate-Server", 5046 config: Config{ 5047 MaxVersion: VersionTLS12, 5048 }, 5049 // Setting SSL_VERIFY_PEER allows anonymous clients. 5050 flags: []string{"-verify-peer"}, 5051 }) 5052 } 5053 if config.protocol != dtls { 5054 tests = append(tests, testCase{ 5055 testType: clientTest, 5056 name: "ClientAuth-NoCertificate-Client-TLS13", 5057 config: Config{ 5058 MaxVersion: VersionTLS13, 5059 ClientAuth: RequestClientCert, 5060 }, 5061 }) 5062 tests = append(tests, testCase{ 5063 testType: serverTest, 5064 name: "ClientAuth-NoCertificate-Server-TLS13", 5065 config: Config{ 5066 MaxVersion: VersionTLS13, 5067 }, 5068 // Setting SSL_VERIFY_PEER allows anonymous clients. 5069 flags: []string{"-verify-peer"}, 5070 }) 5071 } 5072 if config.protocol != quic { 5073 tests = append(tests, testCase{ 5074 testType: clientTest, 5075 name: "ClientAuth-RSA-Client", 5076 config: Config{ 5077 MaxVersion: VersionTLS12, 5078 ClientAuth: RequireAnyClientCert, 5079 }, 5080 shimCertificate: &rsaCertificate, 5081 }) 5082 } 5083 tests = append(tests, testCase{ 5084 testType: clientTest, 5085 name: "ClientAuth-RSA-Client-TLS13", 5086 config: Config{ 5087 MaxVersion: VersionTLS13, 5088 ClientAuth: RequireAnyClientCert, 5089 }, 5090 shimCertificate: &rsaCertificate, 5091 }) 5092 if config.protocol != quic { 5093 tests = append(tests, testCase{ 5094 testType: clientTest, 5095 name: "ClientAuth-ECDSA-Client", 5096 config: Config{ 5097 MaxVersion: VersionTLS12, 5098 ClientAuth: RequireAnyClientCert, 5099 }, 5100 shimCertificate: &ecdsaP256Certificate, 5101 }) 5102 } 5103 tests = append(tests, testCase{ 5104 testType: clientTest, 5105 name: "ClientAuth-ECDSA-Client-TLS13", 5106 config: Config{ 5107 MaxVersion: VersionTLS13, 5108 ClientAuth: RequireAnyClientCert, 5109 }, 5110 shimCertificate: &ecdsaP256Certificate, 5111 }) 5112 if config.protocol != quic { 5113 tests = append(tests, testCase{ 5114 testType: clientTest, 5115 name: "ClientAuth-NoCertificate-OldCallback", 5116 config: Config{ 5117 MaxVersion: VersionTLS12, 5118 ClientAuth: RequestClientCert, 5119 }, 5120 flags: []string{"-use-old-client-cert-callback"}, 5121 }) 5122 } 5123 tests = append(tests, testCase{ 5124 testType: clientTest, 5125 name: "ClientAuth-NoCertificate-OldCallback-TLS13", 5126 config: Config{ 5127 MaxVersion: VersionTLS13, 5128 ClientAuth: RequestClientCert, 5129 }, 5130 flags: []string{"-use-old-client-cert-callback"}, 5131 }) 5132 if config.protocol != quic { 5133 tests = append(tests, testCase{ 5134 testType: clientTest, 5135 name: "ClientAuth-OldCallback", 5136 config: Config{ 5137 MaxVersion: VersionTLS12, 5138 ClientAuth: RequireAnyClientCert, 5139 }, 5140 shimCertificate: &rsaCertificate, 5141 flags: []string{ 5142 "-use-old-client-cert-callback", 5143 }, 5144 }) 5145 } 5146 tests = append(tests, testCase{ 5147 testType: clientTest, 5148 name: "ClientAuth-OldCallback-TLS13", 5149 config: Config{ 5150 MaxVersion: VersionTLS13, 5151 ClientAuth: RequireAnyClientCert, 5152 }, 5153 shimCertificate: &rsaCertificate, 5154 flags: []string{ 5155 "-use-old-client-cert-callback", 5156 }, 5157 }) 5158 if config.protocol != quic { 5159 tests = append(tests, testCase{ 5160 testType: serverTest, 5161 name: "ClientAuth-Server", 5162 config: Config{ 5163 MaxVersion: VersionTLS12, 5164 Credential: &rsaCertificate, 5165 }, 5166 flags: []string{"-require-any-client-certificate"}, 5167 }) 5168 } 5169 tests = append(tests, testCase{ 5170 testType: serverTest, 5171 name: "ClientAuth-Server-TLS13", 5172 config: Config{ 5173 MaxVersion: VersionTLS13, 5174 Credential: &rsaCertificate, 5175 }, 5176 flags: []string{"-require-any-client-certificate"}, 5177 }) 5178 5179 // Test each key exchange on the server side for async keys. 5180 if config.protocol != quic { 5181 tests = append(tests, testCase{ 5182 testType: serverTest, 5183 name: "Basic-Server-RSA", 5184 config: Config{ 5185 MaxVersion: VersionTLS12, 5186 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 5187 }, 5188 shimCertificate: &rsaCertificate, 5189 }) 5190 tests = append(tests, testCase{ 5191 testType: serverTest, 5192 name: "Basic-Server-ECDHE-RSA", 5193 config: Config{ 5194 MaxVersion: VersionTLS12, 5195 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5196 }, 5197 shimCertificate: &rsaCertificate, 5198 }) 5199 tests = append(tests, testCase{ 5200 testType: serverTest, 5201 name: "Basic-Server-ECDHE-ECDSA", 5202 config: Config{ 5203 MaxVersion: VersionTLS12, 5204 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 5205 }, 5206 shimCertificate: &ecdsaP256Certificate, 5207 }) 5208 tests = append(tests, testCase{ 5209 testType: serverTest, 5210 name: "Basic-Server-Ed25519", 5211 config: Config{ 5212 MaxVersion: VersionTLS12, 5213 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 5214 }, 5215 shimCertificate: &ed25519Certificate, 5216 flags: []string{ 5217 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 5218 }, 5219 }) 5220 5221 // No session ticket support; server doesn't send NewSessionTicket. 5222 tests = append(tests, testCase{ 5223 name: "SessionTicketsDisabled-Client", 5224 config: Config{ 5225 MaxVersion: VersionTLS12, 5226 SessionTicketsDisabled: true, 5227 }, 5228 }) 5229 tests = append(tests, testCase{ 5230 testType: serverTest, 5231 name: "SessionTicketsDisabled-Server", 5232 config: Config{ 5233 MaxVersion: VersionTLS12, 5234 SessionTicketsDisabled: true, 5235 }, 5236 }) 5237 5238 // Skip ServerKeyExchange in PSK key exchange if there's no 5239 // identity hint. 5240 tests = append(tests, testCase{ 5241 name: "EmptyPSKHint-Client", 5242 config: Config{ 5243 MaxVersion: VersionTLS12, 5244 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 5245 PreSharedKey: []byte("secret"), 5246 }, 5247 flags: []string{"-psk", "secret"}, 5248 }) 5249 tests = append(tests, testCase{ 5250 testType: serverTest, 5251 name: "EmptyPSKHint-Server", 5252 config: Config{ 5253 MaxVersion: VersionTLS12, 5254 CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA}, 5255 PreSharedKey: []byte("secret"), 5256 }, 5257 flags: []string{"-psk", "secret"}, 5258 }) 5259 } 5260 5261 // OCSP stapling tests. 5262 for _, vers := range allVersions(config.protocol) { 5263 tests = append(tests, testCase{ 5264 testType: clientTest, 5265 name: "OCSPStapling-Client-" + vers.name, 5266 config: Config{ 5267 MaxVersion: vers.version, 5268 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 5269 }, 5270 flags: []string{ 5271 "-enable-ocsp-stapling", 5272 "-expect-ocsp-response", 5273 base64FlagValue(testOCSPResponse), 5274 "-verify-peer", 5275 }, 5276 resumeSession: true, 5277 }) 5278 tests = append(tests, testCase{ 5279 testType: serverTest, 5280 name: "OCSPStapling-Server-" + vers.name, 5281 config: Config{ 5282 MaxVersion: vers.version, 5283 }, 5284 expectations: connectionExpectations{ 5285 peerCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 5286 }, 5287 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 5288 resumeSession: true, 5289 }) 5290 5291 // The client OCSP callback is an alternate certificate 5292 // verification callback. 5293 tests = append(tests, testCase{ 5294 testType: clientTest, 5295 name: "ClientOCSPCallback-Pass-" + vers.name, 5296 config: Config{ 5297 MaxVersion: vers.version, 5298 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 5299 }, 5300 flags: []string{ 5301 "-enable-ocsp-stapling", 5302 "-use-ocsp-callback", 5303 }, 5304 }) 5305 var expectedLocalError string 5306 if !config.async { 5307 // TODO(davidben): Asynchronous fatal alerts are never 5308 // sent. https://crbug.com/boringssl/130. 5309 expectedLocalError = "remote error: bad certificate status response" 5310 } 5311 tests = append(tests, testCase{ 5312 testType: clientTest, 5313 name: "ClientOCSPCallback-Fail-" + vers.name, 5314 config: Config{ 5315 MaxVersion: vers.version, 5316 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 5317 }, 5318 flags: []string{ 5319 "-enable-ocsp-stapling", 5320 "-use-ocsp-callback", 5321 "-fail-ocsp-callback", 5322 }, 5323 shouldFail: true, 5324 expectedLocalError: expectedLocalError, 5325 expectedError: ":OCSP_CB_ERROR:", 5326 }) 5327 // The callback still runs if the server does not send an OCSP 5328 // response. 5329 tests = append(tests, testCase{ 5330 testType: clientTest, 5331 name: "ClientOCSPCallback-FailNoStaple-" + vers.name, 5332 config: Config{ 5333 MaxVersion: vers.version, 5334 Credential: &rsaCertificate, 5335 }, 5336 flags: []string{ 5337 "-enable-ocsp-stapling", 5338 "-use-ocsp-callback", 5339 "-fail-ocsp-callback", 5340 }, 5341 shouldFail: true, 5342 expectedLocalError: expectedLocalError, 5343 expectedError: ":OCSP_CB_ERROR:", 5344 }) 5345 5346 // The server OCSP callback is a legacy mechanism for 5347 // configuring OCSP, used by unreliable server software. 5348 tests = append(tests, testCase{ 5349 testType: serverTest, 5350 name: "ServerOCSPCallback-SetInCallback-" + vers.name, 5351 config: Config{ 5352 MaxVersion: vers.version, 5353 }, 5354 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 5355 expectations: connectionExpectations{ 5356 peerCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 5357 }, 5358 flags: []string{ 5359 "-use-ocsp-callback", 5360 "-set-ocsp-in-callback", 5361 }, 5362 resumeSession: true, 5363 }) 5364 5365 // The callback may decline OCSP, in which case we act as if 5366 // the client did not support it, even if a response was 5367 // configured. 5368 tests = append(tests, testCase{ 5369 testType: serverTest, 5370 name: "ServerOCSPCallback-Decline-" + vers.name, 5371 config: Config{ 5372 MaxVersion: vers.version, 5373 }, 5374 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 5375 expectations: connectionExpectations{ 5376 // There should be no OCSP response from the peer. 5377 peerCertificate: &rsaCertificate, 5378 }, 5379 flags: []string{ 5380 "-use-ocsp-callback", 5381 "-decline-ocsp-callback", 5382 }, 5383 resumeSession: true, 5384 }) 5385 5386 // The callback may also signal an internal error. 5387 tests = append(tests, testCase{ 5388 testType: serverTest, 5389 name: "ServerOCSPCallback-Fail-" + vers.name, 5390 config: Config{ 5391 MaxVersion: vers.version, 5392 }, 5393 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 5394 flags: []string{ 5395 "-use-ocsp-callback", 5396 "-fail-ocsp-callback", 5397 }, 5398 shouldFail: true, 5399 expectedError: ":OCSP_CB_ERROR:", 5400 }) 5401 } 5402 5403 // Certificate verification tests. 5404 for _, vers := range allVersions(config.protocol) { 5405 for _, useCustomCallback := range []bool{false, true} { 5406 for _, testType := range []testType{clientTest, serverTest} { 5407 suffix := "-Client" 5408 if testType == serverTest { 5409 suffix = "-Server" 5410 } 5411 suffix += "-" + vers.name 5412 if useCustomCallback { 5413 suffix += "-CustomCallback" 5414 } 5415 5416 // The custom callback and legacy callback have different default 5417 // alerts. 5418 verifyFailLocalError := "remote error: handshake failure" 5419 if useCustomCallback { 5420 verifyFailLocalError = "remote error: unknown certificate" 5421 } 5422 5423 // We do not reliably send asynchronous fatal alerts. See 5424 // https://crbug.com/boringssl/130. 5425 if config.async { 5426 verifyFailLocalError = "" 5427 } 5428 5429 flags := []string{"-verify-peer"} 5430 if testType == serverTest { 5431 flags = append(flags, "-require-any-client-certificate") 5432 } 5433 if useCustomCallback { 5434 flags = append(flags, "-use-custom-verify-callback") 5435 } 5436 5437 tests = append(tests, testCase{ 5438 testType: testType, 5439 name: "CertificateVerificationSucceed" + suffix, 5440 config: Config{ 5441 MaxVersion: vers.version, 5442 Credential: &rsaCertificate, 5443 }, 5444 flags: append([]string{"-expect-verify-result"}, flags...), 5445 resumeSession: true, 5446 }) 5447 tests = append(tests, testCase{ 5448 testType: testType, 5449 name: "CertificateVerificationFail" + suffix, 5450 config: Config{ 5451 MaxVersion: vers.version, 5452 Credential: &rsaCertificate, 5453 }, 5454 flags: append([]string{"-verify-fail"}, flags...), 5455 shouldFail: true, 5456 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5457 expectedLocalError: verifyFailLocalError, 5458 }) 5459 // Tests that although the verify callback fails on resumption, by default we don't call it. 5460 tests = append(tests, testCase{ 5461 testType: testType, 5462 name: "CertificateVerificationDoesNotFailOnResume" + suffix, 5463 config: Config{ 5464 MaxVersion: vers.version, 5465 Credential: &rsaCertificate, 5466 }, 5467 flags: append([]string{"-on-resume-verify-fail"}, flags...), 5468 resumeSession: true, 5469 }) 5470 if testType == clientTest && useCustomCallback { 5471 tests = append(tests, testCase{ 5472 testType: testType, 5473 name: "CertificateVerificationFailsOnResume" + suffix, 5474 config: Config{ 5475 MaxVersion: vers.version, 5476 Credential: &rsaCertificate, 5477 }, 5478 flags: append([]string{ 5479 "-on-resume-verify-fail", 5480 "-reverify-on-resume", 5481 }, flags...), 5482 resumeSession: true, 5483 shouldFail: true, 5484 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5485 expectedLocalError: verifyFailLocalError, 5486 }) 5487 tests = append(tests, testCase{ 5488 testType: testType, 5489 name: "CertificateVerificationPassesOnResume" + suffix, 5490 config: Config{ 5491 MaxVersion: vers.version, 5492 Credential: &rsaCertificate, 5493 }, 5494 flags: append([]string{ 5495 "-reverify-on-resume", 5496 }, flags...), 5497 resumeSession: true, 5498 }) 5499 if vers.version >= VersionTLS13 { 5500 tests = append(tests, testCase{ 5501 testType: testType, 5502 name: "EarlyData-RejectTicket-Client-Reverify" + suffix, 5503 config: Config{ 5504 MaxVersion: vers.version, 5505 }, 5506 resumeConfig: &Config{ 5507 MaxVersion: vers.version, 5508 SessionTicketsDisabled: true, 5509 }, 5510 resumeSession: true, 5511 expectResumeRejected: true, 5512 earlyData: true, 5513 expectEarlyDataRejected: true, 5514 flags: append([]string{ 5515 "-reverify-on-resume", 5516 // Session tickets are disabled, so the runner will not send a ticket. 5517 "-on-retry-expect-no-session", 5518 }, flags...), 5519 }) 5520 tests = append(tests, testCase{ 5521 testType: testType, 5522 name: "EarlyData-Reject0RTT-Client-Reverify" + suffix, 5523 config: Config{ 5524 MaxVersion: vers.version, 5525 Bugs: ProtocolBugs{ 5526 AlwaysRejectEarlyData: true, 5527 }, 5528 }, 5529 resumeSession: true, 5530 expectResumeRejected: false, 5531 earlyData: true, 5532 expectEarlyDataRejected: true, 5533 flags: append([]string{ 5534 "-reverify-on-resume", 5535 }, flags...), 5536 }) 5537 tests = append(tests, testCase{ 5538 testType: testType, 5539 name: "EarlyData-RejectTicket-Client-ReverifyFails" + suffix, 5540 config: Config{ 5541 MaxVersion: vers.version, 5542 }, 5543 resumeConfig: &Config{ 5544 MaxVersion: vers.version, 5545 SessionTicketsDisabled: true, 5546 }, 5547 resumeSession: true, 5548 expectResumeRejected: true, 5549 earlyData: true, 5550 expectEarlyDataRejected: true, 5551 shouldFail: true, 5552 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5553 flags: append([]string{ 5554 "-reverify-on-resume", 5555 // Session tickets are disabled, so the runner will not send a ticket. 5556 "-on-retry-expect-no-session", 5557 "-on-retry-verify-fail", 5558 }, flags...), 5559 }) 5560 tests = append(tests, testCase{ 5561 testType: testType, 5562 name: "EarlyData-Reject0RTT-Client-ReverifyFails" + suffix, 5563 config: Config{ 5564 MaxVersion: vers.version, 5565 Bugs: ProtocolBugs{ 5566 AlwaysRejectEarlyData: true, 5567 }, 5568 }, 5569 resumeSession: true, 5570 expectResumeRejected: false, 5571 earlyData: true, 5572 expectEarlyDataRejected: true, 5573 shouldFail: true, 5574 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5575 expectedLocalError: verifyFailLocalError, 5576 flags: append([]string{ 5577 "-reverify-on-resume", 5578 "-on-retry-verify-fail", 5579 }, flags...), 5580 }) 5581 // This tests that we only call the verify callback once. 5582 tests = append(tests, testCase{ 5583 testType: testType, 5584 name: "EarlyData-Accept0RTT-Client-Reverify" + suffix, 5585 config: Config{ 5586 MaxVersion: vers.version, 5587 }, 5588 resumeSession: true, 5589 earlyData: true, 5590 flags: append([]string{ 5591 "-reverify-on-resume", 5592 }, flags...), 5593 }) 5594 tests = append(tests, testCase{ 5595 testType: testType, 5596 name: "EarlyData-Accept0RTT-Client-ReverifyFails" + suffix, 5597 config: Config{ 5598 MaxVersion: vers.version, 5599 }, 5600 resumeSession: true, 5601 earlyData: true, 5602 shouldFail: true, 5603 expectedError: ":CERTIFICATE_VERIFY_FAILED:", 5604 // We do not set expectedLocalError here because the shim rejects 5605 // the connection without an alert. 5606 flags: append([]string{ 5607 "-reverify-on-resume", 5608 "-on-resume-verify-fail", 5609 }, flags...), 5610 }) 5611 } 5612 } 5613 } 5614 } 5615 5616 // By default, the client is in a soft fail mode where the peer 5617 // certificate is verified but failures are non-fatal. 5618 tests = append(tests, testCase{ 5619 testType: clientTest, 5620 name: "CertificateVerificationSoftFail-" + vers.name, 5621 config: Config{ 5622 MaxVersion: vers.version, 5623 Credential: &rsaCertificate, 5624 }, 5625 flags: []string{ 5626 "-verify-fail", 5627 "-expect-verify-result", 5628 }, 5629 resumeSession: true, 5630 }) 5631 } 5632 5633 tests = append(tests, testCase{ 5634 name: "ShimSendAlert", 5635 flags: []string{"-send-alert"}, 5636 shimWritesFirst: true, 5637 shouldFail: true, 5638 expectedLocalError: "remote error: decompression failure", 5639 }) 5640 5641 if config.protocol == tls { 5642 tests = append(tests, testCase{ 5643 name: "Renegotiate-Client", 5644 config: Config{ 5645 MaxVersion: VersionTLS12, 5646 }, 5647 renegotiate: 1, 5648 flags: []string{ 5649 "-renegotiate-freely", 5650 "-expect-total-renegotiations", "1", 5651 }, 5652 }) 5653 5654 tests = append(tests, testCase{ 5655 name: "Renegotiate-Client-Explicit", 5656 config: Config{ 5657 MaxVersion: VersionTLS12, 5658 }, 5659 renegotiate: 1, 5660 flags: []string{ 5661 "-renegotiate-explicit", 5662 "-expect-total-renegotiations", "1", 5663 }, 5664 }) 5665 5666 halfHelloRequestError := ":UNEXPECTED_RECORD:" 5667 if config.packHandshake { 5668 // If the HelloRequest is sent in the same record as the server Finished, 5669 // BoringSSL rejects it before the handshake completes. 5670 halfHelloRequestError = ":EXCESS_HANDSHAKE_DATA:" 5671 } 5672 tests = append(tests, testCase{ 5673 name: "SendHalfHelloRequest", 5674 config: Config{ 5675 MaxVersion: VersionTLS12, 5676 Bugs: ProtocolBugs{ 5677 PackHelloRequestWithFinished: config.packHandshake, 5678 }, 5679 }, 5680 sendHalfHelloRequest: true, 5681 flags: []string{"-renegotiate-ignore"}, 5682 shouldFail: true, 5683 expectedError: halfHelloRequestError, 5684 }) 5685 5686 // NPN on client and server; results in post-ChangeCipherSpec message. 5687 tests = append(tests, testCase{ 5688 name: "NPN-Client", 5689 config: Config{ 5690 MaxVersion: VersionTLS12, 5691 NextProtos: []string{"foo"}, 5692 }, 5693 flags: []string{"-select-next-proto", "foo"}, 5694 resumeSession: true, 5695 expectations: connectionExpectations{ 5696 nextProto: "foo", 5697 nextProtoType: npn, 5698 }, 5699 }) 5700 tests = append(tests, testCase{ 5701 testType: serverTest, 5702 name: "NPN-Server", 5703 config: Config{ 5704 MaxVersion: VersionTLS12, 5705 NextProtos: []string{"bar"}, 5706 }, 5707 flags: []string{ 5708 "-advertise-npn", "\x03foo\x03bar\x03baz", 5709 "-expect-next-proto", "bar", 5710 }, 5711 resumeSession: true, 5712 expectations: connectionExpectations{ 5713 nextProto: "bar", 5714 nextProtoType: npn, 5715 }, 5716 }) 5717 5718 // The client may select no protocol after seeing the server list. 5719 tests = append(tests, testCase{ 5720 name: "NPN-Client-ClientSelectEmpty", 5721 config: Config{ 5722 MaxVersion: VersionTLS12, 5723 NextProtos: []string{"foo"}, 5724 }, 5725 flags: []string{"-select-empty-next-proto"}, 5726 resumeSession: true, 5727 expectations: connectionExpectations{ 5728 noNextProto: true, 5729 nextProtoType: npn, 5730 }, 5731 }) 5732 tests = append(tests, testCase{ 5733 testType: serverTest, 5734 name: "NPN-Server-ClientSelectEmpty", 5735 config: Config{ 5736 MaxVersion: VersionTLS12, 5737 NextProtos: []string{"no-match"}, 5738 NoFallbackNextProto: true, 5739 }, 5740 flags: []string{ 5741 "-advertise-npn", "\x03foo\x03bar\x03baz", 5742 "-expect-no-next-proto", 5743 }, 5744 resumeSession: true, 5745 expectations: connectionExpectations{ 5746 noNextProto: true, 5747 nextProtoType: npn, 5748 }, 5749 }) 5750 5751 // The server may negotiate NPN, despite offering no protocols. In this 5752 // case, the server must still be prepared for the client to select a 5753 // fallback protocol. 5754 tests = append(tests, testCase{ 5755 name: "NPN-Client-ServerAdvertiseEmpty", 5756 config: Config{ 5757 MaxVersion: VersionTLS12, 5758 NegotiateNPNWithNoProtos: true, 5759 }, 5760 flags: []string{"-select-next-proto", "foo"}, 5761 resumeSession: true, 5762 expectations: connectionExpectations{ 5763 nextProto: "foo", 5764 nextProtoType: npn, 5765 }, 5766 }) 5767 tests = append(tests, testCase{ 5768 testType: serverTest, 5769 name: "NPN-Server-ServerAdvertiseEmpty", 5770 config: Config{ 5771 MaxVersion: VersionTLS12, 5772 NextProtos: []string{"foo"}, 5773 }, 5774 flags: []string{ 5775 "-advertise-empty-npn", 5776 "-expect-next-proto", "foo", 5777 }, 5778 resumeSession: true, 5779 expectations: connectionExpectations{ 5780 nextProto: "foo", 5781 nextProtoType: npn, 5782 }, 5783 }) 5784 5785 // Client does False Start and negotiates NPN. 5786 tests = append(tests, testCase{ 5787 name: "FalseStart", 5788 config: Config{ 5789 MaxVersion: VersionTLS12, 5790 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5791 NextProtos: []string{"foo"}, 5792 Bugs: ProtocolBugs{ 5793 ExpectFalseStart: true, 5794 }, 5795 }, 5796 flags: []string{ 5797 "-false-start", 5798 "-select-next-proto", "foo", 5799 }, 5800 shimWritesFirst: true, 5801 resumeSession: true, 5802 }) 5803 5804 // Client does False Start and negotiates ALPN. 5805 tests = append(tests, testCase{ 5806 name: "FalseStart-ALPN", 5807 config: Config{ 5808 MaxVersion: VersionTLS12, 5809 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5810 NextProtos: []string{"foo"}, 5811 Bugs: ProtocolBugs{ 5812 ExpectFalseStart: true, 5813 }, 5814 }, 5815 flags: []string{ 5816 "-false-start", 5817 "-advertise-alpn", "\x03foo", 5818 "-expect-alpn", "foo", 5819 }, 5820 shimWritesFirst: true, 5821 resumeSession: true, 5822 }) 5823 5824 // False Start without session tickets. 5825 tests = append(tests, testCase{ 5826 name: "FalseStart-SessionTicketsDisabled", 5827 config: Config{ 5828 MaxVersion: VersionTLS12, 5829 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5830 NextProtos: []string{"foo"}, 5831 SessionTicketsDisabled: true, 5832 Bugs: ProtocolBugs{ 5833 ExpectFalseStart: true, 5834 }, 5835 }, 5836 flags: []string{ 5837 "-false-start", 5838 "-select-next-proto", "foo", 5839 }, 5840 shimWritesFirst: true, 5841 }) 5842 5843 // Server parses a V2ClientHello. Test different lengths for the 5844 // challenge field. 5845 for _, challengeLength := range []int{16, 31, 32, 33, 48} { 5846 tests = append(tests, testCase{ 5847 testType: serverTest, 5848 name: fmt.Sprintf("SendV2ClientHello-%d", challengeLength), 5849 config: Config{ 5850 // Choose a cipher suite that does not involve 5851 // elliptic curves, so no extensions are 5852 // involved. 5853 MaxVersion: VersionTLS12, 5854 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 5855 Bugs: ProtocolBugs{ 5856 SendV2ClientHello: true, 5857 V2ClientHelloChallengeLength: challengeLength, 5858 }, 5859 }, 5860 flags: []string{ 5861 "-expect-msg-callback", 5862 `read v2clienthello 5863write hs 2 5864write hs 11 5865write hs 14 5866read hs 16 5867read ccs 5868read hs 20 5869write ccs 5870write hs 20 5871read alert 1 0 5872`, 5873 }, 5874 }) 5875 } 5876 5877 // Channel ID and NPN at the same time, to ensure their relative 5878 // ordering is correct. 5879 tests = append(tests, testCase{ 5880 name: "ChannelID-NPN-Client", 5881 config: Config{ 5882 MaxVersion: VersionTLS12, 5883 RequestChannelID: true, 5884 NextProtos: []string{"foo"}, 5885 }, 5886 flags: []string{ 5887 "-send-channel-id", channelIDKeyPath, 5888 "-select-next-proto", "foo", 5889 }, 5890 resumeSession: true, 5891 expectations: connectionExpectations{ 5892 channelID: true, 5893 nextProto: "foo", 5894 nextProtoType: npn, 5895 }, 5896 }) 5897 tests = append(tests, testCase{ 5898 testType: serverTest, 5899 name: "ChannelID-NPN-Server", 5900 config: Config{ 5901 MaxVersion: VersionTLS12, 5902 ChannelID: &channelIDKey, 5903 NextProtos: []string{"bar"}, 5904 }, 5905 flags: []string{ 5906 "-expect-channel-id", 5907 base64FlagValue(channelIDBytes), 5908 "-advertise-npn", "\x03foo\x03bar\x03baz", 5909 "-expect-next-proto", "bar", 5910 }, 5911 resumeSession: true, 5912 expectations: connectionExpectations{ 5913 channelID: true, 5914 nextProto: "bar", 5915 nextProtoType: npn, 5916 }, 5917 }) 5918 5919 // Bidirectional shutdown with the runner initiating. 5920 tests = append(tests, testCase{ 5921 name: "Shutdown-Runner", 5922 config: Config{ 5923 Bugs: ProtocolBugs{ 5924 ExpectCloseNotify: true, 5925 }, 5926 }, 5927 flags: []string{"-check-close-notify"}, 5928 }) 5929 } 5930 if config.protocol != dtls { 5931 // Test Channel ID 5932 for _, ver := range allVersions(config.protocol) { 5933 if ver.version < VersionTLS10 { 5934 continue 5935 } 5936 // Client sends a Channel ID. 5937 tests = append(tests, testCase{ 5938 name: "ChannelID-Client-" + ver.name, 5939 config: Config{ 5940 MaxVersion: ver.version, 5941 RequestChannelID: true, 5942 }, 5943 flags: []string{"-send-channel-id", channelIDKeyPath}, 5944 resumeSession: true, 5945 expectations: connectionExpectations{ 5946 channelID: true, 5947 }, 5948 }) 5949 5950 // Server accepts a Channel ID. 5951 tests = append(tests, testCase{ 5952 testType: serverTest, 5953 name: "ChannelID-Server-" + ver.name, 5954 config: Config{ 5955 MaxVersion: ver.version, 5956 ChannelID: &channelIDKey, 5957 }, 5958 flags: []string{ 5959 "-expect-channel-id", 5960 base64FlagValue(channelIDBytes), 5961 }, 5962 resumeSession: true, 5963 expectations: connectionExpectations{ 5964 channelID: true, 5965 }, 5966 }) 5967 5968 tests = append(tests, testCase{ 5969 testType: serverTest, 5970 name: "InvalidChannelIDSignature-" + ver.name, 5971 config: Config{ 5972 MaxVersion: ver.version, 5973 ChannelID: &channelIDKey, 5974 Bugs: ProtocolBugs{ 5975 InvalidChannelIDSignature: true, 5976 }, 5977 }, 5978 flags: []string{"-enable-channel-id"}, 5979 shouldFail: true, 5980 expectedError: ":CHANNEL_ID_SIGNATURE_INVALID:", 5981 }) 5982 5983 if ver.version < VersionTLS13 { 5984 // Channel ID requires ECDHE ciphers. 5985 tests = append(tests, testCase{ 5986 testType: serverTest, 5987 name: "ChannelID-NoECDHE-" + ver.name, 5988 config: Config{ 5989 MaxVersion: ver.version, 5990 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 5991 ChannelID: &channelIDKey, 5992 }, 5993 expectations: connectionExpectations{ 5994 channelID: false, 5995 }, 5996 flags: []string{"-enable-channel-id"}, 5997 }) 5998 5999 // Sanity-check setting expectations.channelID false works. 6000 tests = append(tests, testCase{ 6001 testType: serverTest, 6002 name: "ChannelID-ECDHE-" + ver.name, 6003 config: Config{ 6004 MaxVersion: ver.version, 6005 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 6006 ChannelID: &channelIDKey, 6007 }, 6008 expectations: connectionExpectations{ 6009 channelID: false, 6010 }, 6011 flags: []string{"-enable-channel-id"}, 6012 shouldFail: true, 6013 expectedLocalError: "channel ID unexpectedly negotiated", 6014 }) 6015 } 6016 } 6017 6018 if !config.implicitHandshake { 6019 // Bidirectional shutdown with the shim initiating. The runner, 6020 // in the meantime, sends garbage before the close_notify which 6021 // the shim must ignore. This test is disabled under implicit 6022 // handshake tests because the shim never reads or writes. 6023 6024 // Tests that require checking for a close notify alert don't work with 6025 // QUIC because alerts are handled outside of the TLS stack in QUIC. 6026 if config.protocol != quic { 6027 tests = append(tests, testCase{ 6028 name: "Shutdown-Shim", 6029 config: Config{ 6030 MaxVersion: VersionTLS12, 6031 Bugs: ProtocolBugs{ 6032 ExpectCloseNotify: true, 6033 }, 6034 }, 6035 shimShutsDown: true, 6036 sendEmptyRecords: 1, 6037 sendWarningAlerts: 1, 6038 flags: []string{"-check-close-notify"}, 6039 }) 6040 6041 // The shim should reject unexpected application data 6042 // when shutting down. 6043 tests = append(tests, testCase{ 6044 name: "Shutdown-Shim-ApplicationData", 6045 config: Config{ 6046 MaxVersion: VersionTLS12, 6047 Bugs: ProtocolBugs{ 6048 ExpectCloseNotify: true, 6049 }, 6050 }, 6051 shimShutsDown: true, 6052 messageCount: 1, 6053 sendEmptyRecords: 1, 6054 sendWarningAlerts: 1, 6055 flags: []string{"-check-close-notify"}, 6056 shouldFail: true, 6057 expectedError: ":APPLICATION_DATA_ON_SHUTDOWN:", 6058 }) 6059 6060 // Test that SSL_shutdown still processes KeyUpdate. 6061 tests = append(tests, testCase{ 6062 name: "Shutdown-Shim-KeyUpdate", 6063 config: Config{ 6064 MinVersion: VersionTLS13, 6065 MaxVersion: VersionTLS13, 6066 Bugs: ProtocolBugs{ 6067 ExpectCloseNotify: true, 6068 }, 6069 }, 6070 shimShutsDown: true, 6071 sendKeyUpdates: 1, 6072 keyUpdateRequest: keyUpdateRequested, 6073 flags: []string{"-check-close-notify"}, 6074 }) 6075 6076 // Test that SSL_shutdown processes HelloRequest 6077 // correctly. 6078 tests = append(tests, testCase{ 6079 name: "Shutdown-Shim-HelloRequest-Ignore", 6080 config: Config{ 6081 MinVersion: VersionTLS12, 6082 MaxVersion: VersionTLS12, 6083 Bugs: ProtocolBugs{ 6084 SendHelloRequestBeforeEveryAppDataRecord: true, 6085 ExpectCloseNotify: true, 6086 }, 6087 }, 6088 shimShutsDown: true, 6089 flags: []string{ 6090 "-renegotiate-ignore", 6091 "-check-close-notify", 6092 }, 6093 }) 6094 tests = append(tests, testCase{ 6095 name: "Shutdown-Shim-HelloRequest-Reject", 6096 config: Config{ 6097 MinVersion: VersionTLS12, 6098 MaxVersion: VersionTLS12, 6099 Bugs: ProtocolBugs{ 6100 ExpectCloseNotify: true, 6101 }, 6102 }, 6103 shimShutsDown: true, 6104 renegotiate: 1, 6105 shouldFail: true, 6106 expectedError: ":NO_RENEGOTIATION:", 6107 flags: []string{"-check-close-notify"}, 6108 }) 6109 tests = append(tests, testCase{ 6110 name: "Shutdown-Shim-HelloRequest-CannotHandshake", 6111 config: Config{ 6112 MinVersion: VersionTLS12, 6113 MaxVersion: VersionTLS12, 6114 Bugs: ProtocolBugs{ 6115 ExpectCloseNotify: true, 6116 }, 6117 }, 6118 shimShutsDown: true, 6119 renegotiate: 1, 6120 shouldFail: true, 6121 expectedError: ":NO_RENEGOTIATION:", 6122 flags: []string{ 6123 "-check-close-notify", 6124 "-renegotiate-freely", 6125 }, 6126 }) 6127 6128 tests = append(tests, testCase{ 6129 testType: serverTest, 6130 name: "Shutdown-Shim-Renegotiate-Server-Forbidden", 6131 config: Config{ 6132 MaxVersion: VersionTLS12, 6133 Bugs: ProtocolBugs{ 6134 ExpectCloseNotify: true, 6135 }, 6136 }, 6137 shimShutsDown: true, 6138 renegotiate: 1, 6139 shouldFail: true, 6140 expectedError: ":NO_RENEGOTIATION:", 6141 flags: []string{ 6142 "-check-close-notify", 6143 }, 6144 }) 6145 } 6146 } 6147 } 6148 if config.protocol == dtls { 6149 // TODO(davidben): DTLS 1.3 will want a similar thing for 6150 // HelloRetryRequest. 6151 tests = append(tests, testCase{ 6152 name: "SkipHelloVerifyRequest", 6153 config: Config{ 6154 MaxVersion: VersionTLS12, 6155 Bugs: ProtocolBugs{ 6156 SkipHelloVerifyRequest: true, 6157 }, 6158 }, 6159 }) 6160 } 6161 6162 for _, test := range tests { 6163 test.protocol = config.protocol 6164 test.name += "-" + config.protocol.String() 6165 if config.async { 6166 test.name += "-Async" 6167 test.flags = append(test.flags, "-async") 6168 } else { 6169 test.name += "-Sync" 6170 } 6171 if config.splitHandshake { 6172 test.name += "-SplitHandshakeRecords" 6173 test.config.Bugs.MaxHandshakeRecordLength = 1 6174 if config.protocol == dtls { 6175 test.config.Bugs.MaxPacketLength = 256 6176 test.flags = append(test.flags, "-mtu", "256") 6177 } 6178 } 6179 if config.packHandshake { 6180 test.name += "-PackHandshake" 6181 if config.protocol == dtls { 6182 test.config.Bugs.MaxHandshakeRecordLength = 2 6183 test.config.Bugs.PackHandshakeFragments = 20 6184 test.config.Bugs.PackHandshakeRecords = 1500 6185 test.config.Bugs.PackAppDataWithHandshake = true 6186 } else { 6187 test.config.Bugs.PackHandshakeFlight = true 6188 } 6189 } 6190 if config.implicitHandshake { 6191 test.name += "-ImplicitHandshake" 6192 test.flags = append(test.flags, "-implicit-handshake") 6193 } 6194 testCases = append(testCases, test) 6195 } 6196} 6197 6198func addDDoSCallbackTests() { 6199 // DDoS callback. 6200 for _, resume := range []bool{false, true} { 6201 suffix := "Resume" 6202 if resume { 6203 suffix = "No" + suffix 6204 } 6205 6206 testCases = append(testCases, testCase{ 6207 testType: serverTest, 6208 name: "Server-DDoS-OK-" + suffix, 6209 config: Config{ 6210 MaxVersion: VersionTLS12, 6211 }, 6212 flags: []string{"-install-ddos-callback"}, 6213 resumeSession: resume, 6214 }) 6215 testCases = append(testCases, testCase{ 6216 testType: serverTest, 6217 name: "Server-DDoS-OK-" + suffix + "-TLS13", 6218 config: Config{ 6219 MaxVersion: VersionTLS13, 6220 }, 6221 flags: []string{"-install-ddos-callback"}, 6222 resumeSession: resume, 6223 }) 6224 6225 failFlag := "-fail-ddos-callback" 6226 if resume { 6227 failFlag = "-on-resume-fail-ddos-callback" 6228 } 6229 testCases = append(testCases, testCase{ 6230 testType: serverTest, 6231 name: "Server-DDoS-Reject-" + suffix, 6232 config: Config{ 6233 MaxVersion: VersionTLS12, 6234 }, 6235 flags: []string{"-install-ddos-callback", failFlag}, 6236 resumeSession: resume, 6237 shouldFail: true, 6238 expectedError: ":CONNECTION_REJECTED:", 6239 expectedLocalError: "remote error: internal error", 6240 }) 6241 testCases = append(testCases, testCase{ 6242 testType: serverTest, 6243 name: "Server-DDoS-Reject-" + suffix + "-TLS13", 6244 config: Config{ 6245 MaxVersion: VersionTLS13, 6246 }, 6247 flags: []string{"-install-ddos-callback", failFlag}, 6248 resumeSession: resume, 6249 shouldFail: true, 6250 expectedError: ":CONNECTION_REJECTED:", 6251 expectedLocalError: "remote error: internal error", 6252 }) 6253 } 6254} 6255 6256func addVersionNegotiationTests() { 6257 for _, protocol := range []protocol{tls, dtls, quic} { 6258 for _, shimVers := range allVersions(protocol) { 6259 // Assemble flags to disable all newer versions on the shim. 6260 var flags []string 6261 for _, vers := range allVersions(protocol) { 6262 if vers.version > shimVers.version { 6263 flags = append(flags, vers.excludeFlag) 6264 } 6265 } 6266 6267 flags2 := []string{"-max-version", shimVers.shimFlag(protocol)} 6268 6269 // Test configuring the runner's maximum version. 6270 for _, runnerVers := range allVersions(protocol) { 6271 expectedVersion := shimVers.version 6272 if runnerVers.version < shimVers.version { 6273 expectedVersion = runnerVers.version 6274 } 6275 6276 suffix := shimVers.name + "-" + runnerVers.name 6277 suffix += "-" + protocol.String() 6278 6279 // Determine the expected initial record-layer versions. 6280 clientVers := shimVers.version 6281 if clientVers > VersionTLS10 { 6282 clientVers = VersionTLS10 6283 } 6284 clientVers = recordVersionToWire(clientVers, protocol) 6285 serverVers := expectedVersion 6286 if expectedVersion >= VersionTLS13 { 6287 serverVers = VersionTLS12 6288 } 6289 serverVers = recordVersionToWire(serverVers, protocol) 6290 6291 testCases = append(testCases, testCase{ 6292 protocol: protocol, 6293 testType: clientTest, 6294 name: "VersionNegotiation-Client-" + suffix, 6295 config: Config{ 6296 MaxVersion: runnerVers.version, 6297 Bugs: ProtocolBugs{ 6298 ExpectInitialRecordVersion: clientVers, 6299 }, 6300 }, 6301 flags: flags, 6302 expectations: connectionExpectations{ 6303 version: expectedVersion, 6304 }, 6305 // The version name check does not recognize the 6306 // |excludeFlag| construction in |flags|. 6307 skipVersionNameCheck: true, 6308 }) 6309 testCases = append(testCases, testCase{ 6310 protocol: protocol, 6311 testType: clientTest, 6312 name: "VersionNegotiation-Client2-" + suffix, 6313 config: Config{ 6314 MaxVersion: runnerVers.version, 6315 Bugs: ProtocolBugs{ 6316 ExpectInitialRecordVersion: clientVers, 6317 }, 6318 }, 6319 flags: flags2, 6320 expectations: connectionExpectations{ 6321 version: expectedVersion, 6322 }, 6323 }) 6324 6325 testCases = append(testCases, testCase{ 6326 protocol: protocol, 6327 testType: serverTest, 6328 name: "VersionNegotiation-Server-" + suffix, 6329 config: Config{ 6330 MaxVersion: runnerVers.version, 6331 Bugs: ProtocolBugs{ 6332 ExpectInitialRecordVersion: serverVers, 6333 }, 6334 }, 6335 flags: flags, 6336 expectations: connectionExpectations{ 6337 version: expectedVersion, 6338 }, 6339 // The version name check does not recognize the 6340 // |excludeFlag| construction in |flags|. 6341 skipVersionNameCheck: true, 6342 }) 6343 testCases = append(testCases, testCase{ 6344 protocol: protocol, 6345 testType: serverTest, 6346 name: "VersionNegotiation-Server2-" + suffix, 6347 config: Config{ 6348 MaxVersion: runnerVers.version, 6349 Bugs: ProtocolBugs{ 6350 ExpectInitialRecordVersion: serverVers, 6351 }, 6352 }, 6353 flags: flags2, 6354 expectations: connectionExpectations{ 6355 version: expectedVersion, 6356 }, 6357 }) 6358 } 6359 } 6360 } 6361 6362 // Test the version extension at all versions. 6363 for _, protocol := range []protocol{tls, dtls, quic} { 6364 for _, vers := range allVersions(protocol) { 6365 suffix := vers.name + "-" + protocol.String() 6366 6367 testCases = append(testCases, testCase{ 6368 protocol: protocol, 6369 testType: serverTest, 6370 name: "VersionNegotiationExtension-" + suffix, 6371 config: Config{ 6372 Bugs: ProtocolBugs{ 6373 SendSupportedVersions: []uint16{0x1111, vers.wire(protocol), 0x2222}, 6374 IgnoreTLS13DowngradeRandom: true, 6375 }, 6376 }, 6377 expectations: connectionExpectations{ 6378 version: vers.version, 6379 }, 6380 }) 6381 } 6382 } 6383 6384 // If all versions are unknown, negotiation fails. 6385 testCases = append(testCases, testCase{ 6386 testType: serverTest, 6387 name: "NoSupportedVersions", 6388 config: Config{ 6389 Bugs: ProtocolBugs{ 6390 SendSupportedVersions: []uint16{0x1111}, 6391 }, 6392 }, 6393 shouldFail: true, 6394 expectedError: ":UNSUPPORTED_PROTOCOL:", 6395 }) 6396 testCases = append(testCases, testCase{ 6397 protocol: dtls, 6398 testType: serverTest, 6399 name: "NoSupportedVersions-DTLS", 6400 config: Config{ 6401 Bugs: ProtocolBugs{ 6402 SendSupportedVersions: []uint16{0x1111}, 6403 }, 6404 }, 6405 shouldFail: true, 6406 expectedError: ":UNSUPPORTED_PROTOCOL:", 6407 }) 6408 6409 testCases = append(testCases, testCase{ 6410 testType: serverTest, 6411 name: "ClientHelloVersionTooHigh", 6412 config: Config{ 6413 MaxVersion: VersionTLS13, 6414 Bugs: ProtocolBugs{ 6415 SendClientVersion: 0x0304, 6416 OmitSupportedVersions: true, 6417 IgnoreTLS13DowngradeRandom: true, 6418 }, 6419 }, 6420 expectations: connectionExpectations{ 6421 version: VersionTLS12, 6422 }, 6423 }) 6424 6425 testCases = append(testCases, testCase{ 6426 testType: serverTest, 6427 name: "ConflictingVersionNegotiation", 6428 config: Config{ 6429 Bugs: ProtocolBugs{ 6430 SendClientVersion: VersionTLS12, 6431 SendSupportedVersions: []uint16{VersionTLS11}, 6432 IgnoreTLS13DowngradeRandom: true, 6433 }, 6434 }, 6435 // The extension takes precedence over the ClientHello version. 6436 expectations: connectionExpectations{ 6437 version: VersionTLS11, 6438 }, 6439 }) 6440 6441 testCases = append(testCases, testCase{ 6442 testType: serverTest, 6443 name: "ConflictingVersionNegotiation-2", 6444 config: Config{ 6445 Bugs: ProtocolBugs{ 6446 SendClientVersion: VersionTLS11, 6447 SendSupportedVersions: []uint16{VersionTLS12}, 6448 IgnoreTLS13DowngradeRandom: true, 6449 }, 6450 }, 6451 // The extension takes precedence over the ClientHello version. 6452 expectations: connectionExpectations{ 6453 version: VersionTLS12, 6454 }, 6455 }) 6456 6457 // Test that TLS 1.2 isn't negotiated by the supported_versions extension in 6458 // the ServerHello. 6459 testCases = append(testCases, testCase{ 6460 testType: clientTest, 6461 name: "SupportedVersionSelection-TLS12", 6462 config: Config{ 6463 MaxVersion: VersionTLS12, 6464 Bugs: ProtocolBugs{ 6465 SendServerSupportedVersionExtension: VersionTLS12, 6466 }, 6467 }, 6468 shouldFail: true, 6469 expectedError: ":UNEXPECTED_EXTENSION:", 6470 }) 6471 6472 // Test that the maximum version is selected regardless of the 6473 // client-sent order. 6474 testCases = append(testCases, testCase{ 6475 testType: serverTest, 6476 name: "IgnoreClientVersionOrder", 6477 config: Config{ 6478 Bugs: ProtocolBugs{ 6479 SendSupportedVersions: []uint16{VersionTLS12, VersionTLS13}, 6480 }, 6481 }, 6482 expectations: connectionExpectations{ 6483 version: VersionTLS13, 6484 }, 6485 }) 6486 6487 // Test for version tolerance. 6488 testCases = append(testCases, testCase{ 6489 testType: serverTest, 6490 name: "MinorVersionTolerance", 6491 config: Config{ 6492 Bugs: ProtocolBugs{ 6493 SendClientVersion: 0x03ff, 6494 OmitSupportedVersions: true, 6495 IgnoreTLS13DowngradeRandom: true, 6496 }, 6497 }, 6498 expectations: connectionExpectations{ 6499 version: VersionTLS12, 6500 }, 6501 }) 6502 testCases = append(testCases, testCase{ 6503 testType: serverTest, 6504 name: "MajorVersionTolerance", 6505 config: Config{ 6506 Bugs: ProtocolBugs{ 6507 SendClientVersion: 0x0400, 6508 OmitSupportedVersions: true, 6509 IgnoreTLS13DowngradeRandom: true, 6510 }, 6511 }, 6512 // TLS 1.3 must be negotiated with the supported_versions 6513 // extension, not ClientHello.version. 6514 expectations: connectionExpectations{ 6515 version: VersionTLS12, 6516 }, 6517 }) 6518 testCases = append(testCases, testCase{ 6519 testType: serverTest, 6520 name: "VersionTolerance-TLS13", 6521 config: Config{ 6522 Bugs: ProtocolBugs{ 6523 // Although TLS 1.3 does not use 6524 // ClientHello.version, it still tolerates high 6525 // values there. 6526 SendClientVersion: 0x0400, 6527 }, 6528 }, 6529 expectations: connectionExpectations{ 6530 version: VersionTLS13, 6531 }, 6532 }) 6533 6534 testCases = append(testCases, testCase{ 6535 protocol: dtls, 6536 testType: serverTest, 6537 name: "MinorVersionTolerance-DTLS", 6538 config: Config{ 6539 Bugs: ProtocolBugs{ 6540 SendClientVersion: 0xfe00, 6541 OmitSupportedVersions: true, 6542 }, 6543 }, 6544 expectations: connectionExpectations{ 6545 version: VersionTLS12, 6546 }, 6547 }) 6548 testCases = append(testCases, testCase{ 6549 protocol: dtls, 6550 testType: serverTest, 6551 name: "MajorVersionTolerance-DTLS", 6552 config: Config{ 6553 Bugs: ProtocolBugs{ 6554 SendClientVersion: 0xfdff, 6555 OmitSupportedVersions: true, 6556 }, 6557 }, 6558 expectations: connectionExpectations{ 6559 version: VersionTLS12, 6560 }, 6561 }) 6562 6563 // Test that versions below 3.0 are rejected. 6564 testCases = append(testCases, testCase{ 6565 testType: serverTest, 6566 name: "VersionTooLow", 6567 config: Config{ 6568 Bugs: ProtocolBugs{ 6569 SendClientVersion: 0x0200, 6570 OmitSupportedVersions: true, 6571 }, 6572 }, 6573 shouldFail: true, 6574 expectedError: ":UNSUPPORTED_PROTOCOL:", 6575 }) 6576 testCases = append(testCases, testCase{ 6577 protocol: dtls, 6578 testType: serverTest, 6579 name: "VersionTooLow-DTLS", 6580 config: Config{ 6581 Bugs: ProtocolBugs{ 6582 SendClientVersion: 0xffff, 6583 }, 6584 }, 6585 shouldFail: true, 6586 expectedError: ":UNSUPPORTED_PROTOCOL:", 6587 }) 6588 6589 testCases = append(testCases, testCase{ 6590 name: "ServerBogusVersion", 6591 config: Config{ 6592 Bugs: ProtocolBugs{ 6593 SendServerHelloVersion: 0x1234, 6594 }, 6595 }, 6596 shouldFail: true, 6597 expectedError: ":UNSUPPORTED_PROTOCOL:", 6598 }) 6599 6600 // Test TLS 1.3's downgrade signal. 6601 var downgradeTests = []struct { 6602 name string 6603 version uint16 6604 clientShimError string 6605 }{ 6606 {"TLS12", VersionTLS12, "tls: downgrade from TLS 1.3 detected"}, 6607 {"TLS11", VersionTLS11, "tls: downgrade from TLS 1.2 detected"}, 6608 // TLS 1.0 does not have a dedicated value. 6609 {"TLS10", VersionTLS10, "tls: downgrade from TLS 1.2 detected"}, 6610 } 6611 6612 for _, test := range downgradeTests { 6613 // The client should enforce the downgrade sentinel. 6614 testCases = append(testCases, testCase{ 6615 name: "Downgrade-" + test.name + "-Client", 6616 config: Config{ 6617 Bugs: ProtocolBugs{ 6618 NegotiateVersion: test.version, 6619 }, 6620 }, 6621 expectations: connectionExpectations{ 6622 version: test.version, 6623 }, 6624 shouldFail: true, 6625 expectedError: ":TLS13_DOWNGRADE:", 6626 expectedLocalError: "remote error: illegal parameter", 6627 }) 6628 6629 // The server should emit the downgrade signal. 6630 testCases = append(testCases, testCase{ 6631 testType: serverTest, 6632 name: "Downgrade-" + test.name + "-Server", 6633 config: Config{ 6634 Bugs: ProtocolBugs{ 6635 SendSupportedVersions: []uint16{test.version}, 6636 }, 6637 }, 6638 expectations: connectionExpectations{ 6639 version: test.version, 6640 }, 6641 shouldFail: true, 6642 expectedLocalError: test.clientShimError, 6643 }) 6644 } 6645 6646 // SSL 3.0 support has been removed. Test that the shim does not 6647 // support it. 6648 testCases = append(testCases, testCase{ 6649 name: "NoSSL3-Client", 6650 config: Config{ 6651 MinVersion: VersionSSL30, 6652 MaxVersion: VersionSSL30, 6653 }, 6654 shouldFail: true, 6655 expectedLocalError: "tls: client did not offer any supported protocol versions", 6656 }) 6657 testCases = append(testCases, testCase{ 6658 name: "NoSSL3-Client-Unsolicited", 6659 config: Config{ 6660 MinVersion: VersionSSL30, 6661 MaxVersion: VersionSSL30, 6662 Bugs: ProtocolBugs{ 6663 // The above test asserts the client does not 6664 // offer SSL 3.0 in the supported_versions 6665 // list. Additionally assert that it rejects an 6666 // unsolicited SSL 3.0 ServerHello. 6667 NegotiateVersion: VersionSSL30, 6668 }, 6669 }, 6670 shouldFail: true, 6671 expectedError: ":UNSUPPORTED_PROTOCOL:", 6672 expectedLocalError: "remote error: protocol version not supported", 6673 }) 6674 testCases = append(testCases, testCase{ 6675 testType: serverTest, 6676 name: "NoSSL3-Server", 6677 config: Config{ 6678 MinVersion: VersionSSL30, 6679 MaxVersion: VersionSSL30, 6680 }, 6681 shouldFail: true, 6682 expectedError: ":UNSUPPORTED_PROTOCOL:", 6683 expectedLocalError: "remote error: protocol version not supported", 6684 }) 6685} 6686 6687func addMinimumVersionTests() { 6688 for _, protocol := range []protocol{tls, dtls, quic} { 6689 for _, shimVers := range allVersions(protocol) { 6690 // Assemble flags to disable all older versions on the shim. 6691 var flags []string 6692 for _, vers := range allVersions(protocol) { 6693 if vers.version < shimVers.version { 6694 flags = append(flags, vers.excludeFlag) 6695 } 6696 } 6697 6698 flags2 := []string{"-min-version", shimVers.shimFlag(protocol)} 6699 6700 for _, runnerVers := range allVersions(protocol) { 6701 suffix := shimVers.name + "-" + runnerVers.name 6702 suffix += "-" + protocol.String() 6703 6704 var expectedVersion uint16 6705 var shouldFail bool 6706 var expectedError, expectedLocalError string 6707 if runnerVers.version >= shimVers.version { 6708 expectedVersion = runnerVers.version 6709 } else { 6710 shouldFail = true 6711 expectedError = ":UNSUPPORTED_PROTOCOL:" 6712 expectedLocalError = "remote error: protocol version not supported" 6713 } 6714 6715 testCases = append(testCases, testCase{ 6716 protocol: protocol, 6717 testType: clientTest, 6718 name: "MinimumVersion-Client-" + suffix, 6719 config: Config{ 6720 MaxVersion: runnerVers.version, 6721 Bugs: ProtocolBugs{ 6722 // Ensure the server does not decline to 6723 // select a version (versions extension) or 6724 // cipher (some ciphers depend on versions). 6725 NegotiateVersion: runnerVers.wire(protocol), 6726 IgnorePeerCipherPreferences: shouldFail, 6727 }, 6728 }, 6729 flags: flags, 6730 expectations: connectionExpectations{ 6731 version: expectedVersion, 6732 }, 6733 shouldFail: shouldFail, 6734 expectedError: expectedError, 6735 expectedLocalError: expectedLocalError, 6736 // The version name check does not recognize the 6737 // |excludeFlag| construction in |flags|. 6738 skipVersionNameCheck: true, 6739 }) 6740 testCases = append(testCases, testCase{ 6741 protocol: protocol, 6742 testType: clientTest, 6743 name: "MinimumVersion-Client2-" + suffix, 6744 config: Config{ 6745 MaxVersion: runnerVers.version, 6746 Bugs: ProtocolBugs{ 6747 // Ensure the server does not decline to 6748 // select a version (versions extension) or 6749 // cipher (some ciphers depend on versions). 6750 NegotiateVersion: runnerVers.wire(protocol), 6751 IgnorePeerCipherPreferences: shouldFail, 6752 }, 6753 }, 6754 flags: flags2, 6755 expectations: connectionExpectations{ 6756 version: expectedVersion, 6757 }, 6758 shouldFail: shouldFail, 6759 expectedError: expectedError, 6760 expectedLocalError: expectedLocalError, 6761 }) 6762 6763 testCases = append(testCases, testCase{ 6764 protocol: protocol, 6765 testType: serverTest, 6766 name: "MinimumVersion-Server-" + suffix, 6767 config: Config{ 6768 MaxVersion: runnerVers.version, 6769 }, 6770 flags: flags, 6771 expectations: connectionExpectations{ 6772 version: expectedVersion, 6773 }, 6774 shouldFail: shouldFail, 6775 expectedError: expectedError, 6776 expectedLocalError: expectedLocalError, 6777 // The version name check does not recognize the 6778 // |excludeFlag| construction in |flags|. 6779 skipVersionNameCheck: true, 6780 }) 6781 testCases = append(testCases, testCase{ 6782 protocol: protocol, 6783 testType: serverTest, 6784 name: "MinimumVersion-Server2-" + suffix, 6785 config: Config{ 6786 MaxVersion: runnerVers.version, 6787 }, 6788 flags: flags2, 6789 expectations: connectionExpectations{ 6790 version: expectedVersion, 6791 }, 6792 shouldFail: shouldFail, 6793 expectedError: expectedError, 6794 expectedLocalError: expectedLocalError, 6795 }) 6796 } 6797 } 6798 } 6799} 6800 6801func addExtensionTests() { 6802 exampleCertificate := generateSingleCertChain(&x509.Certificate{ 6803 SerialNumber: big.NewInt(57005), 6804 Subject: pkix.Name{ 6805 CommonName: "test cert", 6806 }, 6807 NotBefore: time.Now().Add(-time.Hour), 6808 NotAfter: time.Now().Add(time.Hour), 6809 DNSNames: []string{"example.com"}, 6810 IsCA: true, 6811 BasicConstraintsValid: true, 6812 }, &ecdsaP256Key) 6813 6814 // Repeat extensions tests at all versions. 6815 for _, protocol := range []protocol{tls, dtls, quic} { 6816 for _, ver := range allVersions(protocol) { 6817 suffix := fmt.Sprintf("%s-%s", protocol.String(), ver.name) 6818 6819 // Test that duplicate extensions are rejected. 6820 testCases = append(testCases, testCase{ 6821 protocol: protocol, 6822 testType: clientTest, 6823 name: "DuplicateExtensionClient-" + suffix, 6824 config: Config{ 6825 MaxVersion: ver.version, 6826 Bugs: ProtocolBugs{ 6827 DuplicateExtension: true, 6828 }, 6829 }, 6830 shouldFail: true, 6831 expectedLocalError: "remote error: error decoding message", 6832 }) 6833 testCases = append(testCases, testCase{ 6834 protocol: protocol, 6835 testType: serverTest, 6836 name: "DuplicateExtensionServer-" + suffix, 6837 config: Config{ 6838 MaxVersion: ver.version, 6839 Bugs: ProtocolBugs{ 6840 DuplicateExtension: true, 6841 }, 6842 }, 6843 shouldFail: true, 6844 expectedLocalError: "remote error: error decoding message", 6845 }) 6846 6847 // Test SNI. 6848 testCases = append(testCases, testCase{ 6849 protocol: protocol, 6850 testType: clientTest, 6851 name: "ServerNameExtensionClient-" + suffix, 6852 config: Config{ 6853 MaxVersion: ver.version, 6854 Bugs: ProtocolBugs{ 6855 ExpectServerName: "example.com", 6856 }, 6857 Credential: &exampleCertificate, 6858 }, 6859 flags: []string{"-host-name", "example.com"}, 6860 }) 6861 testCases = append(testCases, testCase{ 6862 protocol: protocol, 6863 testType: clientTest, 6864 name: "ServerNameExtensionClientMismatch-" + suffix, 6865 config: Config{ 6866 MaxVersion: ver.version, 6867 Bugs: ProtocolBugs{ 6868 ExpectServerName: "mismatch.com", 6869 }, 6870 }, 6871 flags: []string{"-host-name", "example.com"}, 6872 shouldFail: true, 6873 expectedLocalError: "tls: unexpected server name", 6874 }) 6875 testCases = append(testCases, testCase{ 6876 protocol: protocol, 6877 testType: clientTest, 6878 name: "ServerNameExtensionClientMissing-" + suffix, 6879 config: Config{ 6880 MaxVersion: ver.version, 6881 Bugs: ProtocolBugs{ 6882 ExpectServerName: "missing.com", 6883 }, 6884 }, 6885 shouldFail: true, 6886 expectedLocalError: "tls: unexpected server name", 6887 }) 6888 testCases = append(testCases, testCase{ 6889 protocol: protocol, 6890 testType: clientTest, 6891 name: "TolerateServerNameAck-" + suffix, 6892 config: Config{ 6893 MaxVersion: ver.version, 6894 Bugs: ProtocolBugs{ 6895 SendServerNameAck: true, 6896 }, 6897 Credential: &exampleCertificate, 6898 }, 6899 flags: []string{"-host-name", "example.com"}, 6900 resumeSession: true, 6901 }) 6902 testCases = append(testCases, testCase{ 6903 protocol: protocol, 6904 testType: clientTest, 6905 name: "UnsolicitedServerNameAck-" + suffix, 6906 config: Config{ 6907 MaxVersion: ver.version, 6908 Bugs: ProtocolBugs{ 6909 SendServerNameAck: true, 6910 }, 6911 }, 6912 shouldFail: true, 6913 expectedError: ":UNEXPECTED_EXTENSION:", 6914 expectedLocalError: "remote error: unsupported extension", 6915 }) 6916 testCases = append(testCases, testCase{ 6917 protocol: protocol, 6918 testType: serverTest, 6919 name: "ServerNameExtensionServer-" + suffix, 6920 config: Config{ 6921 MaxVersion: ver.version, 6922 ServerName: "example.com", 6923 }, 6924 flags: []string{"-expect-server-name", "example.com"}, 6925 resumeSession: true, 6926 }) 6927 6928 // Test ALPN. 6929 testCases = append(testCases, testCase{ 6930 protocol: protocol, 6931 testType: clientTest, 6932 skipQUICALPNConfig: true, 6933 name: "ALPNClient-" + suffix, 6934 config: Config{ 6935 MaxVersion: ver.version, 6936 NextProtos: []string{"foo"}, 6937 }, 6938 flags: []string{ 6939 "-advertise-alpn", "\x03foo\x03bar\x03baz", 6940 "-expect-alpn", "foo", 6941 }, 6942 expectations: connectionExpectations{ 6943 nextProto: "foo", 6944 nextProtoType: alpn, 6945 }, 6946 resumeSession: true, 6947 }) 6948 testCases = append(testCases, testCase{ 6949 protocol: protocol, 6950 testType: clientTest, 6951 skipQUICALPNConfig: true, 6952 name: "ALPNClient-RejectUnknown-" + suffix, 6953 config: Config{ 6954 MaxVersion: ver.version, 6955 Bugs: ProtocolBugs{ 6956 SendALPN: "baz", 6957 }, 6958 }, 6959 flags: []string{ 6960 "-advertise-alpn", "\x03foo\x03bar", 6961 }, 6962 shouldFail: true, 6963 expectedError: ":INVALID_ALPN_PROTOCOL:", 6964 expectedLocalError: "remote error: illegal parameter", 6965 }) 6966 testCases = append(testCases, testCase{ 6967 protocol: protocol, 6968 testType: clientTest, 6969 skipQUICALPNConfig: true, 6970 name: "ALPNClient-AllowUnknown-" + suffix, 6971 config: Config{ 6972 MaxVersion: ver.version, 6973 Bugs: ProtocolBugs{ 6974 SendALPN: "baz", 6975 }, 6976 }, 6977 flags: []string{ 6978 "-advertise-alpn", "\x03foo\x03bar", 6979 "-allow-unknown-alpn-protos", 6980 "-expect-alpn", "baz", 6981 }, 6982 }) 6983 testCases = append(testCases, testCase{ 6984 protocol: protocol, 6985 testType: serverTest, 6986 skipQUICALPNConfig: true, 6987 name: "ALPNServer-" + suffix, 6988 config: Config{ 6989 MaxVersion: ver.version, 6990 NextProtos: []string{"foo", "bar", "baz"}, 6991 }, 6992 flags: []string{ 6993 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 6994 "-select-alpn", "foo", 6995 }, 6996 expectations: connectionExpectations{ 6997 nextProto: "foo", 6998 nextProtoType: alpn, 6999 }, 7000 resumeSession: true, 7001 }) 7002 7003 var shouldDeclineALPNFail bool 7004 var declineALPNError, declineALPNLocalError string 7005 if protocol == quic { 7006 // ALPN is mandatory in QUIC. 7007 shouldDeclineALPNFail = true 7008 declineALPNError = ":NO_APPLICATION_PROTOCOL:" 7009 declineALPNLocalError = "remote error: no application protocol" 7010 } 7011 testCases = append(testCases, testCase{ 7012 protocol: protocol, 7013 testType: serverTest, 7014 skipQUICALPNConfig: true, 7015 name: "ALPNServer-Decline-" + suffix, 7016 config: Config{ 7017 MaxVersion: ver.version, 7018 NextProtos: []string{"foo", "bar", "baz"}, 7019 }, 7020 flags: []string{"-decline-alpn"}, 7021 expectations: connectionExpectations{ 7022 noNextProto: true, 7023 }, 7024 resumeSession: true, 7025 shouldFail: shouldDeclineALPNFail, 7026 expectedError: declineALPNError, 7027 expectedLocalError: declineALPNLocalError, 7028 }) 7029 7030 testCases = append(testCases, testCase{ 7031 protocol: protocol, 7032 testType: serverTest, 7033 skipQUICALPNConfig: true, 7034 name: "ALPNServer-Reject-" + suffix, 7035 config: Config{ 7036 MaxVersion: ver.version, 7037 NextProtos: []string{"foo", "bar", "baz"}, 7038 }, 7039 flags: []string{"-reject-alpn"}, 7040 shouldFail: true, 7041 expectedError: ":NO_APPLICATION_PROTOCOL:", 7042 expectedLocalError: "remote error: no application protocol", 7043 }) 7044 7045 // Test that the server implementation catches itself if the 7046 // callback tries to return an invalid empty ALPN protocol. 7047 testCases = append(testCases, testCase{ 7048 protocol: protocol, 7049 testType: serverTest, 7050 skipQUICALPNConfig: true, 7051 name: "ALPNServer-SelectEmpty-" + suffix, 7052 config: Config{ 7053 MaxVersion: ver.version, 7054 NextProtos: []string{"foo", "bar", "baz"}, 7055 }, 7056 flags: []string{ 7057 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7058 "-select-empty-alpn", 7059 }, 7060 shouldFail: true, 7061 expectedLocalError: "remote error: internal error", 7062 expectedError: ":INVALID_ALPN_PROTOCOL:", 7063 }) 7064 7065 // Test ALPN in async mode as well to ensure that extensions callbacks are only 7066 // called once. 7067 testCases = append(testCases, testCase{ 7068 protocol: protocol, 7069 testType: serverTest, 7070 skipQUICALPNConfig: true, 7071 name: "ALPNServer-Async-" + suffix, 7072 config: Config{ 7073 MaxVersion: ver.version, 7074 NextProtos: []string{"foo", "bar", "baz"}, 7075 // Prior to TLS 1.3, exercise the asynchronous session callback. 7076 SessionTicketsDisabled: ver.version < VersionTLS13, 7077 }, 7078 flags: []string{ 7079 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7080 "-select-alpn", "foo", 7081 "-async", 7082 }, 7083 expectations: connectionExpectations{ 7084 nextProto: "foo", 7085 nextProtoType: alpn, 7086 }, 7087 resumeSession: true, 7088 }) 7089 7090 var emptyString string 7091 testCases = append(testCases, testCase{ 7092 protocol: protocol, 7093 testType: clientTest, 7094 skipQUICALPNConfig: true, 7095 name: "ALPNClient-EmptyProtocolName-" + suffix, 7096 config: Config{ 7097 MaxVersion: ver.version, 7098 NextProtos: []string{""}, 7099 Bugs: ProtocolBugs{ 7100 // A server returning an empty ALPN protocol 7101 // should be rejected. 7102 ALPNProtocol: &emptyString, 7103 }, 7104 }, 7105 flags: []string{ 7106 "-advertise-alpn", "\x03foo", 7107 }, 7108 shouldFail: true, 7109 expectedError: ":PARSE_TLSEXT:", 7110 }) 7111 testCases = append(testCases, testCase{ 7112 protocol: protocol, 7113 testType: serverTest, 7114 skipQUICALPNConfig: true, 7115 name: "ALPNServer-EmptyProtocolName-" + suffix, 7116 config: Config{ 7117 MaxVersion: ver.version, 7118 // A ClientHello containing an empty ALPN protocol 7119 // should be rejected. 7120 NextProtos: []string{"foo", "", "baz"}, 7121 }, 7122 flags: []string{ 7123 "-select-alpn", "foo", 7124 }, 7125 shouldFail: true, 7126 expectedError: ":PARSE_TLSEXT:", 7127 }) 7128 7129 // Test NPN and the interaction with ALPN. 7130 if ver.version < VersionTLS13 && protocol == tls { 7131 // Test that the server prefers ALPN over NPN. 7132 testCases = append(testCases, testCase{ 7133 protocol: protocol, 7134 testType: serverTest, 7135 name: "ALPNServer-Preferred-" + suffix, 7136 config: Config{ 7137 MaxVersion: ver.version, 7138 NextProtos: []string{"foo", "bar", "baz"}, 7139 }, 7140 flags: []string{ 7141 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7142 "-select-alpn", "foo", 7143 "-advertise-npn", "\x03foo\x03bar\x03baz", 7144 }, 7145 expectations: connectionExpectations{ 7146 nextProto: "foo", 7147 nextProtoType: alpn, 7148 }, 7149 resumeSession: true, 7150 }) 7151 testCases = append(testCases, testCase{ 7152 protocol: protocol, 7153 testType: serverTest, 7154 name: "ALPNServer-Preferred-Swapped-" + suffix, 7155 config: Config{ 7156 MaxVersion: ver.version, 7157 NextProtos: []string{"foo", "bar", "baz"}, 7158 Bugs: ProtocolBugs{ 7159 SwapNPNAndALPN: true, 7160 }, 7161 }, 7162 flags: []string{ 7163 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7164 "-select-alpn", "foo", 7165 "-advertise-npn", "\x03foo\x03bar\x03baz", 7166 }, 7167 expectations: connectionExpectations{ 7168 nextProto: "foo", 7169 nextProtoType: alpn, 7170 }, 7171 resumeSession: true, 7172 }) 7173 7174 // Test that negotiating both NPN and ALPN is forbidden. 7175 testCases = append(testCases, testCase{ 7176 protocol: protocol, 7177 name: "NegotiateALPNAndNPN-" + suffix, 7178 config: Config{ 7179 MaxVersion: ver.version, 7180 NextProtos: []string{"foo", "bar", "baz"}, 7181 Bugs: ProtocolBugs{ 7182 NegotiateALPNAndNPN: true, 7183 }, 7184 }, 7185 flags: []string{ 7186 "-advertise-alpn", "\x03foo", 7187 "-select-next-proto", "foo", 7188 }, 7189 shouldFail: true, 7190 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:", 7191 }) 7192 testCases = append(testCases, testCase{ 7193 protocol: protocol, 7194 name: "NegotiateALPNAndNPN-Swapped-" + suffix, 7195 config: Config{ 7196 MaxVersion: ver.version, 7197 NextProtos: []string{"foo", "bar", "baz"}, 7198 Bugs: ProtocolBugs{ 7199 NegotiateALPNAndNPN: true, 7200 SwapNPNAndALPN: true, 7201 }, 7202 }, 7203 flags: []string{ 7204 "-advertise-alpn", "\x03foo", 7205 "-select-next-proto", "foo", 7206 }, 7207 shouldFail: true, 7208 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:", 7209 }) 7210 } 7211 7212 // Test missing ALPN in QUIC 7213 if protocol == quic { 7214 testCases = append(testCases, testCase{ 7215 testType: clientTest, 7216 protocol: protocol, 7217 name: "Client-ALPNMissingFromConfig-" + suffix, 7218 config: Config{ 7219 MinVersion: ver.version, 7220 MaxVersion: ver.version, 7221 }, 7222 skipQUICALPNConfig: true, 7223 shouldFail: true, 7224 expectedError: ":NO_APPLICATION_PROTOCOL:", 7225 }) 7226 testCases = append(testCases, testCase{ 7227 testType: clientTest, 7228 protocol: protocol, 7229 name: "Client-ALPNMissing-" + suffix, 7230 config: Config{ 7231 MinVersion: ver.version, 7232 MaxVersion: ver.version, 7233 }, 7234 flags: []string{ 7235 "-advertise-alpn", "\x03foo", 7236 }, 7237 skipQUICALPNConfig: true, 7238 shouldFail: true, 7239 expectedError: ":NO_APPLICATION_PROTOCOL:", 7240 expectedLocalError: "remote error: no application protocol", 7241 }) 7242 testCases = append(testCases, testCase{ 7243 testType: serverTest, 7244 protocol: protocol, 7245 name: "Server-ALPNMissing-" + suffix, 7246 config: Config{ 7247 MinVersion: ver.version, 7248 MaxVersion: ver.version, 7249 }, 7250 skipQUICALPNConfig: true, 7251 shouldFail: true, 7252 expectedError: ":NO_APPLICATION_PROTOCOL:", 7253 expectedLocalError: "remote error: no application protocol", 7254 }) 7255 testCases = append(testCases, testCase{ 7256 testType: serverTest, 7257 protocol: protocol, 7258 name: "Server-ALPNMismatch-" + suffix, 7259 config: Config{ 7260 MinVersion: ver.version, 7261 MaxVersion: ver.version, 7262 NextProtos: []string{"foo"}, 7263 }, 7264 flags: []string{ 7265 "-decline-alpn", 7266 }, 7267 skipQUICALPNConfig: true, 7268 shouldFail: true, 7269 expectedError: ":NO_APPLICATION_PROTOCOL:", 7270 expectedLocalError: "remote error: no application protocol", 7271 }) 7272 } 7273 7274 // Test ALPS. 7275 if ver.version >= VersionTLS13 { 7276 // Test basic client with different ALPS codepoint. 7277 for _, alpsCodePoint := range []ALPSUseCodepoint{ALPSUseCodepointNew, ALPSUseCodepointOld} { 7278 flags := []string{} 7279 expectations := connectionExpectations{ 7280 peerApplicationSettingsOld: []byte("shim1"), 7281 } 7282 resumeExpectations := &connectionExpectations{ 7283 peerApplicationSettingsOld: []byte("shim2"), 7284 } 7285 7286 if alpsCodePoint == ALPSUseCodepointNew { 7287 flags = append(flags, "-alps-use-new-codepoint") 7288 expectations = connectionExpectations{ 7289 peerApplicationSettings: []byte("shim1"), 7290 } 7291 resumeExpectations = &connectionExpectations{ 7292 peerApplicationSettings: []byte("shim2"), 7293 } 7294 } 7295 7296 flags = append(flags, 7297 "-advertise-alpn", "\x05proto", 7298 "-expect-alpn", "proto", 7299 "-on-initial-application-settings", "proto,shim1", 7300 "-on-initial-expect-peer-application-settings", "runner1", 7301 "-on-resume-application-settings", "proto,shim2", 7302 "-on-resume-expect-peer-application-settings", "runner2") 7303 7304 // Test that server can negotiate ALPS, including different values 7305 // on resumption. 7306 testCases = append(testCases, testCase{ 7307 protocol: protocol, 7308 testType: clientTest, 7309 name: fmt.Sprintf("ALPS-Basic-Client-%s-%s", alpsCodePoint, suffix), 7310 skipQUICALPNConfig: true, 7311 config: Config{ 7312 MaxVersion: ver.version, 7313 NextProtos: []string{"proto"}, 7314 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7315 ALPSUseNewCodepoint: alpsCodePoint, 7316 }, 7317 resumeConfig: &Config{ 7318 MaxVersion: ver.version, 7319 NextProtos: []string{"proto"}, 7320 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7321 ALPSUseNewCodepoint: alpsCodePoint, 7322 }, 7323 resumeSession: true, 7324 expectations: expectations, 7325 resumeExpectations: resumeExpectations, 7326 flags: flags, 7327 }) 7328 7329 // Test basic server with different ALPS codepoint. 7330 flags = []string{} 7331 expectations = connectionExpectations{ 7332 peerApplicationSettingsOld: []byte("shim1"), 7333 } 7334 resumeExpectations = &connectionExpectations{ 7335 peerApplicationSettingsOld: []byte("shim2"), 7336 } 7337 7338 if alpsCodePoint == ALPSUseCodepointNew { 7339 flags = append(flags, "-alps-use-new-codepoint") 7340 expectations = connectionExpectations{ 7341 peerApplicationSettings: []byte("shim1"), 7342 } 7343 resumeExpectations = &connectionExpectations{ 7344 peerApplicationSettings: []byte("shim2"), 7345 } 7346 } 7347 7348 flags = append(flags, 7349 "-select-alpn", "proto", 7350 "-on-initial-application-settings", "proto,shim1", 7351 "-on-initial-expect-peer-application-settings", "runner1", 7352 "-on-resume-application-settings", "proto,shim2", 7353 "-on-resume-expect-peer-application-settings", "runner2") 7354 7355 // Test that server can negotiate ALPS, including different values 7356 // on resumption. 7357 testCases = append(testCases, testCase{ 7358 protocol: protocol, 7359 testType: serverTest, 7360 name: fmt.Sprintf("ALPS-Basic-Server-%s-%s", alpsCodePoint, suffix), 7361 skipQUICALPNConfig: true, 7362 config: Config{ 7363 MaxVersion: ver.version, 7364 NextProtos: []string{"proto"}, 7365 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7366 ALPSUseNewCodepoint: alpsCodePoint, 7367 }, 7368 resumeConfig: &Config{ 7369 MaxVersion: ver.version, 7370 NextProtos: []string{"proto"}, 7371 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7372 ALPSUseNewCodepoint: alpsCodePoint, 7373 }, 7374 resumeSession: true, 7375 expectations: expectations, 7376 resumeExpectations: resumeExpectations, 7377 flags: flags, 7378 }) 7379 7380 // Try different ALPS codepoint for all the existing tests. 7381 alpsFlags := []string{} 7382 expectations = connectionExpectations{ 7383 peerApplicationSettingsOld: []byte("shim1"), 7384 } 7385 resumeExpectations = &connectionExpectations{ 7386 peerApplicationSettingsOld: []byte("shim2"), 7387 } 7388 if alpsCodePoint == ALPSUseCodepointNew { 7389 alpsFlags = append(alpsFlags, "-alps-use-new-codepoint") 7390 expectations = connectionExpectations{ 7391 peerApplicationSettings: []byte("shim1"), 7392 } 7393 resumeExpectations = &connectionExpectations{ 7394 peerApplicationSettings: []byte("shim2"), 7395 } 7396 } 7397 7398 // Test that the server can defer its ALPS configuration to the ALPN 7399 // selection callback. 7400 testCases = append(testCases, testCase{ 7401 protocol: protocol, 7402 testType: serverTest, 7403 name: fmt.Sprintf("ALPS-Basic-Server-Defer-%s-%s", alpsCodePoint, suffix), 7404 skipQUICALPNConfig: true, 7405 config: Config{ 7406 MaxVersion: ver.version, 7407 NextProtos: []string{"proto"}, 7408 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7409 ALPSUseNewCodepoint: alpsCodePoint, 7410 }, 7411 resumeConfig: &Config{ 7412 MaxVersion: ver.version, 7413 NextProtos: []string{"proto"}, 7414 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7415 ALPSUseNewCodepoint: alpsCodePoint, 7416 }, 7417 resumeSession: true, 7418 expectations: expectations, 7419 resumeExpectations: resumeExpectations, 7420 flags: append([]string{ 7421 "-select-alpn", "proto", 7422 "-defer-alps", 7423 "-on-initial-application-settings", "proto,shim1", 7424 "-on-initial-expect-peer-application-settings", "runner1", 7425 "-on-resume-application-settings", "proto,shim2", 7426 "-on-resume-expect-peer-application-settings", "runner2", 7427 }, alpsFlags...), 7428 }) 7429 7430 expectations = connectionExpectations{ 7431 peerApplicationSettingsOld: []byte{}, 7432 } 7433 if alpsCodePoint == ALPSUseCodepointNew { 7434 expectations = connectionExpectations{ 7435 peerApplicationSettings: []byte{}, 7436 } 7437 } 7438 // Test the client and server correctly handle empty settings. 7439 testCases = append(testCases, testCase{ 7440 protocol: protocol, 7441 testType: clientTest, 7442 name: fmt.Sprintf("ALPS-Empty-Client-%s-%s", alpsCodePoint, suffix), 7443 skipQUICALPNConfig: true, 7444 config: Config{ 7445 MaxVersion: ver.version, 7446 NextProtos: []string{"proto"}, 7447 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7448 ALPSUseNewCodepoint: alpsCodePoint, 7449 }, 7450 resumeSession: true, 7451 expectations: expectations, 7452 flags: append([]string{ 7453 "-advertise-alpn", "\x05proto", 7454 "-expect-alpn", "proto", 7455 "-application-settings", "proto,", 7456 "-expect-peer-application-settings", "", 7457 }, alpsFlags...), 7458 }) 7459 testCases = append(testCases, testCase{ 7460 protocol: protocol, 7461 testType: serverTest, 7462 name: fmt.Sprintf("ALPS-Empty-Server-%s-%s", alpsCodePoint, suffix), 7463 skipQUICALPNConfig: true, 7464 config: Config{ 7465 MaxVersion: ver.version, 7466 NextProtos: []string{"proto"}, 7467 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7468 ALPSUseNewCodepoint: alpsCodePoint, 7469 }, 7470 resumeSession: true, 7471 expectations: expectations, 7472 flags: append([]string{ 7473 "-select-alpn", "proto", 7474 "-application-settings", "proto,", 7475 "-expect-peer-application-settings", "", 7476 }, alpsFlags...), 7477 }) 7478 7479 bugs := ProtocolBugs{ 7480 AlwaysNegotiateApplicationSettingsOld: true, 7481 } 7482 if alpsCodePoint == ALPSUseCodepointNew { 7483 bugs = ProtocolBugs{ 7484 AlwaysNegotiateApplicationSettingsNew: true, 7485 } 7486 } 7487 // Test the client rejects application settings from the server on 7488 // protocols it doesn't have them. 7489 testCases = append(testCases, testCase{ 7490 protocol: protocol, 7491 testType: clientTest, 7492 name: fmt.Sprintf("ALPS-UnsupportedProtocol-Client-%s-%s", alpsCodePoint, suffix), 7493 skipQUICALPNConfig: true, 7494 config: Config{ 7495 MaxVersion: ver.version, 7496 NextProtos: []string{"proto1"}, 7497 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7498 Bugs: bugs, 7499 ALPSUseNewCodepoint: alpsCodePoint, 7500 }, 7501 // The client supports ALPS with "proto2", but not "proto1". 7502 flags: append([]string{ 7503 "-advertise-alpn", "\x06proto1\x06proto2", 7504 "-application-settings", "proto2,shim", 7505 "-expect-alpn", "proto1", 7506 }, alpsFlags...), 7507 // The server sends ALPS with "proto1", which is invalid. 7508 shouldFail: true, 7509 expectedError: ":INVALID_ALPN_PROTOCOL:", 7510 expectedLocalError: "remote error: illegal parameter", 7511 }) 7512 7513 // Test client rejects application settings from the server when 7514 // server sends the wrong ALPS codepoint. 7515 bugs = ProtocolBugs{ 7516 AlwaysNegotiateApplicationSettingsOld: true, 7517 } 7518 if alpsCodePoint == ALPSUseCodepointOld { 7519 bugs = ProtocolBugs{ 7520 AlwaysNegotiateApplicationSettingsNew: true, 7521 } 7522 } 7523 7524 testCases = append(testCases, testCase{ 7525 protocol: protocol, 7526 testType: clientTest, 7527 name: fmt.Sprintf("ALPS-WrongServerCodepoint-Client-%s-%s", alpsCodePoint, suffix), 7528 skipQUICALPNConfig: true, 7529 config: Config{ 7530 MaxVersion: ver.version, 7531 NextProtos: []string{"proto"}, 7532 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7533 Bugs: bugs, 7534 ALPSUseNewCodepoint: alpsCodePoint, 7535 }, 7536 flags: append([]string{ 7537 "-advertise-alpn", "\x05proto", 7538 "-expect-alpn", "proto", 7539 "-application-settings", "proto,", 7540 "-expect-peer-application-settings", "", 7541 }, alpsFlags...), 7542 shouldFail: true, 7543 expectedError: ":UNEXPECTED_EXTENSION:", 7544 expectedLocalError: "remote error: unsupported extension", 7545 }) 7546 7547 // Test server ignore wrong codepoint from client. 7548 clientSends := ALPSUseCodepointNew 7549 if alpsCodePoint == ALPSUseCodepointNew { 7550 clientSends = ALPSUseCodepointOld 7551 } 7552 7553 testCases = append(testCases, testCase{ 7554 protocol: protocol, 7555 testType: serverTest, 7556 name: fmt.Sprintf("ALPS-IgnoreClientWrongCodepoint-Server-%s-%s", alpsCodePoint, suffix), 7557 skipQUICALPNConfig: true, 7558 config: Config{ 7559 MaxVersion: ver.version, 7560 NextProtos: []string{"proto"}, 7561 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7562 ALPSUseNewCodepoint: clientSends, 7563 }, 7564 resumeConfig: &Config{ 7565 MaxVersion: ver.version, 7566 NextProtos: []string{"proto"}, 7567 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7568 ALPSUseNewCodepoint: clientSends, 7569 }, 7570 resumeSession: true, 7571 flags: append([]string{ 7572 "-select-alpn", "proto", 7573 "-on-initial-application-settings", "proto,shim1", 7574 "-on-resume-application-settings", "proto,shim2", 7575 }, alpsFlags...), 7576 }) 7577 7578 // Test the server declines ALPS if it doesn't support it for the 7579 // specified protocol. 7580 testCases = append(testCases, testCase{ 7581 protocol: protocol, 7582 testType: serverTest, 7583 name: fmt.Sprintf("ALPS-UnsupportedProtocol-Server-%s-%s", alpsCodePoint, suffix), 7584 skipQUICALPNConfig: true, 7585 config: Config{ 7586 MaxVersion: ver.version, 7587 NextProtos: []string{"proto1"}, 7588 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7589 ALPSUseNewCodepoint: alpsCodePoint, 7590 }, 7591 // The server supports ALPS with "proto2", but not "proto1". 7592 flags: append([]string{ 7593 "-select-alpn", "proto1", 7594 "-application-settings", "proto2,shim", 7595 }, alpsFlags...), 7596 }) 7597 7598 // Test the client rejects application settings from the server when 7599 // it always negotiate both codepoint. 7600 testCases = append(testCases, testCase{ 7601 protocol: protocol, 7602 testType: clientTest, 7603 name: fmt.Sprintf("ALPS-UnsupportedProtocol-Client-ServerBoth-%s-%s", alpsCodePoint, suffix), 7604 skipQUICALPNConfig: true, 7605 config: Config{ 7606 MaxVersion: ver.version, 7607 NextProtos: []string{"proto1"}, 7608 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7609 Bugs: ProtocolBugs{ 7610 AlwaysNegotiateApplicationSettingsBoth: true, 7611 }, 7612 ALPSUseNewCodepoint: alpsCodePoint, 7613 }, 7614 flags: append([]string{ 7615 "-advertise-alpn", "\x06proto1\x06proto2", 7616 "-application-settings", "proto1,shim", 7617 "-expect-alpn", "proto1", 7618 }, alpsFlags...), 7619 // The server sends ALPS with both application settings, which is invalid. 7620 shouldFail: true, 7621 expectedError: ":UNEXPECTED_EXTENSION:", 7622 expectedLocalError: "remote error: unsupported extension", 7623 }) 7624 7625 expectations = connectionExpectations{ 7626 peerApplicationSettingsOld: []byte("shim"), 7627 } 7628 if alpsCodePoint == ALPSUseCodepointNew { 7629 expectations = connectionExpectations{ 7630 peerApplicationSettings: []byte("shim"), 7631 } 7632 } 7633 7634 // Test that the server rejects a missing application_settings extension. 7635 testCases = append(testCases, testCase{ 7636 protocol: protocol, 7637 testType: serverTest, 7638 name: fmt.Sprintf("ALPS-OmitClientApplicationSettings-%s-%s", alpsCodePoint, suffix), 7639 skipQUICALPNConfig: true, 7640 config: Config{ 7641 MaxVersion: ver.version, 7642 NextProtos: []string{"proto"}, 7643 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7644 Bugs: ProtocolBugs{ 7645 OmitClientApplicationSettings: true, 7646 }, 7647 ALPSUseNewCodepoint: alpsCodePoint, 7648 }, 7649 flags: append([]string{ 7650 "-select-alpn", "proto", 7651 "-application-settings", "proto,shim", 7652 }, alpsFlags...), 7653 // The runner is a client, so it only processes the shim's alert 7654 // after checking connection state. 7655 expectations: expectations, 7656 shouldFail: true, 7657 expectedError: ":MISSING_EXTENSION:", 7658 expectedLocalError: "remote error: missing extension", 7659 }) 7660 7661 // Test that the server rejects a missing EncryptedExtensions message. 7662 testCases = append(testCases, testCase{ 7663 protocol: protocol, 7664 testType: serverTest, 7665 name: fmt.Sprintf("ALPS-OmitClientEncryptedExtensions-%s-%s", alpsCodePoint, suffix), 7666 skipQUICALPNConfig: true, 7667 config: Config{ 7668 MaxVersion: ver.version, 7669 NextProtos: []string{"proto"}, 7670 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7671 Bugs: ProtocolBugs{ 7672 OmitClientEncryptedExtensions: true, 7673 }, 7674 ALPSUseNewCodepoint: alpsCodePoint, 7675 }, 7676 flags: append([]string{ 7677 "-select-alpn", "proto", 7678 "-application-settings", "proto,shim", 7679 }, alpsFlags...), 7680 // The runner is a client, so it only processes the shim's alert 7681 // after checking connection state. 7682 expectations: expectations, 7683 shouldFail: true, 7684 expectedError: ":UNEXPECTED_MESSAGE:", 7685 expectedLocalError: "remote error: unexpected message", 7686 }) 7687 7688 // Test that the server rejects an unexpected EncryptedExtensions message. 7689 testCases = append(testCases, testCase{ 7690 protocol: protocol, 7691 testType: serverTest, 7692 name: fmt.Sprintf("UnexpectedClientEncryptedExtensions-%s-%s", alpsCodePoint, suffix), 7693 config: Config{ 7694 MaxVersion: ver.version, 7695 Bugs: ProtocolBugs{ 7696 AlwaysSendClientEncryptedExtensions: true, 7697 }, 7698 ALPSUseNewCodepoint: alpsCodePoint, 7699 }, 7700 shouldFail: true, 7701 expectedError: ":UNEXPECTED_MESSAGE:", 7702 expectedLocalError: "remote error: unexpected message", 7703 }) 7704 7705 // Test that the server rejects an unexpected extension in an 7706 // expected EncryptedExtensions message. 7707 testCases = append(testCases, testCase{ 7708 protocol: protocol, 7709 testType: serverTest, 7710 name: fmt.Sprintf("ExtraClientEncryptedExtension-%s-%s", alpsCodePoint, suffix), 7711 skipQUICALPNConfig: true, 7712 config: Config{ 7713 MaxVersion: ver.version, 7714 NextProtos: []string{"proto"}, 7715 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7716 Bugs: ProtocolBugs{ 7717 SendExtraClientEncryptedExtension: true, 7718 }, 7719 ALPSUseNewCodepoint: alpsCodePoint, 7720 }, 7721 flags: append([]string{ 7722 "-select-alpn", "proto", 7723 "-application-settings", "proto,shim", 7724 }, alpsFlags...), 7725 // The runner is a client, so it only processes the shim's alert 7726 // after checking connection state. 7727 expectations: expectations, 7728 shouldFail: true, 7729 expectedError: ":UNEXPECTED_EXTENSION:", 7730 expectedLocalError: "remote error: unsupported extension", 7731 }) 7732 7733 // Test that ALPS is carried over on 0-RTT. 7734 for _, empty := range []bool{false, true} { 7735 maybeEmpty := "" 7736 runnerSettings := "runner" 7737 shimSettings := "shim" 7738 if empty { 7739 maybeEmpty = "Empty-" 7740 runnerSettings = "" 7741 shimSettings = "" 7742 } 7743 7744 expectations = connectionExpectations{ 7745 peerApplicationSettingsOld: []byte(shimSettings), 7746 } 7747 if alpsCodePoint == ALPSUseCodepointNew { 7748 expectations = connectionExpectations{ 7749 peerApplicationSettings: []byte(shimSettings), 7750 } 7751 } 7752 testCases = append(testCases, testCase{ 7753 protocol: protocol, 7754 testType: clientTest, 7755 name: fmt.Sprintf("ALPS-EarlyData-Client-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7756 skipQUICALPNConfig: true, 7757 config: Config{ 7758 MaxVersion: ver.version, 7759 NextProtos: []string{"proto"}, 7760 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7761 ALPSUseNewCodepoint: alpsCodePoint, 7762 }, 7763 resumeSession: true, 7764 earlyData: true, 7765 flags: append([]string{ 7766 "-advertise-alpn", "\x05proto", 7767 "-expect-alpn", "proto", 7768 "-application-settings", "proto," + shimSettings, 7769 "-expect-peer-application-settings", runnerSettings, 7770 }, alpsFlags...), 7771 expectations: expectations, 7772 }) 7773 testCases = append(testCases, testCase{ 7774 protocol: protocol, 7775 testType: serverTest, 7776 name: fmt.Sprintf("ALPS-EarlyData-Server-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7777 skipQUICALPNConfig: true, 7778 config: Config{ 7779 MaxVersion: ver.version, 7780 NextProtos: []string{"proto"}, 7781 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7782 ALPSUseNewCodepoint: alpsCodePoint, 7783 }, 7784 resumeSession: true, 7785 earlyData: true, 7786 flags: append([]string{ 7787 "-select-alpn", "proto", 7788 "-application-settings", "proto," + shimSettings, 7789 "-expect-peer-application-settings", runnerSettings, 7790 }, alpsFlags...), 7791 expectations: expectations, 7792 }) 7793 7794 // Sending application settings in 0-RTT handshakes is forbidden. 7795 testCases = append(testCases, testCase{ 7796 protocol: protocol, 7797 testType: clientTest, 7798 name: fmt.Sprintf("ALPS-EarlyData-SendApplicationSettingsWithEarlyData-Client-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7799 skipQUICALPNConfig: true, 7800 config: Config{ 7801 MaxVersion: ver.version, 7802 NextProtos: []string{"proto"}, 7803 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7804 Bugs: ProtocolBugs{ 7805 SendApplicationSettingsWithEarlyData: true, 7806 }, 7807 ALPSUseNewCodepoint: alpsCodePoint, 7808 }, 7809 resumeSession: true, 7810 earlyData: true, 7811 flags: append([]string{ 7812 "-advertise-alpn", "\x05proto", 7813 "-expect-alpn", "proto", 7814 "-application-settings", "proto," + shimSettings, 7815 "-expect-peer-application-settings", runnerSettings, 7816 }, alpsFlags...), 7817 expectations: expectations, 7818 shouldFail: true, 7819 expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:", 7820 expectedLocalError: "remote error: illegal parameter", 7821 }) 7822 testCases = append(testCases, testCase{ 7823 protocol: protocol, 7824 testType: serverTest, 7825 name: fmt.Sprintf("ALPS-EarlyData-SendApplicationSettingsWithEarlyData-Server-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7826 skipQUICALPNConfig: true, 7827 config: Config{ 7828 MaxVersion: ver.version, 7829 NextProtos: []string{"proto"}, 7830 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7831 Bugs: ProtocolBugs{ 7832 SendApplicationSettingsWithEarlyData: true, 7833 }, 7834 ALPSUseNewCodepoint: alpsCodePoint, 7835 }, 7836 resumeSession: true, 7837 earlyData: true, 7838 flags: append([]string{ 7839 "-select-alpn", "proto", 7840 "-application-settings", "proto," + shimSettings, 7841 "-expect-peer-application-settings", runnerSettings, 7842 }, alpsFlags...), 7843 expectations: expectations, 7844 shouldFail: true, 7845 expectedError: ":UNEXPECTED_MESSAGE:", 7846 expectedLocalError: "remote error: unexpected message", 7847 }) 7848 } 7849 7850 // Test that the client and server each decline early data if local 7851 // ALPS preferences has changed for the current connection. 7852 alpsMismatchTests := []struct { 7853 name string 7854 initialSettings, resumeSettings []byte 7855 }{ 7856 {"DifferentValues", []byte("settings1"), []byte("settings2")}, 7857 {"OnOff", []byte("settings"), nil}, 7858 {"OffOn", nil, []byte("settings")}, 7859 // The empty settings value should not be mistaken for ALPS not 7860 // being negotiated. 7861 {"OnEmpty", []byte("settings"), []byte{}}, 7862 {"EmptyOn", []byte{}, []byte("settings")}, 7863 {"EmptyOff", []byte{}, nil}, 7864 {"OffEmpty", nil, []byte{}}, 7865 } 7866 for _, test := range alpsMismatchTests { 7867 flags := []string{"-on-resume-expect-early-data-reason", "alps_mismatch"} 7868 flags = append(flags, alpsFlags...) 7869 if test.initialSettings != nil { 7870 flags = append(flags, "-on-initial-application-settings", "proto,"+string(test.initialSettings)) 7871 flags = append(flags, "-on-initial-expect-peer-application-settings", "runner") 7872 } 7873 if test.resumeSettings != nil { 7874 flags = append(flags, "-on-resume-application-settings", "proto,"+string(test.resumeSettings)) 7875 flags = append(flags, "-on-resume-expect-peer-application-settings", "runner") 7876 } 7877 7878 expectations = connectionExpectations{ 7879 peerApplicationSettingsOld: test.initialSettings, 7880 } 7881 resumeExpectations = &connectionExpectations{ 7882 peerApplicationSettingsOld: test.resumeSettings, 7883 } 7884 if alpsCodePoint == ALPSUseCodepointNew { 7885 expectations = connectionExpectations{ 7886 peerApplicationSettings: test.initialSettings, 7887 } 7888 resumeExpectations = &connectionExpectations{ 7889 peerApplicationSettings: test.resumeSettings, 7890 } 7891 } 7892 // The client should not offer early data if the session is 7893 // inconsistent with the new configuration. Note that if 7894 // the session did not negotiate ALPS (test.initialSettings 7895 // is nil), the client always offers early data. 7896 if test.initialSettings != nil { 7897 testCases = append(testCases, testCase{ 7898 protocol: protocol, 7899 testType: clientTest, 7900 name: fmt.Sprintf("ALPS-EarlyData-Mismatch-%s-Client-%s-%s", test.name, alpsCodePoint, suffix), 7901 skipQUICALPNConfig: true, 7902 config: Config{ 7903 MaxVersion: ver.version, 7904 MaxEarlyDataSize: 16384, 7905 NextProtos: []string{"proto"}, 7906 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7907 ALPSUseNewCodepoint: alpsCodePoint, 7908 }, 7909 resumeSession: true, 7910 flags: append([]string{ 7911 "-enable-early-data", 7912 "-expect-ticket-supports-early-data", 7913 "-expect-no-offer-early-data", 7914 "-advertise-alpn", "\x05proto", 7915 "-expect-alpn", "proto", 7916 }, flags...), 7917 expectations: expectations, 7918 resumeExpectations: resumeExpectations, 7919 }) 7920 } 7921 7922 // The server should reject early data if the session is 7923 // inconsistent with the new selection. 7924 testCases = append(testCases, testCase{ 7925 protocol: protocol, 7926 testType: serverTest, 7927 name: fmt.Sprintf("ALPS-EarlyData-Mismatch-%s-Server-%s-%s", test.name, alpsCodePoint, suffix), 7928 skipQUICALPNConfig: true, 7929 config: Config{ 7930 MaxVersion: ver.version, 7931 NextProtos: []string{"proto"}, 7932 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7933 ALPSUseNewCodepoint: alpsCodePoint, 7934 }, 7935 resumeSession: true, 7936 earlyData: true, 7937 expectEarlyDataRejected: true, 7938 flags: append([]string{ 7939 "-select-alpn", "proto", 7940 }, flags...), 7941 expectations: expectations, 7942 resumeExpectations: resumeExpectations, 7943 }) 7944 } 7945 7946 // Test that 0-RTT continues working when the shim configures 7947 // ALPS but the peer does not. 7948 testCases = append(testCases, testCase{ 7949 protocol: protocol, 7950 testType: clientTest, 7951 name: fmt.Sprintf("ALPS-EarlyData-Client-ServerDecline-%s-%s", alpsCodePoint, suffix), 7952 skipQUICALPNConfig: true, 7953 config: Config{ 7954 MaxVersion: ver.version, 7955 NextProtos: []string{"proto"}, 7956 ALPSUseNewCodepoint: alpsCodePoint, 7957 }, 7958 resumeSession: true, 7959 earlyData: true, 7960 flags: append([]string{ 7961 "-advertise-alpn", "\x05proto", 7962 "-expect-alpn", "proto", 7963 "-application-settings", "proto,shim", 7964 }, alpsFlags...), 7965 }) 7966 testCases = append(testCases, testCase{ 7967 protocol: protocol, 7968 testType: serverTest, 7969 name: fmt.Sprintf("ALPS-EarlyData-Server-ClientNoOffe-%s-%s", alpsCodePoint, suffix), 7970 skipQUICALPNConfig: true, 7971 config: Config{ 7972 MaxVersion: ver.version, 7973 NextProtos: []string{"proto"}, 7974 ALPSUseNewCodepoint: alpsCodePoint, 7975 }, 7976 resumeSession: true, 7977 earlyData: true, 7978 flags: append([]string{ 7979 "-select-alpn", "proto", 7980 "-application-settings", "proto,shim", 7981 }, alpsFlags...), 7982 }) 7983 } 7984 } else { 7985 // Test the client rejects the ALPS extension if the server 7986 // negotiated TLS 1.2 or below. 7987 for _, alpsCodePoint := range []ALPSUseCodepoint{ALPSUseCodepointNew, ALPSUseCodepointOld} { 7988 flags := []string{ 7989 "-advertise-alpn", "\x03foo", 7990 "-expect-alpn", "foo", 7991 "-application-settings", "foo,shim", 7992 } 7993 bugs := ProtocolBugs{ 7994 AlwaysNegotiateApplicationSettingsOld: true, 7995 } 7996 if alpsCodePoint == ALPSUseCodepointNew { 7997 flags = append(flags, "-alps-use-new-codepoint") 7998 bugs = ProtocolBugs{ 7999 AlwaysNegotiateApplicationSettingsNew: true, 8000 } 8001 } 8002 testCases = append(testCases, testCase{ 8003 protocol: protocol, 8004 testType: clientTest, 8005 name: fmt.Sprintf("ALPS-Reject-Client-%s-%s", alpsCodePoint, suffix), 8006 config: Config{ 8007 MaxVersion: ver.version, 8008 NextProtos: []string{"foo"}, 8009 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 8010 Bugs: bugs, 8011 ALPSUseNewCodepoint: alpsCodePoint, 8012 }, 8013 flags: flags, 8014 shouldFail: true, 8015 expectedError: ":UNEXPECTED_EXTENSION:", 8016 expectedLocalError: "remote error: unsupported extension", 8017 }) 8018 8019 flags = []string{ 8020 "-on-resume-advertise-alpn", "\x03foo", 8021 "-on-resume-expect-alpn", "foo", 8022 "-on-resume-application-settings", "foo,shim", 8023 } 8024 bugs = ProtocolBugs{ 8025 AlwaysNegotiateApplicationSettingsOld: true, 8026 } 8027 if alpsCodePoint == ALPSUseCodepointNew { 8028 flags = append(flags, "-alps-use-new-codepoint") 8029 bugs = ProtocolBugs{ 8030 AlwaysNegotiateApplicationSettingsNew: true, 8031 } 8032 } 8033 testCases = append(testCases, testCase{ 8034 protocol: protocol, 8035 testType: clientTest, 8036 name: fmt.Sprintf("ALPS-Reject-Client-Resume-%s-%s", alpsCodePoint, suffix), 8037 config: Config{ 8038 MaxVersion: ver.version, 8039 }, 8040 resumeConfig: &Config{ 8041 MaxVersion: ver.version, 8042 NextProtos: []string{"foo"}, 8043 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 8044 Bugs: bugs, 8045 ALPSUseNewCodepoint: alpsCodePoint, 8046 }, 8047 resumeSession: true, 8048 flags: flags, 8049 shouldFail: true, 8050 expectedError: ":UNEXPECTED_EXTENSION:", 8051 expectedLocalError: "remote error: unsupported extension", 8052 }) 8053 8054 // Test the server declines ALPS if it negotiates TLS 1.2 or below. 8055 flags = []string{ 8056 "-select-alpn", "foo", 8057 "-application-settings", "foo,shim", 8058 } 8059 if alpsCodePoint == ALPSUseCodepointNew { 8060 flags = append(flags, "-alps-use-new-codepoint") 8061 } 8062 testCases = append(testCases, testCase{ 8063 protocol: protocol, 8064 testType: serverTest, 8065 name: fmt.Sprintf("ALPS-Decline-Server-%s-%s", alpsCodePoint, suffix), 8066 config: Config{ 8067 MaxVersion: ver.version, 8068 NextProtos: []string{"foo"}, 8069 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 8070 ALPSUseNewCodepoint: alpsCodePoint, 8071 }, 8072 // Test both TLS 1.2 full and resumption handshakes. 8073 resumeSession: true, 8074 flags: flags, 8075 // If not specified, runner and shim both implicitly expect ALPS 8076 // is not negotiated. 8077 }) 8078 } 8079 } 8080 8081 // Test QUIC transport params 8082 if protocol == quic { 8083 // Client sends params 8084 for _, clientConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8085 for _, serverSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 8086 useCodepointFlag := "0" 8087 if clientConfig == QUICUseCodepointLegacy { 8088 useCodepointFlag = "1" 8089 } 8090 flags := []string{ 8091 "-quic-transport-params", 8092 base64FlagValue([]byte{1, 2}), 8093 "-quic-use-legacy-codepoint", useCodepointFlag, 8094 } 8095 expectations := connectionExpectations{ 8096 quicTransportParams: []byte{1, 2}, 8097 } 8098 shouldFail := false 8099 expectedError := "" 8100 expectedLocalError := "" 8101 if clientConfig == QUICUseCodepointLegacy { 8102 expectations = connectionExpectations{ 8103 quicTransportParamsLegacy: []byte{1, 2}, 8104 } 8105 } 8106 if serverSends != clientConfig { 8107 expectations = connectionExpectations{} 8108 shouldFail = true 8109 if serverSends == QUICUseCodepointNeither { 8110 expectedError = ":MISSING_EXTENSION:" 8111 } else { 8112 expectedLocalError = "remote error: unsupported extension" 8113 } 8114 } else { 8115 flags = append(flags, 8116 "-expect-quic-transport-params", 8117 base64FlagValue([]byte{3, 4})) 8118 } 8119 testCases = append(testCases, testCase{ 8120 testType: clientTest, 8121 protocol: protocol, 8122 name: fmt.Sprintf("QUICTransportParams-Client-Client%s-Server%s-%s", clientConfig, serverSends, suffix), 8123 config: Config{ 8124 MinVersion: ver.version, 8125 MaxVersion: ver.version, 8126 QUICTransportParams: []byte{3, 4}, 8127 QUICTransportParamsUseLegacyCodepoint: serverSends, 8128 }, 8129 flags: flags, 8130 expectations: expectations, 8131 shouldFail: shouldFail, 8132 expectedError: expectedError, 8133 expectedLocalError: expectedLocalError, 8134 skipTransportParamsConfig: true, 8135 }) 8136 } 8137 } 8138 // Server sends params 8139 for _, clientSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 8140 for _, serverConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8141 expectations := connectionExpectations{ 8142 quicTransportParams: []byte{3, 4}, 8143 } 8144 shouldFail := false 8145 expectedError := "" 8146 useCodepointFlag := "0" 8147 if serverConfig == QUICUseCodepointLegacy { 8148 useCodepointFlag = "1" 8149 expectations = connectionExpectations{ 8150 quicTransportParamsLegacy: []byte{3, 4}, 8151 } 8152 } 8153 flags := []string{ 8154 "-quic-transport-params", 8155 base64FlagValue([]byte{3, 4}), 8156 "-quic-use-legacy-codepoint", useCodepointFlag, 8157 } 8158 if clientSends != QUICUseCodepointBoth && clientSends != serverConfig { 8159 expectations = connectionExpectations{} 8160 shouldFail = true 8161 expectedError = ":MISSING_EXTENSION:" 8162 } else { 8163 flags = append(flags, 8164 "-expect-quic-transport-params", 8165 base64FlagValue([]byte{1, 2}), 8166 ) 8167 } 8168 testCases = append(testCases, testCase{ 8169 testType: serverTest, 8170 protocol: protocol, 8171 name: fmt.Sprintf("QUICTransportParams-Server-Client%s-Server%s-%s", clientSends, serverConfig, suffix), 8172 config: Config{ 8173 MinVersion: ver.version, 8174 MaxVersion: ver.version, 8175 QUICTransportParams: []byte{1, 2}, 8176 QUICTransportParamsUseLegacyCodepoint: clientSends, 8177 }, 8178 flags: flags, 8179 expectations: expectations, 8180 shouldFail: shouldFail, 8181 expectedError: expectedError, 8182 skipTransportParamsConfig: true, 8183 }) 8184 } 8185 } 8186 } else { 8187 // Ensure non-QUIC client doesn't send QUIC transport parameters. 8188 for _, clientConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8189 useCodepointFlag := "0" 8190 if clientConfig == QUICUseCodepointLegacy { 8191 useCodepointFlag = "1" 8192 } 8193 testCases = append(testCases, testCase{ 8194 protocol: protocol, 8195 testType: clientTest, 8196 name: fmt.Sprintf("QUICTransportParams-Client-NotSentInNonQUIC-%s-%s", clientConfig, suffix), 8197 config: Config{ 8198 MinVersion: ver.version, 8199 MaxVersion: ver.version, 8200 QUICTransportParamsUseLegacyCodepoint: clientConfig, 8201 }, 8202 flags: []string{ 8203 "-max-version", 8204 strconv.Itoa(int(ver.versionWire)), 8205 "-quic-transport-params", 8206 base64FlagValue([]byte{3, 4}), 8207 "-quic-use-legacy-codepoint", useCodepointFlag, 8208 }, 8209 shouldFail: true, 8210 expectedError: ":QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED:", 8211 skipTransportParamsConfig: true, 8212 }) 8213 } 8214 // Ensure non-QUIC server rejects codepoint 57 but ignores legacy 0xffa5. 8215 for _, clientSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 8216 for _, serverConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8217 shouldFail := false 8218 expectedLocalError := "" 8219 useCodepointFlag := "0" 8220 if serverConfig == QUICUseCodepointLegacy { 8221 useCodepointFlag = "1" 8222 } 8223 if clientSends == QUICUseCodepointStandard || clientSends == QUICUseCodepointBoth { 8224 shouldFail = true 8225 expectedLocalError = "remote error: unsupported extension" 8226 } 8227 testCases = append(testCases, testCase{ 8228 protocol: protocol, 8229 testType: serverTest, 8230 name: fmt.Sprintf("QUICTransportParams-NonQUICServer-Client%s-Server%s-%s", clientSends, serverConfig, suffix), 8231 config: Config{ 8232 MinVersion: ver.version, 8233 MaxVersion: ver.version, 8234 QUICTransportParams: []byte{1, 2}, 8235 QUICTransportParamsUseLegacyCodepoint: clientSends, 8236 }, 8237 flags: []string{ 8238 "-quic-use-legacy-codepoint", useCodepointFlag, 8239 }, 8240 shouldFail: shouldFail, 8241 expectedLocalError: expectedLocalError, 8242 skipTransportParamsConfig: true, 8243 }) 8244 } 8245 } 8246 8247 } 8248 8249 // Test ticket behavior. 8250 8251 // Resume with a corrupt ticket. 8252 testCases = append(testCases, testCase{ 8253 protocol: protocol, 8254 testType: serverTest, 8255 name: "CorruptTicket-" + suffix, 8256 config: Config{ 8257 MaxVersion: ver.version, 8258 Bugs: ProtocolBugs{ 8259 FilterTicket: func(in []byte) ([]byte, error) { 8260 in[len(in)-1] ^= 1 8261 return in, nil 8262 }, 8263 }, 8264 }, 8265 resumeSession: true, 8266 expectResumeRejected: true, 8267 }) 8268 // Test the ticket callback, with and without renewal. 8269 testCases = append(testCases, testCase{ 8270 protocol: protocol, 8271 testType: serverTest, 8272 name: "TicketCallback-" + suffix, 8273 config: Config{ 8274 MaxVersion: ver.version, 8275 }, 8276 resumeSession: true, 8277 flags: []string{"-use-ticket-callback"}, 8278 }) 8279 testCases = append(testCases, testCase{ 8280 protocol: protocol, 8281 testType: serverTest, 8282 name: "TicketCallback-Renew-" + suffix, 8283 config: Config{ 8284 MaxVersion: ver.version, 8285 Bugs: ProtocolBugs{ 8286 ExpectNewTicket: true, 8287 }, 8288 }, 8289 flags: []string{"-use-ticket-callback", "-renew-ticket"}, 8290 resumeSession: true, 8291 }) 8292 8293 // Test that the ticket callback is only called once when everything before 8294 // it in the ClientHello is asynchronous. This corrupts the ticket so 8295 // certificate selection callbacks run. 8296 testCases = append(testCases, testCase{ 8297 protocol: protocol, 8298 testType: serverTest, 8299 name: "TicketCallback-SingleCall-" + suffix, 8300 config: Config{ 8301 MaxVersion: ver.version, 8302 Bugs: ProtocolBugs{ 8303 FilterTicket: func(in []byte) ([]byte, error) { 8304 in[len(in)-1] ^= 1 8305 return in, nil 8306 }, 8307 }, 8308 }, 8309 resumeSession: true, 8310 expectResumeRejected: true, 8311 flags: []string{ 8312 "-use-ticket-callback", 8313 "-async", 8314 }, 8315 }) 8316 8317 // Resume with various lengths of ticket session id. 8318 if ver.version < VersionTLS13 { 8319 testCases = append(testCases, testCase{ 8320 protocol: protocol, 8321 testType: serverTest, 8322 name: "TicketSessionIDLength-0-" + suffix, 8323 config: Config{ 8324 MaxVersion: ver.version, 8325 Bugs: ProtocolBugs{ 8326 EmptyTicketSessionID: true, 8327 }, 8328 }, 8329 resumeSession: true, 8330 }) 8331 testCases = append(testCases, testCase{ 8332 protocol: protocol, 8333 testType: serverTest, 8334 name: "TicketSessionIDLength-16-" + suffix, 8335 config: Config{ 8336 MaxVersion: ver.version, 8337 Bugs: ProtocolBugs{ 8338 TicketSessionIDLength: 16, 8339 }, 8340 }, 8341 resumeSession: true, 8342 }) 8343 testCases = append(testCases, testCase{ 8344 protocol: protocol, 8345 testType: serverTest, 8346 name: "TicketSessionIDLength-32-" + suffix, 8347 config: Config{ 8348 MaxVersion: ver.version, 8349 Bugs: ProtocolBugs{ 8350 TicketSessionIDLength: 32, 8351 }, 8352 }, 8353 resumeSession: true, 8354 }) 8355 testCases = append(testCases, testCase{ 8356 protocol: protocol, 8357 testType: serverTest, 8358 name: "TicketSessionIDLength-33-" + suffix, 8359 config: Config{ 8360 MaxVersion: ver.version, 8361 Bugs: ProtocolBugs{ 8362 TicketSessionIDLength: 33, 8363 }, 8364 }, 8365 resumeSession: true, 8366 shouldFail: true, 8367 // The maximum session ID length is 32. 8368 expectedError: ":DECODE_ERROR:", 8369 }) 8370 } 8371 8372 // Basic DTLS-SRTP tests. Include fake profiles to ensure they 8373 // are ignored. 8374 if protocol == dtls { 8375 testCases = append(testCases, testCase{ 8376 protocol: protocol, 8377 name: "SRTP-Client-" + suffix, 8378 config: Config{ 8379 MaxVersion: ver.version, 8380 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8381 }, 8382 flags: []string{ 8383 "-srtp-profiles", 8384 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8385 }, 8386 expectations: connectionExpectations{ 8387 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8388 }, 8389 }) 8390 testCases = append(testCases, testCase{ 8391 protocol: protocol, 8392 testType: serverTest, 8393 name: "SRTP-Server-" + suffix, 8394 config: Config{ 8395 MaxVersion: ver.version, 8396 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8397 }, 8398 flags: []string{ 8399 "-srtp-profiles", 8400 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8401 }, 8402 expectations: connectionExpectations{ 8403 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8404 }, 8405 }) 8406 // Test that the MKI is ignored. 8407 testCases = append(testCases, testCase{ 8408 protocol: protocol, 8409 testType: serverTest, 8410 name: "SRTP-Server-IgnoreMKI-" + suffix, 8411 config: Config{ 8412 MaxVersion: ver.version, 8413 SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80}, 8414 Bugs: ProtocolBugs{ 8415 SRTPMasterKeyIdentifier: "bogus", 8416 }, 8417 }, 8418 flags: []string{ 8419 "-srtp-profiles", 8420 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8421 }, 8422 expectations: connectionExpectations{ 8423 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8424 }, 8425 }) 8426 // Test that SRTP isn't negotiated on the server if there were 8427 // no matching profiles. 8428 testCases = append(testCases, testCase{ 8429 protocol: protocol, 8430 testType: serverTest, 8431 name: "SRTP-Server-NoMatch-" + suffix, 8432 config: Config{ 8433 MaxVersion: ver.version, 8434 SRTPProtectionProfiles: []uint16{100, 101, 102}, 8435 }, 8436 flags: []string{ 8437 "-srtp-profiles", 8438 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8439 }, 8440 expectations: connectionExpectations{ 8441 srtpProtectionProfile: 0, 8442 }, 8443 }) 8444 // Test that the server returning an invalid SRTP profile is 8445 // flagged as an error by the client. 8446 testCases = append(testCases, testCase{ 8447 protocol: protocol, 8448 name: "SRTP-Client-NoMatch-" + suffix, 8449 config: Config{ 8450 MaxVersion: ver.version, 8451 Bugs: ProtocolBugs{ 8452 SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32, 8453 }, 8454 }, 8455 flags: []string{ 8456 "-srtp-profiles", 8457 "SRTP_AES128_CM_SHA1_80", 8458 }, 8459 shouldFail: true, 8460 expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:", 8461 }) 8462 } else { 8463 // DTLS-SRTP is not defined for other protocols. Configuring it 8464 // on the client and server should ignore the extension. 8465 testCases = append(testCases, testCase{ 8466 protocol: protocol, 8467 name: "SRTP-Client-Ignore-" + suffix, 8468 config: Config{ 8469 MaxVersion: ver.version, 8470 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8471 }, 8472 flags: []string{ 8473 "-srtp-profiles", 8474 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8475 }, 8476 expectations: connectionExpectations{ 8477 srtpProtectionProfile: 0, 8478 }, 8479 }) 8480 testCases = append(testCases, testCase{ 8481 protocol: protocol, 8482 testType: serverTest, 8483 name: "SRTP-Server-Ignore-" + suffix, 8484 config: Config{ 8485 MaxVersion: ver.version, 8486 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8487 }, 8488 flags: []string{ 8489 "-srtp-profiles", 8490 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8491 }, 8492 expectations: connectionExpectations{ 8493 srtpProtectionProfile: 0, 8494 }, 8495 }) 8496 } 8497 8498 // Test SCT list. 8499 testCases = append(testCases, testCase{ 8500 protocol: protocol, 8501 name: "SignedCertificateTimestampList-Client-" + suffix, 8502 testType: clientTest, 8503 config: Config{ 8504 MaxVersion: ver.version, 8505 Credential: rsaCertificate.WithSCTList(testSCTList), 8506 }, 8507 flags: []string{ 8508 "-enable-signed-cert-timestamps", 8509 "-expect-signed-cert-timestamps", 8510 base64FlagValue(testSCTList), 8511 }, 8512 resumeSession: true, 8513 }) 8514 8515 var differentSCTList []byte 8516 differentSCTList = append(differentSCTList, testSCTList...) 8517 differentSCTList[len(differentSCTList)-1] ^= 1 8518 8519 // The SCT extension did not specify that it must only be sent on the inital handshake as it 8520 // should have, so test that we tolerate but ignore it. This is only an issue pre-1.3, since 8521 // SCTs are sent in the CertificateEntry message in 1.3, whereas they were previously sent 8522 // in an extension in the ServerHello pre-1.3. 8523 testCases = append(testCases, testCase{ 8524 protocol: protocol, 8525 name: "SendSCTListOnResume-" + suffix, 8526 config: Config{ 8527 MaxVersion: ver.version, 8528 Credential: rsaCertificate.WithSCTList(testSCTList), 8529 Bugs: ProtocolBugs{ 8530 SendSCTListOnResume: differentSCTList, 8531 }, 8532 }, 8533 flags: []string{ 8534 "-enable-signed-cert-timestamps", 8535 "-expect-signed-cert-timestamps", 8536 base64FlagValue(testSCTList), 8537 }, 8538 resumeSession: true, 8539 }) 8540 8541 testCases = append(testCases, testCase{ 8542 protocol: protocol, 8543 name: "SignedCertificateTimestampList-Server-" + suffix, 8544 testType: serverTest, 8545 config: Config{ 8546 MaxVersion: ver.version, 8547 }, 8548 shimCertificate: rsaCertificate.WithSCTList(testSCTList), 8549 expectations: connectionExpectations{ 8550 peerCertificate: rsaCertificate.WithSCTList(testSCTList), 8551 }, 8552 resumeSession: true, 8553 }) 8554 8555 // Test empty SCT list. 8556 testCases = append(testCases, testCase{ 8557 protocol: protocol, 8558 name: "SignedCertificateTimestampListEmpty-Client-" + suffix, 8559 testType: clientTest, 8560 config: Config{ 8561 MaxVersion: ver.version, 8562 Credential: rsaCertificate.WithSCTList([]byte{0, 0}), 8563 }, 8564 flags: []string{ 8565 "-enable-signed-cert-timestamps", 8566 }, 8567 shouldFail: true, 8568 expectedError: ":ERROR_PARSING_EXTENSION:", 8569 }) 8570 8571 // Test empty SCT in non-empty list. 8572 testCases = append(testCases, testCase{ 8573 protocol: protocol, 8574 name: "SignedCertificateTimestampListEmptySCT-Client-" + suffix, 8575 testType: clientTest, 8576 config: Config{ 8577 MaxVersion: ver.version, 8578 Credential: rsaCertificate.WithSCTList([]byte{0, 6, 0, 2, 1, 2, 0, 0}), 8579 }, 8580 flags: []string{ 8581 "-enable-signed-cert-timestamps", 8582 }, 8583 shouldFail: true, 8584 expectedError: ":ERROR_PARSING_EXTENSION:", 8585 }) 8586 8587 // Test that certificate-related extensions are not sent unsolicited. 8588 testCases = append(testCases, testCase{ 8589 protocol: protocol, 8590 testType: serverTest, 8591 name: "UnsolicitedCertificateExtensions-" + suffix, 8592 config: Config{ 8593 MaxVersion: ver.version, 8594 Bugs: ProtocolBugs{ 8595 NoOCSPStapling: true, 8596 NoSignedCertificateTimestamps: true, 8597 }, 8598 }, 8599 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8600 }) 8601 8602 // Extension permutation should interact correctly with other extensions, 8603 // HelloVerifyRequest, HelloRetryRequest, and ECH. SSLTest.PermuteExtensions 8604 // in ssl_test.cc tests that the extensions are actually permuted. This 8605 // tests the handshake still works. 8606 // 8607 // This test also tests that all our extensions interact with each other. 8608 for _, ech := range []bool{false, true} { 8609 if ech && ver.version < VersionTLS13 { 8610 continue 8611 } 8612 8613 test := testCase{ 8614 protocol: protocol, 8615 name: "AllExtensions-Client-Permute", 8616 skipQUICALPNConfig: true, 8617 config: Config{ 8618 MinVersion: ver.version, 8619 MaxVersion: ver.version, 8620 Credential: rsaCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8621 NextProtos: []string{"proto"}, 8622 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 8623 Bugs: ProtocolBugs{ 8624 SendServerNameAck: true, 8625 ExpectServerName: "example.com", 8626 ExpectGREASE: true, 8627 }, 8628 }, 8629 resumeSession: true, 8630 flags: []string{ 8631 "-permute-extensions", 8632 "-enable-grease", 8633 "-enable-ocsp-stapling", 8634 "-enable-signed-cert-timestamps", 8635 "-advertise-alpn", "\x05proto", 8636 "-expect-alpn", "proto", 8637 "-host-name", "example.com", 8638 }, 8639 } 8640 8641 if ech { 8642 test.name += "-ECH" 8643 echConfig := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 8644 test.config.ServerECHConfigs = []ServerECHConfig{echConfig} 8645 test.flags = append(test.flags, 8646 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 8647 "-expect-ech-accept", 8648 ) 8649 test.expectations.echAccepted = true 8650 } 8651 8652 if ver.version >= VersionTLS13 { 8653 // Trigger a HelloRetryRequest to test both ClientHellos. Note 8654 // our DTLS tests always enable HelloVerifyRequest. 8655 test.name += "-HelloRetryRequest" 8656 8657 // ALPS is only available on TLS 1.3. 8658 test.config.ApplicationSettings = map[string][]byte{"proto": []byte("runner")} 8659 test.flags = append(test.flags, 8660 "-application-settings", "proto,shim", 8661 "-alps-use-new-codepoint", 8662 "-expect-peer-application-settings", "runner") 8663 test.expectations.peerApplicationSettings = []byte("shim") 8664 } 8665 8666 if protocol == dtls { 8667 test.config.SRTPProtectionProfiles = []uint16{SRTP_AES128_CM_HMAC_SHA1_80} 8668 test.flags = append(test.flags, "-srtp-profiles", "SRTP_AES128_CM_SHA1_80") 8669 test.expectations.srtpProtectionProfile = SRTP_AES128_CM_HMAC_SHA1_80 8670 } 8671 8672 test.name += "-" + suffix 8673 testCases = append(testCases, test) 8674 } 8675 } 8676 } 8677 8678 testCases = append(testCases, testCase{ 8679 testType: clientTest, 8680 name: "ClientHelloPadding", 8681 config: Config{ 8682 Bugs: ProtocolBugs{ 8683 RequireClientHelloSize: 512, 8684 }, 8685 }, 8686 // This hostname just needs to be long enough to push the 8687 // ClientHello into F5's danger zone between 256 and 511 bytes 8688 // long. 8689 flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"}, 8690 }) 8691 8692 // Test that illegal extensions in TLS 1.3 are rejected by the client if 8693 // in ServerHello. 8694 testCases = append(testCases, testCase{ 8695 name: "NPN-Forbidden-TLS13", 8696 config: Config{ 8697 MaxVersion: VersionTLS13, 8698 NextProtos: []string{"foo"}, 8699 Bugs: ProtocolBugs{ 8700 NegotiateNPNAtAllVersions: true, 8701 }, 8702 }, 8703 flags: []string{"-select-next-proto", "foo"}, 8704 shouldFail: true, 8705 expectedError: ":ERROR_PARSING_EXTENSION:", 8706 }) 8707 testCases = append(testCases, testCase{ 8708 name: "EMS-Forbidden-TLS13", 8709 config: Config{ 8710 MaxVersion: VersionTLS13, 8711 Bugs: ProtocolBugs{ 8712 NegotiateEMSAtAllVersions: true, 8713 }, 8714 }, 8715 shouldFail: true, 8716 expectedError: ":ERROR_PARSING_EXTENSION:", 8717 }) 8718 testCases = append(testCases, testCase{ 8719 name: "RenegotiationInfo-Forbidden-TLS13", 8720 config: Config{ 8721 MaxVersion: VersionTLS13, 8722 Bugs: ProtocolBugs{ 8723 NegotiateRenegotiationInfoAtAllVersions: true, 8724 }, 8725 }, 8726 shouldFail: true, 8727 expectedError: ":ERROR_PARSING_EXTENSION:", 8728 }) 8729 testCases = append(testCases, testCase{ 8730 name: "Ticket-Forbidden-TLS13", 8731 config: Config{ 8732 MaxVersion: VersionTLS12, 8733 }, 8734 resumeConfig: &Config{ 8735 MaxVersion: VersionTLS13, 8736 Bugs: ProtocolBugs{ 8737 AdvertiseTicketExtension: true, 8738 }, 8739 }, 8740 resumeSession: true, 8741 shouldFail: true, 8742 expectedError: ":ERROR_PARSING_EXTENSION:", 8743 }) 8744 8745 // Test that illegal extensions in TLS 1.3 are declined by the server if 8746 // offered in ClientHello. The runner's server will fail if this occurs, 8747 // so we exercise the offering path. (EMS and Renegotiation Info are 8748 // implicit in every test.) 8749 testCases = append(testCases, testCase{ 8750 testType: serverTest, 8751 name: "NPN-Declined-TLS13", 8752 config: Config{ 8753 MaxVersion: VersionTLS13, 8754 NextProtos: []string{"bar"}, 8755 }, 8756 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"}, 8757 }) 8758 8759 // OpenSSL sends the status_request extension on resumption in TLS 1.2. Test that this is 8760 // tolerated. 8761 testCases = append(testCases, testCase{ 8762 name: "SendOCSPResponseOnResume-TLS12", 8763 config: Config{ 8764 MaxVersion: VersionTLS12, 8765 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 8766 Bugs: ProtocolBugs{ 8767 SendOCSPResponseOnResume: []byte("bogus"), 8768 }, 8769 }, 8770 flags: []string{ 8771 "-enable-ocsp-stapling", 8772 "-expect-ocsp-response", 8773 base64FlagValue(testOCSPResponse), 8774 }, 8775 resumeSession: true, 8776 }) 8777 8778 testCases = append(testCases, testCase{ 8779 name: "SendUnsolicitedOCSPOnCertificate-TLS13", 8780 config: Config{ 8781 MaxVersion: VersionTLS13, 8782 Bugs: ProtocolBugs{ 8783 SendExtensionOnCertificate: testOCSPExtension, 8784 }, 8785 }, 8786 shouldFail: true, 8787 expectedError: ":UNEXPECTED_EXTENSION:", 8788 }) 8789 8790 testCases = append(testCases, testCase{ 8791 name: "SendUnsolicitedSCTOnCertificate-TLS13", 8792 config: Config{ 8793 MaxVersion: VersionTLS13, 8794 Bugs: ProtocolBugs{ 8795 SendExtensionOnCertificate: testSCTExtension, 8796 }, 8797 }, 8798 shouldFail: true, 8799 expectedError: ":UNEXPECTED_EXTENSION:", 8800 }) 8801 8802 // Test that extensions on client certificates are never accepted. 8803 testCases = append(testCases, testCase{ 8804 name: "SendExtensionOnClientCertificate-TLS13", 8805 testType: serverTest, 8806 config: Config{ 8807 MaxVersion: VersionTLS13, 8808 Credential: &rsaCertificate, 8809 Bugs: ProtocolBugs{ 8810 SendExtensionOnCertificate: testOCSPExtension, 8811 }, 8812 }, 8813 flags: []string{ 8814 "-enable-ocsp-stapling", 8815 "-require-any-client-certificate", 8816 }, 8817 shouldFail: true, 8818 expectedError: ":UNEXPECTED_EXTENSION:", 8819 }) 8820 8821 testCases = append(testCases, testCase{ 8822 name: "SendUnknownExtensionOnCertificate-TLS13", 8823 config: Config{ 8824 MaxVersion: VersionTLS13, 8825 Bugs: ProtocolBugs{ 8826 SendExtensionOnCertificate: []byte{0x00, 0x7f, 0, 0}, 8827 }, 8828 }, 8829 shouldFail: true, 8830 expectedError: ":UNEXPECTED_EXTENSION:", 8831 }) 8832 8833 // Test that extensions on intermediates are allowed but ignored. 8834 testCases = append(testCases, testCase{ 8835 name: "IgnoreExtensionsOnIntermediates-TLS13", 8836 config: Config{ 8837 MaxVersion: VersionTLS13, 8838 Credential: rsaChainCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8839 Bugs: ProtocolBugs{ 8840 // Send different values on the intermediate. This tests 8841 // the intermediate's extensions do not override the 8842 // leaf's. 8843 SendOCSPOnIntermediates: testOCSPResponse2, 8844 SendSCTOnIntermediates: testSCTList2, 8845 }, 8846 }, 8847 flags: []string{ 8848 "-enable-ocsp-stapling", 8849 "-expect-ocsp-response", 8850 base64FlagValue(testOCSPResponse), 8851 "-enable-signed-cert-timestamps", 8852 "-expect-signed-cert-timestamps", 8853 base64FlagValue(testSCTList), 8854 }, 8855 resumeSession: true, 8856 }) 8857 8858 // Test that extensions are not sent on intermediates when configured 8859 // only for a leaf. 8860 testCases = append(testCases, testCase{ 8861 testType: serverTest, 8862 name: "SendNoExtensionsOnIntermediate-TLS13", 8863 config: Config{ 8864 MaxVersion: VersionTLS13, 8865 Bugs: ProtocolBugs{ 8866 ExpectNoExtensionsOnIntermediate: true, 8867 }, 8868 }, 8869 shimCertificate: rsaChainCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8870 }) 8871 8872 // Test that extensions are not sent on client certificates. 8873 testCases = append(testCases, testCase{ 8874 name: "SendNoClientCertificateExtensions-TLS13", 8875 config: Config{ 8876 MaxVersion: VersionTLS13, 8877 ClientAuth: RequireAnyClientCert, 8878 }, 8879 shimCertificate: rsaChainCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8880 }) 8881 8882 testCases = append(testCases, testCase{ 8883 name: "SendDuplicateExtensionsOnCerts-TLS13", 8884 config: Config{ 8885 MaxVersion: VersionTLS13, 8886 Credential: rsaCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8887 Bugs: ProtocolBugs{ 8888 SendDuplicateCertExtensions: true, 8889 }, 8890 }, 8891 flags: []string{ 8892 "-enable-ocsp-stapling", 8893 "-enable-signed-cert-timestamps", 8894 }, 8895 resumeSession: true, 8896 shouldFail: true, 8897 expectedError: ":DUPLICATE_EXTENSION:", 8898 }) 8899 8900 testCases = append(testCases, testCase{ 8901 name: "SignedCertificateTimestampListInvalid-Server", 8902 testType: serverTest, 8903 shimCertificate: rsaCertificate.WithSCTList([]byte{0, 0}), 8904 shouldFail: true, 8905 expectedError: ":INVALID_SCT_LIST:", 8906 }) 8907} 8908 8909func addResumptionVersionTests() { 8910 for _, sessionVers := range tlsVersions { 8911 for _, resumeVers := range tlsVersions { 8912 protocols := []protocol{tls} 8913 if sessionVers.hasDTLS && resumeVers.hasDTLS { 8914 protocols = append(protocols, dtls) 8915 } 8916 if sessionVers.hasQUIC && resumeVers.hasQUIC { 8917 protocols = append(protocols, quic) 8918 } 8919 for _, protocol := range protocols { 8920 suffix := "-" + sessionVers.name + "-" + resumeVers.name 8921 suffix += "-" + protocol.String() 8922 8923 if sessionVers.version == resumeVers.version { 8924 testCases = append(testCases, testCase{ 8925 protocol: protocol, 8926 name: "Resume-Client" + suffix, 8927 resumeSession: true, 8928 config: Config{ 8929 MaxVersion: sessionVers.version, 8930 Bugs: ProtocolBugs{ 8931 ExpectNoTLS13PSK: sessionVers.version < VersionTLS13, 8932 }, 8933 }, 8934 expectations: connectionExpectations{ 8935 version: sessionVers.version, 8936 }, 8937 resumeExpectations: &connectionExpectations{ 8938 version: resumeVers.version, 8939 }, 8940 }) 8941 } else { 8942 testCases = append(testCases, testCase{ 8943 protocol: protocol, 8944 name: "Resume-Client-Mismatch" + suffix, 8945 resumeSession: true, 8946 config: Config{ 8947 MaxVersion: sessionVers.version, 8948 }, 8949 expectations: connectionExpectations{ 8950 version: sessionVers.version, 8951 }, 8952 resumeConfig: &Config{ 8953 MaxVersion: resumeVers.version, 8954 Bugs: ProtocolBugs{ 8955 AcceptAnySession: true, 8956 }, 8957 }, 8958 resumeExpectations: &connectionExpectations{ 8959 version: resumeVers.version, 8960 }, 8961 shouldFail: true, 8962 expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:", 8963 }) 8964 } 8965 8966 testCases = append(testCases, testCase{ 8967 protocol: protocol, 8968 name: "Resume-Client-NoResume" + suffix, 8969 resumeSession: true, 8970 config: Config{ 8971 MaxVersion: sessionVers.version, 8972 }, 8973 expectations: connectionExpectations{ 8974 version: sessionVers.version, 8975 }, 8976 resumeConfig: &Config{ 8977 MaxVersion: resumeVers.version, 8978 }, 8979 newSessionsOnResume: true, 8980 expectResumeRejected: true, 8981 resumeExpectations: &connectionExpectations{ 8982 version: resumeVers.version, 8983 }, 8984 }) 8985 8986 testCases = append(testCases, testCase{ 8987 protocol: protocol, 8988 testType: serverTest, 8989 name: "Resume-Server" + suffix, 8990 resumeSession: true, 8991 config: Config{ 8992 MaxVersion: sessionVers.version, 8993 }, 8994 expectations: connectionExpectations{ 8995 version: sessionVers.version, 8996 }, 8997 expectResumeRejected: sessionVers != resumeVers, 8998 resumeConfig: &Config{ 8999 MaxVersion: resumeVers.version, 9000 Bugs: ProtocolBugs{ 9001 SendBothTickets: true, 9002 }, 9003 }, 9004 resumeExpectations: &connectionExpectations{ 9005 version: resumeVers.version, 9006 }, 9007 }) 9008 9009 // Repeat the test using session IDs, rather than tickets. 9010 if sessionVers.version < VersionTLS13 && resumeVers.version < VersionTLS13 { 9011 testCases = append(testCases, testCase{ 9012 protocol: protocol, 9013 testType: serverTest, 9014 name: "Resume-Server-NoTickets" + suffix, 9015 resumeSession: true, 9016 config: Config{ 9017 MaxVersion: sessionVers.version, 9018 SessionTicketsDisabled: true, 9019 }, 9020 expectations: connectionExpectations{ 9021 version: sessionVers.version, 9022 }, 9023 expectResumeRejected: sessionVers != resumeVers, 9024 resumeConfig: &Config{ 9025 MaxVersion: resumeVers.version, 9026 SessionTicketsDisabled: true, 9027 }, 9028 resumeExpectations: &connectionExpectations{ 9029 version: resumeVers.version, 9030 }, 9031 }) 9032 } 9033 } 9034 } 9035 } 9036 9037 // Make sure shim ticket mutations are functional. 9038 testCases = append(testCases, testCase{ 9039 testType: serverTest, 9040 name: "ShimTicketRewritable", 9041 resumeSession: true, 9042 config: Config{ 9043 MaxVersion: VersionTLS12, 9044 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9045 Bugs: ProtocolBugs{ 9046 FilterTicket: func(in []byte) ([]byte, error) { 9047 in, err := SetShimTicketVersion(in, VersionTLS12) 9048 if err != nil { 9049 return nil, err 9050 } 9051 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) 9052 }, 9053 }, 9054 }, 9055 flags: []string{ 9056 "-ticket-key", 9057 base64FlagValue(TestShimTicketKey), 9058 }, 9059 }) 9060 9061 // Resumptions are declined if the version does not match. 9062 testCases = append(testCases, testCase{ 9063 testType: serverTest, 9064 name: "Resume-Server-DeclineCrossVersion", 9065 resumeSession: true, 9066 config: Config{ 9067 MaxVersion: VersionTLS12, 9068 Bugs: ProtocolBugs{ 9069 ExpectNewTicket: true, 9070 FilterTicket: func(in []byte) ([]byte, error) { 9071 return SetShimTicketVersion(in, VersionTLS13) 9072 }, 9073 }, 9074 }, 9075 flags: []string{ 9076 "-ticket-key", 9077 base64FlagValue(TestShimTicketKey), 9078 }, 9079 expectResumeRejected: true, 9080 }) 9081 9082 testCases = append(testCases, testCase{ 9083 testType: serverTest, 9084 name: "Resume-Server-DeclineCrossVersion-TLS13", 9085 resumeSession: true, 9086 config: Config{ 9087 MaxVersion: VersionTLS13, 9088 Bugs: ProtocolBugs{ 9089 FilterTicket: func(in []byte) ([]byte, error) { 9090 return SetShimTicketVersion(in, VersionTLS12) 9091 }, 9092 }, 9093 }, 9094 flags: []string{ 9095 "-ticket-key", 9096 base64FlagValue(TestShimTicketKey), 9097 }, 9098 expectResumeRejected: true, 9099 }) 9100 9101 // Resumptions are declined if the cipher is invalid or disabled. 9102 testCases = append(testCases, testCase{ 9103 testType: serverTest, 9104 name: "Resume-Server-DeclineBadCipher", 9105 resumeSession: true, 9106 config: Config{ 9107 MaxVersion: VersionTLS12, 9108 Bugs: ProtocolBugs{ 9109 ExpectNewTicket: true, 9110 FilterTicket: func(in []byte) ([]byte, error) { 9111 return SetShimTicketCipherSuite(in, TLS_AES_128_GCM_SHA256) 9112 }, 9113 }, 9114 }, 9115 flags: []string{ 9116 "-ticket-key", 9117 base64FlagValue(TestShimTicketKey), 9118 }, 9119 expectResumeRejected: true, 9120 }) 9121 9122 testCases = append(testCases, testCase{ 9123 testType: serverTest, 9124 name: "Resume-Server-DeclineBadCipher-2", 9125 resumeSession: true, 9126 config: Config{ 9127 MaxVersion: VersionTLS12, 9128 Bugs: ProtocolBugs{ 9129 ExpectNewTicket: true, 9130 FilterTicket: func(in []byte) ([]byte, error) { 9131 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) 9132 }, 9133 }, 9134 }, 9135 flags: []string{ 9136 "-cipher", "AES128", 9137 "-ticket-key", 9138 base64FlagValue(TestShimTicketKey), 9139 }, 9140 expectResumeRejected: true, 9141 }) 9142 9143 // Sessions are not resumed if they do not use the preferred cipher. 9144 testCases = append(testCases, testCase{ 9145 testType: serverTest, 9146 name: "Resume-Server-CipherNotPreferred", 9147 resumeSession: true, 9148 config: Config{ 9149 MaxVersion: VersionTLS12, 9150 Bugs: ProtocolBugs{ 9151 ExpectNewTicket: true, 9152 FilterTicket: func(in []byte) ([]byte, error) { 9153 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) 9154 }, 9155 }, 9156 }, 9157 flags: []string{ 9158 "-ticket-key", 9159 base64FlagValue(TestShimTicketKey), 9160 }, 9161 shouldFail: false, 9162 expectResumeRejected: true, 9163 }) 9164 9165 // TLS 1.3 allows sessions to be resumed at a different cipher if their 9166 // PRF hashes match, but BoringSSL will always decline such resumptions. 9167 testCases = append(testCases, testCase{ 9168 testType: serverTest, 9169 name: "Resume-Server-CipherNotPreferred-TLS13", 9170 resumeSession: true, 9171 config: Config{ 9172 MaxVersion: VersionTLS13, 9173 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_GCM_SHA256}, 9174 Bugs: ProtocolBugs{ 9175 FilterTicket: func(in []byte) ([]byte, error) { 9176 // If the client (runner) offers ChaCha20-Poly1305 first, the 9177 // server (shim) always prefers it. Switch it to AES-GCM. 9178 return SetShimTicketCipherSuite(in, TLS_AES_128_GCM_SHA256) 9179 }, 9180 }, 9181 }, 9182 flags: []string{ 9183 "-ticket-key", 9184 base64FlagValue(TestShimTicketKey), 9185 }, 9186 shouldFail: false, 9187 expectResumeRejected: true, 9188 }) 9189 9190 // Sessions may not be resumed if they contain another version's cipher. 9191 testCases = append(testCases, testCase{ 9192 testType: serverTest, 9193 name: "Resume-Server-DeclineBadCipher-TLS13", 9194 resumeSession: true, 9195 config: Config{ 9196 MaxVersion: VersionTLS13, 9197 Bugs: ProtocolBugs{ 9198 FilterTicket: func(in []byte) ([]byte, error) { 9199 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) 9200 }, 9201 }, 9202 }, 9203 flags: []string{ 9204 "-ticket-key", 9205 base64FlagValue(TestShimTicketKey), 9206 }, 9207 expectResumeRejected: true, 9208 }) 9209 9210 // If the client does not offer the cipher from the session, decline to 9211 // resume. Clients are forbidden from doing this, but BoringSSL selects 9212 // the cipher first, so we only decline. 9213 testCases = append(testCases, testCase{ 9214 testType: serverTest, 9215 name: "Resume-Server-UnofferedCipher", 9216 resumeSession: true, 9217 config: Config{ 9218 MaxVersion: VersionTLS12, 9219 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 9220 }, 9221 resumeConfig: &Config{ 9222 MaxVersion: VersionTLS12, 9223 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 9224 Bugs: ProtocolBugs{ 9225 SendCipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9226 }, 9227 }, 9228 expectResumeRejected: true, 9229 }) 9230 9231 // In TLS 1.3, clients may advertise a cipher list which does not 9232 // include the selected cipher. Test that we tolerate this. Servers may 9233 // resume at another cipher if the PRF matches and are not doing 0-RTT, but 9234 // BoringSSL will always decline. 9235 testCases = append(testCases, testCase{ 9236 testType: serverTest, 9237 name: "Resume-Server-UnofferedCipher-TLS13", 9238 resumeSession: true, 9239 config: Config{ 9240 MaxVersion: VersionTLS13, 9241 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 9242 }, 9243 resumeConfig: &Config{ 9244 MaxVersion: VersionTLS13, 9245 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 9246 Bugs: ProtocolBugs{ 9247 SendCipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9248 }, 9249 }, 9250 expectResumeRejected: true, 9251 }) 9252 9253 // Sessions may not be resumed at a different cipher. 9254 testCases = append(testCases, testCase{ 9255 name: "Resume-Client-CipherMismatch", 9256 resumeSession: true, 9257 config: Config{ 9258 MaxVersion: VersionTLS12, 9259 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 9260 }, 9261 resumeConfig: &Config{ 9262 MaxVersion: VersionTLS12, 9263 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 9264 Bugs: ProtocolBugs{ 9265 SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA, 9266 }, 9267 }, 9268 shouldFail: true, 9269 expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:", 9270 }) 9271 9272 // Session resumption in TLS 1.3 may change the cipher suite if the PRF 9273 // matches. 9274 testCases = append(testCases, testCase{ 9275 name: "Resume-Client-CipherMismatch-TLS13", 9276 resumeSession: true, 9277 config: Config{ 9278 MaxVersion: VersionTLS13, 9279 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9280 }, 9281 resumeConfig: &Config{ 9282 MaxVersion: VersionTLS13, 9283 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 9284 }, 9285 }) 9286 9287 // Session resumption in TLS 1.3 is forbidden if the PRF does not match. 9288 testCases = append(testCases, testCase{ 9289 name: "Resume-Client-PRFMismatch-TLS13", 9290 resumeSession: true, 9291 config: Config{ 9292 MaxVersion: VersionTLS13, 9293 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9294 }, 9295 resumeConfig: &Config{ 9296 MaxVersion: VersionTLS13, 9297 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9298 Bugs: ProtocolBugs{ 9299 SendCipherSuite: TLS_AES_256_GCM_SHA384, 9300 }, 9301 }, 9302 shouldFail: true, 9303 expectedError: ":OLD_SESSION_PRF_HASH_MISMATCH:", 9304 }) 9305 9306 for _, secondBinder := range []bool{false, true} { 9307 var suffix string 9308 var defaultCurves []CurveID 9309 if secondBinder { 9310 suffix = "-SecondBinder" 9311 // Force a HelloRetryRequest by predicting an empty curve list. 9312 defaultCurves = []CurveID{} 9313 } 9314 9315 testCases = append(testCases, testCase{ 9316 testType: serverTest, 9317 name: "Resume-Server-BinderWrongLength" + suffix, 9318 resumeSession: true, 9319 config: Config{ 9320 MaxVersion: VersionTLS13, 9321 DefaultCurves: defaultCurves, 9322 Bugs: ProtocolBugs{ 9323 SendShortPSKBinder: true, 9324 OnlyCorruptSecondPSKBinder: secondBinder, 9325 }, 9326 }, 9327 shouldFail: true, 9328 expectedLocalError: "remote error: error decrypting message", 9329 expectedError: ":DIGEST_CHECK_FAILED:", 9330 }) 9331 9332 testCases = append(testCases, testCase{ 9333 testType: serverTest, 9334 name: "Resume-Server-NoPSKBinder" + suffix, 9335 resumeSession: true, 9336 config: Config{ 9337 MaxVersion: VersionTLS13, 9338 DefaultCurves: defaultCurves, 9339 Bugs: ProtocolBugs{ 9340 SendNoPSKBinder: true, 9341 OnlyCorruptSecondPSKBinder: secondBinder, 9342 }, 9343 }, 9344 shouldFail: true, 9345 expectedLocalError: "remote error: error decoding message", 9346 expectedError: ":DECODE_ERROR:", 9347 }) 9348 9349 testCases = append(testCases, testCase{ 9350 testType: serverTest, 9351 name: "Resume-Server-ExtraPSKBinder" + suffix, 9352 resumeSession: true, 9353 config: Config{ 9354 MaxVersion: VersionTLS13, 9355 DefaultCurves: defaultCurves, 9356 Bugs: ProtocolBugs{ 9357 SendExtraPSKBinder: true, 9358 OnlyCorruptSecondPSKBinder: secondBinder, 9359 }, 9360 }, 9361 shouldFail: true, 9362 expectedLocalError: "remote error: illegal parameter", 9363 expectedError: ":PSK_IDENTITY_BINDER_COUNT_MISMATCH:", 9364 }) 9365 9366 testCases = append(testCases, testCase{ 9367 testType: serverTest, 9368 name: "Resume-Server-ExtraIdentityNoBinder" + suffix, 9369 resumeSession: true, 9370 config: Config{ 9371 MaxVersion: VersionTLS13, 9372 DefaultCurves: defaultCurves, 9373 Bugs: ProtocolBugs{ 9374 ExtraPSKIdentity: true, 9375 OnlyCorruptSecondPSKBinder: secondBinder, 9376 }, 9377 }, 9378 shouldFail: true, 9379 expectedLocalError: "remote error: illegal parameter", 9380 expectedError: ":PSK_IDENTITY_BINDER_COUNT_MISMATCH:", 9381 }) 9382 9383 testCases = append(testCases, testCase{ 9384 testType: serverTest, 9385 name: "Resume-Server-InvalidPSKBinder" + suffix, 9386 resumeSession: true, 9387 config: Config{ 9388 MaxVersion: VersionTLS13, 9389 DefaultCurves: defaultCurves, 9390 Bugs: ProtocolBugs{ 9391 SendInvalidPSKBinder: true, 9392 OnlyCorruptSecondPSKBinder: secondBinder, 9393 }, 9394 }, 9395 shouldFail: true, 9396 expectedLocalError: "remote error: error decrypting message", 9397 expectedError: ":DIGEST_CHECK_FAILED:", 9398 }) 9399 9400 testCases = append(testCases, testCase{ 9401 testType: serverTest, 9402 name: "Resume-Server-PSKBinderFirstExtension" + suffix, 9403 resumeSession: true, 9404 config: Config{ 9405 MaxVersion: VersionTLS13, 9406 DefaultCurves: defaultCurves, 9407 Bugs: ProtocolBugs{ 9408 PSKBinderFirst: true, 9409 OnlyCorruptSecondPSKBinder: secondBinder, 9410 }, 9411 }, 9412 shouldFail: true, 9413 expectedLocalError: "remote error: illegal parameter", 9414 expectedError: ":PRE_SHARED_KEY_MUST_BE_LAST:", 9415 }) 9416 } 9417 9418 testCases = append(testCases, testCase{ 9419 testType: serverTest, 9420 name: "Resume-Server-OmitPSKsOnSecondClientHello", 9421 resumeSession: true, 9422 config: Config{ 9423 MaxVersion: VersionTLS13, 9424 DefaultCurves: []CurveID{}, 9425 Bugs: ProtocolBugs{ 9426 OmitPSKsOnSecondClientHello: true, 9427 }, 9428 }, 9429 shouldFail: true, 9430 expectedLocalError: "remote error: illegal parameter", 9431 expectedError: ":INCONSISTENT_CLIENT_HELLO:", 9432 }) 9433} 9434 9435func addRenegotiationTests() { 9436 // Servers cannot renegotiate. 9437 testCases = append(testCases, testCase{ 9438 testType: serverTest, 9439 name: "Renegotiate-Server-Forbidden", 9440 config: Config{ 9441 MaxVersion: VersionTLS12, 9442 }, 9443 renegotiate: 1, 9444 shouldFail: true, 9445 expectedError: ":NO_RENEGOTIATION:", 9446 expectedLocalError: "remote error: no renegotiation", 9447 }) 9448 // The server shouldn't echo the renegotiation extension unless 9449 // requested by the client. 9450 testCases = append(testCases, testCase{ 9451 testType: serverTest, 9452 name: "Renegotiate-Server-NoExt", 9453 config: Config{ 9454 MaxVersion: VersionTLS12, 9455 Bugs: ProtocolBugs{ 9456 NoRenegotiationInfo: true, 9457 RequireRenegotiationInfo: true, 9458 }, 9459 }, 9460 shouldFail: true, 9461 expectedLocalError: "renegotiation extension missing", 9462 }) 9463 // The renegotiation SCSV should be sufficient for the server to echo 9464 // the extension. 9465 testCases = append(testCases, testCase{ 9466 testType: serverTest, 9467 name: "Renegotiate-Server-NoExt-SCSV", 9468 config: Config{ 9469 MaxVersion: VersionTLS12, 9470 Bugs: ProtocolBugs{ 9471 NoRenegotiationInfo: true, 9472 SendRenegotiationSCSV: true, 9473 RequireRenegotiationInfo: true, 9474 }, 9475 }, 9476 }) 9477 testCases = append(testCases, testCase{ 9478 name: "Renegotiate-Client", 9479 config: Config{ 9480 MaxVersion: VersionTLS12, 9481 Bugs: ProtocolBugs{ 9482 FailIfResumeOnRenego: true, 9483 }, 9484 }, 9485 renegotiate: 1, 9486 // Test renegotiation after both an initial and resumption 9487 // handshake. 9488 resumeSession: true, 9489 flags: []string{ 9490 "-renegotiate-freely", 9491 "-expect-total-renegotiations", "1", 9492 "-expect-secure-renegotiation", 9493 }, 9494 }) 9495 testCases = append(testCases, testCase{ 9496 name: "Renegotiate-Client-TLS12", 9497 config: Config{ 9498 MaxVersion: VersionTLS12, 9499 Bugs: ProtocolBugs{ 9500 FailIfResumeOnRenego: true, 9501 }, 9502 }, 9503 renegotiate: 1, 9504 // Test renegotiation after both an initial and resumption 9505 // handshake. 9506 resumeSession: true, 9507 flags: []string{ 9508 "-renegotiate-freely", 9509 "-expect-total-renegotiations", "1", 9510 "-expect-secure-renegotiation", 9511 }, 9512 }) 9513 testCases = append(testCases, testCase{ 9514 name: "Renegotiate-Client-EmptyExt", 9515 renegotiate: 1, 9516 config: Config{ 9517 MaxVersion: VersionTLS12, 9518 Bugs: ProtocolBugs{ 9519 EmptyRenegotiationInfo: true, 9520 }, 9521 }, 9522 flags: []string{"-renegotiate-freely"}, 9523 shouldFail: true, 9524 expectedError: ":RENEGOTIATION_MISMATCH:", 9525 expectedLocalError: "handshake failure", 9526 }) 9527 testCases = append(testCases, testCase{ 9528 name: "Renegotiate-Client-BadExt", 9529 renegotiate: 1, 9530 config: Config{ 9531 MaxVersion: VersionTLS12, 9532 Bugs: ProtocolBugs{ 9533 BadRenegotiationInfo: true, 9534 }, 9535 }, 9536 flags: []string{"-renegotiate-freely"}, 9537 shouldFail: true, 9538 expectedError: ":RENEGOTIATION_MISMATCH:", 9539 expectedLocalError: "handshake failure", 9540 }) 9541 testCases = append(testCases, testCase{ 9542 name: "Renegotiate-Client-BadExt2", 9543 renegotiate: 1, 9544 config: Config{ 9545 MaxVersion: VersionTLS12, 9546 Bugs: ProtocolBugs{ 9547 BadRenegotiationInfoEnd: true, 9548 }, 9549 }, 9550 flags: []string{"-renegotiate-freely"}, 9551 shouldFail: true, 9552 expectedError: ":RENEGOTIATION_MISMATCH:", 9553 expectedLocalError: "handshake failure", 9554 }) 9555 testCases = append(testCases, testCase{ 9556 name: "Renegotiate-Client-Downgrade", 9557 renegotiate: 1, 9558 config: Config{ 9559 MaxVersion: VersionTLS12, 9560 Bugs: ProtocolBugs{ 9561 NoRenegotiationInfoAfterInitial: true, 9562 }, 9563 }, 9564 flags: []string{"-renegotiate-freely"}, 9565 shouldFail: true, 9566 expectedError: ":RENEGOTIATION_MISMATCH:", 9567 expectedLocalError: "handshake failure", 9568 }) 9569 testCases = append(testCases, testCase{ 9570 name: "Renegotiate-Client-Upgrade", 9571 renegotiate: 1, 9572 config: Config{ 9573 MaxVersion: VersionTLS12, 9574 Bugs: ProtocolBugs{ 9575 NoRenegotiationInfoInInitial: true, 9576 }, 9577 }, 9578 flags: []string{"-renegotiate-freely"}, 9579 shouldFail: true, 9580 expectedError: ":RENEGOTIATION_MISMATCH:", 9581 expectedLocalError: "handshake failure", 9582 }) 9583 testCases = append(testCases, testCase{ 9584 name: "Renegotiate-Client-NoExt-Allowed", 9585 renegotiate: 1, 9586 config: Config{ 9587 MaxVersion: VersionTLS12, 9588 Bugs: ProtocolBugs{ 9589 NoRenegotiationInfo: true, 9590 }, 9591 }, 9592 flags: []string{ 9593 "-renegotiate-freely", 9594 "-expect-total-renegotiations", "1", 9595 "-expect-no-secure-renegotiation", 9596 }, 9597 }) 9598 9599 // Test that the server may switch ciphers on renegotiation without 9600 // problems. 9601 testCases = append(testCases, testCase{ 9602 name: "Renegotiate-Client-SwitchCiphers", 9603 renegotiate: 1, 9604 config: Config{ 9605 MaxVersion: VersionTLS12, 9606 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 9607 }, 9608 renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9609 flags: []string{ 9610 "-renegotiate-freely", 9611 "-expect-total-renegotiations", "1", 9612 }, 9613 }) 9614 testCases = append(testCases, testCase{ 9615 name: "Renegotiate-Client-SwitchCiphers2", 9616 renegotiate: 1, 9617 config: Config{ 9618 MaxVersion: VersionTLS12, 9619 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9620 }, 9621 renegotiateCiphers: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 9622 flags: []string{ 9623 "-renegotiate-freely", 9624 "-expect-total-renegotiations", "1", 9625 }, 9626 }) 9627 9628 // Test that the server may not switch versions on renegotiation. 9629 testCases = append(testCases, testCase{ 9630 name: "Renegotiate-Client-SwitchVersion", 9631 config: Config{ 9632 MaxVersion: VersionTLS12, 9633 // Pick a cipher which exists at both versions. 9634 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 9635 Bugs: ProtocolBugs{ 9636 NegotiateVersionOnRenego: VersionTLS11, 9637 // Avoid failing early at the record layer. 9638 SendRecordVersion: VersionTLS12, 9639 }, 9640 }, 9641 renegotiate: 1, 9642 flags: []string{ 9643 "-renegotiate-freely", 9644 "-expect-total-renegotiations", "1", 9645 }, 9646 shouldFail: true, 9647 expectedError: ":WRONG_SSL_VERSION:", 9648 }) 9649 9650 testCases = append(testCases, testCase{ 9651 name: "Renegotiate-SameClientVersion", 9652 renegotiate: 1, 9653 config: Config{ 9654 MaxVersion: VersionTLS10, 9655 Bugs: ProtocolBugs{ 9656 RequireSameRenegoClientVersion: true, 9657 }, 9658 }, 9659 flags: []string{ 9660 "-renegotiate-freely", 9661 "-expect-total-renegotiations", "1", 9662 }, 9663 }) 9664 testCases = append(testCases, testCase{ 9665 name: "Renegotiate-FalseStart", 9666 renegotiate: 1, 9667 config: Config{ 9668 MaxVersion: VersionTLS12, 9669 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9670 NextProtos: []string{"foo"}, 9671 }, 9672 flags: []string{ 9673 "-false-start", 9674 "-select-next-proto", "foo", 9675 "-renegotiate-freely", 9676 "-expect-total-renegotiations", "1", 9677 }, 9678 shimWritesFirst: true, 9679 }) 9680 9681 // Client-side renegotiation controls. 9682 testCases = append(testCases, testCase{ 9683 name: "Renegotiate-Client-Forbidden-1", 9684 config: Config{ 9685 MaxVersion: VersionTLS12, 9686 }, 9687 renegotiate: 1, 9688 shouldFail: true, 9689 expectedError: ":NO_RENEGOTIATION:", 9690 expectedLocalError: "remote error: no renegotiation", 9691 }) 9692 testCases = append(testCases, testCase{ 9693 name: "Renegotiate-Client-Once-1", 9694 config: Config{ 9695 MaxVersion: VersionTLS12, 9696 }, 9697 renegotiate: 1, 9698 flags: []string{ 9699 "-renegotiate-once", 9700 "-expect-total-renegotiations", "1", 9701 }, 9702 }) 9703 testCases = append(testCases, testCase{ 9704 name: "Renegotiate-Client-Freely-1", 9705 config: Config{ 9706 MaxVersion: VersionTLS12, 9707 }, 9708 renegotiate: 1, 9709 flags: []string{ 9710 "-renegotiate-freely", 9711 "-expect-total-renegotiations", "1", 9712 }, 9713 }) 9714 testCases = append(testCases, testCase{ 9715 name: "Renegotiate-Client-Once-2", 9716 config: Config{ 9717 MaxVersion: VersionTLS12, 9718 }, 9719 renegotiate: 2, 9720 flags: []string{"-renegotiate-once"}, 9721 shouldFail: true, 9722 expectedError: ":NO_RENEGOTIATION:", 9723 expectedLocalError: "remote error: no renegotiation", 9724 }) 9725 testCases = append(testCases, testCase{ 9726 name: "Renegotiate-Client-Freely-2", 9727 config: Config{ 9728 MaxVersion: VersionTLS12, 9729 }, 9730 renegotiate: 2, 9731 flags: []string{ 9732 "-renegotiate-freely", 9733 "-expect-total-renegotiations", "2", 9734 }, 9735 }) 9736 testCases = append(testCases, testCase{ 9737 name: "Renegotiate-Client-NoIgnore", 9738 config: Config{ 9739 MaxVersion: VersionTLS12, 9740 Bugs: ProtocolBugs{ 9741 SendHelloRequestBeforeEveryAppDataRecord: true, 9742 }, 9743 }, 9744 shouldFail: true, 9745 expectedError: ":NO_RENEGOTIATION:", 9746 }) 9747 testCases = append(testCases, testCase{ 9748 name: "Renegotiate-Client-Ignore", 9749 config: Config{ 9750 MaxVersion: VersionTLS12, 9751 Bugs: ProtocolBugs{ 9752 SendHelloRequestBeforeEveryAppDataRecord: true, 9753 }, 9754 }, 9755 flags: []string{ 9756 "-renegotiate-ignore", 9757 "-expect-total-renegotiations", "0", 9758 }, 9759 }) 9760 9761 // Renegotiation may be enabled and then disabled immediately after the 9762 // handshake. 9763 testCases = append(testCases, testCase{ 9764 name: "Renegotiate-ForbidAfterHandshake", 9765 config: Config{ 9766 MaxVersion: VersionTLS12, 9767 }, 9768 renegotiate: 1, 9769 flags: []string{"-forbid-renegotiation-after-handshake"}, 9770 shouldFail: true, 9771 expectedError: ":NO_RENEGOTIATION:", 9772 expectedLocalError: "remote error: no renegotiation", 9773 }) 9774 9775 // Renegotiation is not allowed when there is an unfinished write. 9776 testCases = append(testCases, testCase{ 9777 name: "Renegotiate-Client-UnfinishedWrite", 9778 config: Config{ 9779 MaxVersion: VersionTLS12, 9780 }, 9781 renegotiate: 1, 9782 readWithUnfinishedWrite: true, 9783 flags: []string{ 9784 "-async", 9785 "-renegotiate-freely", 9786 }, 9787 shouldFail: true, 9788 expectedError: ":NO_RENEGOTIATION:", 9789 // We do not successfully send the no_renegotiation alert in 9790 // this case. https://crbug.com/boringssl/130 9791 }) 9792 9793 // We reject stray HelloRequests during the handshake in TLS 1.2. 9794 testCases = append(testCases, testCase{ 9795 name: "StrayHelloRequest", 9796 config: Config{ 9797 MaxVersion: VersionTLS12, 9798 Bugs: ProtocolBugs{ 9799 SendHelloRequestBeforeEveryHandshakeMessage: true, 9800 }, 9801 }, 9802 shouldFail: true, 9803 expectedError: ":UNEXPECTED_MESSAGE:", 9804 }) 9805 testCases = append(testCases, testCase{ 9806 name: "StrayHelloRequest-Packed", 9807 config: Config{ 9808 MaxVersion: VersionTLS12, 9809 Bugs: ProtocolBugs{ 9810 PackHandshakeFlight: true, 9811 SendHelloRequestBeforeEveryHandshakeMessage: true, 9812 }, 9813 }, 9814 shouldFail: true, 9815 expectedError: ":UNEXPECTED_MESSAGE:", 9816 }) 9817 9818 // Test that HelloRequest is rejected if it comes in the same record as the 9819 // server Finished. 9820 testCases = append(testCases, testCase{ 9821 name: "Renegotiate-Client-Packed", 9822 config: Config{ 9823 MaxVersion: VersionTLS12, 9824 Bugs: ProtocolBugs{ 9825 PackHandshakeFlight: true, 9826 PackHelloRequestWithFinished: true, 9827 }, 9828 }, 9829 renegotiate: 1, 9830 flags: []string{"-renegotiate-freely"}, 9831 shouldFail: true, 9832 expectedError: ":EXCESS_HANDSHAKE_DATA:", 9833 expectedLocalError: "remote error: unexpected message", 9834 }) 9835 9836 // Renegotiation is forbidden in TLS 1.3. 9837 testCases = append(testCases, testCase{ 9838 name: "Renegotiate-Client-TLS13", 9839 config: Config{ 9840 MaxVersion: VersionTLS13, 9841 Bugs: ProtocolBugs{ 9842 SendHelloRequestBeforeEveryAppDataRecord: true, 9843 }, 9844 }, 9845 flags: []string{ 9846 "-renegotiate-freely", 9847 }, 9848 shouldFail: true, 9849 expectedError: ":UNEXPECTED_MESSAGE:", 9850 }) 9851 9852 // Stray HelloRequests during the handshake are forbidden in TLS 1.3. 9853 testCases = append(testCases, testCase{ 9854 name: "StrayHelloRequest-TLS13", 9855 config: Config{ 9856 MaxVersion: VersionTLS13, 9857 Bugs: ProtocolBugs{ 9858 SendHelloRequestBeforeEveryHandshakeMessage: true, 9859 }, 9860 }, 9861 shouldFail: true, 9862 expectedError: ":UNEXPECTED_MESSAGE:", 9863 }) 9864 9865 // The renegotiation_info extension is not sent in TLS 1.3, but TLS 1.3 9866 // always reads as supporting it, regardless of whether it was 9867 // negotiated. 9868 testCases = append(testCases, testCase{ 9869 name: "AlwaysReportRenegotiationInfo-TLS13", 9870 config: Config{ 9871 MaxVersion: VersionTLS13, 9872 Bugs: ProtocolBugs{ 9873 NoRenegotiationInfo: true, 9874 }, 9875 }, 9876 flags: []string{ 9877 "-expect-secure-renegotiation", 9878 }, 9879 }) 9880 9881 // Certificates may not change on renegotiation. 9882 testCases = append(testCases, testCase{ 9883 name: "Renegotiation-CertificateChange", 9884 config: Config{ 9885 MaxVersion: VersionTLS12, 9886 Credential: &rsaCertificate, 9887 Bugs: ProtocolBugs{ 9888 RenegotiationCertificate: &rsaChainCertificate, 9889 }, 9890 }, 9891 renegotiate: 1, 9892 flags: []string{"-renegotiate-freely"}, 9893 shouldFail: true, 9894 expectedError: ":SERVER_CERT_CHANGED:", 9895 }) 9896 testCases = append(testCases, testCase{ 9897 name: "Renegotiation-CertificateChange-2", 9898 config: Config{ 9899 MaxVersion: VersionTLS12, 9900 Credential: &rsaCertificate, 9901 Bugs: ProtocolBugs{ 9902 RenegotiationCertificate: &rsa1024Certificate, 9903 }, 9904 }, 9905 renegotiate: 1, 9906 flags: []string{"-renegotiate-freely"}, 9907 shouldFail: true, 9908 expectedError: ":SERVER_CERT_CHANGED:", 9909 }) 9910 9911 // We do not negotiate ALPN after the initial handshake. This is 9912 // error-prone and only risks bugs in consumers. 9913 testCases = append(testCases, testCase{ 9914 testType: clientTest, 9915 name: "Renegotiation-ForbidALPN", 9916 config: Config{ 9917 MaxVersion: VersionTLS12, 9918 Bugs: ProtocolBugs{ 9919 // Forcibly negotiate ALPN on both initial and 9920 // renegotiation handshakes. The test stack will 9921 // internally check the client does not offer 9922 // it. 9923 SendALPN: "foo", 9924 }, 9925 }, 9926 flags: []string{ 9927 "-advertise-alpn", "\x03foo\x03bar\x03baz", 9928 "-expect-alpn", "foo", 9929 "-renegotiate-freely", 9930 }, 9931 renegotiate: 1, 9932 shouldFail: true, 9933 expectedError: ":UNEXPECTED_EXTENSION:", 9934 }) 9935 9936 // The server may send different stapled OCSP responses or SCT lists on 9937 // renegotiation, but BoringSSL ignores this and reports the old values. 9938 // Also test that non-fatal verify results are preserved. 9939 testCases = append(testCases, testCase{ 9940 testType: clientTest, 9941 name: "Renegotiation-ChangeAuthProperties", 9942 config: Config{ 9943 MaxVersion: VersionTLS12, 9944 Credential: rsaCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 9945 Bugs: ProtocolBugs{ 9946 SendOCSPResponseOnRenegotiation: testOCSPResponse2, 9947 SendSCTListOnRenegotiation: testSCTList2, 9948 }, 9949 }, 9950 renegotiate: 1, 9951 flags: []string{ 9952 "-renegotiate-freely", 9953 "-expect-total-renegotiations", "1", 9954 "-enable-ocsp-stapling", 9955 "-expect-ocsp-response", 9956 base64FlagValue(testOCSPResponse), 9957 "-enable-signed-cert-timestamps", 9958 "-expect-signed-cert-timestamps", 9959 base64FlagValue(testSCTList), 9960 "-verify-fail", 9961 "-expect-verify-result", 9962 }, 9963 }) 9964} 9965 9966func addDTLSReplayTests() { 9967 // Test that sequence number replays are detected. 9968 testCases = append(testCases, testCase{ 9969 protocol: dtls, 9970 name: "DTLS-Replay", 9971 messageCount: 200, 9972 replayWrites: true, 9973 }) 9974 9975 // Test the incoming sequence number skipping by values larger 9976 // than the retransmit window. 9977 testCases = append(testCases, testCase{ 9978 protocol: dtls, 9979 name: "DTLS-Replay-LargeGaps", 9980 config: Config{ 9981 Bugs: ProtocolBugs{ 9982 SequenceNumberMapping: func(in uint64) uint64 { 9983 return in * 1023 9984 }, 9985 }, 9986 }, 9987 messageCount: 200, 9988 replayWrites: true, 9989 }) 9990 9991 // Test the incoming sequence number changing non-monotonically. 9992 testCases = append(testCases, testCase{ 9993 protocol: dtls, 9994 name: "DTLS-Replay-NonMonotonic", 9995 config: Config{ 9996 Bugs: ProtocolBugs{ 9997 SequenceNumberMapping: func(in uint64) uint64 { 9998 // This mapping has numbers counting backwards in groups 9999 // of 256, and then jumping forwards 511 numbers. 10000 return in ^ 255 10001 }, 10002 }, 10003 }, 10004 // This messageCount is large enough to make sure that the SequenceNumberMapping 10005 // will reach the point where it jumps forwards after stepping backwards. 10006 messageCount: 500, 10007 replayWrites: true, 10008 }) 10009} 10010 10011var testSignatureAlgorithms = []struct { 10012 name string 10013 id signatureAlgorithm 10014 baseCert *Credential 10015 // If non-zero, the curve that must be supported in TLS 1.2 for cert to be 10016 // accepted. 10017 curve CurveID 10018}{ 10019 {"RSA_PKCS1_SHA1", signatureRSAPKCS1WithSHA1, &rsaCertificate, 0}, 10020 {"RSA_PKCS1_SHA256", signatureRSAPKCS1WithSHA256, &rsaCertificate, 0}, 10021 {"RSA_PKCS1_SHA256_LEGACY", signatureRSAPKCS1WithSHA256Legacy, &rsaCertificate, 0}, 10022 {"RSA_PKCS1_SHA384", signatureRSAPKCS1WithSHA384, &rsaCertificate, 0}, 10023 {"RSA_PKCS1_SHA512", signatureRSAPKCS1WithSHA512, &rsaCertificate, 0}, 10024 {"ECDSA_SHA1", signatureECDSAWithSHA1, &ecdsaP256Certificate, CurveP256}, 10025 // The “P256” in the following line is not a mistake. In TLS 1.2 the 10026 // hash function doesn't have to match the curve and so the same 10027 // signature algorithm works with P-224. 10028 {"ECDSA_P224_SHA256", signatureECDSAWithP256AndSHA256, &ecdsaP224Certificate, CurveP224}, 10029 {"ECDSA_P256_SHA256", signatureECDSAWithP256AndSHA256, &ecdsaP256Certificate, CurveP256}, 10030 {"ECDSA_P384_SHA384", signatureECDSAWithP384AndSHA384, &ecdsaP384Certificate, CurveP384}, 10031 {"ECDSA_P521_SHA512", signatureECDSAWithP521AndSHA512, &ecdsaP521Certificate, CurveP521}, 10032 {"RSA_PSS_SHA256", signatureRSAPSSWithSHA256, &rsaCertificate, 0}, 10033 {"RSA_PSS_SHA384", signatureRSAPSSWithSHA384, &rsaCertificate, 0}, 10034 {"RSA_PSS_SHA512", signatureRSAPSSWithSHA512, &rsaCertificate, 0}, 10035 {"Ed25519", signatureEd25519, &ed25519Certificate, 0}, 10036 // Tests for key types prior to TLS 1.2. 10037 {"RSA", 0, &rsaCertificate, 0}, 10038 {"ECDSA", 0, &ecdsaP256Certificate, CurveP256}, 10039} 10040 10041const fakeSigAlg1 signatureAlgorithm = 0x2a01 10042const fakeSigAlg2 signatureAlgorithm = 0xff01 10043 10044func addSignatureAlgorithmTests() { 10045 // Not all ciphers involve a signature. Advertise a list which gives all 10046 // versions a signing cipher. 10047 signingCiphers := []uint16{ 10048 TLS_AES_256_GCM_SHA384, 10049 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 10050 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 10051 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 10052 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 10053 } 10054 10055 var allAlgorithms []signatureAlgorithm 10056 for _, alg := range testSignatureAlgorithms { 10057 if alg.id != 0 { 10058 allAlgorithms = append(allAlgorithms, alg.id) 10059 } 10060 } 10061 10062 // Make sure each signature algorithm works. Include some fake values in 10063 // the list and ensure they're ignored. 10064 for _, alg := range testSignatureAlgorithms { 10065 // Make a version of the certificate that will not sign any other algorithm. 10066 cert := alg.baseCert 10067 if alg.id != 0 { 10068 cert = cert.WithSignatureAlgorithms(alg.id) 10069 } 10070 10071 for _, ver := range tlsVersions { 10072 if (ver.version < VersionTLS12) != (alg.id == 0) { 10073 continue 10074 } 10075 10076 suffix := "-" + alg.name + "-" + ver.name 10077 for _, signTestType := range []testType{clientTest, serverTest} { 10078 signPrefix := "Client-" 10079 verifyPrefix := "Server-" 10080 verifyTestType := serverTest 10081 if signTestType == serverTest { 10082 verifyTestType = clientTest 10083 signPrefix, verifyPrefix = verifyPrefix, signPrefix 10084 } 10085 10086 var shouldFail bool 10087 isTLS12PKCS1 := hasComponent(alg.name, "PKCS1") && !hasComponent(alg.name, "LEGACY") 10088 isTLS13PKCS1 := hasComponent(alg.name, "PKCS1") && hasComponent(alg.name, "LEGACY") 10089 10090 // TLS 1.3 removes a number of signature algorithms. 10091 if ver.version >= VersionTLS13 && (alg.curve == CurveP224 || alg.id == signatureECDSAWithSHA1 || isTLS12PKCS1) { 10092 shouldFail = true 10093 } 10094 10095 // The backported RSA-PKCS1 code points only exist for TLS 1.3 10096 // client certificates. 10097 if (ver.version < VersionTLS13 || signTestType == serverTest) && isTLS13PKCS1 { 10098 shouldFail = true 10099 } 10100 10101 // By default, BoringSSL does not sign with these algorithms. 10102 signDefault := !shouldFail 10103 if isTLS13PKCS1 { 10104 signDefault = false 10105 } 10106 10107 // By default, BoringSSL does not accept these algorithms. 10108 verifyDefault := !shouldFail 10109 if alg.id == signatureECDSAWithSHA1 || alg.id == signatureECDSAWithP521AndSHA512 || alg.id == signatureEd25519 || isTLS13PKCS1 { 10110 verifyDefault = false 10111 } 10112 10113 var curveFlags []string 10114 var runnerCurves []CurveID 10115 if alg.curve != 0 && ver.version <= VersionTLS12 { 10116 // In TLS 1.2, the ECDH curve list also constrains ECDSA keys. Ensure the 10117 // corresponding curve is enabled. Also include X25519 to ensure the shim 10118 // and runner have something in common for ECDH. 10119 curveFlags = flagInts("-curves", []int{int(CurveX25519), int(alg.curve)}) 10120 runnerCurves = []CurveID{CurveX25519, alg.curve} 10121 } 10122 10123 signError := func(shouldFail bool) string { 10124 if !shouldFail { 10125 return "" 10126 } 10127 // In TLS 1.3, the shim should report no common signature algorithms if 10128 // it cannot generate a signature. In TLS 1.2 servers, signature 10129 // algorithm and cipher selection are integrated, so it is reported as 10130 // no shared cipher. 10131 if ver.version <= VersionTLS12 && signTestType == serverTest { 10132 return ":NO_SHARED_CIPHER:" 10133 } 10134 return ":NO_COMMON_SIGNATURE_ALGORITHMS:" 10135 } 10136 signLocalError := func(shouldFail bool) string { 10137 if !shouldFail { 10138 return "" 10139 } 10140 // The shim should send handshake_failure when it cannot 10141 // negotiate parameters. 10142 return "remote error: handshake failure" 10143 } 10144 verifyError := func(shouldFail bool) string { 10145 if !shouldFail { 10146 return "" 10147 } 10148 // If the shim rejects the signature algorithm, but the 10149 // runner forcibly selects it anyway, the shim should notice. 10150 return ":WRONG_SIGNATURE_TYPE:" 10151 } 10152 verifyLocalError := func(shouldFail bool) string { 10153 if !shouldFail { 10154 return "" 10155 } 10156 // The shim should send an illegal_parameter alert if the runner 10157 // uses a signature algorithm it isn't allowed to use. 10158 return "remote error: illegal parameter" 10159 } 10160 10161 // Test the shim using the algorithm for signing. 10162 signTest := testCase{ 10163 testType: signTestType, 10164 name: signPrefix + "Sign" + suffix, 10165 config: Config{ 10166 MaxVersion: ver.version, 10167 CurvePreferences: runnerCurves, 10168 VerifySignatureAlgorithms: []signatureAlgorithm{ 10169 fakeSigAlg1, 10170 alg.id, 10171 fakeSigAlg2, 10172 }, 10173 }, 10174 shimCertificate: cert, 10175 flags: curveFlags, 10176 shouldFail: shouldFail, 10177 expectedError: signError(shouldFail), 10178 expectedLocalError: signLocalError(shouldFail), 10179 expectations: connectionExpectations{ 10180 peerSignatureAlgorithm: alg.id, 10181 }, 10182 } 10183 10184 // Test whether the shim enables the algorithm by default. 10185 signDefaultTest := testCase{ 10186 testType: signTestType, 10187 name: signPrefix + "SignDefault" + suffix, 10188 config: Config{ 10189 MaxVersion: ver.version, 10190 CurvePreferences: runnerCurves, 10191 VerifySignatureAlgorithms: []signatureAlgorithm{ 10192 fakeSigAlg1, 10193 alg.id, 10194 fakeSigAlg2, 10195 }, 10196 }, 10197 // cert has been configured with the specified algorithm, 10198 // while alg.baseCert uses the defaults. 10199 shimCertificate: alg.baseCert, 10200 flags: curveFlags, 10201 shouldFail: !signDefault, 10202 expectedError: signError(!signDefault), 10203 expectedLocalError: signLocalError(!signDefault), 10204 expectations: connectionExpectations{ 10205 peerSignatureAlgorithm: alg.id, 10206 }, 10207 } 10208 10209 // Test that the shim will select the algorithm when configured to only 10210 // support it. 10211 negotiateTest := testCase{ 10212 testType: signTestType, 10213 name: signPrefix + "Sign-Negotiate" + suffix, 10214 config: Config{ 10215 MaxVersion: ver.version, 10216 CurvePreferences: runnerCurves, 10217 VerifySignatureAlgorithms: allAlgorithms, 10218 }, 10219 shimCertificate: cert, 10220 flags: curveFlags, 10221 expectations: connectionExpectations{ 10222 peerSignatureAlgorithm: alg.id, 10223 }, 10224 } 10225 10226 if signTestType == serverTest { 10227 // TLS 1.2 servers only sign on some cipher suites. 10228 signTest.config.CipherSuites = signingCiphers 10229 signDefaultTest.config.CipherSuites = signingCiphers 10230 negotiateTest.config.CipherSuites = signingCiphers 10231 } else { 10232 // TLS 1.2 clients only sign when the server requests certificates. 10233 signTest.config.ClientAuth = RequireAnyClientCert 10234 signDefaultTest.config.ClientAuth = RequireAnyClientCert 10235 negotiateTest.config.ClientAuth = RequireAnyClientCert 10236 } 10237 testCases = append(testCases, signTest, signDefaultTest) 10238 if ver.version >= VersionTLS12 && !shouldFail { 10239 testCases = append(testCases, negotiateTest) 10240 } 10241 10242 // Test the shim using the algorithm for verifying. 10243 verifyTest := testCase{ 10244 testType: verifyTestType, 10245 name: verifyPrefix + "Verify" + suffix, 10246 config: Config{ 10247 MaxVersion: ver.version, 10248 Credential: cert, 10249 Bugs: ProtocolBugs{ 10250 SkipECDSACurveCheck: shouldFail, 10251 IgnoreSignatureVersionChecks: shouldFail, 10252 // Some signature algorithms may not be advertised. 10253 IgnorePeerSignatureAlgorithmPreferences: shouldFail, 10254 }, 10255 }, 10256 flags: curveFlags, 10257 // Resume the session to assert the peer signature 10258 // algorithm is reported on both handshakes. 10259 resumeSession: !shouldFail, 10260 shouldFail: shouldFail, 10261 expectedError: verifyError(shouldFail), 10262 expectedLocalError: verifyLocalError(shouldFail), 10263 } 10264 if alg.id != 0 { 10265 verifyTest.flags = append(verifyTest.flags, "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))) 10266 // The algorithm may be disabled by default, so explicitly enable it. 10267 verifyTest.flags = append(verifyTest.flags, "-verify-prefs", strconv.Itoa(int(alg.id))) 10268 } 10269 10270 // Test whether the shim expects the algorithm enabled by default. 10271 defaultTest := testCase{ 10272 testType: verifyTestType, 10273 name: verifyPrefix + "VerifyDefault" + suffix, 10274 config: Config{ 10275 MaxVersion: ver.version, 10276 Credential: cert, 10277 Bugs: ProtocolBugs{ 10278 SkipECDSACurveCheck: !verifyDefault, 10279 IgnoreSignatureVersionChecks: !verifyDefault, 10280 // Some signature algorithms may not be advertised. 10281 IgnorePeerSignatureAlgorithmPreferences: !verifyDefault, 10282 }, 10283 }, 10284 flags: append( 10285 []string{"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))}, 10286 curveFlags..., 10287 ), 10288 // Resume the session to assert the peer signature 10289 // algorithm is reported on both handshakes. 10290 resumeSession: verifyDefault, 10291 shouldFail: !verifyDefault, 10292 expectedError: verifyError(!verifyDefault), 10293 expectedLocalError: verifyLocalError(!verifyDefault), 10294 } 10295 10296 // Test whether the shim handles invalid signatures for this algorithm. 10297 invalidTest := testCase{ 10298 testType: verifyTestType, 10299 name: verifyPrefix + "InvalidSignature" + suffix, 10300 config: Config{ 10301 MaxVersion: ver.version, 10302 Credential: cert, 10303 Bugs: ProtocolBugs{ 10304 InvalidSignature: true, 10305 }, 10306 }, 10307 flags: curveFlags, 10308 shouldFail: true, 10309 expectedError: ":BAD_SIGNATURE:", 10310 } 10311 if alg.id != 0 { 10312 // The algorithm may be disabled by default, so explicitly enable it. 10313 invalidTest.flags = append(invalidTest.flags, "-verify-prefs", strconv.Itoa(int(alg.id))) 10314 } 10315 10316 if verifyTestType == serverTest { 10317 // TLS 1.2 servers only verify when they request client certificates. 10318 verifyTest.flags = append(verifyTest.flags, "-require-any-client-certificate") 10319 defaultTest.flags = append(defaultTest.flags, "-require-any-client-certificate") 10320 invalidTest.flags = append(invalidTest.flags, "-require-any-client-certificate") 10321 } else { 10322 // TLS 1.2 clients only verify on some cipher suites. 10323 verifyTest.config.CipherSuites = signingCiphers 10324 defaultTest.config.CipherSuites = signingCiphers 10325 invalidTest.config.CipherSuites = signingCiphers 10326 } 10327 testCases = append(testCases, verifyTest, defaultTest) 10328 if !shouldFail { 10329 testCases = append(testCases, invalidTest) 10330 } 10331 } 10332 } 10333 } 10334 10335 // Test the peer's verify preferences are available. 10336 for _, ver := range tlsVersions { 10337 if ver.version < VersionTLS12 { 10338 continue 10339 } 10340 testCases = append(testCases, testCase{ 10341 name: "ClientAuth-PeerVerifyPrefs-" + ver.name, 10342 config: Config{ 10343 MaxVersion: ver.version, 10344 ClientAuth: RequireAnyClientCert, 10345 VerifySignatureAlgorithms: []signatureAlgorithm{ 10346 signatureRSAPSSWithSHA256, 10347 signatureEd25519, 10348 signatureECDSAWithP256AndSHA256, 10349 }, 10350 }, 10351 shimCertificate: &rsaCertificate, 10352 flags: []string{ 10353 "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 10354 "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), 10355 "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 10356 }, 10357 }) 10358 10359 testCases = append(testCases, testCase{ 10360 testType: serverTest, 10361 name: "ServerAuth-PeerVerifyPrefs-" + ver.name, 10362 config: Config{ 10363 MaxVersion: ver.version, 10364 VerifySignatureAlgorithms: []signatureAlgorithm{ 10365 signatureRSAPSSWithSHA256, 10366 signatureEd25519, 10367 signatureECDSAWithP256AndSHA256, 10368 }, 10369 }, 10370 shimCertificate: &rsaCertificate, 10371 flags: []string{ 10372 "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 10373 "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), 10374 "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 10375 }, 10376 }) 10377 10378 } 10379 10380 // Test that algorithm selection takes the key type into account. 10381 testCases = append(testCases, testCase{ 10382 name: "ClientAuth-SignatureType", 10383 config: Config{ 10384 ClientAuth: RequireAnyClientCert, 10385 MaxVersion: VersionTLS12, 10386 VerifySignatureAlgorithms: []signatureAlgorithm{ 10387 signatureECDSAWithP521AndSHA512, 10388 signatureRSAPKCS1WithSHA384, 10389 signatureECDSAWithSHA1, 10390 }, 10391 }, 10392 shimCertificate: &rsaCertificate, 10393 expectations: connectionExpectations{ 10394 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, 10395 }, 10396 }) 10397 10398 testCases = append(testCases, testCase{ 10399 name: "ClientAuth-SignatureType-TLS13", 10400 config: Config{ 10401 ClientAuth: RequireAnyClientCert, 10402 MaxVersion: VersionTLS13, 10403 VerifySignatureAlgorithms: []signatureAlgorithm{ 10404 signatureECDSAWithP521AndSHA512, 10405 signatureRSAPKCS1WithSHA384, 10406 signatureRSAPSSWithSHA384, 10407 signatureECDSAWithSHA1, 10408 }, 10409 }, 10410 shimCertificate: &rsaCertificate, 10411 expectations: connectionExpectations{ 10412 peerSignatureAlgorithm: signatureRSAPSSWithSHA384, 10413 }, 10414 }) 10415 10416 testCases = append(testCases, testCase{ 10417 testType: serverTest, 10418 name: "ServerAuth-SignatureType", 10419 config: Config{ 10420 MaxVersion: VersionTLS12, 10421 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10422 VerifySignatureAlgorithms: []signatureAlgorithm{ 10423 signatureECDSAWithP521AndSHA512, 10424 signatureRSAPKCS1WithSHA384, 10425 signatureECDSAWithSHA1, 10426 }, 10427 }, 10428 expectations: connectionExpectations{ 10429 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, 10430 }, 10431 }) 10432 10433 testCases = append(testCases, testCase{ 10434 testType: serverTest, 10435 name: "ServerAuth-SignatureType-TLS13", 10436 config: Config{ 10437 MaxVersion: VersionTLS13, 10438 VerifySignatureAlgorithms: []signatureAlgorithm{ 10439 signatureECDSAWithP521AndSHA512, 10440 signatureRSAPKCS1WithSHA384, 10441 signatureRSAPSSWithSHA384, 10442 signatureECDSAWithSHA1, 10443 }, 10444 }, 10445 expectations: connectionExpectations{ 10446 peerSignatureAlgorithm: signatureRSAPSSWithSHA384, 10447 }, 10448 }) 10449 10450 // Test that signature verification takes the key type into account. 10451 testCases = append(testCases, testCase{ 10452 testType: serverTest, 10453 name: "Verify-ClientAuth-SignatureType", 10454 config: Config{ 10455 MaxVersion: VersionTLS12, 10456 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithSHA256), 10457 Bugs: ProtocolBugs{ 10458 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10459 }, 10460 }, 10461 flags: []string{ 10462 "-require-any-client-certificate", 10463 }, 10464 shouldFail: true, 10465 expectedError: ":WRONG_SIGNATURE_TYPE:", 10466 }) 10467 10468 testCases = append(testCases, testCase{ 10469 testType: serverTest, 10470 name: "Verify-ClientAuth-SignatureType-TLS13", 10471 config: Config{ 10472 MaxVersion: VersionTLS13, 10473 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 10474 Bugs: ProtocolBugs{ 10475 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10476 }, 10477 }, 10478 flags: []string{ 10479 "-require-any-client-certificate", 10480 }, 10481 shouldFail: true, 10482 expectedError: ":WRONG_SIGNATURE_TYPE:", 10483 }) 10484 10485 testCases = append(testCases, testCase{ 10486 name: "Verify-ServerAuth-SignatureType", 10487 config: Config{ 10488 MaxVersion: VersionTLS12, 10489 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10490 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithSHA256), 10491 Bugs: ProtocolBugs{ 10492 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10493 }, 10494 }, 10495 shouldFail: true, 10496 expectedError: ":WRONG_SIGNATURE_TYPE:", 10497 }) 10498 10499 testCases = append(testCases, testCase{ 10500 name: "Verify-ServerAuth-SignatureType-TLS13", 10501 config: Config{ 10502 MaxVersion: VersionTLS13, 10503 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 10504 Bugs: ProtocolBugs{ 10505 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10506 }, 10507 }, 10508 shouldFail: true, 10509 expectedError: ":WRONG_SIGNATURE_TYPE:", 10510 }) 10511 10512 // Test that, if the ClientHello list is missing, the server falls back 10513 // to SHA-1 in TLS 1.2, but not TLS 1.3. 10514 testCases = append(testCases, testCase{ 10515 testType: serverTest, 10516 name: "ServerAuth-SHA1-Fallback-RSA", 10517 config: Config{ 10518 MaxVersion: VersionTLS12, 10519 VerifySignatureAlgorithms: []signatureAlgorithm{ 10520 signatureRSAPKCS1WithSHA1, 10521 }, 10522 Bugs: ProtocolBugs{ 10523 NoSignatureAlgorithms: true, 10524 }, 10525 }, 10526 shimCertificate: &rsaCertificate, 10527 }) 10528 10529 testCases = append(testCases, testCase{ 10530 testType: serverTest, 10531 name: "ServerAuth-SHA1-Fallback-ECDSA", 10532 config: Config{ 10533 MaxVersion: VersionTLS12, 10534 VerifySignatureAlgorithms: []signatureAlgorithm{ 10535 signatureECDSAWithSHA1, 10536 }, 10537 Bugs: ProtocolBugs{ 10538 NoSignatureAlgorithms: true, 10539 }, 10540 }, 10541 shimCertificate: &ecdsaP256Certificate, 10542 }) 10543 10544 testCases = append(testCases, testCase{ 10545 testType: serverTest, 10546 name: "ServerAuth-NoFallback-TLS13", 10547 config: Config{ 10548 MaxVersion: VersionTLS13, 10549 VerifySignatureAlgorithms: []signatureAlgorithm{ 10550 signatureRSAPKCS1WithSHA1, 10551 }, 10552 Bugs: ProtocolBugs{ 10553 NoSignatureAlgorithms: true, 10554 }, 10555 }, 10556 shouldFail: true, 10557 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10558 }) 10559 10560 // The CertificateRequest list, however, may never be omitted. It is a 10561 // syntax error for it to be empty. 10562 testCases = append(testCases, testCase{ 10563 name: "ClientAuth-NoFallback-RSA", 10564 config: Config{ 10565 MaxVersion: VersionTLS12, 10566 ClientAuth: RequireAnyClientCert, 10567 VerifySignatureAlgorithms: []signatureAlgorithm{ 10568 signatureRSAPKCS1WithSHA1, 10569 }, 10570 Bugs: ProtocolBugs{ 10571 NoSignatureAlgorithms: true, 10572 }, 10573 }, 10574 shimCertificate: &rsaCertificate, 10575 shouldFail: true, 10576 expectedError: ":DECODE_ERROR:", 10577 expectedLocalError: "remote error: error decoding message", 10578 }) 10579 10580 testCases = append(testCases, testCase{ 10581 name: "ClientAuth-NoFallback-ECDSA", 10582 config: Config{ 10583 MaxVersion: VersionTLS12, 10584 ClientAuth: RequireAnyClientCert, 10585 VerifySignatureAlgorithms: []signatureAlgorithm{ 10586 signatureECDSAWithSHA1, 10587 }, 10588 Bugs: ProtocolBugs{ 10589 NoSignatureAlgorithms: true, 10590 }, 10591 }, 10592 shimCertificate: &ecdsaP256Certificate, 10593 shouldFail: true, 10594 expectedError: ":DECODE_ERROR:", 10595 expectedLocalError: "remote error: error decoding message", 10596 }) 10597 10598 testCases = append(testCases, testCase{ 10599 name: "ClientAuth-NoFallback-TLS13", 10600 config: Config{ 10601 MaxVersion: VersionTLS13, 10602 ClientAuth: RequireAnyClientCert, 10603 VerifySignatureAlgorithms: []signatureAlgorithm{ 10604 signatureRSAPKCS1WithSHA1, 10605 }, 10606 Bugs: ProtocolBugs{ 10607 NoSignatureAlgorithms: true, 10608 }, 10609 }, 10610 shimCertificate: &rsaCertificate, 10611 shouldFail: true, 10612 expectedError: ":DECODE_ERROR:", 10613 expectedLocalError: "remote error: error decoding message", 10614 }) 10615 10616 // Test that signature preferences are enforced. BoringSSL does not 10617 // implement MD5 signatures. 10618 testCases = append(testCases, testCase{ 10619 testType: serverTest, 10620 name: "ClientAuth-Enforced", 10621 config: Config{ 10622 MaxVersion: VersionTLS12, 10623 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 10624 Bugs: ProtocolBugs{ 10625 IgnorePeerSignatureAlgorithmPreferences: true, 10626 }, 10627 }, 10628 flags: []string{"-require-any-client-certificate"}, 10629 shouldFail: true, 10630 expectedError: ":WRONG_SIGNATURE_TYPE:", 10631 }) 10632 10633 testCases = append(testCases, testCase{ 10634 name: "ServerAuth-Enforced", 10635 config: Config{ 10636 MaxVersion: VersionTLS12, 10637 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10638 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 10639 Bugs: ProtocolBugs{ 10640 IgnorePeerSignatureAlgorithmPreferences: true, 10641 }, 10642 }, 10643 shouldFail: true, 10644 expectedError: ":WRONG_SIGNATURE_TYPE:", 10645 }) 10646 testCases = append(testCases, testCase{ 10647 testType: serverTest, 10648 name: "ClientAuth-Enforced-TLS13", 10649 config: Config{ 10650 MaxVersion: VersionTLS13, 10651 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 10652 Bugs: ProtocolBugs{ 10653 IgnorePeerSignatureAlgorithmPreferences: true, 10654 IgnoreSignatureVersionChecks: true, 10655 }, 10656 }, 10657 flags: []string{"-require-any-client-certificate"}, 10658 shouldFail: true, 10659 expectedError: ":WRONG_SIGNATURE_TYPE:", 10660 }) 10661 10662 testCases = append(testCases, testCase{ 10663 name: "ServerAuth-Enforced-TLS13", 10664 config: Config{ 10665 MaxVersion: VersionTLS13, 10666 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 10667 Bugs: ProtocolBugs{ 10668 IgnorePeerSignatureAlgorithmPreferences: true, 10669 IgnoreSignatureVersionChecks: true, 10670 }, 10671 }, 10672 shouldFail: true, 10673 expectedError: ":WRONG_SIGNATURE_TYPE:", 10674 }) 10675 10676 // Test that the negotiated signature algorithm respects the client and 10677 // server preferences. 10678 testCases = append(testCases, testCase{ 10679 name: "NoCommonAlgorithms", 10680 config: Config{ 10681 MaxVersion: VersionTLS12, 10682 ClientAuth: RequireAnyClientCert, 10683 VerifySignatureAlgorithms: []signatureAlgorithm{ 10684 signatureRSAPKCS1WithSHA512, 10685 signatureRSAPKCS1WithSHA1, 10686 }, 10687 }, 10688 shimCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithSHA256), 10689 shouldFail: true, 10690 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10691 }) 10692 testCases = append(testCases, testCase{ 10693 name: "NoCommonAlgorithms-TLS13", 10694 config: Config{ 10695 MaxVersion: VersionTLS13, 10696 ClientAuth: RequireAnyClientCert, 10697 VerifySignatureAlgorithms: []signatureAlgorithm{ 10698 signatureRSAPSSWithSHA512, 10699 signatureRSAPSSWithSHA384, 10700 }, 10701 }, 10702 shimCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 10703 shouldFail: true, 10704 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10705 }) 10706 testCases = append(testCases, testCase{ 10707 name: "Agree-Digest-SHA256", 10708 config: Config{ 10709 MaxVersion: VersionTLS12, 10710 ClientAuth: RequireAnyClientCert, 10711 VerifySignatureAlgorithms: []signatureAlgorithm{ 10712 signatureRSAPKCS1WithSHA1, 10713 signatureRSAPKCS1WithSHA256, 10714 }, 10715 }, 10716 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 10717 signatureRSAPKCS1WithSHA256, 10718 signatureRSAPKCS1WithSHA1, 10719 ), 10720 expectations: connectionExpectations{ 10721 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10722 }, 10723 }) 10724 testCases = append(testCases, testCase{ 10725 name: "Agree-Digest-SHA1", 10726 config: Config{ 10727 MaxVersion: VersionTLS12, 10728 ClientAuth: RequireAnyClientCert, 10729 VerifySignatureAlgorithms: []signatureAlgorithm{ 10730 signatureRSAPKCS1WithSHA1, 10731 }, 10732 }, 10733 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 10734 signatureRSAPKCS1WithSHA512, 10735 signatureRSAPKCS1WithSHA256, 10736 signatureRSAPKCS1WithSHA1, 10737 ), 10738 expectations: connectionExpectations{ 10739 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA1, 10740 }, 10741 }) 10742 testCases = append(testCases, testCase{ 10743 name: "Agree-Digest-Default", 10744 config: Config{ 10745 MaxVersion: VersionTLS12, 10746 ClientAuth: RequireAnyClientCert, 10747 VerifySignatureAlgorithms: []signatureAlgorithm{ 10748 signatureRSAPKCS1WithSHA256, 10749 signatureECDSAWithP256AndSHA256, 10750 signatureRSAPKCS1WithSHA1, 10751 signatureECDSAWithSHA1, 10752 }, 10753 }, 10754 shimCertificate: &rsaCertificate, 10755 expectations: connectionExpectations{ 10756 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10757 }, 10758 }) 10759 10760 // Test that the signing preference list may include extra algorithms 10761 // without negotiation problems. 10762 testCases = append(testCases, testCase{ 10763 testType: serverTest, 10764 name: "FilterExtraAlgorithms", 10765 config: Config{ 10766 MaxVersion: VersionTLS12, 10767 VerifySignatureAlgorithms: []signatureAlgorithm{ 10768 signatureRSAPKCS1WithSHA256, 10769 }, 10770 }, 10771 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 10772 signatureECDSAWithP256AndSHA256, 10773 signatureRSAPKCS1WithSHA256, 10774 ), 10775 expectations: connectionExpectations{ 10776 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10777 }, 10778 }) 10779 10780 // In TLS 1.2 and below, ECDSA uses the curve list rather than the 10781 // signature algorithms. 10782 testCases = append(testCases, testCase{ 10783 name: "CheckLeafCurve", 10784 config: Config{ 10785 MaxVersion: VersionTLS12, 10786 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 10787 Credential: &ecdsaP256Certificate, 10788 }, 10789 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 10790 shouldFail: true, 10791 expectedError: ":BAD_ECC_CERT:", 10792 }) 10793 10794 // In TLS 1.3, ECDSA does not use the ECDHE curve list. 10795 testCases = append(testCases, testCase{ 10796 name: "CheckLeafCurve-TLS13", 10797 config: Config{ 10798 MaxVersion: VersionTLS13, 10799 Credential: &ecdsaP256Certificate, 10800 }, 10801 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 10802 }) 10803 10804 // In TLS 1.2, the ECDSA curve is not in the signature algorithm, so the 10805 // shim should accept P-256 with SHA-384. 10806 testCases = append(testCases, testCase{ 10807 name: "ECDSACurveMismatch-Verify-TLS12", 10808 config: Config{ 10809 MaxVersion: VersionTLS12, 10810 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 10811 Credential: ecdsaP256Certificate.WithSignatureAlgorithms(signatureECDSAWithP384AndSHA384), 10812 }, 10813 }) 10814 10815 // In TLS 1.3, the ECDSA curve comes from the signature algorithm, so the 10816 // shim should reject P-256 with SHA-384. 10817 testCases = append(testCases, testCase{ 10818 name: "ECDSACurveMismatch-Verify-TLS13", 10819 config: Config{ 10820 MaxVersion: VersionTLS13, 10821 Credential: ecdsaP256Certificate.WithSignatureAlgorithms(signatureECDSAWithP384AndSHA384), 10822 Bugs: ProtocolBugs{ 10823 SkipECDSACurveCheck: true, 10824 }, 10825 }, 10826 shouldFail: true, 10827 expectedError: ":WRONG_SIGNATURE_TYPE:", 10828 }) 10829 10830 // Signature algorithm selection in TLS 1.3 should take the curve into 10831 // account. 10832 testCases = append(testCases, testCase{ 10833 testType: serverTest, 10834 name: "ECDSACurveMismatch-Sign-TLS13", 10835 config: Config{ 10836 MaxVersion: VersionTLS13, 10837 VerifySignatureAlgorithms: []signatureAlgorithm{ 10838 signatureECDSAWithP384AndSHA384, 10839 signatureECDSAWithP256AndSHA256, 10840 }, 10841 }, 10842 shimCertificate: &ecdsaP256Certificate, 10843 expectations: connectionExpectations{ 10844 peerSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10845 }, 10846 }) 10847 10848 // RSASSA-PSS with SHA-512 is too large for 1024-bit RSA. Test that the 10849 // server does not attempt to sign in that case. 10850 testCases = append(testCases, testCase{ 10851 testType: serverTest, 10852 name: "RSA-PSS-Large", 10853 config: Config{ 10854 MaxVersion: VersionTLS13, 10855 VerifySignatureAlgorithms: []signatureAlgorithm{ 10856 signatureRSAPSSWithSHA512, 10857 }, 10858 }, 10859 shimCertificate: &rsa1024Certificate, 10860 shouldFail: true, 10861 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10862 }) 10863 10864 // Test that RSA-PSS is enabled by default for TLS 1.2. 10865 testCases = append(testCases, testCase{ 10866 testType: clientTest, 10867 name: "RSA-PSS-Default-Verify", 10868 config: Config{ 10869 MaxVersion: VersionTLS12, 10870 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 10871 }, 10872 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 10873 }) 10874 10875 testCases = append(testCases, testCase{ 10876 testType: serverTest, 10877 name: "RSA-PSS-Default-Sign", 10878 config: Config{ 10879 MaxVersion: VersionTLS12, 10880 VerifySignatureAlgorithms: []signatureAlgorithm{ 10881 signatureRSAPSSWithSHA256, 10882 }, 10883 }, 10884 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 10885 }) 10886 10887 // TLS 1.1 and below has no way to advertise support for or negotiate 10888 // Ed25519's signature algorithm. 10889 testCases = append(testCases, testCase{ 10890 testType: clientTest, 10891 name: "NoEd25519-TLS11-ServerAuth-Verify", 10892 config: Config{ 10893 MaxVersion: VersionTLS11, 10894 Credential: &ed25519Certificate, 10895 Bugs: ProtocolBugs{ 10896 // Sign with Ed25519 even though it is TLS 1.1. 10897 SigningAlgorithmForLegacyVersions: signatureEd25519, 10898 }, 10899 }, 10900 flags: []string{"-verify-prefs", strconv.Itoa(int(signatureEd25519))}, 10901 shouldFail: true, 10902 expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:", 10903 }) 10904 testCases = append(testCases, testCase{ 10905 testType: serverTest, 10906 name: "NoEd25519-TLS11-ServerAuth-Sign", 10907 config: Config{ 10908 MaxVersion: VersionTLS11, 10909 }, 10910 shimCertificate: &ed25519Certificate, 10911 shouldFail: true, 10912 expectedError: ":NO_SHARED_CIPHER:", 10913 }) 10914 testCases = append(testCases, testCase{ 10915 testType: serverTest, 10916 name: "NoEd25519-TLS11-ClientAuth-Verify", 10917 config: Config{ 10918 MaxVersion: VersionTLS11, 10919 Credential: &ed25519Certificate, 10920 Bugs: ProtocolBugs{ 10921 // Sign with Ed25519 even though it is TLS 1.1. 10922 SigningAlgorithmForLegacyVersions: signatureEd25519, 10923 }, 10924 }, 10925 flags: []string{ 10926 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 10927 "-require-any-client-certificate", 10928 }, 10929 shouldFail: true, 10930 expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:", 10931 }) 10932 testCases = append(testCases, testCase{ 10933 testType: clientTest, 10934 name: "NoEd25519-TLS11-ClientAuth-Sign", 10935 config: Config{ 10936 MaxVersion: VersionTLS11, 10937 ClientAuth: RequireAnyClientCert, 10938 }, 10939 shimCertificate: &ed25519Certificate, 10940 shouldFail: true, 10941 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10942 }) 10943 10944 // Test Ed25519 is not advertised by default. 10945 testCases = append(testCases, testCase{ 10946 testType: clientTest, 10947 name: "Ed25519DefaultDisable-NoAdvertise", 10948 config: Config{ 10949 Credential: &ed25519Certificate, 10950 }, 10951 shouldFail: true, 10952 expectedLocalError: "tls: no common signature algorithms", 10953 }) 10954 10955 // Test Ed25519, when disabled, is not accepted if the peer ignores our 10956 // preferences. 10957 testCases = append(testCases, testCase{ 10958 testType: clientTest, 10959 name: "Ed25519DefaultDisable-NoAccept", 10960 config: Config{ 10961 Credential: &ed25519Certificate, 10962 Bugs: ProtocolBugs{ 10963 IgnorePeerSignatureAlgorithmPreferences: true, 10964 }, 10965 }, 10966 shouldFail: true, 10967 expectedLocalError: "remote error: illegal parameter", 10968 expectedError: ":WRONG_SIGNATURE_TYPE:", 10969 }) 10970 10971 // Test that configuring verify preferences changes what the client 10972 // advertises. 10973 testCases = append(testCases, testCase{ 10974 name: "VerifyPreferences-Advertised", 10975 config: Config{ 10976 Credential: rsaCertificate.WithSignatureAlgorithms( 10977 signatureRSAPSSWithSHA256, 10978 signatureRSAPSSWithSHA384, 10979 signatureRSAPSSWithSHA512, 10980 ), 10981 }, 10982 flags: []string{ 10983 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10984 "-expect-peer-signature-algorithm", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10985 }, 10986 }) 10987 10988 // Test that the client advertises a set which the runner can find 10989 // nothing in common with. 10990 testCases = append(testCases, testCase{ 10991 name: "VerifyPreferences-NoCommonAlgorithms", 10992 config: Config{ 10993 Credential: rsaCertificate.WithSignatureAlgorithms( 10994 signatureRSAPSSWithSHA256, 10995 signatureRSAPSSWithSHA512, 10996 ), 10997 }, 10998 flags: []string{ 10999 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 11000 }, 11001 shouldFail: true, 11002 expectedLocalError: "tls: no common signature algorithms", 11003 }) 11004 11005 // Test that the client enforces its preferences when configured. 11006 testCases = append(testCases, testCase{ 11007 name: "VerifyPreferences-Enforced", 11008 config: Config{ 11009 Credential: rsaCertificate.WithSignatureAlgorithms( 11010 signatureRSAPSSWithSHA256, 11011 signatureRSAPSSWithSHA512, 11012 ), 11013 Bugs: ProtocolBugs{ 11014 IgnorePeerSignatureAlgorithmPreferences: true, 11015 }, 11016 }, 11017 flags: []string{ 11018 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 11019 }, 11020 shouldFail: true, 11021 expectedLocalError: "remote error: illegal parameter", 11022 expectedError: ":WRONG_SIGNATURE_TYPE:", 11023 }) 11024 11025 // Test that explicitly configuring Ed25519 is as good as changing the 11026 // boolean toggle. 11027 testCases = append(testCases, testCase{ 11028 name: "VerifyPreferences-Ed25519", 11029 config: Config{ 11030 Credential: &ed25519Certificate, 11031 }, 11032 flags: []string{ 11033 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 11034 }, 11035 }) 11036 11037 for _, testType := range []testType{clientTest, serverTest} { 11038 for _, ver := range tlsVersions { 11039 if ver.version < VersionTLS12 { 11040 continue 11041 } 11042 11043 prefix := "Client-" + ver.name + "-" 11044 noCommonAlgorithmsError := ":NO_COMMON_SIGNATURE_ALGORITHMS:" 11045 if testType == serverTest { 11046 prefix = "Server-" + ver.name + "-" 11047 // In TLS 1.2 servers, cipher selection and algorithm 11048 // selection are linked. 11049 if ver.version <= VersionTLS12 { 11050 noCommonAlgorithmsError = ":NO_SHARED_CIPHER:" 11051 } 11052 } 11053 11054 // Test that the shim will not sign MD5/SHA1 with RSA at TLS 1.2, 11055 // even if specified in signing preferences. 11056 testCases = append(testCases, testCase{ 11057 testType: testType, 11058 name: prefix + "NoSign-RSA_PKCS1_MD5_SHA1", 11059 config: Config{ 11060 MaxVersion: ver.version, 11061 CipherSuites: signingCiphers, 11062 ClientAuth: RequireAnyClientCert, 11063 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPKCS1WithMD5AndSHA1}, 11064 }, 11065 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 11066 signatureRSAPKCS1WithMD5AndSHA1, 11067 // Include a valid algorithm as well, to avoid an empty list 11068 // if filtered out. 11069 signatureRSAPKCS1WithSHA256, 11070 ), 11071 shouldFail: true, 11072 expectedError: noCommonAlgorithmsError, 11073 }) 11074 11075 // Test that the shim will not accept MD5/SHA1 with RSA at TLS 1.2, 11076 // even if specified in verify preferences. 11077 testCases = append(testCases, testCase{ 11078 testType: testType, 11079 name: prefix + "NoVerify-RSA_PKCS1_MD5_SHA1", 11080 config: Config{ 11081 MaxVersion: ver.version, 11082 Credential: &rsaCertificate, 11083 Bugs: ProtocolBugs{ 11084 IgnorePeerSignatureAlgorithmPreferences: true, 11085 AlwaysSignAsLegacyVersion: true, 11086 SendSignatureAlgorithm: signatureRSAPKCS1WithMD5AndSHA1, 11087 }, 11088 }, 11089 shimCertificate: &rsaCertificate, 11090 flags: []string{ 11091 "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithMD5AndSHA1)), 11092 // Include a valid algorithm as well, to avoid an empty list 11093 // if filtered out. 11094 "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 11095 "-require-any-client-certificate", 11096 }, 11097 shouldFail: true, 11098 expectedError: ":WRONG_SIGNATURE_TYPE:", 11099 }) 11100 } 11101 } 11102 11103 // Test that, when there are no signature algorithms in common in TLS 11104 // 1.2, the server will still consider the legacy RSA key exchange. 11105 testCases = append(testCases, testCase{ 11106 testType: serverTest, 11107 name: "NoCommonSignatureAlgorithms-TLS12-Fallback", 11108 config: Config{ 11109 MaxVersion: VersionTLS12, 11110 CipherSuites: []uint16{ 11111 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11112 TLS_RSA_WITH_AES_128_GCM_SHA256, 11113 }, 11114 VerifySignatureAlgorithms: []signatureAlgorithm{ 11115 signatureECDSAWithP256AndSHA256, 11116 }, 11117 }, 11118 expectations: connectionExpectations{ 11119 cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, 11120 }, 11121 }) 11122} 11123 11124// timeouts is the retransmit schedule for BoringSSL. It doubles and 11125// caps at 60 seconds. On the 13th timeout, it gives up. 11126var timeouts = []time.Duration{ 11127 1 * time.Second, 11128 2 * time.Second, 11129 4 * time.Second, 11130 8 * time.Second, 11131 16 * time.Second, 11132 32 * time.Second, 11133 60 * time.Second, 11134 60 * time.Second, 11135 60 * time.Second, 11136 60 * time.Second, 11137 60 * time.Second, 11138 60 * time.Second, 11139 60 * time.Second, 11140} 11141 11142// shortTimeouts is an alternate set of timeouts which would occur if the 11143// initial timeout duration was set to 250ms. 11144var shortTimeouts = []time.Duration{ 11145 250 * time.Millisecond, 11146 500 * time.Millisecond, 11147 1 * time.Second, 11148 2 * time.Second, 11149 4 * time.Second, 11150 8 * time.Second, 11151 16 * time.Second, 11152 32 * time.Second, 11153 60 * time.Second, 11154 60 * time.Second, 11155 60 * time.Second, 11156 60 * time.Second, 11157 60 * time.Second, 11158} 11159 11160func addDTLSRetransmitTests() { 11161 // These tests work by coordinating some behavior on both the shim and 11162 // the runner. 11163 // 11164 // TimeoutSchedule configures the runner to send a series of timeout 11165 // opcodes to the shim (see packetAdaptor) immediately before reading 11166 // each peer handshake flight N. The timeout opcode both simulates a 11167 // timeout in the shim and acts as a synchronization point to help the 11168 // runner bracket each handshake flight. 11169 // 11170 // We assume the shim does not read from the channel eagerly. It must 11171 // first wait until it has sent flight N and is ready to receive 11172 // handshake flight N+1. At this point, it will process the timeout 11173 // opcode. It must then immediately respond with a timeout ACK and act 11174 // as if the shim was idle for the specified amount of time. 11175 // 11176 // The runner then drops all packets received before the ACK and 11177 // continues waiting for flight N. This ordering results in one attempt 11178 // at sending flight N to be dropped. For the test to complete, the 11179 // shim must send flight N again, testing that the shim implements DTLS 11180 // retransmit on a timeout. 11181 11182 // TODO(davidben): Add DTLS 1.3 versions of these tests. There will 11183 // likely be more epochs to cross and the final message's retransmit may 11184 // be more complex. 11185 11186 // Test that this is indeed the timeout schedule. Stress all 11187 // four patterns of handshake. 11188 for i := 1; i < len(timeouts); i++ { 11189 number := strconv.Itoa(i) 11190 testCases = append(testCases, testCase{ 11191 protocol: dtls, 11192 name: "DTLS-Retransmit-Client-" + number, 11193 config: Config{ 11194 MaxVersion: VersionTLS12, 11195 Bugs: ProtocolBugs{ 11196 TimeoutSchedule: timeouts[:i], 11197 }, 11198 }, 11199 resumeSession: true, 11200 flags: []string{"-async"}, 11201 }) 11202 testCases = append(testCases, testCase{ 11203 protocol: dtls, 11204 testType: serverTest, 11205 name: "DTLS-Retransmit-Server-" + number, 11206 config: Config{ 11207 MaxVersion: VersionTLS12, 11208 Bugs: ProtocolBugs{ 11209 TimeoutSchedule: timeouts[:i], 11210 }, 11211 }, 11212 resumeSession: true, 11213 flags: []string{"-async"}, 11214 }) 11215 } 11216 11217 // Test that exceeding the timeout schedule hits a read 11218 // timeout. 11219 testCases = append(testCases, testCase{ 11220 protocol: dtls, 11221 name: "DTLS-Retransmit-Timeout", 11222 config: Config{ 11223 MaxVersion: VersionTLS12, 11224 Bugs: ProtocolBugs{ 11225 TimeoutSchedule: timeouts, 11226 }, 11227 }, 11228 resumeSession: true, 11229 flags: []string{"-async"}, 11230 shouldFail: true, 11231 expectedError: ":READ_TIMEOUT_EXPIRED:", 11232 }) 11233 11234 // Test that timeout handling has a fudge factor, due to API 11235 // problems. 11236 testCases = append(testCases, testCase{ 11237 protocol: dtls, 11238 name: "DTLS-Retransmit-Fudge", 11239 config: Config{ 11240 MaxVersion: VersionTLS12, 11241 Bugs: ProtocolBugs{ 11242 TimeoutSchedule: []time.Duration{ 11243 timeouts[0] - 10*time.Millisecond, 11244 }, 11245 }, 11246 }, 11247 resumeSession: true, 11248 flags: []string{"-async"}, 11249 }) 11250 11251 // Test that the final Finished retransmitting isn't 11252 // duplicated if the peer badly fragments everything. 11253 testCases = append(testCases, testCase{ 11254 testType: serverTest, 11255 protocol: dtls, 11256 name: "DTLS-Retransmit-Fragmented", 11257 config: Config{ 11258 MaxVersion: VersionTLS12, 11259 Bugs: ProtocolBugs{ 11260 TimeoutSchedule: []time.Duration{timeouts[0]}, 11261 MaxHandshakeRecordLength: 2, 11262 }, 11263 }, 11264 flags: []string{"-async"}, 11265 }) 11266 11267 // Test the timeout schedule when a shorter initial timeout duration is set. 11268 testCases = append(testCases, testCase{ 11269 protocol: dtls, 11270 name: "DTLS-Retransmit-Short-Client", 11271 config: Config{ 11272 MaxVersion: VersionTLS12, 11273 Bugs: ProtocolBugs{ 11274 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1], 11275 }, 11276 }, 11277 resumeSession: true, 11278 flags: []string{ 11279 "-async", 11280 "-initial-timeout-duration-ms", "250", 11281 }, 11282 }) 11283 testCases = append(testCases, testCase{ 11284 protocol: dtls, 11285 testType: serverTest, 11286 name: "DTLS-Retransmit-Short-Server", 11287 config: Config{ 11288 MaxVersion: VersionTLS12, 11289 Bugs: ProtocolBugs{ 11290 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1], 11291 }, 11292 }, 11293 resumeSession: true, 11294 flags: []string{ 11295 "-async", 11296 "-initial-timeout-duration-ms", "250", 11297 }, 11298 }) 11299 11300 // If the shim sends the last Finished (server full or client resume 11301 // handshakes), it must retransmit that Finished when it sees a 11302 // post-handshake penultimate Finished from the runner. The above tests 11303 // cover this. Conversely, if the shim sends the penultimate Finished 11304 // (client full or server resume), test that it does not retransmit. 11305 testCases = append(testCases, testCase{ 11306 protocol: dtls, 11307 testType: clientTest, 11308 name: "DTLS-StrayRetransmitFinished-ClientFull", 11309 config: Config{ 11310 MaxVersion: VersionTLS12, 11311 Bugs: ProtocolBugs{ 11312 RetransmitFinished: true, 11313 }, 11314 }, 11315 }) 11316 testCases = append(testCases, testCase{ 11317 protocol: dtls, 11318 testType: serverTest, 11319 name: "DTLS-StrayRetransmitFinished-ServerResume", 11320 config: Config{ 11321 MaxVersion: VersionTLS12, 11322 }, 11323 resumeConfig: &Config{ 11324 MaxVersion: VersionTLS12, 11325 Bugs: ProtocolBugs{ 11326 RetransmitFinished: true, 11327 }, 11328 }, 11329 resumeSession: true, 11330 }) 11331} 11332 11333func addExportKeyingMaterialTests() { 11334 for _, vers := range tlsVersions { 11335 testCases = append(testCases, testCase{ 11336 name: "ExportKeyingMaterial-" + vers.name, 11337 config: Config{ 11338 MaxVersion: vers.version, 11339 }, 11340 // Test the exporter in both initial and resumption 11341 // handshakes. 11342 resumeSession: true, 11343 exportKeyingMaterial: 1024, 11344 exportLabel: "label", 11345 exportContext: "context", 11346 useExportContext: true, 11347 }) 11348 testCases = append(testCases, testCase{ 11349 name: "ExportKeyingMaterial-NoContext-" + vers.name, 11350 config: Config{ 11351 MaxVersion: vers.version, 11352 }, 11353 exportKeyingMaterial: 1024, 11354 }) 11355 testCases = append(testCases, testCase{ 11356 name: "ExportKeyingMaterial-EmptyContext-" + vers.name, 11357 config: Config{ 11358 MaxVersion: vers.version, 11359 }, 11360 exportKeyingMaterial: 1024, 11361 useExportContext: true, 11362 }) 11363 testCases = append(testCases, testCase{ 11364 name: "ExportKeyingMaterial-Small-" + vers.name, 11365 config: Config{ 11366 MaxVersion: vers.version, 11367 }, 11368 exportKeyingMaterial: 1, 11369 exportLabel: "label", 11370 exportContext: "context", 11371 useExportContext: true, 11372 }) 11373 11374 if vers.version >= VersionTLS13 { 11375 // Test the exporters do not work while the client is 11376 // sending 0-RTT data. 11377 testCases = append(testCases, testCase{ 11378 name: "NoEarlyKeyingMaterial-Client-InEarlyData-" + vers.name, 11379 config: Config{ 11380 MaxVersion: vers.version, 11381 }, 11382 resumeSession: true, 11383 earlyData: true, 11384 flags: []string{ 11385 "-on-resume-export-keying-material", "1024", 11386 "-on-resume-export-label", "label", 11387 "-on-resume-export-context", "context", 11388 }, 11389 shouldFail: true, 11390 expectedError: ":HANDSHAKE_NOT_COMPLETE:", 11391 }) 11392 11393 // Test the normal exporter on the server in half-RTT. 11394 testCases = append(testCases, testCase{ 11395 testType: serverTest, 11396 name: "ExportKeyingMaterial-Server-HalfRTT-" + vers.name, 11397 config: Config{ 11398 MaxVersion: vers.version, 11399 Bugs: ProtocolBugs{ 11400 // The shim writes exported data immediately after 11401 // the handshake returns, so disable the built-in 11402 // early data test. 11403 SendEarlyData: [][]byte{}, 11404 ExpectHalfRTTData: [][]byte{}, 11405 }, 11406 }, 11407 resumeSession: true, 11408 earlyData: true, 11409 exportKeyingMaterial: 1024, 11410 exportLabel: "label", 11411 exportContext: "context", 11412 useExportContext: true, 11413 }) 11414 } 11415 } 11416 11417 // Exporters work during a False Start. 11418 testCases = append(testCases, testCase{ 11419 name: "ExportKeyingMaterial-FalseStart", 11420 config: Config{ 11421 MaxVersion: VersionTLS12, 11422 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11423 NextProtos: []string{"foo"}, 11424 Bugs: ProtocolBugs{ 11425 ExpectFalseStart: true, 11426 }, 11427 }, 11428 flags: []string{ 11429 "-false-start", 11430 "-advertise-alpn", "\x03foo", 11431 "-expect-alpn", "foo", 11432 }, 11433 shimWritesFirst: true, 11434 exportKeyingMaterial: 1024, 11435 exportLabel: "label", 11436 exportContext: "context", 11437 useExportContext: true, 11438 }) 11439 11440 // Exporters do not work in the middle of a renegotiation. Test this by 11441 // triggering the exporter after every SSL_read call and configuring the 11442 // shim to run asynchronously. 11443 testCases = append(testCases, testCase{ 11444 name: "ExportKeyingMaterial-Renegotiate", 11445 config: Config{ 11446 MaxVersion: VersionTLS12, 11447 }, 11448 renegotiate: 1, 11449 flags: []string{ 11450 "-async", 11451 "-use-exporter-between-reads", 11452 "-renegotiate-freely", 11453 "-expect-total-renegotiations", "1", 11454 }, 11455 shouldFail: true, 11456 expectedError: "failed to export keying material", 11457 }) 11458} 11459 11460func addExportTrafficSecretsTests() { 11461 for _, cipherSuite := range []testCipherSuite{ 11462 // Test a SHA-256 and SHA-384 based cipher suite. 11463 {"AEAD-AES128-GCM-SHA256", TLS_AES_128_GCM_SHA256}, 11464 {"AEAD-AES256-GCM-SHA384", TLS_AES_256_GCM_SHA384}, 11465 } { 11466 11467 testCases = append(testCases, testCase{ 11468 name: "ExportTrafficSecrets-" + cipherSuite.name, 11469 config: Config{ 11470 MinVersion: VersionTLS13, 11471 CipherSuites: []uint16{cipherSuite.id}, 11472 }, 11473 exportTrafficSecrets: true, 11474 }) 11475 } 11476} 11477 11478func addTLSUniqueTests() { 11479 for _, isClient := range []bool{false, true} { 11480 for _, isResumption := range []bool{false, true} { 11481 for _, hasEMS := range []bool{false, true} { 11482 var suffix string 11483 if isResumption { 11484 suffix = "Resume-" 11485 } else { 11486 suffix = "Full-" 11487 } 11488 11489 if hasEMS { 11490 suffix += "EMS-" 11491 } else { 11492 suffix += "NoEMS-" 11493 } 11494 11495 if isClient { 11496 suffix += "Client" 11497 } else { 11498 suffix += "Server" 11499 } 11500 11501 test := testCase{ 11502 name: "TLSUnique-" + suffix, 11503 testTLSUnique: true, 11504 config: Config{ 11505 MaxVersion: VersionTLS12, 11506 Bugs: ProtocolBugs{ 11507 NoExtendedMasterSecret: !hasEMS, 11508 }, 11509 }, 11510 } 11511 11512 if isResumption { 11513 test.resumeSession = true 11514 test.resumeConfig = &Config{ 11515 MaxVersion: VersionTLS12, 11516 Bugs: ProtocolBugs{ 11517 NoExtendedMasterSecret: !hasEMS, 11518 }, 11519 } 11520 } 11521 11522 if isResumption && !hasEMS { 11523 test.shouldFail = true 11524 test.expectedError = "failed to get tls-unique" 11525 } 11526 11527 testCases = append(testCases, test) 11528 } 11529 } 11530 } 11531} 11532 11533func addCustomExtensionTests() { 11534 // Test an unknown extension from the server. 11535 testCases = append(testCases, testCase{ 11536 testType: clientTest, 11537 name: "UnknownExtension-Client", 11538 config: Config{ 11539 MaxVersion: VersionTLS12, 11540 Bugs: ProtocolBugs{ 11541 CustomExtension: "custom extension", 11542 }, 11543 }, 11544 shouldFail: true, 11545 expectedError: ":UNEXPECTED_EXTENSION:", 11546 expectedLocalError: "remote error: unsupported extension", 11547 }) 11548 testCases = append(testCases, testCase{ 11549 testType: clientTest, 11550 name: "UnknownExtension-Client-TLS13", 11551 config: Config{ 11552 MaxVersion: VersionTLS13, 11553 Bugs: ProtocolBugs{ 11554 CustomExtension: "custom extension", 11555 }, 11556 }, 11557 shouldFail: true, 11558 expectedError: ":UNEXPECTED_EXTENSION:", 11559 expectedLocalError: "remote error: unsupported extension", 11560 }) 11561 testCases = append(testCases, testCase{ 11562 testType: clientTest, 11563 name: "UnknownUnencryptedExtension-Client-TLS13", 11564 config: Config{ 11565 MaxVersion: VersionTLS13, 11566 Bugs: ProtocolBugs{ 11567 CustomUnencryptedExtension: "custom extension", 11568 }, 11569 }, 11570 shouldFail: true, 11571 expectedError: ":UNEXPECTED_EXTENSION:", 11572 // The shim must send an alert, but alerts at this point do not 11573 // get successfully decrypted by the runner. 11574 expectedLocalError: "local error: bad record MAC", 11575 }) 11576 testCases = append(testCases, testCase{ 11577 testType: clientTest, 11578 name: "UnexpectedUnencryptedExtension-Client-TLS13", 11579 config: Config{ 11580 MaxVersion: VersionTLS13, 11581 Bugs: ProtocolBugs{ 11582 SendUnencryptedALPN: "foo", 11583 }, 11584 }, 11585 flags: []string{ 11586 "-advertise-alpn", "\x03foo\x03bar", 11587 }, 11588 shouldFail: true, 11589 expectedError: ":UNEXPECTED_EXTENSION:", 11590 // The shim must send an alert, but alerts at this point do not 11591 // get successfully decrypted by the runner. 11592 expectedLocalError: "local error: bad record MAC", 11593 }) 11594 11595 // Test a known but unoffered extension from the server. 11596 testCases = append(testCases, testCase{ 11597 testType: clientTest, 11598 name: "UnofferedExtension-Client", 11599 config: Config{ 11600 MaxVersion: VersionTLS12, 11601 Bugs: ProtocolBugs{ 11602 SendALPN: "alpn", 11603 }, 11604 }, 11605 shouldFail: true, 11606 expectedError: ":UNEXPECTED_EXTENSION:", 11607 expectedLocalError: "remote error: unsupported extension", 11608 }) 11609 testCases = append(testCases, testCase{ 11610 testType: clientTest, 11611 name: "UnofferedExtension-Client-TLS13", 11612 config: Config{ 11613 MaxVersion: VersionTLS13, 11614 Bugs: ProtocolBugs{ 11615 SendALPN: "alpn", 11616 }, 11617 }, 11618 shouldFail: true, 11619 expectedError: ":UNEXPECTED_EXTENSION:", 11620 expectedLocalError: "remote error: unsupported extension", 11621 }) 11622} 11623 11624func addRSAClientKeyExchangeTests() { 11625 for bad := RSABadValue(1); bad < NumRSABadValues; bad++ { 11626 testCases = append(testCases, testCase{ 11627 testType: serverTest, 11628 name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad), 11629 config: Config{ 11630 // Ensure the ClientHello version and final 11631 // version are different, to detect if the 11632 // server uses the wrong one. 11633 MaxVersion: VersionTLS11, 11634 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 11635 Bugs: ProtocolBugs{ 11636 BadRSAClientKeyExchange: bad, 11637 }, 11638 }, 11639 shouldFail: true, 11640 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 11641 }) 11642 } 11643 11644 // The server must compare whatever was in ClientHello.version for the 11645 // RSA premaster. 11646 testCases = append(testCases, testCase{ 11647 testType: serverTest, 11648 name: "SendClientVersion-RSA", 11649 config: Config{ 11650 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 11651 Bugs: ProtocolBugs{ 11652 SendClientVersion: 0x1234, 11653 }, 11654 }, 11655 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 11656 }) 11657} 11658 11659var testCurves = []struct { 11660 name string 11661 id CurveID 11662}{ 11663 {"P-224", CurveP224}, 11664 {"P-256", CurveP256}, 11665 {"P-384", CurveP384}, 11666 {"P-521", CurveP521}, 11667 {"X25519", CurveX25519}, 11668 {"Kyber", CurveX25519Kyber768}, 11669} 11670 11671const bogusCurve = 0x1234 11672 11673func isPqGroup(r CurveID) bool { 11674 return r == CurveX25519Kyber768 11675} 11676 11677func addCurveTests() { 11678 for _, curve := range testCurves { 11679 for _, ver := range tlsVersions { 11680 if isPqGroup(curve.id) && ver.version < VersionTLS13 { 11681 continue 11682 } 11683 11684 suffix := curve.name + "-" + ver.name 11685 11686 testCases = append(testCases, testCase{ 11687 name: "CurveTest-Client-" + suffix, 11688 config: Config{ 11689 MaxVersion: ver.version, 11690 CipherSuites: []uint16{ 11691 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11692 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11693 TLS_AES_256_GCM_SHA384, 11694 }, 11695 CurvePreferences: []CurveID{curve.id}, 11696 }, 11697 flags: append( 11698 []string{"-expect-curve-id", strconv.Itoa(int(curve.id))}, 11699 flagInts("-curves", shimConfig.AllCurves)..., 11700 ), 11701 expectations: connectionExpectations{ 11702 curveID: curve.id, 11703 }, 11704 }) 11705 testCases = append(testCases, testCase{ 11706 testType: serverTest, 11707 name: "CurveTest-Server-" + suffix, 11708 config: Config{ 11709 MaxVersion: ver.version, 11710 CipherSuites: []uint16{ 11711 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11712 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11713 TLS_AES_256_GCM_SHA384, 11714 }, 11715 CurvePreferences: []CurveID{curve.id}, 11716 }, 11717 flags: append( 11718 []string{"-expect-curve-id", strconv.Itoa(int(curve.id))}, 11719 flagInts("-curves", shimConfig.AllCurves)..., 11720 ), 11721 expectations: connectionExpectations{ 11722 curveID: curve.id, 11723 }, 11724 }) 11725 11726 if curve.id != CurveX25519 && !isPqGroup(curve.id) { 11727 testCases = append(testCases, testCase{ 11728 name: "CurveTest-Client-Compressed-" + suffix, 11729 config: Config{ 11730 MaxVersion: ver.version, 11731 CipherSuites: []uint16{ 11732 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11733 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11734 TLS_AES_256_GCM_SHA384, 11735 }, 11736 CurvePreferences: []CurveID{curve.id}, 11737 Bugs: ProtocolBugs{ 11738 SendCompressedCoordinates: true, 11739 }, 11740 }, 11741 flags: flagInts("-curves", shimConfig.AllCurves), 11742 shouldFail: true, 11743 expectedError: ":BAD_ECPOINT:", 11744 }) 11745 testCases = append(testCases, testCase{ 11746 testType: serverTest, 11747 name: "CurveTest-Server-Compressed-" + suffix, 11748 config: Config{ 11749 MaxVersion: ver.version, 11750 CipherSuites: []uint16{ 11751 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11752 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11753 TLS_AES_256_GCM_SHA384, 11754 }, 11755 CurvePreferences: []CurveID{curve.id}, 11756 Bugs: ProtocolBugs{ 11757 SendCompressedCoordinates: true, 11758 }, 11759 }, 11760 flags: flagInts("-curves", shimConfig.AllCurves), 11761 shouldFail: true, 11762 expectedError: ":BAD_ECPOINT:", 11763 }) 11764 } 11765 } 11766 } 11767 11768 // The server must be tolerant to bogus curves. 11769 testCases = append(testCases, testCase{ 11770 testType: serverTest, 11771 name: "UnknownCurve", 11772 config: Config{ 11773 MaxVersion: VersionTLS12, 11774 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11775 CurvePreferences: []CurveID{bogusCurve, CurveP256}, 11776 }, 11777 }) 11778 11779 // The server must be tolerant to bogus curves. 11780 testCases = append(testCases, testCase{ 11781 testType: serverTest, 11782 name: "UnknownCurve-TLS13", 11783 config: Config{ 11784 MaxVersion: VersionTLS13, 11785 CurvePreferences: []CurveID{bogusCurve, CurveP256}, 11786 }, 11787 }) 11788 11789 // The server must not consider ECDHE ciphers when there are no 11790 // supported curves. 11791 testCases = append(testCases, testCase{ 11792 testType: serverTest, 11793 name: "NoSupportedCurves", 11794 config: Config{ 11795 MaxVersion: VersionTLS12, 11796 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11797 Bugs: ProtocolBugs{ 11798 NoSupportedCurves: true, 11799 }, 11800 }, 11801 shouldFail: true, 11802 expectedError: ":NO_SHARED_CIPHER:", 11803 }) 11804 testCases = append(testCases, testCase{ 11805 testType: serverTest, 11806 name: "NoSupportedCurves-TLS13", 11807 config: Config{ 11808 MaxVersion: VersionTLS13, 11809 Bugs: ProtocolBugs{ 11810 NoSupportedCurves: true, 11811 }, 11812 }, 11813 shouldFail: true, 11814 expectedError: ":NO_SHARED_GROUP:", 11815 }) 11816 11817 // The server must fall back to another cipher when there are no 11818 // supported curves. 11819 testCases = append(testCases, testCase{ 11820 testType: serverTest, 11821 name: "NoCommonCurves", 11822 config: Config{ 11823 MaxVersion: VersionTLS12, 11824 CipherSuites: []uint16{ 11825 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11826 TLS_RSA_WITH_AES_128_GCM_SHA256, 11827 }, 11828 CurvePreferences: []CurveID{CurveP224}, 11829 }, 11830 expectations: connectionExpectations{ 11831 cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, 11832 }, 11833 }) 11834 11835 // The client must reject bogus curves and disabled curves. 11836 testCases = append(testCases, testCase{ 11837 name: "BadECDHECurve", 11838 config: Config{ 11839 MaxVersion: VersionTLS12, 11840 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11841 Bugs: ProtocolBugs{ 11842 SendCurve: bogusCurve, 11843 }, 11844 }, 11845 shouldFail: true, 11846 expectedError: ":WRONG_CURVE:", 11847 }) 11848 testCases = append(testCases, testCase{ 11849 name: "BadECDHECurve-TLS13", 11850 config: Config{ 11851 MaxVersion: VersionTLS13, 11852 Bugs: ProtocolBugs{ 11853 SendCurve: bogusCurve, 11854 }, 11855 }, 11856 shouldFail: true, 11857 expectedError: ":WRONG_CURVE:", 11858 }) 11859 11860 testCases = append(testCases, testCase{ 11861 name: "UnsupportedCurve", 11862 config: Config{ 11863 MaxVersion: VersionTLS12, 11864 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11865 CurvePreferences: []CurveID{CurveP256}, 11866 Bugs: ProtocolBugs{ 11867 IgnorePeerCurvePreferences: true, 11868 }, 11869 }, 11870 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 11871 shouldFail: true, 11872 expectedError: ":WRONG_CURVE:", 11873 }) 11874 11875 testCases = append(testCases, testCase{ 11876 // TODO(davidben): Add a TLS 1.3 version where 11877 // HelloRetryRequest requests an unsupported curve. 11878 name: "UnsupportedCurve-ServerHello-TLS13", 11879 config: Config{ 11880 MaxVersion: VersionTLS13, 11881 CurvePreferences: []CurveID{CurveP384}, 11882 Bugs: ProtocolBugs{ 11883 SendCurve: CurveP256, 11884 }, 11885 }, 11886 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 11887 shouldFail: true, 11888 expectedError: ":WRONG_CURVE:", 11889 }) 11890 11891 // Test invalid curve points. 11892 testCases = append(testCases, testCase{ 11893 name: "InvalidECDHPoint-Client", 11894 config: Config{ 11895 MaxVersion: VersionTLS12, 11896 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11897 CurvePreferences: []CurveID{CurveP256}, 11898 Bugs: ProtocolBugs{ 11899 InvalidECDHPoint: true, 11900 }, 11901 }, 11902 shouldFail: true, 11903 expectedError: ":BAD_ECPOINT:", 11904 }) 11905 testCases = append(testCases, testCase{ 11906 name: "InvalidECDHPoint-Client-TLS13", 11907 config: Config{ 11908 MaxVersion: VersionTLS13, 11909 CurvePreferences: []CurveID{CurveP256}, 11910 Bugs: ProtocolBugs{ 11911 InvalidECDHPoint: true, 11912 }, 11913 }, 11914 shouldFail: true, 11915 expectedError: ":BAD_ECPOINT:", 11916 }) 11917 testCases = append(testCases, testCase{ 11918 testType: serverTest, 11919 name: "InvalidECDHPoint-Server", 11920 config: Config{ 11921 MaxVersion: VersionTLS12, 11922 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11923 CurvePreferences: []CurveID{CurveP256}, 11924 Bugs: ProtocolBugs{ 11925 InvalidECDHPoint: true, 11926 }, 11927 }, 11928 shouldFail: true, 11929 expectedError: ":BAD_ECPOINT:", 11930 }) 11931 testCases = append(testCases, testCase{ 11932 testType: serverTest, 11933 name: "InvalidECDHPoint-Server-TLS13", 11934 config: Config{ 11935 MaxVersion: VersionTLS13, 11936 CurvePreferences: []CurveID{CurveP256}, 11937 Bugs: ProtocolBugs{ 11938 InvalidECDHPoint: true, 11939 }, 11940 }, 11941 shouldFail: true, 11942 expectedError: ":BAD_ECPOINT:", 11943 }) 11944 11945 // The previous curve ID should be reported on TLS 1.2 resumption. 11946 testCases = append(testCases, testCase{ 11947 name: "CurveID-Resume-Client", 11948 config: Config{ 11949 MaxVersion: VersionTLS12, 11950 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11951 CurvePreferences: []CurveID{CurveX25519}, 11952 }, 11953 flags: []string{"-expect-curve-id", strconv.Itoa(int(CurveX25519))}, 11954 resumeSession: true, 11955 }) 11956 testCases = append(testCases, testCase{ 11957 testType: serverTest, 11958 name: "CurveID-Resume-Server", 11959 config: Config{ 11960 MaxVersion: VersionTLS12, 11961 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11962 CurvePreferences: []CurveID{CurveX25519}, 11963 }, 11964 flags: []string{"-expect-curve-id", strconv.Itoa(int(CurveX25519))}, 11965 resumeSession: true, 11966 }) 11967 11968 // TLS 1.3 allows resuming at a differet curve. If this happens, the new 11969 // one should be reported. 11970 testCases = append(testCases, testCase{ 11971 name: "CurveID-Resume-Client-TLS13", 11972 config: Config{ 11973 MaxVersion: VersionTLS13, 11974 CurvePreferences: []CurveID{CurveX25519}, 11975 }, 11976 resumeConfig: &Config{ 11977 MaxVersion: VersionTLS13, 11978 CurvePreferences: []CurveID{CurveP256}, 11979 }, 11980 flags: []string{ 11981 "-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)), 11982 "-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)), 11983 }, 11984 resumeSession: true, 11985 }) 11986 testCases = append(testCases, testCase{ 11987 testType: serverTest, 11988 name: "CurveID-Resume-Server-TLS13", 11989 config: Config{ 11990 MaxVersion: VersionTLS13, 11991 CurvePreferences: []CurveID{CurveX25519}, 11992 }, 11993 resumeConfig: &Config{ 11994 MaxVersion: VersionTLS13, 11995 CurvePreferences: []CurveID{CurveP256}, 11996 }, 11997 flags: []string{ 11998 "-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)), 11999 "-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)), 12000 }, 12001 resumeSession: true, 12002 }) 12003 12004 // Server-sent point formats are legal in TLS 1.2, but not in TLS 1.3. 12005 testCases = append(testCases, testCase{ 12006 name: "PointFormat-ServerHello-TLS12", 12007 config: Config{ 12008 MaxVersion: VersionTLS12, 12009 Bugs: ProtocolBugs{ 12010 SendSupportedPointFormats: []byte{pointFormatUncompressed}, 12011 }, 12012 }, 12013 }) 12014 testCases = append(testCases, testCase{ 12015 name: "PointFormat-EncryptedExtensions-TLS13", 12016 config: Config{ 12017 MaxVersion: VersionTLS13, 12018 Bugs: ProtocolBugs{ 12019 SendSupportedPointFormats: []byte{pointFormatUncompressed}, 12020 }, 12021 }, 12022 shouldFail: true, 12023 expectedError: ":ERROR_PARSING_EXTENSION:", 12024 }) 12025 12026 // Server-sent supported groups/curves are legal in TLS 1.3. They are 12027 // illegal in TLS 1.2, but some servers send them anyway, so we must 12028 // tolerate them. 12029 testCases = append(testCases, testCase{ 12030 name: "SupportedCurves-ServerHello-TLS12", 12031 config: Config{ 12032 MaxVersion: VersionTLS12, 12033 Bugs: ProtocolBugs{ 12034 SendServerSupportedCurves: true, 12035 }, 12036 }, 12037 }) 12038 testCases = append(testCases, testCase{ 12039 name: "SupportedCurves-EncryptedExtensions-TLS13", 12040 config: Config{ 12041 MaxVersion: VersionTLS13, 12042 Bugs: ProtocolBugs{ 12043 SendServerSupportedCurves: true, 12044 }, 12045 }, 12046 }) 12047 12048 // Test that we tolerate unknown point formats, as long as 12049 // pointFormatUncompressed is present. Limit ciphers to ECDHE ciphers to 12050 // check they are still functional. 12051 testCases = append(testCases, testCase{ 12052 name: "PointFormat-Client-Tolerance", 12053 config: Config{ 12054 MaxVersion: VersionTLS12, 12055 Bugs: ProtocolBugs{ 12056 SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime}, 12057 }, 12058 }, 12059 }) 12060 testCases = append(testCases, testCase{ 12061 testType: serverTest, 12062 name: "PointFormat-Server-Tolerance", 12063 config: Config{ 12064 MaxVersion: VersionTLS12, 12065 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 12066 Bugs: ProtocolBugs{ 12067 SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime}, 12068 }, 12069 }, 12070 }) 12071 12072 // Test TLS 1.2 does not require the point format extension to be 12073 // present. 12074 testCases = append(testCases, testCase{ 12075 name: "PointFormat-Client-Missing", 12076 config: Config{ 12077 MaxVersion: VersionTLS12, 12078 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 12079 Bugs: ProtocolBugs{ 12080 SendSupportedPointFormats: []byte{}, 12081 }, 12082 }, 12083 }) 12084 testCases = append(testCases, testCase{ 12085 testType: serverTest, 12086 name: "PointFormat-Server-Missing", 12087 config: Config{ 12088 MaxVersion: VersionTLS12, 12089 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 12090 Bugs: ProtocolBugs{ 12091 SendSupportedPointFormats: []byte{}, 12092 }, 12093 }, 12094 }) 12095 12096 // If the point format extension is present, uncompressed points must be 12097 // offered. BoringSSL requires this whether or not ECDHE is used. 12098 testCases = append(testCases, testCase{ 12099 name: "PointFormat-Client-MissingUncompressed", 12100 config: Config{ 12101 MaxVersion: VersionTLS12, 12102 Bugs: ProtocolBugs{ 12103 SendSupportedPointFormats: []byte{pointFormatCompressedPrime}, 12104 }, 12105 }, 12106 shouldFail: true, 12107 expectedError: ":ERROR_PARSING_EXTENSION:", 12108 }) 12109 testCases = append(testCases, testCase{ 12110 testType: serverTest, 12111 name: "PointFormat-Server-MissingUncompressed", 12112 config: Config{ 12113 MaxVersion: VersionTLS12, 12114 Bugs: ProtocolBugs{ 12115 SendSupportedPointFormats: []byte{pointFormatCompressedPrime}, 12116 }, 12117 }, 12118 shouldFail: true, 12119 expectedError: ":ERROR_PARSING_EXTENSION:", 12120 }) 12121 12122 // Implementations should mask off the high order bit in X25519. 12123 testCases = append(testCases, testCase{ 12124 name: "SetX25519HighBit", 12125 config: Config{ 12126 CipherSuites: []uint16{ 12127 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 12128 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 12129 TLS_AES_128_GCM_SHA256, 12130 }, 12131 CurvePreferences: []CurveID{CurveX25519}, 12132 Bugs: ProtocolBugs{ 12133 SetX25519HighBit: true, 12134 }, 12135 }, 12136 }) 12137 12138 // Kyber should not be offered by a TLS < 1.3 client. 12139 testCases = append(testCases, testCase{ 12140 name: "KyberNotInTLS12", 12141 config: Config{ 12142 Bugs: ProtocolBugs{ 12143 FailIfKyberOffered: true, 12144 }, 12145 }, 12146 flags: []string{ 12147 "-max-version", strconv.Itoa(VersionTLS12), 12148 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12149 "-curves", strconv.Itoa(int(CurveX25519)), 12150 }, 12151 }) 12152 12153 // Kyber should not crash a TLS < 1.3 client if the server mistakenly 12154 // selects it. 12155 testCases = append(testCases, testCase{ 12156 name: "KyberNotAcceptedByTLS12Client", 12157 config: Config{ 12158 Bugs: ProtocolBugs{ 12159 SendCurve: CurveX25519Kyber768, 12160 }, 12161 }, 12162 flags: []string{ 12163 "-max-version", strconv.Itoa(VersionTLS12), 12164 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12165 "-curves", strconv.Itoa(int(CurveX25519)), 12166 }, 12167 shouldFail: true, 12168 expectedError: ":WRONG_CURVE:", 12169 }) 12170 12171 // Kyber should not be offered by default as a client. 12172 testCases = append(testCases, testCase{ 12173 name: "KyberNotEnabledByDefaultInClients", 12174 config: Config{ 12175 MinVersion: VersionTLS13, 12176 Bugs: ProtocolBugs{ 12177 FailIfKyberOffered: true, 12178 }, 12179 }, 12180 }) 12181 12182 // If Kyber is offered, both X25519 and Kyber should have a key-share. 12183 testCases = append(testCases, testCase{ 12184 name: "NotJustKyberKeyShare", 12185 config: Config{ 12186 MinVersion: VersionTLS13, 12187 Bugs: ProtocolBugs{ 12188 ExpectedKeyShares: []CurveID{CurveX25519Kyber768, CurveX25519}, 12189 }, 12190 }, 12191 flags: []string{ 12192 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12193 "-curves", strconv.Itoa(int(CurveX25519)), 12194 "-expect-curve-id", strconv.Itoa(int(CurveX25519Kyber768)), 12195 }, 12196 }) 12197 12198 // ... and the other way around 12199 testCases = append(testCases, testCase{ 12200 name: "KyberKeyShareIncludedSecond", 12201 config: Config{ 12202 MinVersion: VersionTLS13, 12203 Bugs: ProtocolBugs{ 12204 ExpectedKeyShares: []CurveID{CurveX25519, CurveX25519Kyber768}, 12205 }, 12206 }, 12207 flags: []string{ 12208 "-curves", strconv.Itoa(int(CurveX25519)), 12209 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12210 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 12211 }, 12212 }) 12213 12214 // ... and even if there's another curve in the middle because it's the 12215 // first classical and first post-quantum "curves" that get key shares 12216 // included. 12217 testCases = append(testCases, testCase{ 12218 name: "KyberKeyShareIncludedThird", 12219 config: Config{ 12220 MinVersion: VersionTLS13, 12221 Bugs: ProtocolBugs{ 12222 ExpectedKeyShares: []CurveID{CurveX25519, CurveX25519Kyber768}, 12223 }, 12224 }, 12225 flags: []string{ 12226 "-curves", strconv.Itoa(int(CurveX25519)), 12227 "-curves", strconv.Itoa(int(CurveP256)), 12228 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12229 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 12230 }, 12231 }) 12232 12233 // If Kyber is the only configured curve, the key share is sent. 12234 testCases = append(testCases, testCase{ 12235 name: "JustConfiguringKyberWorks", 12236 config: Config{ 12237 MinVersion: VersionTLS13, 12238 Bugs: ProtocolBugs{ 12239 ExpectedKeyShares: []CurveID{CurveX25519Kyber768}, 12240 }, 12241 }, 12242 flags: []string{ 12243 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12244 "-expect-curve-id", strconv.Itoa(int(CurveX25519Kyber768)), 12245 }, 12246 }) 12247 12248 // As a server, Kyber is not yet supported by default. 12249 testCases = append(testCases, testCase{ 12250 testType: serverTest, 12251 name: "KyberNotEnabledByDefaultForAServer", 12252 config: Config{ 12253 MinVersion: VersionTLS13, 12254 CurvePreferences: []CurveID{CurveX25519Kyber768, CurveX25519}, 12255 DefaultCurves: []CurveID{CurveX25519Kyber768}, 12256 }, 12257 flags: []string{ 12258 "-server-preference", 12259 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 12260 }, 12261 }) 12262 12263 // In TLS 1.2, the curve list is also used to signal ECDSA curves. 12264 testCases = append(testCases, testCase{ 12265 testType: serverTest, 12266 name: "CheckECDSACurve-TLS12", 12267 config: Config{ 12268 MinVersion: VersionTLS12, 12269 MaxVersion: VersionTLS12, 12270 CurvePreferences: []CurveID{CurveP384}, 12271 }, 12272 shimCertificate: &ecdsaP256Certificate, 12273 shouldFail: true, 12274 expectedError: ":WRONG_CURVE:", 12275 }) 12276 12277 // This behavior may, temporarily, be disabled with a flag. 12278 testCases = append(testCases, testCase{ 12279 testType: serverTest, 12280 name: "NoCheckECDSACurve-TLS12", 12281 config: Config{ 12282 MinVersion: VersionTLS12, 12283 MaxVersion: VersionTLS12, 12284 CurvePreferences: []CurveID{CurveP384}, 12285 }, 12286 shimCertificate: &ecdsaP256Certificate, 12287 flags: []string{"-no-check-ecdsa-curve"}, 12288 }) 12289 12290 // If the ECDSA certificate is ineligible due to a curve mismatch, the 12291 // server may still consider a PSK cipher suite. 12292 testCases = append(testCases, testCase{ 12293 testType: serverTest, 12294 name: "CheckECDSACurve-PSK-TLS12", 12295 config: Config{ 12296 MinVersion: VersionTLS12, 12297 MaxVersion: VersionTLS12, 12298 CipherSuites: []uint16{ 12299 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 12300 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 12301 }, 12302 CurvePreferences: []CurveID{CurveP384}, 12303 PreSharedKey: []byte("12345"), 12304 PreSharedKeyIdentity: "luggage combo", 12305 }, 12306 shimCertificate: &ecdsaP256Certificate, 12307 expectations: connectionExpectations{ 12308 cipher: TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 12309 }, 12310 flags: []string{ 12311 "-psk", "12345", 12312 "-psk-identity", "luggage combo", 12313 }, 12314 }) 12315 12316 // In TLS 1.3, the curve list only controls ECDH. 12317 testCases = append(testCases, testCase{ 12318 testType: serverTest, 12319 name: "CheckECDSACurve-NotApplicable-TLS13", 12320 config: Config{ 12321 MinVersion: VersionTLS13, 12322 MaxVersion: VersionTLS13, 12323 CurvePreferences: []CurveID{CurveP384}, 12324 }, 12325 shimCertificate: &ecdsaP256Certificate, 12326 }) 12327} 12328 12329func addTLS13RecordTests() { 12330 testCases = append(testCases, testCase{ 12331 name: "TLS13-RecordPadding", 12332 config: Config{ 12333 MaxVersion: VersionTLS13, 12334 MinVersion: VersionTLS13, 12335 Bugs: ProtocolBugs{ 12336 RecordPadding: 10, 12337 }, 12338 }, 12339 }) 12340 12341 testCases = append(testCases, testCase{ 12342 name: "TLS13-EmptyRecords", 12343 config: Config{ 12344 MaxVersion: VersionTLS13, 12345 MinVersion: VersionTLS13, 12346 Bugs: ProtocolBugs{ 12347 OmitRecordContents: true, 12348 }, 12349 }, 12350 shouldFail: true, 12351 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 12352 }) 12353 12354 testCases = append(testCases, testCase{ 12355 name: "TLS13-OnlyPadding", 12356 config: Config{ 12357 MaxVersion: VersionTLS13, 12358 MinVersion: VersionTLS13, 12359 Bugs: ProtocolBugs{ 12360 OmitRecordContents: true, 12361 RecordPadding: 10, 12362 }, 12363 }, 12364 shouldFail: true, 12365 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 12366 }) 12367 12368 testCases = append(testCases, testCase{ 12369 name: "TLS13-WrongOuterRecord", 12370 config: Config{ 12371 MaxVersion: VersionTLS13, 12372 MinVersion: VersionTLS13, 12373 Bugs: ProtocolBugs{ 12374 OuterRecordType: recordTypeHandshake, 12375 }, 12376 }, 12377 shouldFail: true, 12378 expectedError: ":INVALID_OUTER_RECORD_TYPE:", 12379 }) 12380} 12381 12382func addSessionTicketTests() { 12383 testCases = append(testCases, testCase{ 12384 // In TLS 1.2 and below, empty NewSessionTicket messages 12385 // mean the server changed its mind on sending a ticket. 12386 name: "SendEmptySessionTicket", 12387 config: Config{ 12388 MaxVersion: VersionTLS12, 12389 Bugs: ProtocolBugs{ 12390 SendEmptySessionTicket: true, 12391 }, 12392 }, 12393 flags: []string{"-expect-no-session"}, 12394 }) 12395 12396 // Test that the server ignores unknown PSK modes. 12397 testCases = append(testCases, testCase{ 12398 testType: serverTest, 12399 name: "TLS13-SendUnknownModeSessionTicket-Server", 12400 config: Config{ 12401 MaxVersion: VersionTLS13, 12402 Bugs: ProtocolBugs{ 12403 SendPSKKeyExchangeModes: []byte{0x1a, pskDHEKEMode, 0x2a}, 12404 }, 12405 }, 12406 resumeSession: true, 12407 expectations: connectionExpectations{ 12408 version: VersionTLS13, 12409 }, 12410 }) 12411 12412 // Test that the server does not send session tickets with no matching key exchange mode. 12413 testCases = append(testCases, testCase{ 12414 testType: serverTest, 12415 name: "TLS13-ExpectNoSessionTicketOnBadKEMode-Server", 12416 config: Config{ 12417 MaxVersion: VersionTLS13, 12418 Bugs: ProtocolBugs{ 12419 SendPSKKeyExchangeModes: []byte{0x1a}, 12420 ExpectNoNewSessionTicket: true, 12421 }, 12422 }, 12423 }) 12424 12425 // Test that the server does not accept a session with no matching key exchange mode. 12426 testCases = append(testCases, testCase{ 12427 testType: serverTest, 12428 name: "TLS13-SendBadKEModeSessionTicket-Server", 12429 config: Config{ 12430 MaxVersion: VersionTLS13, 12431 }, 12432 resumeConfig: &Config{ 12433 MaxVersion: VersionTLS13, 12434 Bugs: ProtocolBugs{ 12435 SendPSKKeyExchangeModes: []byte{0x1a}, 12436 }, 12437 }, 12438 resumeSession: true, 12439 expectResumeRejected: true, 12440 }) 12441 12442 // Test that the server rejects ClientHellos with pre_shared_key but without 12443 // psk_key_exchange_modes. 12444 testCases = append(testCases, testCase{ 12445 testType: serverTest, 12446 name: "TLS13-SendNoKEMModesWithPSK-Server", 12447 config: Config{ 12448 MaxVersion: VersionTLS13, 12449 }, 12450 resumeConfig: &Config{ 12451 MaxVersion: VersionTLS13, 12452 Bugs: ProtocolBugs{ 12453 SendPSKKeyExchangeModes: []byte{}, 12454 }, 12455 }, 12456 resumeSession: true, 12457 shouldFail: true, 12458 expectedLocalError: "remote error: missing extension", 12459 expectedError: ":MISSING_EXTENSION:", 12460 }) 12461 12462 // Test that the client ticket age is sent correctly. 12463 testCases = append(testCases, testCase{ 12464 testType: clientTest, 12465 name: "TLS13-TestValidTicketAge-Client", 12466 config: Config{ 12467 MaxVersion: VersionTLS13, 12468 Bugs: ProtocolBugs{ 12469 ExpectTicketAge: 10 * time.Second, 12470 }, 12471 }, 12472 resumeSession: true, 12473 flags: []string{ 12474 "-resumption-delay", "10", 12475 }, 12476 }) 12477 12478 // Test that the client ticket age is enforced. 12479 testCases = append(testCases, testCase{ 12480 testType: clientTest, 12481 name: "TLS13-TestBadTicketAge-Client", 12482 config: Config{ 12483 MaxVersion: VersionTLS13, 12484 Bugs: ProtocolBugs{ 12485 ExpectTicketAge: 1000 * time.Second, 12486 }, 12487 }, 12488 resumeSession: true, 12489 shouldFail: true, 12490 expectedLocalError: "tls: invalid ticket age", 12491 }) 12492 12493 // Test that the server's ticket age skew reporting works. 12494 testCases = append(testCases, testCase{ 12495 testType: serverTest, 12496 name: "TLS13-TicketAgeSkew-Forward", 12497 config: Config{ 12498 MaxVersion: VersionTLS13, 12499 Bugs: ProtocolBugs{ 12500 SendTicketAge: 15 * time.Second, 12501 }, 12502 }, 12503 resumeSession: true, 12504 resumeRenewedSession: true, 12505 flags: []string{ 12506 "-resumption-delay", "10", 12507 "-expect-ticket-age-skew", "5", 12508 }, 12509 }) 12510 testCases = append(testCases, testCase{ 12511 testType: serverTest, 12512 name: "TLS13-TicketAgeSkew-Backward", 12513 config: Config{ 12514 MaxVersion: VersionTLS13, 12515 Bugs: ProtocolBugs{ 12516 SendTicketAge: 5 * time.Second, 12517 }, 12518 }, 12519 resumeSession: true, 12520 resumeRenewedSession: true, 12521 flags: []string{ 12522 "-resumption-delay", "10", 12523 "-expect-ticket-age-skew", "-5", 12524 }, 12525 }) 12526 12527 // Test that ticket age skew up to 60 seconds in either direction is accepted. 12528 testCases = append(testCases, testCase{ 12529 testType: serverTest, 12530 name: "TLS13-TicketAgeSkew-Forward-60-Accept", 12531 config: Config{ 12532 MaxVersion: VersionTLS13, 12533 Bugs: ProtocolBugs{ 12534 SendTicketAge: 70 * time.Second, 12535 }, 12536 }, 12537 resumeSession: true, 12538 earlyData: true, 12539 flags: []string{ 12540 "-resumption-delay", "10", 12541 "-expect-ticket-age-skew", "60", 12542 }, 12543 }) 12544 testCases = append(testCases, testCase{ 12545 testType: serverTest, 12546 name: "TLS13-TicketAgeSkew-Backward-60-Accept", 12547 config: Config{ 12548 MaxVersion: VersionTLS13, 12549 Bugs: ProtocolBugs{ 12550 SendTicketAge: 10 * time.Second, 12551 }, 12552 }, 12553 resumeSession: true, 12554 earlyData: true, 12555 flags: []string{ 12556 "-resumption-delay", "70", 12557 "-expect-ticket-age-skew", "-60", 12558 }, 12559 }) 12560 12561 // Test that ticket age skew beyond 60 seconds in either direction is rejected. 12562 testCases = append(testCases, testCase{ 12563 testType: serverTest, 12564 name: "TLS13-TicketAgeSkew-Forward-61-Reject", 12565 config: Config{ 12566 MaxVersion: VersionTLS13, 12567 Bugs: ProtocolBugs{ 12568 SendTicketAge: 71 * time.Second, 12569 }, 12570 }, 12571 resumeSession: true, 12572 earlyData: true, 12573 expectEarlyDataRejected: true, 12574 flags: []string{ 12575 "-resumption-delay", "10", 12576 "-expect-ticket-age-skew", "61", 12577 "-on-resume-expect-early-data-reason", "ticket_age_skew", 12578 }, 12579 }) 12580 testCases = append(testCases, testCase{ 12581 testType: serverTest, 12582 name: "TLS13-TicketAgeSkew-Backward-61-Reject", 12583 config: Config{ 12584 MaxVersion: VersionTLS13, 12585 Bugs: ProtocolBugs{ 12586 SendTicketAge: 10 * time.Second, 12587 }, 12588 }, 12589 resumeSession: true, 12590 earlyData: true, 12591 expectEarlyDataRejected: true, 12592 flags: []string{ 12593 "-resumption-delay", "71", 12594 "-expect-ticket-age-skew", "-61", 12595 "-on-resume-expect-early-data-reason", "ticket_age_skew", 12596 }, 12597 }) 12598 12599 testCases = append(testCases, testCase{ 12600 testType: clientTest, 12601 name: "TLS13-SendTicketEarlyDataSupport", 12602 config: Config{ 12603 MaxVersion: VersionTLS13, 12604 MaxEarlyDataSize: 16384, 12605 }, 12606 flags: []string{ 12607 "-enable-early-data", 12608 "-expect-ticket-supports-early-data", 12609 }, 12610 }) 12611 12612 // Test that 0-RTT tickets are still recorded as such when early data is disabled overall. 12613 testCases = append(testCases, testCase{ 12614 testType: clientTest, 12615 name: "TLS13-SendTicketEarlyDataSupport-Disabled", 12616 config: Config{ 12617 MaxVersion: VersionTLS13, 12618 MaxEarlyDataSize: 16384, 12619 }, 12620 flags: []string{ 12621 "-expect-ticket-supports-early-data", 12622 }, 12623 }) 12624 12625 testCases = append(testCases, testCase{ 12626 testType: clientTest, 12627 name: "TLS13-DuplicateTicketEarlyDataSupport", 12628 config: Config{ 12629 MaxVersion: VersionTLS13, 12630 MaxEarlyDataSize: 16384, 12631 Bugs: ProtocolBugs{ 12632 DuplicateTicketEarlyData: true, 12633 }, 12634 }, 12635 shouldFail: true, 12636 expectedError: ":DUPLICATE_EXTENSION:", 12637 expectedLocalError: "remote error: illegal parameter", 12638 }) 12639 12640 testCases = append(testCases, testCase{ 12641 testType: serverTest, 12642 name: "TLS13-ExpectTicketEarlyDataSupport", 12643 config: Config{ 12644 MaxVersion: VersionTLS13, 12645 Bugs: ProtocolBugs{ 12646 ExpectTicketEarlyData: true, 12647 }, 12648 }, 12649 flags: []string{ 12650 "-enable-early-data", 12651 }, 12652 }) 12653 12654 // Test that, in TLS 1.3, the server-offered NewSessionTicket lifetime 12655 // is honored. 12656 testCases = append(testCases, testCase{ 12657 testType: clientTest, 12658 name: "TLS13-HonorServerSessionTicketLifetime", 12659 config: Config{ 12660 MaxVersion: VersionTLS13, 12661 Bugs: ProtocolBugs{ 12662 SendTicketLifetime: 20 * time.Second, 12663 }, 12664 }, 12665 flags: []string{ 12666 "-resumption-delay", "19", 12667 }, 12668 resumeSession: true, 12669 }) 12670 testCases = append(testCases, testCase{ 12671 testType: clientTest, 12672 name: "TLS13-HonorServerSessionTicketLifetime-2", 12673 config: Config{ 12674 MaxVersion: VersionTLS13, 12675 Bugs: ProtocolBugs{ 12676 SendTicketLifetime: 20 * time.Second, 12677 // The client should not offer the expired session. 12678 ExpectNoTLS13PSK: true, 12679 }, 12680 }, 12681 flags: []string{ 12682 "-resumption-delay", "21", 12683 }, 12684 resumeSession: true, 12685 expectResumeRejected: true, 12686 }) 12687 12688 for _, ver := range tlsVersions { 12689 // Prior to TLS 1.3, disabling session tickets enables session IDs. 12690 useStatefulResumption := ver.version < VersionTLS13 12691 12692 // SSL_OP_NO_TICKET implies the server must not mint any tickets. 12693 testCases = append(testCases, testCase{ 12694 testType: serverTest, 12695 name: ver.name + "-NoTicket-NoMint", 12696 config: Config{ 12697 MinVersion: ver.version, 12698 MaxVersion: ver.version, 12699 Bugs: ProtocolBugs{ 12700 ExpectNoNewSessionTicket: true, 12701 RequireSessionIDs: useStatefulResumption, 12702 }, 12703 }, 12704 resumeSession: useStatefulResumption, 12705 flags: []string{"-no-ticket"}, 12706 }) 12707 12708 // SSL_OP_NO_TICKET implies the server must not accept any tickets. 12709 testCases = append(testCases, testCase{ 12710 testType: serverTest, 12711 name: ver.name + "-NoTicket-NoAccept", 12712 config: Config{ 12713 MinVersion: ver.version, 12714 MaxVersion: ver.version, 12715 }, 12716 resumeSession: true, 12717 expectResumeRejected: true, 12718 // Set SSL_OP_NO_TICKET on the second connection, after the first 12719 // has established tickets. 12720 flags: []string{"-on-resume-no-ticket"}, 12721 }) 12722 } 12723} 12724 12725func addChangeCipherSpecTests() { 12726 // Test missing ChangeCipherSpecs. 12727 testCases = append(testCases, testCase{ 12728 name: "SkipChangeCipherSpec-Client", 12729 config: Config{ 12730 MaxVersion: VersionTLS12, 12731 Bugs: ProtocolBugs{ 12732 SkipChangeCipherSpec: true, 12733 }, 12734 }, 12735 shouldFail: true, 12736 expectedError: ":UNEXPECTED_RECORD:", 12737 }) 12738 testCases = append(testCases, testCase{ 12739 testType: serverTest, 12740 name: "SkipChangeCipherSpec-Server", 12741 config: Config{ 12742 MaxVersion: VersionTLS12, 12743 Bugs: ProtocolBugs{ 12744 SkipChangeCipherSpec: true, 12745 }, 12746 }, 12747 shouldFail: true, 12748 expectedError: ":UNEXPECTED_RECORD:", 12749 }) 12750 testCases = append(testCases, testCase{ 12751 testType: serverTest, 12752 name: "SkipChangeCipherSpec-Server-NPN", 12753 config: Config{ 12754 MaxVersion: VersionTLS12, 12755 NextProtos: []string{"bar"}, 12756 Bugs: ProtocolBugs{ 12757 SkipChangeCipherSpec: true, 12758 }, 12759 }, 12760 flags: []string{ 12761 "-advertise-npn", "\x03foo\x03bar\x03baz", 12762 }, 12763 shouldFail: true, 12764 expectedError: ":UNEXPECTED_RECORD:", 12765 }) 12766 12767 // Test synchronization between the handshake and ChangeCipherSpec. 12768 // Partial post-CCS handshake messages before ChangeCipherSpec should be 12769 // rejected. Test both with and without handshake packing to handle both 12770 // when the partial post-CCS message is in its own record and when it is 12771 // attached to the pre-CCS message. 12772 for _, packed := range []bool{false, true} { 12773 var suffix string 12774 if packed { 12775 suffix = "-Packed" 12776 } 12777 12778 testCases = append(testCases, testCase{ 12779 name: "FragmentAcrossChangeCipherSpec-Client" + suffix, 12780 config: Config{ 12781 MaxVersion: VersionTLS12, 12782 Bugs: ProtocolBugs{ 12783 FragmentAcrossChangeCipherSpec: true, 12784 PackHandshakeFlight: packed, 12785 }, 12786 }, 12787 shouldFail: true, 12788 expectedError: ":UNEXPECTED_RECORD:", 12789 }) 12790 testCases = append(testCases, testCase{ 12791 name: "FragmentAcrossChangeCipherSpec-Client-Resume" + suffix, 12792 config: Config{ 12793 MaxVersion: VersionTLS12, 12794 }, 12795 resumeSession: true, 12796 resumeConfig: &Config{ 12797 MaxVersion: VersionTLS12, 12798 Bugs: ProtocolBugs{ 12799 FragmentAcrossChangeCipherSpec: true, 12800 PackHandshakeFlight: packed, 12801 }, 12802 }, 12803 shouldFail: true, 12804 expectedError: ":UNEXPECTED_RECORD:", 12805 }) 12806 testCases = append(testCases, testCase{ 12807 testType: serverTest, 12808 name: "FragmentAcrossChangeCipherSpec-Server" + suffix, 12809 config: Config{ 12810 MaxVersion: VersionTLS12, 12811 Bugs: ProtocolBugs{ 12812 FragmentAcrossChangeCipherSpec: true, 12813 PackHandshakeFlight: packed, 12814 }, 12815 }, 12816 shouldFail: true, 12817 expectedError: ":UNEXPECTED_RECORD:", 12818 }) 12819 testCases = append(testCases, testCase{ 12820 testType: serverTest, 12821 name: "FragmentAcrossChangeCipherSpec-Server-Resume" + suffix, 12822 config: Config{ 12823 MaxVersion: VersionTLS12, 12824 }, 12825 resumeSession: true, 12826 resumeConfig: &Config{ 12827 MaxVersion: VersionTLS12, 12828 Bugs: ProtocolBugs{ 12829 FragmentAcrossChangeCipherSpec: true, 12830 PackHandshakeFlight: packed, 12831 }, 12832 }, 12833 shouldFail: true, 12834 expectedError: ":UNEXPECTED_RECORD:", 12835 }) 12836 testCases = append(testCases, testCase{ 12837 testType: serverTest, 12838 name: "FragmentAcrossChangeCipherSpec-Server-NPN" + suffix, 12839 config: Config{ 12840 MaxVersion: VersionTLS12, 12841 NextProtos: []string{"bar"}, 12842 Bugs: ProtocolBugs{ 12843 FragmentAcrossChangeCipherSpec: true, 12844 PackHandshakeFlight: packed, 12845 }, 12846 }, 12847 flags: []string{ 12848 "-advertise-npn", "\x03foo\x03bar\x03baz", 12849 }, 12850 shouldFail: true, 12851 expectedError: ":UNEXPECTED_RECORD:", 12852 }) 12853 } 12854 12855 // In TLS 1.2 resumptions, the client sends ClientHello in the first flight 12856 // and ChangeCipherSpec + Finished in the second flight. Test the server's 12857 // behavior when the Finished message is fragmented across not only 12858 // ChangeCipherSpec but also the flight boundary. 12859 testCases = append(testCases, testCase{ 12860 testType: serverTest, 12861 name: "PartialClientFinishedWithClientHello-TLS12-Resume", 12862 config: Config{ 12863 MaxVersion: VersionTLS12, 12864 }, 12865 resumeConfig: &Config{ 12866 MaxVersion: VersionTLS12, 12867 Bugs: ProtocolBugs{ 12868 PartialClientFinishedWithClientHello: true, 12869 }, 12870 }, 12871 resumeSession: true, 12872 shouldFail: true, 12873 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12874 expectedLocalError: "remote error: unexpected message", 12875 }) 12876 12877 // In TLS 1.2 full handshakes without tickets, the server's first flight ends 12878 // with ServerHelloDone and the second flight is ChangeCipherSpec + Finished. 12879 // Test the client's behavior when the Finished message is fragmented across 12880 // not only ChangeCipherSpec but also the flight boundary. 12881 testCases = append(testCases, testCase{ 12882 testType: clientTest, 12883 name: "PartialFinishedWithServerHelloDone", 12884 config: Config{ 12885 MaxVersion: VersionTLS12, 12886 SessionTicketsDisabled: true, 12887 Bugs: ProtocolBugs{ 12888 PartialFinishedWithServerHelloDone: true, 12889 }, 12890 }, 12891 shouldFail: true, 12892 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12893 expectedLocalError: "remote error: unexpected message", 12894 }) 12895 12896 // Test that, in DTLS, ChangeCipherSpec is not allowed when there are 12897 // messages in the handshake queue. Do this by testing the server 12898 // reading the client Finished, reversing the flight so Finished comes 12899 // first. 12900 testCases = append(testCases, testCase{ 12901 protocol: dtls, 12902 testType: serverTest, 12903 name: "SendUnencryptedFinished-DTLS", 12904 config: Config{ 12905 MaxVersion: VersionTLS12, 12906 Bugs: ProtocolBugs{ 12907 SendUnencryptedFinished: true, 12908 ReverseHandshakeFragments: true, 12909 }, 12910 }, 12911 shouldFail: true, 12912 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12913 }) 12914 12915 // Test synchronization between encryption changes and the handshake in 12916 // TLS 1.3, where ChangeCipherSpec is implicit. 12917 testCases = append(testCases, testCase{ 12918 name: "PartialEncryptedExtensionsWithServerHello", 12919 config: Config{ 12920 MaxVersion: VersionTLS13, 12921 Bugs: ProtocolBugs{ 12922 PartialEncryptedExtensionsWithServerHello: true, 12923 }, 12924 }, 12925 shouldFail: true, 12926 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12927 }) 12928 testCases = append(testCases, testCase{ 12929 testType: serverTest, 12930 name: "PartialClientFinishedWithClientHello", 12931 config: Config{ 12932 MaxVersion: VersionTLS13, 12933 Bugs: ProtocolBugs{ 12934 PartialClientFinishedWithClientHello: true, 12935 }, 12936 }, 12937 shouldFail: true, 12938 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12939 }) 12940 testCases = append(testCases, testCase{ 12941 testType: serverTest, 12942 name: "PartialClientFinishedWithSecondClientHello", 12943 config: Config{ 12944 MaxVersion: VersionTLS13, 12945 // Trigger a curve-based HelloRetryRequest. 12946 DefaultCurves: []CurveID{}, 12947 Bugs: ProtocolBugs{ 12948 PartialClientFinishedWithSecondClientHello: true, 12949 }, 12950 }, 12951 shouldFail: true, 12952 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12953 }) 12954 testCases = append(testCases, testCase{ 12955 testType: serverTest, 12956 name: "PartialEndOfEarlyDataWithClientHello", 12957 config: Config{ 12958 MaxVersion: VersionTLS13, 12959 }, 12960 resumeConfig: &Config{ 12961 MaxVersion: VersionTLS13, 12962 Bugs: ProtocolBugs{ 12963 PartialEndOfEarlyDataWithClientHello: true, 12964 }, 12965 }, 12966 resumeSession: true, 12967 earlyData: true, 12968 shouldFail: true, 12969 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12970 }) 12971 12972 // Test that early ChangeCipherSpecs are handled correctly. 12973 testCases = append(testCases, testCase{ 12974 testType: serverTest, 12975 name: "EarlyChangeCipherSpec-server-1", 12976 config: Config{ 12977 MaxVersion: VersionTLS12, 12978 Bugs: ProtocolBugs{ 12979 EarlyChangeCipherSpec: 1, 12980 }, 12981 }, 12982 shouldFail: true, 12983 expectedError: ":UNEXPECTED_RECORD:", 12984 }) 12985 testCases = append(testCases, testCase{ 12986 testType: serverTest, 12987 name: "EarlyChangeCipherSpec-server-2", 12988 config: Config{ 12989 MaxVersion: VersionTLS12, 12990 Bugs: ProtocolBugs{ 12991 EarlyChangeCipherSpec: 2, 12992 }, 12993 }, 12994 shouldFail: true, 12995 expectedError: ":UNEXPECTED_RECORD:", 12996 }) 12997 testCases = append(testCases, testCase{ 12998 protocol: dtls, 12999 name: "StrayChangeCipherSpec", 13000 config: Config{ 13001 // TODO(davidben): Once DTLS 1.3 exists, test 13002 // that stray ChangeCipherSpec messages are 13003 // rejected. 13004 MaxVersion: VersionTLS12, 13005 Bugs: ProtocolBugs{ 13006 StrayChangeCipherSpec: true, 13007 }, 13008 }, 13009 }) 13010 13011 // Test that reordered ChangeCipherSpecs are tolerated. 13012 testCases = append(testCases, testCase{ 13013 protocol: dtls, 13014 name: "ReorderChangeCipherSpec-DTLS-Client", 13015 config: Config{ 13016 MaxVersion: VersionTLS12, 13017 Bugs: ProtocolBugs{ 13018 ReorderChangeCipherSpec: true, 13019 }, 13020 }, 13021 resumeSession: true, 13022 }) 13023 testCases = append(testCases, testCase{ 13024 testType: serverTest, 13025 protocol: dtls, 13026 name: "ReorderChangeCipherSpec-DTLS-Server", 13027 config: Config{ 13028 MaxVersion: VersionTLS12, 13029 Bugs: ProtocolBugs{ 13030 ReorderChangeCipherSpec: true, 13031 }, 13032 }, 13033 resumeSession: true, 13034 }) 13035 13036 // Test that the contents of ChangeCipherSpec are checked. 13037 testCases = append(testCases, testCase{ 13038 name: "BadChangeCipherSpec-1", 13039 config: Config{ 13040 MaxVersion: VersionTLS12, 13041 Bugs: ProtocolBugs{ 13042 BadChangeCipherSpec: []byte{2}, 13043 }, 13044 }, 13045 shouldFail: true, 13046 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 13047 }) 13048 testCases = append(testCases, testCase{ 13049 name: "BadChangeCipherSpec-2", 13050 config: Config{ 13051 MaxVersion: VersionTLS12, 13052 Bugs: ProtocolBugs{ 13053 BadChangeCipherSpec: []byte{1, 1}, 13054 }, 13055 }, 13056 shouldFail: true, 13057 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 13058 }) 13059 testCases = append(testCases, testCase{ 13060 protocol: dtls, 13061 name: "BadChangeCipherSpec-DTLS-1", 13062 config: Config{ 13063 MaxVersion: VersionTLS12, 13064 Bugs: ProtocolBugs{ 13065 BadChangeCipherSpec: []byte{2}, 13066 }, 13067 }, 13068 shouldFail: true, 13069 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 13070 }) 13071 testCases = append(testCases, testCase{ 13072 protocol: dtls, 13073 name: "BadChangeCipherSpec-DTLS-2", 13074 config: Config{ 13075 MaxVersion: VersionTLS12, 13076 Bugs: ProtocolBugs{ 13077 BadChangeCipherSpec: []byte{1, 1}, 13078 }, 13079 }, 13080 shouldFail: true, 13081 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 13082 }) 13083} 13084 13085// addEndOfFlightTests adds tests where the runner adds extra data in the final 13086// record of each handshake flight. Depending on the implementation strategy, 13087// this data may be carried over to the next flight (assuming no key change) or 13088// may be rejected. To avoid differences with split handshakes and generally 13089// reject misbehavior, BoringSSL treats this as an error. When possible, these 13090// tests pull the extra data from the subsequent flight to distinguish the data 13091// being carried over from a general syntax error. 13092// 13093// These tests are similar to tests in |addChangeCipherSpecTests| that send 13094// extra data at key changes. Not all key changes are at the end of a flight and 13095// not all flights end at a key change. 13096func addEndOfFlightTests() { 13097 // TLS 1.3 client handshakes. 13098 // 13099 // Data following the second TLS 1.3 ClientHello is covered by 13100 // PartialClientFinishedWithClientHello, 13101 // PartialClientFinishedWithSecondClientHello, and 13102 // PartialEndOfEarlyDataWithClientHello in |addChangeCipherSpecTests|. 13103 testCases = append(testCases, testCase{ 13104 testType: serverTest, 13105 name: "PartialSecondClientHelloAfterFirst", 13106 config: Config{ 13107 MaxVersion: VersionTLS13, 13108 // Trigger a curve-based HelloRetryRequest. 13109 DefaultCurves: []CurveID{}, 13110 Bugs: ProtocolBugs{ 13111 PartialSecondClientHelloAfterFirst: true, 13112 }, 13113 }, 13114 shouldFail: true, 13115 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13116 expectedLocalError: "remote error: unexpected message", 13117 }) 13118 13119 // TLS 1.3 server handshakes. 13120 testCases = append(testCases, testCase{ 13121 testType: clientTest, 13122 name: "PartialServerHelloWithHelloRetryRequest", 13123 config: Config{ 13124 MaxVersion: VersionTLS13, 13125 // P-384 requires HelloRetryRequest in BoringSSL. 13126 CurvePreferences: []CurveID{CurveP384}, 13127 Bugs: ProtocolBugs{ 13128 PartialServerHelloWithHelloRetryRequest: true, 13129 }, 13130 }, 13131 shouldFail: true, 13132 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13133 expectedLocalError: "remote error: unexpected message", 13134 }) 13135 13136 // TLS 1.2 client handshakes. 13137 testCases = append(testCases, testCase{ 13138 testType: serverTest, 13139 name: "PartialClientKeyExchangeWithClientHello", 13140 config: Config{ 13141 MaxVersion: VersionTLS12, 13142 Bugs: ProtocolBugs{ 13143 PartialClientKeyExchangeWithClientHello: true, 13144 }, 13145 }, 13146 shouldFail: true, 13147 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13148 expectedLocalError: "remote error: unexpected message", 13149 }) 13150 13151 // TLS 1.2 server handshakes. 13152 testCases = append(testCases, testCase{ 13153 testType: clientTest, 13154 name: "PartialNewSessionTicketWithServerHelloDone", 13155 config: Config{ 13156 MaxVersion: VersionTLS12, 13157 Bugs: ProtocolBugs{ 13158 PartialNewSessionTicketWithServerHelloDone: true, 13159 }, 13160 }, 13161 shouldFail: true, 13162 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13163 expectedLocalError: "remote error: unexpected message", 13164 }) 13165 13166 for _, vers := range tlsVersions { 13167 for _, testType := range []testType{clientTest, serverTest} { 13168 suffix := "-Client" 13169 if testType == serverTest { 13170 suffix = "-Server" 13171 } 13172 suffix += "-" + vers.name 13173 13174 testCases = append(testCases, testCase{ 13175 testType: testType, 13176 name: "TrailingDataWithFinished" + suffix, 13177 config: Config{ 13178 MaxVersion: vers.version, 13179 Bugs: ProtocolBugs{ 13180 TrailingDataWithFinished: true, 13181 }, 13182 }, 13183 shouldFail: true, 13184 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13185 expectedLocalError: "remote error: unexpected message", 13186 }) 13187 testCases = append(testCases, testCase{ 13188 testType: testType, 13189 name: "TrailingDataWithFinished-Resume" + suffix, 13190 config: Config{ 13191 MaxVersion: vers.version, 13192 }, 13193 resumeConfig: &Config{ 13194 MaxVersion: vers.version, 13195 Bugs: ProtocolBugs{ 13196 TrailingDataWithFinished: true, 13197 }, 13198 }, 13199 resumeSession: true, 13200 shouldFail: true, 13201 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13202 expectedLocalError: "remote error: unexpected message", 13203 }) 13204 } 13205 } 13206} 13207 13208type perMessageTest struct { 13209 messageType uint8 13210 test testCase 13211} 13212 13213// makePerMessageTests returns a series of test templates which cover each 13214// message in the TLS handshake. These may be used with bugs like 13215// WrongMessageType to fully test a per-message bug. 13216func makePerMessageTests() []perMessageTest { 13217 var ret []perMessageTest 13218 // The following tests are limited to TLS 1.2, so QUIC is not tested. 13219 for _, protocol := range []protocol{tls, dtls} { 13220 suffix := "-" + protocol.String() 13221 13222 ret = append(ret, perMessageTest{ 13223 messageType: typeClientHello, 13224 test: testCase{ 13225 protocol: protocol, 13226 testType: serverTest, 13227 name: "ClientHello" + suffix, 13228 config: Config{ 13229 MaxVersion: VersionTLS12, 13230 }, 13231 }, 13232 }) 13233 13234 if protocol == dtls { 13235 ret = append(ret, perMessageTest{ 13236 messageType: typeHelloVerifyRequest, 13237 test: testCase{ 13238 protocol: protocol, 13239 name: "HelloVerifyRequest" + suffix, 13240 config: Config{ 13241 MaxVersion: VersionTLS12, 13242 }, 13243 }, 13244 }) 13245 } 13246 13247 ret = append(ret, perMessageTest{ 13248 messageType: typeServerHello, 13249 test: testCase{ 13250 protocol: protocol, 13251 name: "ServerHello" + suffix, 13252 config: Config{ 13253 MaxVersion: VersionTLS12, 13254 }, 13255 }, 13256 }) 13257 13258 ret = append(ret, perMessageTest{ 13259 messageType: typeCertificate, 13260 test: testCase{ 13261 protocol: protocol, 13262 name: "ServerCertificate" + suffix, 13263 config: Config{ 13264 MaxVersion: VersionTLS12, 13265 }, 13266 }, 13267 }) 13268 13269 ret = append(ret, perMessageTest{ 13270 messageType: typeCertificateStatus, 13271 test: testCase{ 13272 protocol: protocol, 13273 name: "CertificateStatus" + suffix, 13274 config: Config{ 13275 MaxVersion: VersionTLS12, 13276 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 13277 }, 13278 flags: []string{"-enable-ocsp-stapling"}, 13279 }, 13280 }) 13281 13282 ret = append(ret, perMessageTest{ 13283 messageType: typeServerKeyExchange, 13284 test: testCase{ 13285 protocol: protocol, 13286 name: "ServerKeyExchange" + suffix, 13287 config: Config{ 13288 MaxVersion: VersionTLS12, 13289 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 13290 }, 13291 }, 13292 }) 13293 13294 ret = append(ret, perMessageTest{ 13295 messageType: typeCertificateRequest, 13296 test: testCase{ 13297 protocol: protocol, 13298 name: "CertificateRequest" + suffix, 13299 config: Config{ 13300 MaxVersion: VersionTLS12, 13301 ClientAuth: RequireAnyClientCert, 13302 }, 13303 }, 13304 }) 13305 13306 ret = append(ret, perMessageTest{ 13307 messageType: typeServerHelloDone, 13308 test: testCase{ 13309 protocol: protocol, 13310 name: "ServerHelloDone" + suffix, 13311 config: Config{ 13312 MaxVersion: VersionTLS12, 13313 }, 13314 }, 13315 }) 13316 13317 ret = append(ret, perMessageTest{ 13318 messageType: typeCertificate, 13319 test: testCase{ 13320 testType: serverTest, 13321 protocol: protocol, 13322 name: "ClientCertificate" + suffix, 13323 config: Config{ 13324 Credential: &rsaCertificate, 13325 MaxVersion: VersionTLS12, 13326 }, 13327 flags: []string{"-require-any-client-certificate"}, 13328 }, 13329 }) 13330 13331 ret = append(ret, perMessageTest{ 13332 messageType: typeCertificateVerify, 13333 test: testCase{ 13334 testType: serverTest, 13335 protocol: protocol, 13336 name: "CertificateVerify" + suffix, 13337 config: Config{ 13338 Credential: &rsaCertificate, 13339 MaxVersion: VersionTLS12, 13340 }, 13341 flags: []string{"-require-any-client-certificate"}, 13342 }, 13343 }) 13344 13345 ret = append(ret, perMessageTest{ 13346 messageType: typeClientKeyExchange, 13347 test: testCase{ 13348 testType: serverTest, 13349 protocol: protocol, 13350 name: "ClientKeyExchange" + suffix, 13351 config: Config{ 13352 MaxVersion: VersionTLS12, 13353 }, 13354 }, 13355 }) 13356 13357 if protocol != dtls { 13358 ret = append(ret, perMessageTest{ 13359 messageType: typeNextProtocol, 13360 test: testCase{ 13361 testType: serverTest, 13362 protocol: protocol, 13363 name: "NextProtocol" + suffix, 13364 config: Config{ 13365 MaxVersion: VersionTLS12, 13366 NextProtos: []string{"bar"}, 13367 }, 13368 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"}, 13369 }, 13370 }) 13371 13372 ret = append(ret, perMessageTest{ 13373 messageType: typeChannelID, 13374 test: testCase{ 13375 testType: serverTest, 13376 protocol: protocol, 13377 name: "ChannelID" + suffix, 13378 config: Config{ 13379 MaxVersion: VersionTLS12, 13380 ChannelID: &channelIDKey, 13381 }, 13382 flags: []string{ 13383 "-expect-channel-id", 13384 base64FlagValue(channelIDBytes), 13385 }, 13386 }, 13387 }) 13388 } 13389 13390 ret = append(ret, perMessageTest{ 13391 messageType: typeFinished, 13392 test: testCase{ 13393 testType: serverTest, 13394 protocol: protocol, 13395 name: "ClientFinished" + suffix, 13396 config: Config{ 13397 MaxVersion: VersionTLS12, 13398 }, 13399 }, 13400 }) 13401 13402 ret = append(ret, perMessageTest{ 13403 messageType: typeNewSessionTicket, 13404 test: testCase{ 13405 protocol: protocol, 13406 name: "NewSessionTicket" + suffix, 13407 config: Config{ 13408 MaxVersion: VersionTLS12, 13409 }, 13410 }, 13411 }) 13412 13413 ret = append(ret, perMessageTest{ 13414 messageType: typeFinished, 13415 test: testCase{ 13416 protocol: protocol, 13417 name: "ServerFinished" + suffix, 13418 config: Config{ 13419 MaxVersion: VersionTLS12, 13420 }, 13421 }, 13422 }) 13423 13424 } 13425 13426 for _, protocol := range []protocol{tls, quic} { 13427 suffix := "-" + protocol.String() 13428 ret = append(ret, perMessageTest{ 13429 messageType: typeClientHello, 13430 test: testCase{ 13431 testType: serverTest, 13432 protocol: protocol, 13433 name: "TLS13-ClientHello" + suffix, 13434 config: Config{ 13435 MaxVersion: VersionTLS13, 13436 }, 13437 }, 13438 }) 13439 13440 ret = append(ret, perMessageTest{ 13441 messageType: typeServerHello, 13442 test: testCase{ 13443 name: "TLS13-ServerHello" + suffix, 13444 protocol: protocol, 13445 config: Config{ 13446 MaxVersion: VersionTLS13, 13447 }, 13448 }, 13449 }) 13450 13451 ret = append(ret, perMessageTest{ 13452 messageType: typeEncryptedExtensions, 13453 test: testCase{ 13454 name: "TLS13-EncryptedExtensions" + suffix, 13455 protocol: protocol, 13456 config: Config{ 13457 MaxVersion: VersionTLS13, 13458 }, 13459 }, 13460 }) 13461 13462 ret = append(ret, perMessageTest{ 13463 messageType: typeCertificateRequest, 13464 test: testCase{ 13465 name: "TLS13-CertificateRequest" + suffix, 13466 protocol: protocol, 13467 config: Config{ 13468 MaxVersion: VersionTLS13, 13469 ClientAuth: RequireAnyClientCert, 13470 }, 13471 }, 13472 }) 13473 13474 ret = append(ret, perMessageTest{ 13475 messageType: typeCertificate, 13476 test: testCase{ 13477 name: "TLS13-ServerCertificate" + suffix, 13478 protocol: protocol, 13479 config: Config{ 13480 MaxVersion: VersionTLS13, 13481 }, 13482 }, 13483 }) 13484 13485 ret = append(ret, perMessageTest{ 13486 messageType: typeCertificateVerify, 13487 test: testCase{ 13488 name: "TLS13-ServerCertificateVerify" + suffix, 13489 protocol: protocol, 13490 config: Config{ 13491 MaxVersion: VersionTLS13, 13492 }, 13493 }, 13494 }) 13495 13496 ret = append(ret, perMessageTest{ 13497 messageType: typeFinished, 13498 test: testCase{ 13499 name: "TLS13-ServerFinished" + suffix, 13500 protocol: protocol, 13501 config: Config{ 13502 MaxVersion: VersionTLS13, 13503 }, 13504 }, 13505 }) 13506 13507 ret = append(ret, perMessageTest{ 13508 messageType: typeCertificate, 13509 test: testCase{ 13510 testType: serverTest, 13511 protocol: protocol, 13512 name: "TLS13-ClientCertificate" + suffix, 13513 config: Config{ 13514 Credential: &rsaCertificate, 13515 MaxVersion: VersionTLS13, 13516 }, 13517 flags: []string{"-require-any-client-certificate"}, 13518 }, 13519 }) 13520 13521 ret = append(ret, perMessageTest{ 13522 messageType: typeCertificateVerify, 13523 test: testCase{ 13524 testType: serverTest, 13525 protocol: protocol, 13526 name: "TLS13-ClientCertificateVerify" + suffix, 13527 config: Config{ 13528 Credential: &rsaCertificate, 13529 MaxVersion: VersionTLS13, 13530 }, 13531 flags: []string{"-require-any-client-certificate"}, 13532 }, 13533 }) 13534 13535 ret = append(ret, perMessageTest{ 13536 messageType: typeFinished, 13537 test: testCase{ 13538 testType: serverTest, 13539 protocol: protocol, 13540 name: "TLS13-ClientFinished" + suffix, 13541 config: Config{ 13542 MaxVersion: VersionTLS13, 13543 }, 13544 }, 13545 }) 13546 13547 // Only TLS uses EndOfEarlyData. 13548 if protocol == tls { 13549 ret = append(ret, perMessageTest{ 13550 messageType: typeEndOfEarlyData, 13551 test: testCase{ 13552 testType: serverTest, 13553 protocol: protocol, 13554 name: "TLS13-EndOfEarlyData" + suffix, 13555 config: Config{ 13556 MaxVersion: VersionTLS13, 13557 }, 13558 resumeSession: true, 13559 earlyData: true, 13560 }, 13561 }) 13562 } 13563 } 13564 13565 return ret 13566} 13567 13568func addWrongMessageTypeTests() { 13569 for _, t := range makePerMessageTests() { 13570 t.test.name = "WrongMessageType-" + t.test.name 13571 if t.test.resumeConfig != nil { 13572 t.test.resumeConfig.Bugs.SendWrongMessageType = t.messageType 13573 } else { 13574 t.test.config.Bugs.SendWrongMessageType = t.messageType 13575 } 13576 t.test.shouldFail = true 13577 t.test.expectedError = ":UNEXPECTED_MESSAGE:" 13578 t.test.expectedLocalError = "remote error: unexpected message" 13579 13580 if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello { 13581 // In TLS 1.3, if the server believes it has sent ServerHello, 13582 // but the client cannot process it, the client will send an 13583 // unencrypted alert while the server expects encryption. In TLS, 13584 // this is a decryption failure. In QUIC, the encryption levels 13585 // do not match. 13586 if t.test.protocol == quic { 13587 t.test.expectedLocalError = "received record at initial encryption level, but expected handshake" 13588 } else { 13589 t.test.expectedLocalError = "local error: bad record MAC" 13590 } 13591 } 13592 13593 testCases = append(testCases, t.test) 13594 } 13595} 13596 13597func addTrailingMessageDataTests() { 13598 for _, t := range makePerMessageTests() { 13599 t.test.name = "TrailingMessageData-" + t.test.name 13600 if t.test.resumeConfig != nil { 13601 t.test.resumeConfig.Bugs.SendTrailingMessageData = t.messageType 13602 } else { 13603 t.test.config.Bugs.SendTrailingMessageData = t.messageType 13604 } 13605 t.test.shouldFail = true 13606 t.test.expectedError = ":DECODE_ERROR:" 13607 t.test.expectedLocalError = "remote error: error decoding message" 13608 13609 if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello { 13610 // In TLS 1.3, if the server believes it has sent ServerHello, 13611 // but the client cannot process it, the client will send an 13612 // unencrypted alert while the server expects encryption. In TLS, 13613 // this is a decryption failure. In QUIC, the encryption levels 13614 // do not match. 13615 if t.test.protocol == quic { 13616 t.test.expectedLocalError = "received record at initial encryption level, but expected handshake" 13617 } else { 13618 t.test.expectedLocalError = "local error: bad record MAC" 13619 } 13620 } 13621 13622 if t.messageType == typeFinished { 13623 // Bad Finished messages read as the verify data having 13624 // the wrong length. 13625 t.test.expectedError = ":DIGEST_CHECK_FAILED:" 13626 t.test.expectedLocalError = "remote error: error decrypting message" 13627 } 13628 13629 testCases = append(testCases, t.test) 13630 } 13631} 13632 13633func addTLS13HandshakeTests() { 13634 testCases = append(testCases, testCase{ 13635 testType: clientTest, 13636 name: "NegotiatePSKResumption-TLS13", 13637 config: Config{ 13638 MaxVersion: VersionTLS13, 13639 Bugs: ProtocolBugs{ 13640 NegotiatePSKResumption: true, 13641 }, 13642 }, 13643 resumeSession: true, 13644 shouldFail: true, 13645 expectedError: ":MISSING_KEY_SHARE:", 13646 }) 13647 13648 testCases = append(testCases, testCase{ 13649 testType: clientTest, 13650 name: "MissingKeyShare-Client-TLS13", 13651 config: Config{ 13652 MaxVersion: VersionTLS13, 13653 Bugs: ProtocolBugs{ 13654 MissingKeyShare: true, 13655 }, 13656 }, 13657 shouldFail: true, 13658 expectedError: ":MISSING_KEY_SHARE:", 13659 }) 13660 13661 testCases = append(testCases, testCase{ 13662 testType: serverTest, 13663 name: "MissingKeyShare-Server-TLS13", 13664 config: Config{ 13665 MaxVersion: VersionTLS13, 13666 Bugs: ProtocolBugs{ 13667 MissingKeyShare: true, 13668 }, 13669 }, 13670 shouldFail: true, 13671 expectedError: ":MISSING_KEY_SHARE:", 13672 }) 13673 13674 testCases = append(testCases, testCase{ 13675 testType: serverTest, 13676 name: "DuplicateKeyShares-TLS13", 13677 config: Config{ 13678 MaxVersion: VersionTLS13, 13679 Bugs: ProtocolBugs{ 13680 DuplicateKeyShares: true, 13681 }, 13682 }, 13683 shouldFail: true, 13684 expectedError: ":DUPLICATE_KEY_SHARE:", 13685 }) 13686 13687 testCases = append(testCases, testCase{ 13688 testType: serverTest, 13689 name: "SkipEarlyData-TLS13", 13690 config: Config{ 13691 MaxVersion: VersionTLS13, 13692 Bugs: ProtocolBugs{ 13693 SendFakeEarlyDataLength: 4, 13694 }, 13695 }, 13696 }) 13697 13698 // Test that enabling TLS 1.3 does not interfere with TLS 1.2 session ID 13699 // resumption. 13700 testCases = append(testCases, testCase{ 13701 testType: clientTest, 13702 name: "ResumeTLS12SessionID-TLS13", 13703 config: Config{ 13704 MaxVersion: VersionTLS12, 13705 SessionTicketsDisabled: true, 13706 }, 13707 flags: []string{"-max-version", strconv.Itoa(VersionTLS13)}, 13708 resumeSession: true, 13709 }) 13710 13711 // Test that the client correctly handles a TLS 1.3 ServerHello which echoes 13712 // a TLS 1.2 session ID. 13713 testCases = append(testCases, testCase{ 13714 testType: clientTest, 13715 name: "TLS12SessionID-TLS13", 13716 config: Config{ 13717 MaxVersion: VersionTLS12, 13718 SessionTicketsDisabled: true, 13719 }, 13720 resumeConfig: &Config{ 13721 MaxVersion: VersionTLS13, 13722 }, 13723 resumeSession: true, 13724 expectResumeRejected: true, 13725 }) 13726 13727 // Test that the server correctly echoes back session IDs of 13728 // various lengths. The first test additionally asserts that 13729 // BoringSSL always sends the ChangeCipherSpec messages for 13730 // compatibility mode, rather than negotiating it based on the 13731 // ClientHello. 13732 testCases = append(testCases, testCase{ 13733 testType: serverTest, 13734 name: "EmptySessionID-TLS13", 13735 config: Config{ 13736 MaxVersion: VersionTLS13, 13737 Bugs: ProtocolBugs{ 13738 SendClientHelloSessionID: []byte{}, 13739 }, 13740 }, 13741 }) 13742 13743 testCases = append(testCases, testCase{ 13744 testType: serverTest, 13745 name: "Server-ShortSessionID-TLS13", 13746 config: Config{ 13747 MaxVersion: VersionTLS13, 13748 Bugs: ProtocolBugs{ 13749 SendClientHelloSessionID: make([]byte, 16), 13750 }, 13751 }, 13752 }) 13753 13754 testCases = append(testCases, testCase{ 13755 testType: serverTest, 13756 name: "Server-FullSessionID-TLS13", 13757 config: Config{ 13758 MaxVersion: VersionTLS13, 13759 Bugs: ProtocolBugs{ 13760 SendClientHelloSessionID: make([]byte, 32), 13761 }, 13762 }, 13763 }) 13764 13765 // The server should reject ClientHellos whose session IDs are too long. 13766 testCases = append(testCases, testCase{ 13767 testType: serverTest, 13768 name: "Server-TooLongSessionID-TLS13", 13769 config: Config{ 13770 MaxVersion: VersionTLS13, 13771 Bugs: ProtocolBugs{ 13772 SendClientHelloSessionID: make([]byte, 33), 13773 }, 13774 }, 13775 shouldFail: true, 13776 expectedError: ":DECODE_ERROR:", 13777 expectedLocalError: "remote error: error decoding message", 13778 }) 13779 testCases = append(testCases, testCase{ 13780 testType: serverTest, 13781 name: "Server-TooLongSessionID-TLS12", 13782 config: Config{ 13783 MaxVersion: VersionTLS12, 13784 Bugs: ProtocolBugs{ 13785 SendClientHelloSessionID: make([]byte, 33), 13786 }, 13787 }, 13788 shouldFail: true, 13789 expectedError: ":DECODE_ERROR:", 13790 expectedLocalError: "remote error: error decoding message", 13791 }) 13792 13793 // Test that the client correctly accepts or rejects short session IDs from 13794 // the server. Our tests use 32 bytes by default, so the boundary condition 13795 // is already covered. 13796 testCases = append(testCases, testCase{ 13797 name: "Client-ShortSessionID", 13798 config: Config{ 13799 MaxVersion: VersionTLS12, 13800 SessionTicketsDisabled: true, 13801 Bugs: ProtocolBugs{ 13802 NewSessionIDLength: 1, 13803 }, 13804 }, 13805 resumeSession: true, 13806 }) 13807 testCases = append(testCases, testCase{ 13808 name: "Client-TooLongSessionID", 13809 config: Config{ 13810 MaxVersion: VersionTLS12, 13811 SessionTicketsDisabled: true, 13812 Bugs: ProtocolBugs{ 13813 NewSessionIDLength: 33, 13814 }, 13815 }, 13816 shouldFail: true, 13817 expectedError: ":DECODE_ERROR:", 13818 expectedLocalError: "remote error: error decoding message", 13819 }) 13820 13821 // Test that the client sends a fake session ID in TLS 1.3. We cover both 13822 // normal and resumption handshakes to capture interactions with the 13823 // session resumption path. 13824 testCases = append(testCases, testCase{ 13825 testType: clientTest, 13826 name: "TLS13SessionID-TLS13", 13827 config: Config{ 13828 MaxVersion: VersionTLS13, 13829 Bugs: ProtocolBugs{ 13830 ExpectClientHelloSessionID: true, 13831 }, 13832 }, 13833 resumeSession: true, 13834 }) 13835 13836 // Test that the client omits the fake session ID when the max version is TLS 1.2 and below. 13837 testCases = append(testCases, testCase{ 13838 testType: clientTest, 13839 name: "TLS12NoSessionID-TLS13", 13840 config: Config{ 13841 MaxVersion: VersionTLS13, 13842 Bugs: ProtocolBugs{ 13843 ExpectNoSessionID: true, 13844 }, 13845 }, 13846 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 13847 }) 13848 13849 testCases = append(testCases, testCase{ 13850 testType: clientTest, 13851 name: "EarlyData-Client-TLS13", 13852 config: Config{ 13853 MaxVersion: VersionTLS13, 13854 MinVersion: VersionTLS13, 13855 }, 13856 resumeSession: true, 13857 earlyData: true, 13858 flags: []string{ 13859 "-on-initial-expect-early-data-reason", "no_session_offered", 13860 "-on-resume-expect-early-data-reason", "accept", 13861 }, 13862 }) 13863 13864 testCases = append(testCases, testCase{ 13865 testType: clientTest, 13866 name: "EarlyData-Reject-Client-TLS13", 13867 config: Config{ 13868 MaxVersion: VersionTLS13, 13869 }, 13870 resumeConfig: &Config{ 13871 MaxVersion: VersionTLS13, 13872 Bugs: ProtocolBugs{ 13873 AlwaysRejectEarlyData: true, 13874 }, 13875 }, 13876 resumeSession: true, 13877 earlyData: true, 13878 expectEarlyDataRejected: true, 13879 flags: []string{ 13880 "-on-retry-expect-early-data-reason", "peer_declined", 13881 }, 13882 }) 13883 13884 testCases = append(testCases, testCase{ 13885 testType: serverTest, 13886 name: "EarlyData-Server-TLS13", 13887 config: Config{ 13888 MaxVersion: VersionTLS13, 13889 MinVersion: VersionTLS13, 13890 }, 13891 messageCount: 2, 13892 resumeSession: true, 13893 earlyData: true, 13894 flags: []string{ 13895 "-on-initial-expect-early-data-reason", "no_session_offered", 13896 "-on-resume-expect-early-data-reason", "accept", 13897 }, 13898 }) 13899 13900 // The above tests the most recent ticket. Additionally test that 0-RTT 13901 // works on the first ticket issued by the server. 13902 testCases = append(testCases, testCase{ 13903 testType: serverTest, 13904 name: "EarlyData-FirstTicket-Server-TLS13", 13905 config: Config{ 13906 MaxVersion: VersionTLS13, 13907 MinVersion: VersionTLS13, 13908 Bugs: ProtocolBugs{ 13909 UseFirstSessionTicket: true, 13910 }, 13911 }, 13912 messageCount: 2, 13913 resumeSession: true, 13914 earlyData: true, 13915 flags: []string{ 13916 "-on-resume-expect-early-data-reason", "accept", 13917 }, 13918 }) 13919 13920 testCases = append(testCases, testCase{ 13921 testType: serverTest, 13922 name: "SkipEarlyData-OmitEarlyDataExtension-TLS13", 13923 config: Config{ 13924 MaxVersion: VersionTLS13, 13925 Bugs: ProtocolBugs{ 13926 SendFakeEarlyDataLength: 4, 13927 OmitEarlyDataExtension: true, 13928 }, 13929 }, 13930 shouldFail: true, 13931 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 13932 }) 13933 13934 testCases = append(testCases, testCase{ 13935 testType: serverTest, 13936 name: "SkipEarlyData-OmitEarlyDataExtension-HelloRetryRequest-TLS13", 13937 config: Config{ 13938 MaxVersion: VersionTLS13, 13939 // Require a HelloRetryRequest for every curve. 13940 DefaultCurves: []CurveID{}, 13941 Bugs: ProtocolBugs{ 13942 SendFakeEarlyDataLength: 4, 13943 OmitEarlyDataExtension: true, 13944 }, 13945 }, 13946 shouldFail: true, 13947 expectedError: ":UNEXPECTED_RECORD:", 13948 expectedLocalError: "remote error: unexpected message", 13949 }) 13950 13951 testCases = append(testCases, testCase{ 13952 testType: serverTest, 13953 name: "SkipEarlyData-TooMuchData-TLS13", 13954 config: Config{ 13955 MaxVersion: VersionTLS13, 13956 Bugs: ProtocolBugs{ 13957 SendFakeEarlyDataLength: 16384 + 1, 13958 }, 13959 }, 13960 shouldFail: true, 13961 expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:", 13962 }) 13963 13964 testCases = append(testCases, testCase{ 13965 testType: serverTest, 13966 name: "SkipEarlyData-Interleaved-TLS13", 13967 config: Config{ 13968 MaxVersion: VersionTLS13, 13969 Bugs: ProtocolBugs{ 13970 SendFakeEarlyDataLength: 4, 13971 InterleaveEarlyData: true, 13972 }, 13973 }, 13974 shouldFail: true, 13975 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 13976 }) 13977 13978 testCases = append(testCases, testCase{ 13979 testType: serverTest, 13980 name: "SkipEarlyData-EarlyDataInTLS12-TLS13", 13981 config: Config{ 13982 MaxVersion: VersionTLS13, 13983 Bugs: ProtocolBugs{ 13984 SendFakeEarlyDataLength: 4, 13985 }, 13986 }, 13987 shouldFail: true, 13988 expectedError: ":UNEXPECTED_RECORD:", 13989 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 13990 }) 13991 13992 testCases = append(testCases, testCase{ 13993 testType: serverTest, 13994 name: "SkipEarlyData-HRR-TLS13", 13995 config: Config{ 13996 MaxVersion: VersionTLS13, 13997 Bugs: ProtocolBugs{ 13998 SendFakeEarlyDataLength: 4, 13999 }, 14000 DefaultCurves: []CurveID{}, 14001 }, 14002 // Though the session is not resumed and we send HelloRetryRequest, 14003 // early data being disabled takes priority as the reject reason. 14004 flags: []string{"-expect-early-data-reason", "disabled"}, 14005 }) 14006 14007 testCases = append(testCases, testCase{ 14008 testType: serverTest, 14009 name: "SkipEarlyData-HRR-Interleaved-TLS13", 14010 config: Config{ 14011 MaxVersion: VersionTLS13, 14012 Bugs: ProtocolBugs{ 14013 SendFakeEarlyDataLength: 4, 14014 InterleaveEarlyData: true, 14015 }, 14016 DefaultCurves: []CurveID{}, 14017 }, 14018 shouldFail: true, 14019 expectedError: ":UNEXPECTED_RECORD:", 14020 }) 14021 14022 testCases = append(testCases, testCase{ 14023 testType: serverTest, 14024 name: "SkipEarlyData-HRR-TooMuchData-TLS13", 14025 config: Config{ 14026 MaxVersion: VersionTLS13, 14027 Bugs: ProtocolBugs{ 14028 SendFakeEarlyDataLength: 16384 + 1, 14029 }, 14030 DefaultCurves: []CurveID{}, 14031 }, 14032 shouldFail: true, 14033 expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:", 14034 }) 14035 14036 // Test that skipping early data looking for cleartext correctly 14037 // processes an alert record. 14038 testCases = append(testCases, testCase{ 14039 testType: serverTest, 14040 name: "SkipEarlyData-HRR-FatalAlert-TLS13", 14041 config: Config{ 14042 MaxVersion: VersionTLS13, 14043 Bugs: ProtocolBugs{ 14044 SendEarlyAlert: true, 14045 SendFakeEarlyDataLength: 4, 14046 }, 14047 DefaultCurves: []CurveID{}, 14048 }, 14049 shouldFail: true, 14050 expectedError: ":SSLV3_ALERT_HANDSHAKE_FAILURE:", 14051 }) 14052 14053 testCases = append(testCases, testCase{ 14054 testType: serverTest, 14055 name: "SkipEarlyData-SecondClientHelloEarlyData-TLS13", 14056 config: Config{ 14057 MaxVersion: VersionTLS13, 14058 Bugs: ProtocolBugs{ 14059 SendEarlyDataOnSecondClientHello: true, 14060 }, 14061 DefaultCurves: []CurveID{}, 14062 }, 14063 shouldFail: true, 14064 expectedLocalError: "remote error: bad record MAC", 14065 }) 14066 14067 testCases = append(testCases, testCase{ 14068 testType: clientTest, 14069 name: "EmptyEncryptedExtensions-TLS13", 14070 config: Config{ 14071 MaxVersion: VersionTLS13, 14072 Bugs: ProtocolBugs{ 14073 EmptyEncryptedExtensions: true, 14074 }, 14075 }, 14076 shouldFail: true, 14077 expectedLocalError: "remote error: error decoding message", 14078 }) 14079 14080 testCases = append(testCases, testCase{ 14081 testType: clientTest, 14082 name: "EncryptedExtensionsWithKeyShare-TLS13", 14083 config: Config{ 14084 MaxVersion: VersionTLS13, 14085 Bugs: ProtocolBugs{ 14086 EncryptedExtensionsWithKeyShare: true, 14087 }, 14088 }, 14089 shouldFail: true, 14090 expectedLocalError: "remote error: unsupported extension", 14091 }) 14092 14093 testCases = append(testCases, testCase{ 14094 testType: serverTest, 14095 name: "SendHelloRetryRequest-TLS13", 14096 config: Config{ 14097 MaxVersion: VersionTLS13, 14098 // Require a HelloRetryRequest for every curve. 14099 DefaultCurves: []CurveID{}, 14100 CurvePreferences: []CurveID{CurveX25519}, 14101 }, 14102 expectations: connectionExpectations{ 14103 curveID: CurveX25519, 14104 }, 14105 flags: []string{"-expect-hrr"}, 14106 }) 14107 14108 testCases = append(testCases, testCase{ 14109 testType: serverTest, 14110 name: "SendHelloRetryRequest-2-TLS13", 14111 config: Config{ 14112 MaxVersion: VersionTLS13, 14113 DefaultCurves: []CurveID{CurveP384}, 14114 CurvePreferences: []CurveID{CurveX25519, CurveP384}, 14115 }, 14116 // Although the ClientHello did not predict our preferred curve, 14117 // we always select it whether it is predicted or not. 14118 expectations: connectionExpectations{ 14119 curveID: CurveX25519, 14120 }, 14121 flags: []string{"-expect-hrr"}, 14122 }) 14123 14124 testCases = append(testCases, testCase{ 14125 name: "UnknownCurve-HelloRetryRequest-TLS13", 14126 config: Config{ 14127 MaxVersion: VersionTLS13, 14128 // P-384 requires HelloRetryRequest in BoringSSL. 14129 CurvePreferences: []CurveID{CurveP384}, 14130 Bugs: ProtocolBugs{ 14131 SendHelloRetryRequestCurve: bogusCurve, 14132 }, 14133 }, 14134 shouldFail: true, 14135 expectedError: ":WRONG_CURVE:", 14136 }) 14137 14138 testCases = append(testCases, testCase{ 14139 name: "HelloRetryRequest-CipherChange-TLS13", 14140 config: Config{ 14141 MaxVersion: VersionTLS13, 14142 // P-384 requires HelloRetryRequest in BoringSSL. 14143 CurvePreferences: []CurveID{CurveP384}, 14144 Bugs: ProtocolBugs{ 14145 SendCipherSuite: TLS_AES_128_GCM_SHA256, 14146 SendHelloRetryRequestCipherSuite: TLS_CHACHA20_POLY1305_SHA256, 14147 }, 14148 }, 14149 shouldFail: true, 14150 expectedError: ":WRONG_CIPHER_RETURNED:", 14151 }) 14152 14153 // Test that the client does not offer a PSK in the second ClientHello if the 14154 // HelloRetryRequest is incompatible with it. 14155 testCases = append(testCases, testCase{ 14156 testType: clientTest, 14157 name: "HelloRetryRequest-NonResumableCipher-TLS13", 14158 config: Config{ 14159 MaxVersion: VersionTLS13, 14160 CipherSuites: []uint16{ 14161 TLS_AES_128_GCM_SHA256, 14162 }, 14163 }, 14164 resumeConfig: &Config{ 14165 MaxVersion: VersionTLS13, 14166 // P-384 requires HelloRetryRequest in BoringSSL. 14167 CurvePreferences: []CurveID{CurveP384}, 14168 Bugs: ProtocolBugs{ 14169 ExpectNoTLS13PSKAfterHRR: true, 14170 }, 14171 CipherSuites: []uint16{ 14172 TLS_AES_256_GCM_SHA384, 14173 }, 14174 }, 14175 resumeSession: true, 14176 expectResumeRejected: true, 14177 }) 14178 14179 testCases = append(testCases, testCase{ 14180 name: "DisabledCurve-HelloRetryRequest-TLS13", 14181 config: Config{ 14182 MaxVersion: VersionTLS13, 14183 CurvePreferences: []CurveID{CurveP256}, 14184 Bugs: ProtocolBugs{ 14185 IgnorePeerCurvePreferences: true, 14186 }, 14187 }, 14188 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 14189 shouldFail: true, 14190 expectedError: ":WRONG_CURVE:", 14191 }) 14192 14193 testCases = append(testCases, testCase{ 14194 name: "UnnecessaryHelloRetryRequest-TLS13", 14195 config: Config{ 14196 MaxVersion: VersionTLS13, 14197 CurvePreferences: []CurveID{CurveX25519}, 14198 Bugs: ProtocolBugs{ 14199 SendHelloRetryRequestCurve: CurveX25519, 14200 }, 14201 }, 14202 shouldFail: true, 14203 expectedError: ":WRONG_CURVE:", 14204 }) 14205 14206 testCases = append(testCases, testCase{ 14207 name: "SecondHelloRetryRequest-TLS13", 14208 config: Config{ 14209 MaxVersion: VersionTLS13, 14210 // P-384 requires HelloRetryRequest in BoringSSL. 14211 CurvePreferences: []CurveID{CurveP384}, 14212 Bugs: ProtocolBugs{ 14213 SecondHelloRetryRequest: true, 14214 }, 14215 }, 14216 shouldFail: true, 14217 expectedError: ":UNEXPECTED_MESSAGE:", 14218 }) 14219 14220 testCases = append(testCases, testCase{ 14221 name: "HelloRetryRequest-Empty-TLS13", 14222 config: Config{ 14223 MaxVersion: VersionTLS13, 14224 Bugs: ProtocolBugs{ 14225 AlwaysSendHelloRetryRequest: true, 14226 }, 14227 }, 14228 shouldFail: true, 14229 expectedError: ":EMPTY_HELLO_RETRY_REQUEST:", 14230 expectedLocalError: "remote error: illegal parameter", 14231 }) 14232 14233 testCases = append(testCases, testCase{ 14234 name: "HelloRetryRequest-DuplicateCurve-TLS13", 14235 config: Config{ 14236 MaxVersion: VersionTLS13, 14237 // P-384 requires a HelloRetryRequest against BoringSSL's default 14238 // configuration. Assert this ExpectMissingKeyShare. 14239 CurvePreferences: []CurveID{CurveP384}, 14240 Bugs: ProtocolBugs{ 14241 ExpectMissingKeyShare: true, 14242 DuplicateHelloRetryRequestExtensions: true, 14243 }, 14244 }, 14245 shouldFail: true, 14246 expectedError: ":DUPLICATE_EXTENSION:", 14247 expectedLocalError: "remote error: illegal parameter", 14248 }) 14249 14250 testCases = append(testCases, testCase{ 14251 name: "HelloRetryRequest-Cookie-TLS13", 14252 config: Config{ 14253 MaxVersion: VersionTLS13, 14254 Bugs: ProtocolBugs{ 14255 SendHelloRetryRequestCookie: []byte("cookie"), 14256 }, 14257 }, 14258 }) 14259 14260 testCases = append(testCases, testCase{ 14261 name: "HelloRetryRequest-DuplicateCookie-TLS13", 14262 config: Config{ 14263 MaxVersion: VersionTLS13, 14264 Bugs: ProtocolBugs{ 14265 SendHelloRetryRequestCookie: []byte("cookie"), 14266 DuplicateHelloRetryRequestExtensions: true, 14267 }, 14268 }, 14269 shouldFail: true, 14270 expectedError: ":DUPLICATE_EXTENSION:", 14271 expectedLocalError: "remote error: illegal parameter", 14272 }) 14273 14274 testCases = append(testCases, testCase{ 14275 name: "HelloRetryRequest-EmptyCookie-TLS13", 14276 config: Config{ 14277 MaxVersion: VersionTLS13, 14278 Bugs: ProtocolBugs{ 14279 SendHelloRetryRequestCookie: []byte{}, 14280 }, 14281 }, 14282 shouldFail: true, 14283 expectedError: ":DECODE_ERROR:", 14284 }) 14285 14286 testCases = append(testCases, testCase{ 14287 name: "HelloRetryRequest-Cookie-Curve-TLS13", 14288 config: Config{ 14289 MaxVersion: VersionTLS13, 14290 // P-384 requires HelloRetryRequest in BoringSSL. 14291 CurvePreferences: []CurveID{CurveP384}, 14292 Bugs: ProtocolBugs{ 14293 SendHelloRetryRequestCookie: []byte("cookie"), 14294 ExpectMissingKeyShare: true, 14295 }, 14296 }, 14297 }) 14298 14299 testCases = append(testCases, testCase{ 14300 name: "HelloRetryRequest-Unknown-TLS13", 14301 config: Config{ 14302 MaxVersion: VersionTLS13, 14303 Bugs: ProtocolBugs{ 14304 CustomHelloRetryRequestExtension: "extension", 14305 }, 14306 }, 14307 shouldFail: true, 14308 expectedError: ":UNEXPECTED_EXTENSION:", 14309 expectedLocalError: "remote error: unsupported extension", 14310 }) 14311 14312 testCases = append(testCases, testCase{ 14313 testType: serverTest, 14314 name: "SecondClientHelloMissingKeyShare-TLS13", 14315 config: Config{ 14316 MaxVersion: VersionTLS13, 14317 DefaultCurves: []CurveID{}, 14318 Bugs: ProtocolBugs{ 14319 SecondClientHelloMissingKeyShare: true, 14320 }, 14321 }, 14322 shouldFail: true, 14323 expectedError: ":MISSING_KEY_SHARE:", 14324 }) 14325 14326 testCases = append(testCases, testCase{ 14327 testType: serverTest, 14328 name: "SecondClientHelloWrongCurve-TLS13", 14329 config: Config{ 14330 MaxVersion: VersionTLS13, 14331 DefaultCurves: []CurveID{}, 14332 Bugs: ProtocolBugs{ 14333 MisinterpretHelloRetryRequestCurve: CurveP521, 14334 }, 14335 }, 14336 shouldFail: true, 14337 expectedError: ":WRONG_CURVE:", 14338 }) 14339 14340 testCases = append(testCases, testCase{ 14341 name: "HelloRetryRequestVersionMismatch-TLS13", 14342 config: Config{ 14343 MaxVersion: VersionTLS13, 14344 // P-384 requires HelloRetryRequest in BoringSSL. 14345 CurvePreferences: []CurveID{CurveP384}, 14346 Bugs: ProtocolBugs{ 14347 SendServerHelloVersion: 0x0305, 14348 }, 14349 }, 14350 shouldFail: true, 14351 expectedError: ":DECODE_ERROR:", 14352 }) 14353 14354 testCases = append(testCases, testCase{ 14355 name: "HelloRetryRequestCurveMismatch-TLS13", 14356 config: Config{ 14357 MaxVersion: VersionTLS13, 14358 // P-384 requires HelloRetryRequest in BoringSSL. 14359 CurvePreferences: []CurveID{CurveP384}, 14360 Bugs: ProtocolBugs{ 14361 // Send P-384 (correct) in the HelloRetryRequest. 14362 SendHelloRetryRequestCurve: CurveP384, 14363 // But send P-256 in the ServerHello. 14364 SendCurve: CurveP256, 14365 }, 14366 }, 14367 shouldFail: true, 14368 expectedError: ":WRONG_CURVE:", 14369 }) 14370 14371 // Test the server selecting a curve that requires a HelloRetryRequest 14372 // without sending it. 14373 testCases = append(testCases, testCase{ 14374 name: "SkipHelloRetryRequest-TLS13", 14375 config: Config{ 14376 MaxVersion: VersionTLS13, 14377 // P-384 requires HelloRetryRequest in BoringSSL. 14378 CurvePreferences: []CurveID{CurveP384}, 14379 Bugs: ProtocolBugs{ 14380 SkipHelloRetryRequest: true, 14381 }, 14382 }, 14383 shouldFail: true, 14384 expectedError: ":WRONG_CURVE:", 14385 }) 14386 14387 testCases = append(testCases, testCase{ 14388 name: "SecondServerHelloNoVersion-TLS13", 14389 config: Config{ 14390 MaxVersion: VersionTLS13, 14391 // P-384 requires HelloRetryRequest in BoringSSL. 14392 CurvePreferences: []CurveID{CurveP384}, 14393 Bugs: ProtocolBugs{ 14394 OmitServerSupportedVersionExtension: true, 14395 }, 14396 }, 14397 shouldFail: true, 14398 expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:", 14399 }) 14400 testCases = append(testCases, testCase{ 14401 name: "SecondServerHelloWrongVersion-TLS13", 14402 config: Config{ 14403 MaxVersion: VersionTLS13, 14404 // P-384 requires HelloRetryRequest in BoringSSL. 14405 CurvePreferences: []CurveID{CurveP384}, 14406 Bugs: ProtocolBugs{ 14407 SendServerSupportedVersionExtension: 0x1234, 14408 }, 14409 }, 14410 shouldFail: true, 14411 expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:", 14412 }) 14413 14414 testCases = append(testCases, testCase{ 14415 name: "RequestContextInHandshake-TLS13", 14416 config: Config{ 14417 MaxVersion: VersionTLS13, 14418 MinVersion: VersionTLS13, 14419 ClientAuth: RequireAnyClientCert, 14420 Bugs: ProtocolBugs{ 14421 SendRequestContext: []byte("request context"), 14422 }, 14423 }, 14424 shimCertificate: &rsaCertificate, 14425 shouldFail: true, 14426 expectedError: ":DECODE_ERROR:", 14427 }) 14428 14429 testCases = append(testCases, testCase{ 14430 name: "UnknownExtensionInCertificateRequest-TLS13", 14431 config: Config{ 14432 MaxVersion: VersionTLS13, 14433 MinVersion: VersionTLS13, 14434 ClientAuth: RequireAnyClientCert, 14435 Bugs: ProtocolBugs{ 14436 SendCustomCertificateRequest: 0x1212, 14437 }, 14438 }, 14439 shimCertificate: &rsaCertificate, 14440 }) 14441 14442 testCases = append(testCases, testCase{ 14443 name: "MissingSignatureAlgorithmsInCertificateRequest-TLS13", 14444 config: Config{ 14445 MaxVersion: VersionTLS13, 14446 MinVersion: VersionTLS13, 14447 ClientAuth: RequireAnyClientCert, 14448 Bugs: ProtocolBugs{ 14449 OmitCertificateRequestAlgorithms: true, 14450 }, 14451 }, 14452 shimCertificate: &rsaCertificate, 14453 shouldFail: true, 14454 expectedError: ":DECODE_ERROR:", 14455 }) 14456 14457 testCases = append(testCases, testCase{ 14458 testType: serverTest, 14459 name: "TrailingKeyShareData-TLS13", 14460 config: Config{ 14461 MaxVersion: VersionTLS13, 14462 Bugs: ProtocolBugs{ 14463 TrailingKeyShareData: true, 14464 }, 14465 }, 14466 shouldFail: true, 14467 expectedError: ":DECODE_ERROR:", 14468 }) 14469 14470 testCases = append(testCases, testCase{ 14471 name: "AlwaysSelectPSKIdentity-TLS13", 14472 config: Config{ 14473 MaxVersion: VersionTLS13, 14474 Bugs: ProtocolBugs{ 14475 AlwaysSelectPSKIdentity: true, 14476 }, 14477 }, 14478 shouldFail: true, 14479 expectedError: ":UNEXPECTED_EXTENSION:", 14480 }) 14481 14482 testCases = append(testCases, testCase{ 14483 name: "InvalidPSKIdentity-TLS13", 14484 config: Config{ 14485 MaxVersion: VersionTLS13, 14486 Bugs: ProtocolBugs{ 14487 SelectPSKIdentityOnResume: 1, 14488 }, 14489 }, 14490 resumeSession: true, 14491 shouldFail: true, 14492 expectedError: ":PSK_IDENTITY_NOT_FOUND:", 14493 }) 14494 14495 testCases = append(testCases, testCase{ 14496 testType: serverTest, 14497 name: "ExtraPSKIdentity-TLS13", 14498 config: Config{ 14499 MaxVersion: VersionTLS13, 14500 Bugs: ProtocolBugs{ 14501 ExtraPSKIdentity: true, 14502 SendExtraPSKBinder: true, 14503 }, 14504 }, 14505 resumeSession: true, 14506 }) 14507 14508 // Test that unknown NewSessionTicket extensions are tolerated. 14509 testCases = append(testCases, testCase{ 14510 name: "CustomTicketExtension-TLS13", 14511 config: Config{ 14512 MaxVersion: VersionTLS13, 14513 Bugs: ProtocolBugs{ 14514 CustomTicketExtension: "1234", 14515 }, 14516 }, 14517 }) 14518 14519 // Test the client handles 0-RTT being rejected by a full handshake 14520 // and correctly reports a certificate change. 14521 testCases = append(testCases, testCase{ 14522 testType: clientTest, 14523 name: "EarlyData-RejectTicket-Client-TLS13", 14524 config: Config{ 14525 MaxVersion: VersionTLS13, 14526 Credential: &rsaCertificate, 14527 }, 14528 resumeConfig: &Config{ 14529 MaxVersion: VersionTLS13, 14530 Credential: &ecdsaP256Certificate, 14531 SessionTicketsDisabled: true, 14532 }, 14533 resumeSession: true, 14534 expectResumeRejected: true, 14535 earlyData: true, 14536 expectEarlyDataRejected: true, 14537 flags: []string{ 14538 "-on-retry-expect-early-data-reason", "session_not_resumed", 14539 // Test the peer certificate is reported correctly in each of the 14540 // three logical connections. 14541 "-on-initial-expect-peer-cert-file", rsaCertificate.ChainPath, 14542 "-on-resume-expect-peer-cert-file", rsaCertificate.ChainPath, 14543 "-on-retry-expect-peer-cert-file", ecdsaP256Certificate.ChainPath, 14544 // Session tickets are disabled, so the runner will not send a ticket. 14545 "-on-retry-expect-no-session", 14546 }, 14547 }) 14548 14549 // Test the server rejects 0-RTT if it does not recognize the ticket. 14550 testCases = append(testCases, testCase{ 14551 testType: serverTest, 14552 name: "EarlyData-RejectTicket-Server-TLS13", 14553 config: Config{ 14554 MaxVersion: VersionTLS13, 14555 MinVersion: VersionTLS13, 14556 Bugs: ProtocolBugs{ 14557 // Corrupt the ticket. 14558 FilterTicket: func(in []byte) ([]byte, error) { 14559 in[len(in)-1] ^= 1 14560 return in, nil 14561 }, 14562 }, 14563 }, 14564 messageCount: 2, 14565 resumeSession: true, 14566 expectResumeRejected: true, 14567 earlyData: true, 14568 expectEarlyDataRejected: true, 14569 flags: []string{ 14570 "-on-resume-expect-early-data-reason", "session_not_resumed", 14571 }, 14572 }) 14573 14574 // Test the client handles 0-RTT being rejected via a HelloRetryRequest. 14575 testCases = append(testCases, testCase{ 14576 testType: clientTest, 14577 name: "EarlyData-HRR-Client-TLS13", 14578 config: Config{ 14579 MaxVersion: VersionTLS13, 14580 }, 14581 resumeConfig: &Config{ 14582 MaxVersion: VersionTLS13, 14583 Bugs: ProtocolBugs{ 14584 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14585 }, 14586 }, 14587 resumeSession: true, 14588 earlyData: true, 14589 expectEarlyDataRejected: true, 14590 flags: []string{ 14591 "-on-retry-expect-early-data-reason", "hello_retry_request", 14592 }, 14593 }) 14594 14595 // Test the server rejects 0-RTT if it needs to send a HelloRetryRequest. 14596 testCases = append(testCases, testCase{ 14597 testType: serverTest, 14598 name: "EarlyData-HRR-Server-TLS13", 14599 config: Config{ 14600 MaxVersion: VersionTLS13, 14601 MinVersion: VersionTLS13, 14602 // Require a HelloRetryRequest for every curve. 14603 DefaultCurves: []CurveID{}, 14604 }, 14605 messageCount: 2, 14606 resumeSession: true, 14607 earlyData: true, 14608 expectEarlyDataRejected: true, 14609 flags: []string{ 14610 "-on-resume-expect-early-data-reason", "hello_retry_request", 14611 }, 14612 }) 14613 14614 // Test the client handles a 0-RTT reject from both ticket rejection and 14615 // HelloRetryRequest. 14616 testCases = append(testCases, testCase{ 14617 testType: clientTest, 14618 name: "EarlyData-HRR-RejectTicket-Client-TLS13", 14619 config: Config{ 14620 MaxVersion: VersionTLS13, 14621 Credential: &rsaCertificate, 14622 }, 14623 resumeConfig: &Config{ 14624 MaxVersion: VersionTLS13, 14625 Credential: &ecdsaP256Certificate, 14626 SessionTicketsDisabled: true, 14627 Bugs: ProtocolBugs{ 14628 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14629 }, 14630 }, 14631 resumeSession: true, 14632 expectResumeRejected: true, 14633 earlyData: true, 14634 expectEarlyDataRejected: true, 14635 flags: []string{ 14636 // The client sees HelloRetryRequest before the resumption result, 14637 // though neither value is inherently preferable. 14638 "-on-retry-expect-early-data-reason", "hello_retry_request", 14639 // Test the peer certificate is reported correctly in each of the 14640 // three logical connections. 14641 "-on-initial-expect-peer-cert-file", rsaCertificate.ChainPath, 14642 "-on-resume-expect-peer-cert-file", rsaCertificate.ChainPath, 14643 "-on-retry-expect-peer-cert-file", ecdsaP256Certificate.ChainPath, 14644 // Session tickets are disabled, so the runner will not send a ticket. 14645 "-on-retry-expect-no-session", 14646 }, 14647 }) 14648 14649 // Test the server rejects 0-RTT if it needs to send a HelloRetryRequest. 14650 testCases = append(testCases, testCase{ 14651 testType: serverTest, 14652 name: "EarlyData-HRR-RejectTicket-Server-TLS13", 14653 config: Config{ 14654 MaxVersion: VersionTLS13, 14655 MinVersion: VersionTLS13, 14656 // Require a HelloRetryRequest for every curve. 14657 DefaultCurves: []CurveID{}, 14658 Bugs: ProtocolBugs{ 14659 // Corrupt the ticket. 14660 FilterTicket: func(in []byte) ([]byte, error) { 14661 in[len(in)-1] ^= 1 14662 return in, nil 14663 }, 14664 }, 14665 }, 14666 messageCount: 2, 14667 resumeSession: true, 14668 expectResumeRejected: true, 14669 earlyData: true, 14670 expectEarlyDataRejected: true, 14671 flags: []string{ 14672 // The server sees the missed resumption before HelloRetryRequest, 14673 // though neither value is inherently preferable. 14674 "-on-resume-expect-early-data-reason", "session_not_resumed", 14675 }, 14676 }) 14677 14678 // The client must check the server does not send the early_data 14679 // extension while rejecting the session. 14680 testCases = append(testCases, testCase{ 14681 testType: clientTest, 14682 name: "EarlyDataWithoutResume-Client-TLS13", 14683 config: Config{ 14684 MaxVersion: VersionTLS13, 14685 MaxEarlyDataSize: 16384, 14686 }, 14687 resumeConfig: &Config{ 14688 MaxVersion: VersionTLS13, 14689 SessionTicketsDisabled: true, 14690 Bugs: ProtocolBugs{ 14691 SendEarlyDataExtension: true, 14692 }, 14693 }, 14694 resumeSession: true, 14695 earlyData: true, 14696 shouldFail: true, 14697 expectedError: ":UNEXPECTED_EXTENSION:", 14698 }) 14699 14700 // The client must fail with a dedicated error code if the server 14701 // responds with TLS 1.2 when offering 0-RTT. 14702 testCases = append(testCases, testCase{ 14703 testType: clientTest, 14704 name: "EarlyDataVersionDowngrade-Client-TLS13", 14705 config: Config{ 14706 MaxVersion: VersionTLS13, 14707 }, 14708 resumeConfig: &Config{ 14709 MaxVersion: VersionTLS12, 14710 }, 14711 resumeSession: true, 14712 earlyData: true, 14713 shouldFail: true, 14714 expectedError: ":WRONG_VERSION_ON_EARLY_DATA:", 14715 }) 14716 14717 // Test that the client rejects an (unsolicited) early_data extension if 14718 // the server sent an HRR. 14719 testCases = append(testCases, testCase{ 14720 testType: clientTest, 14721 name: "ServerAcceptsEarlyDataOnHRR-Client-TLS13", 14722 config: Config{ 14723 MaxVersion: VersionTLS13, 14724 }, 14725 resumeConfig: &Config{ 14726 MaxVersion: VersionTLS13, 14727 Bugs: ProtocolBugs{ 14728 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14729 SendEarlyDataExtension: true, 14730 }, 14731 }, 14732 resumeSession: true, 14733 earlyData: true, 14734 // The client will first process an early data reject from the HRR. 14735 expectEarlyDataRejected: true, 14736 shouldFail: true, 14737 expectedError: ":UNEXPECTED_EXTENSION:", 14738 }) 14739 14740 testCases = append(testCases, testCase{ 14741 testType: clientTest, 14742 name: "SkipChangeCipherSpec-Client-TLS13", 14743 config: Config{ 14744 MaxVersion: VersionTLS13, 14745 Bugs: ProtocolBugs{ 14746 SkipChangeCipherSpec: true, 14747 }, 14748 }, 14749 }) 14750 14751 testCases = append(testCases, testCase{ 14752 testType: serverTest, 14753 name: "SkipChangeCipherSpec-Server-TLS13", 14754 config: Config{ 14755 MaxVersion: VersionTLS13, 14756 Bugs: ProtocolBugs{ 14757 SkipChangeCipherSpec: true, 14758 }, 14759 }, 14760 }) 14761 14762 testCases = append(testCases, testCase{ 14763 testType: clientTest, 14764 name: "TooManyChangeCipherSpec-Client-TLS13", 14765 config: Config{ 14766 MaxVersion: VersionTLS13, 14767 Bugs: ProtocolBugs{ 14768 SendExtraChangeCipherSpec: 33, 14769 }, 14770 }, 14771 shouldFail: true, 14772 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 14773 }) 14774 14775 testCases = append(testCases, testCase{ 14776 testType: serverTest, 14777 name: "TooManyChangeCipherSpec-Server-TLS13", 14778 config: Config{ 14779 MaxVersion: VersionTLS13, 14780 Bugs: ProtocolBugs{ 14781 SendExtraChangeCipherSpec: 33, 14782 }, 14783 }, 14784 shouldFail: true, 14785 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 14786 }) 14787 14788 testCases = append(testCases, testCase{ 14789 name: "SendPostHandshakeChangeCipherSpec-TLS13", 14790 config: Config{ 14791 MaxVersion: VersionTLS13, 14792 Bugs: ProtocolBugs{ 14793 SendPostHandshakeChangeCipherSpec: true, 14794 }, 14795 }, 14796 shouldFail: true, 14797 expectedError: ":UNEXPECTED_RECORD:", 14798 expectedLocalError: "remote error: unexpected message", 14799 }) 14800 14801 fooString := "foo" 14802 barString := "bar" 14803 14804 // Test that the client reports the correct ALPN after a 0-RTT reject 14805 // that changed it. 14806 testCases = append(testCases, testCase{ 14807 testType: clientTest, 14808 name: "EarlyData-ALPNMismatch-Client-TLS13", 14809 config: Config{ 14810 MaxVersion: VersionTLS13, 14811 Bugs: ProtocolBugs{ 14812 ALPNProtocol: &fooString, 14813 }, 14814 }, 14815 resumeConfig: &Config{ 14816 MaxVersion: VersionTLS13, 14817 Bugs: ProtocolBugs{ 14818 ALPNProtocol: &barString, 14819 }, 14820 }, 14821 resumeSession: true, 14822 earlyData: true, 14823 expectEarlyDataRejected: true, 14824 flags: []string{ 14825 "-advertise-alpn", "\x03foo\x03bar", 14826 // The client does not learn ALPN was the cause. 14827 "-on-retry-expect-early-data-reason", "peer_declined", 14828 // In the 0-RTT state, we surface the predicted ALPN. After 14829 // processing the reject, we surface the real one. 14830 "-on-initial-expect-alpn", "foo", 14831 "-on-resume-expect-alpn", "foo", 14832 "-on-retry-expect-alpn", "bar", 14833 }, 14834 }) 14835 14836 // Test that the client reports the correct ALPN after a 0-RTT reject if 14837 // ALPN was omitted from the first connection. 14838 testCases = append(testCases, testCase{ 14839 testType: clientTest, 14840 name: "EarlyData-ALPNOmitted1-Client-TLS13", 14841 config: Config{ 14842 MaxVersion: VersionTLS13, 14843 }, 14844 resumeConfig: &Config{ 14845 MaxVersion: VersionTLS13, 14846 NextProtos: []string{"foo"}, 14847 }, 14848 resumeSession: true, 14849 earlyData: true, 14850 expectEarlyDataRejected: true, 14851 flags: []string{ 14852 "-advertise-alpn", "\x03foo\x03bar", 14853 // The client does not learn ALPN was the cause. 14854 "-on-retry-expect-early-data-reason", "peer_declined", 14855 // In the 0-RTT state, we surface the predicted ALPN. After 14856 // processing the reject, we surface the real one. 14857 "-on-initial-expect-alpn", "", 14858 "-on-resume-expect-alpn", "", 14859 "-on-retry-expect-alpn", "foo", 14860 }, 14861 }) 14862 14863 // Test that the client reports the correct ALPN after a 0-RTT reject if 14864 // ALPN was omitted from the second connection. 14865 testCases = append(testCases, testCase{ 14866 testType: clientTest, 14867 name: "EarlyData-ALPNOmitted2-Client-TLS13", 14868 config: Config{ 14869 MaxVersion: VersionTLS13, 14870 NextProtos: []string{"foo"}, 14871 }, 14872 resumeConfig: &Config{ 14873 MaxVersion: VersionTLS13, 14874 }, 14875 resumeSession: true, 14876 earlyData: true, 14877 expectEarlyDataRejected: true, 14878 flags: []string{ 14879 "-advertise-alpn", "\x03foo\x03bar", 14880 // The client does not learn ALPN was the cause. 14881 "-on-retry-expect-early-data-reason", "peer_declined", 14882 // In the 0-RTT state, we surface the predicted ALPN. After 14883 // processing the reject, we surface the real one. 14884 "-on-initial-expect-alpn", "foo", 14885 "-on-resume-expect-alpn", "foo", 14886 "-on-retry-expect-alpn", "", 14887 }, 14888 }) 14889 14890 // Test that the client enforces ALPN match on 0-RTT accept. 14891 testCases = append(testCases, testCase{ 14892 testType: clientTest, 14893 name: "EarlyData-BadALPNMismatch-Client-TLS13", 14894 config: Config{ 14895 MaxVersion: VersionTLS13, 14896 Bugs: ProtocolBugs{ 14897 ALPNProtocol: &fooString, 14898 }, 14899 }, 14900 resumeConfig: &Config{ 14901 MaxVersion: VersionTLS13, 14902 Bugs: ProtocolBugs{ 14903 AlwaysAcceptEarlyData: true, 14904 ALPNProtocol: &barString, 14905 }, 14906 }, 14907 resumeSession: true, 14908 earlyData: true, 14909 flags: []string{ 14910 "-advertise-alpn", "\x03foo\x03bar", 14911 "-on-initial-expect-alpn", "foo", 14912 "-on-resume-expect-alpn", "foo", 14913 "-on-retry-expect-alpn", "bar", 14914 }, 14915 shouldFail: true, 14916 expectedError: ":ALPN_MISMATCH_ON_EARLY_DATA:", 14917 expectedLocalError: "remote error: illegal parameter", 14918 }) 14919 14920 // Test that the client does not offer early data if it is incompatible 14921 // with ALPN preferences. 14922 testCases = append(testCases, testCase{ 14923 testType: clientTest, 14924 name: "EarlyData-ALPNPreferenceChanged-TLS13", 14925 config: Config{ 14926 MaxVersion: VersionTLS13, 14927 MaxEarlyDataSize: 16384, 14928 NextProtos: []string{"foo", "bar"}, 14929 }, 14930 resumeSession: true, 14931 flags: []string{ 14932 "-enable-early-data", 14933 "-expect-ticket-supports-early-data", 14934 "-expect-no-offer-early-data", 14935 // Offer different ALPN values in the initial and resumption. 14936 "-on-initial-advertise-alpn", "\x03foo", 14937 "-on-initial-expect-alpn", "foo", 14938 "-on-resume-advertise-alpn", "\x03bar", 14939 "-on-resume-expect-alpn", "bar", 14940 // The ALPN mismatch comes from the client, so it reports it as the 14941 // reason. 14942 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14943 }, 14944 }) 14945 14946 // Test that the client does not offer 0-RTT to servers which never 14947 // advertise it. 14948 testCases = append(testCases, testCase{ 14949 testType: clientTest, 14950 name: "EarlyData-NonZeroRTTSession-Client-TLS13", 14951 config: Config{ 14952 MaxVersion: VersionTLS13, 14953 }, 14954 resumeSession: true, 14955 flags: []string{ 14956 "-enable-early-data", 14957 "-on-resume-expect-no-offer-early-data", 14958 // The client declines to offer 0-RTT because of the session. 14959 "-on-resume-expect-early-data-reason", "unsupported_for_session", 14960 }, 14961 }) 14962 14963 // Test that the server correctly rejects 0-RTT when the previous 14964 // session did not allow early data on resumption. 14965 testCases = append(testCases, testCase{ 14966 testType: serverTest, 14967 name: "EarlyData-NonZeroRTTSession-Server-TLS13", 14968 config: Config{ 14969 MaxVersion: VersionTLS13, 14970 }, 14971 resumeConfig: &Config{ 14972 MaxVersion: VersionTLS13, 14973 Bugs: ProtocolBugs{ 14974 SendEarlyData: [][]byte{{1, 2, 3, 4}}, 14975 ExpectEarlyDataAccepted: false, 14976 }, 14977 }, 14978 resumeSession: true, 14979 // This test configures early data manually instead of the earlyData 14980 // option, to customize the -enable-early-data flag. 14981 flags: []string{ 14982 "-on-resume-enable-early-data", 14983 "-expect-reject-early-data", 14984 // The server rejects 0-RTT because of the session. 14985 "-on-resume-expect-early-data-reason", "unsupported_for_session", 14986 }, 14987 }) 14988 14989 // Test that we reject early data where ALPN is omitted from the first 14990 // connection, but negotiated in the second. 14991 testCases = append(testCases, testCase{ 14992 testType: serverTest, 14993 name: "EarlyData-ALPNOmitted1-Server-TLS13", 14994 config: Config{ 14995 MaxVersion: VersionTLS13, 14996 NextProtos: []string{}, 14997 }, 14998 resumeConfig: &Config{ 14999 MaxVersion: VersionTLS13, 15000 NextProtos: []string{"foo"}, 15001 }, 15002 resumeSession: true, 15003 earlyData: true, 15004 expectEarlyDataRejected: true, 15005 flags: []string{ 15006 "-on-initial-select-alpn", "", 15007 "-on-resume-select-alpn", "foo", 15008 "-on-resume-expect-early-data-reason", "alpn_mismatch", 15009 }, 15010 }) 15011 15012 // Test that we reject early data where ALPN is omitted from the second 15013 // connection, but negotiated in the first. 15014 testCases = append(testCases, testCase{ 15015 testType: serverTest, 15016 name: "EarlyData-ALPNOmitted2-Server-TLS13", 15017 config: Config{ 15018 MaxVersion: VersionTLS13, 15019 NextProtos: []string{"foo"}, 15020 }, 15021 resumeConfig: &Config{ 15022 MaxVersion: VersionTLS13, 15023 NextProtos: []string{}, 15024 }, 15025 resumeSession: true, 15026 earlyData: true, 15027 expectEarlyDataRejected: true, 15028 flags: []string{ 15029 "-on-initial-select-alpn", "foo", 15030 "-on-resume-select-alpn", "", 15031 "-on-resume-expect-early-data-reason", "alpn_mismatch", 15032 }, 15033 }) 15034 15035 // Test that we reject early data with mismatched ALPN. 15036 testCases = append(testCases, testCase{ 15037 testType: serverTest, 15038 name: "EarlyData-ALPNMismatch-Server-TLS13", 15039 config: Config{ 15040 MaxVersion: VersionTLS13, 15041 NextProtos: []string{"foo"}, 15042 }, 15043 resumeConfig: &Config{ 15044 MaxVersion: VersionTLS13, 15045 NextProtos: []string{"bar"}, 15046 }, 15047 resumeSession: true, 15048 earlyData: true, 15049 expectEarlyDataRejected: true, 15050 flags: []string{ 15051 "-on-initial-select-alpn", "foo", 15052 "-on-resume-select-alpn", "bar", 15053 "-on-resume-expect-early-data-reason", "alpn_mismatch", 15054 }, 15055 }) 15056 15057 // Test that the client offering 0-RTT and Channel ID forbids the server 15058 // from accepting both. 15059 testCases = append(testCases, testCase{ 15060 testType: clientTest, 15061 name: "EarlyDataChannelID-AcceptBoth-Client-TLS13", 15062 config: Config{ 15063 MaxVersion: VersionTLS13, 15064 RequestChannelID: true, 15065 }, 15066 resumeSession: true, 15067 earlyData: true, 15068 expectations: connectionExpectations{ 15069 channelID: true, 15070 }, 15071 shouldFail: true, 15072 expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:", 15073 expectedLocalError: "remote error: illegal parameter", 15074 flags: []string{ 15075 "-send-channel-id", channelIDKeyPath, 15076 }, 15077 }) 15078 15079 // Test that the client offering Channel ID and 0-RTT allows the server 15080 // to decline 0-RTT. 15081 testCases = append(testCases, testCase{ 15082 testType: clientTest, 15083 name: "EarlyDataChannelID-AcceptChannelID-Client-TLS13", 15084 config: Config{ 15085 MaxVersion: VersionTLS13, 15086 RequestChannelID: true, 15087 Bugs: ProtocolBugs{ 15088 AlwaysRejectEarlyData: true, 15089 }, 15090 }, 15091 resumeSession: true, 15092 earlyData: true, 15093 expectEarlyDataRejected: true, 15094 expectations: connectionExpectations{ 15095 channelID: true, 15096 }, 15097 flags: []string{ 15098 "-send-channel-id", channelIDKeyPath, 15099 // The client never learns the reason was Channel ID. 15100 "-on-retry-expect-early-data-reason", "peer_declined", 15101 }, 15102 }) 15103 15104 // Test that the client offering Channel ID and 0-RTT allows the server 15105 // to decline Channel ID. 15106 testCases = append(testCases, testCase{ 15107 testType: clientTest, 15108 name: "EarlyDataChannelID-AcceptEarlyData-Client-TLS13", 15109 config: Config{ 15110 MaxVersion: VersionTLS13, 15111 }, 15112 resumeSession: true, 15113 earlyData: true, 15114 flags: []string{ 15115 "-send-channel-id", channelIDKeyPath, 15116 }, 15117 }) 15118 15119 // Test that the server supporting Channel ID and 0-RTT declines 0-RTT 15120 // if it would negotiate Channel ID. 15121 testCases = append(testCases, testCase{ 15122 testType: serverTest, 15123 name: "EarlyDataChannelID-OfferBoth-Server-TLS13", 15124 config: Config{ 15125 MaxVersion: VersionTLS13, 15126 ChannelID: &channelIDKey, 15127 }, 15128 resumeSession: true, 15129 earlyData: true, 15130 expectEarlyDataRejected: true, 15131 expectations: connectionExpectations{ 15132 channelID: true, 15133 }, 15134 flags: []string{ 15135 "-expect-channel-id", 15136 base64FlagValue(channelIDBytes), 15137 "-on-resume-expect-early-data-reason", "channel_id", 15138 }, 15139 }) 15140 15141 // Test that the server supporting Channel ID and 0-RTT accepts 0-RTT 15142 // if not offered Channel ID. 15143 testCases = append(testCases, testCase{ 15144 testType: serverTest, 15145 name: "EarlyDataChannelID-OfferEarlyData-Server-TLS13", 15146 config: Config{ 15147 MaxVersion: VersionTLS13, 15148 }, 15149 resumeSession: true, 15150 earlyData: true, 15151 expectations: connectionExpectations{ 15152 channelID: false, 15153 }, 15154 flags: []string{ 15155 "-enable-channel-id", 15156 "-on-resume-expect-early-data-reason", "accept", 15157 }, 15158 }) 15159 15160 // Test that the server errors on 0-RTT streams without end_of_early_data. 15161 // The subsequent records should fail to decrypt. 15162 testCases = append(testCases, testCase{ 15163 testType: serverTest, 15164 name: "EarlyData-SkipEndOfEarlyData-TLS13", 15165 config: Config{ 15166 MaxVersion: VersionTLS13, 15167 Bugs: ProtocolBugs{ 15168 SkipEndOfEarlyData: true, 15169 }, 15170 }, 15171 resumeSession: true, 15172 earlyData: true, 15173 shouldFail: true, 15174 expectedLocalError: "remote error: bad record MAC", 15175 expectedError: ":BAD_DECRYPT:", 15176 }) 15177 15178 // Test that the server errors on 0-RTT streams with a stray handshake 15179 // message in them. 15180 testCases = append(testCases, testCase{ 15181 testType: serverTest, 15182 name: "EarlyData-UnexpectedHandshake-Server-TLS13", 15183 config: Config{ 15184 MaxVersion: VersionTLS13, 15185 }, 15186 resumeConfig: &Config{ 15187 MaxVersion: VersionTLS13, 15188 Bugs: ProtocolBugs{ 15189 SendStrayEarlyHandshake: true, 15190 }, 15191 }, 15192 resumeSession: true, 15193 earlyData: true, 15194 shouldFail: true, 15195 expectedError: ":UNEXPECTED_MESSAGE:", 15196 expectedLocalError: "remote error: unexpected message", 15197 }) 15198 15199 // Test that the client reports TLS 1.3 as the version while sending 15200 // early data. 15201 testCases = append(testCases, testCase{ 15202 testType: clientTest, 15203 name: "EarlyData-Client-VersionAPI-TLS13", 15204 config: Config{ 15205 MaxVersion: VersionTLS13, 15206 }, 15207 resumeSession: true, 15208 earlyData: true, 15209 flags: []string{ 15210 "-expect-version", strconv.Itoa(VersionTLS13), 15211 }, 15212 }) 15213 15214 // Test that client and server both notice handshake errors after data 15215 // has started flowing. 15216 testCases = append(testCases, testCase{ 15217 testType: clientTest, 15218 name: "EarlyData-Client-BadFinished-TLS13", 15219 config: Config{ 15220 MaxVersion: VersionTLS13, 15221 }, 15222 resumeConfig: &Config{ 15223 MaxVersion: VersionTLS13, 15224 Bugs: ProtocolBugs{ 15225 BadFinished: true, 15226 }, 15227 }, 15228 resumeSession: true, 15229 earlyData: true, 15230 shouldFail: true, 15231 expectedError: ":DIGEST_CHECK_FAILED:", 15232 expectedLocalError: "remote error: error decrypting message", 15233 }) 15234 testCases = append(testCases, testCase{ 15235 testType: serverTest, 15236 name: "EarlyData-Server-BadFinished-TLS13", 15237 config: Config{ 15238 MaxVersion: VersionTLS13, 15239 }, 15240 resumeConfig: &Config{ 15241 MaxVersion: VersionTLS13, 15242 Bugs: ProtocolBugs{ 15243 BadFinished: true, 15244 }, 15245 }, 15246 resumeSession: true, 15247 earlyData: true, 15248 shouldFail: true, 15249 expectedError: ":DIGEST_CHECK_FAILED:", 15250 expectedLocalError: "remote error: error decrypting message", 15251 }) 15252 15253 testCases = append(testCases, testCase{ 15254 testType: serverTest, 15255 name: "Server-NonEmptyEndOfEarlyData-TLS13", 15256 config: Config{ 15257 MaxVersion: VersionTLS13, 15258 }, 15259 resumeConfig: &Config{ 15260 MaxVersion: VersionTLS13, 15261 Bugs: ProtocolBugs{ 15262 NonEmptyEndOfEarlyData: true, 15263 }, 15264 }, 15265 resumeSession: true, 15266 earlyData: true, 15267 shouldFail: true, 15268 expectedError: ":DECODE_ERROR:", 15269 }) 15270 15271 testCases = append(testCases, testCase{ 15272 testType: serverTest, 15273 name: "ServerSkipCertificateVerify-TLS13", 15274 config: Config{ 15275 MinVersion: VersionTLS13, 15276 MaxVersion: VersionTLS13, 15277 Credential: &rsaChainCertificate, 15278 Bugs: ProtocolBugs{ 15279 SkipCertificateVerify: true, 15280 }, 15281 }, 15282 expectations: connectionExpectations{ 15283 peerCertificate: &rsaCertificate, 15284 }, 15285 shimCertificate: &rsaCertificate, 15286 flags: []string{ 15287 "-require-any-client-certificate", 15288 }, 15289 shouldFail: true, 15290 expectedError: ":UNEXPECTED_MESSAGE:", 15291 expectedLocalError: "remote error: unexpected message", 15292 }) 15293 testCases = append(testCases, testCase{ 15294 testType: clientTest, 15295 name: "ClientSkipCertificateVerify-TLS13", 15296 config: Config{ 15297 MinVersion: VersionTLS13, 15298 MaxVersion: VersionTLS13, 15299 Credential: &rsaChainCertificate, 15300 Bugs: ProtocolBugs{ 15301 SkipCertificateVerify: true, 15302 }, 15303 }, 15304 expectations: connectionExpectations{ 15305 peerCertificate: &rsaCertificate, 15306 }, 15307 shimCertificate: &rsaCertificate, 15308 shouldFail: true, 15309 expectedError: ":UNEXPECTED_MESSAGE:", 15310 expectedLocalError: "remote error: unexpected message", 15311 }) 15312 15313 // If the client or server has 0-RTT enabled but disabled TLS 1.3, it should 15314 // report a reason of protocol_version. 15315 testCases = append(testCases, testCase{ 15316 testType: clientTest, 15317 name: "EarlyDataEnabled-Client-MaxTLS12", 15318 expectations: connectionExpectations{ 15319 version: VersionTLS12, 15320 }, 15321 flags: []string{ 15322 "-enable-early-data", 15323 "-max-version", strconv.Itoa(VersionTLS12), 15324 "-expect-early-data-reason", "protocol_version", 15325 }, 15326 }) 15327 testCases = append(testCases, testCase{ 15328 testType: serverTest, 15329 name: "EarlyDataEnabled-Server-MaxTLS12", 15330 expectations: connectionExpectations{ 15331 version: VersionTLS12, 15332 }, 15333 flags: []string{ 15334 "-enable-early-data", 15335 "-max-version", strconv.Itoa(VersionTLS12), 15336 "-expect-early-data-reason", "protocol_version", 15337 }, 15338 }) 15339 15340 // The server additionally reports protocol_version if it enabled TLS 1.3, 15341 // but the peer negotiated TLS 1.2. (The corresponding situation does not 15342 // exist on the client because negotiating TLS 1.2 with a 0-RTT ClientHello 15343 // is a fatal error.) 15344 testCases = append(testCases, testCase{ 15345 testType: serverTest, 15346 name: "EarlyDataEnabled-Server-NegotiateTLS12", 15347 config: Config{ 15348 MaxVersion: VersionTLS12, 15349 }, 15350 expectations: connectionExpectations{ 15351 version: VersionTLS12, 15352 }, 15353 flags: []string{ 15354 "-enable-early-data", 15355 "-expect-early-data-reason", "protocol_version", 15356 }, 15357 }) 15358 15359 // On 0-RTT reject, the server may end up negotiating a cipher suite with a 15360 // different PRF hash. Test that the client handles this correctly. 15361 testCases = append(testCases, testCase{ 15362 testType: clientTest, 15363 name: "EarlyData-Reject0RTT-DifferentPRF-Client", 15364 config: Config{ 15365 MaxVersion: VersionTLS13, 15366 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 15367 }, 15368 resumeConfig: &Config{ 15369 MaxVersion: VersionTLS13, 15370 CipherSuites: []uint16{TLS_AES_256_GCM_SHA384}, 15371 }, 15372 resumeSession: true, 15373 expectResumeRejected: true, 15374 earlyData: true, 15375 expectEarlyDataRejected: true, 15376 flags: []string{ 15377 "-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15378 // The client initially reports the old cipher suite while sending 15379 // early data. After processing the 0-RTT reject, it reports the 15380 // true cipher suite. 15381 "-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15382 "-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)), 15383 }, 15384 }) 15385 testCases = append(testCases, testCase{ 15386 testType: clientTest, 15387 name: "EarlyData-Reject0RTT-DifferentPRF-HRR-Client", 15388 config: Config{ 15389 MaxVersion: VersionTLS13, 15390 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 15391 }, 15392 resumeConfig: &Config{ 15393 MaxVersion: VersionTLS13, 15394 CipherSuites: []uint16{TLS_AES_256_GCM_SHA384}, 15395 // P-384 requires a HelloRetryRequest against BoringSSL's default 15396 // configuration. Assert this with ExpectMissingKeyShare. 15397 CurvePreferences: []CurveID{CurveP384}, 15398 Bugs: ProtocolBugs{ 15399 ExpectMissingKeyShare: true, 15400 }, 15401 }, 15402 resumeSession: true, 15403 expectResumeRejected: true, 15404 earlyData: true, 15405 expectEarlyDataRejected: true, 15406 flags: []string{ 15407 "-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15408 // The client initially reports the old cipher suite while sending 15409 // early data. After processing the 0-RTT reject, it reports the 15410 // true cipher suite. 15411 "-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15412 "-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)), 15413 }, 15414 }) 15415 15416 // Test that the client enforces cipher suite match on 0-RTT accept. 15417 testCases = append(testCases, testCase{ 15418 testType: clientTest, 15419 name: "EarlyData-CipherMismatch-Client-TLS13", 15420 config: Config{ 15421 MaxVersion: VersionTLS13, 15422 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 15423 }, 15424 resumeConfig: &Config{ 15425 MaxVersion: VersionTLS13, 15426 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 15427 Bugs: ProtocolBugs{ 15428 AlwaysAcceptEarlyData: true, 15429 }, 15430 }, 15431 resumeSession: true, 15432 earlyData: true, 15433 shouldFail: true, 15434 expectedError: ":CIPHER_MISMATCH_ON_EARLY_DATA:", 15435 expectedLocalError: "remote error: illegal parameter", 15436 }) 15437 15438 // Test that the client can write early data when it has received a partial 15439 // ServerHello..Finished flight. See https://crbug.com/1208784. Note the 15440 // EncryptedExtensions test assumes EncryptedExtensions and Finished are in 15441 // separate records, i.e. that PackHandshakeFlight is disabled. 15442 testCases = append(testCases, testCase{ 15443 testType: clientTest, 15444 name: "EarlyData-WriteAfterServerHello", 15445 config: Config{ 15446 MinVersion: VersionTLS13, 15447 MaxVersion: VersionTLS13, 15448 Bugs: ProtocolBugs{ 15449 // Write the server response before expecting early data. 15450 ExpectEarlyData: [][]byte{}, 15451 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 15452 }, 15453 }, 15454 resumeSession: true, 15455 earlyData: true, 15456 flags: []string{ 15457 "-async", 15458 "-on-resume-early-write-after-message", 15459 strconv.Itoa(int(typeServerHello)), 15460 }, 15461 }) 15462 testCases = append(testCases, testCase{ 15463 testType: clientTest, 15464 name: "EarlyData-WriteAfterEncryptedExtensions", 15465 config: Config{ 15466 MinVersion: VersionTLS13, 15467 MaxVersion: VersionTLS13, 15468 Bugs: ProtocolBugs{ 15469 // Write the server response before expecting early data. 15470 ExpectEarlyData: [][]byte{}, 15471 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 15472 }, 15473 }, 15474 resumeSession: true, 15475 earlyData: true, 15476 flags: []string{ 15477 "-async", 15478 "-on-resume-early-write-after-message", 15479 strconv.Itoa(int(typeEncryptedExtensions)), 15480 }, 15481 }) 15482} 15483 15484func addTLS13CipherPreferenceTests() { 15485 // Test that client preference is honored if the shim has AES hardware 15486 // and ChaCha20-Poly1305 is preferred otherwise. 15487 testCases = append(testCases, testCase{ 15488 testType: serverTest, 15489 name: "TLS13-CipherPreference-Server-ChaCha20-AES", 15490 config: Config{ 15491 MaxVersion: VersionTLS13, 15492 CipherSuites: []uint16{ 15493 TLS_CHACHA20_POLY1305_SHA256, 15494 TLS_AES_128_GCM_SHA256, 15495 }, 15496 CurvePreferences: []CurveID{CurveX25519}, 15497 }, 15498 flags: []string{ 15499 "-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15500 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15501 }, 15502 }) 15503 15504 testCases = append(testCases, testCase{ 15505 testType: serverTest, 15506 name: "TLS13-CipherPreference-Server-AES-ChaCha20", 15507 config: Config{ 15508 MaxVersion: VersionTLS13, 15509 CipherSuites: []uint16{ 15510 TLS_AES_128_GCM_SHA256, 15511 TLS_CHACHA20_POLY1305_SHA256, 15512 }, 15513 CurvePreferences: []CurveID{CurveX25519}, 15514 }, 15515 flags: []string{ 15516 "-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15517 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15518 }, 15519 }) 15520 15521 // Test that the client orders ChaCha20-Poly1305 and AES-GCM based on 15522 // whether it has AES hardware. 15523 testCases = append(testCases, testCase{ 15524 name: "TLS13-CipherPreference-Client", 15525 config: Config{ 15526 MaxVersion: VersionTLS13, 15527 // Use the client cipher order. (This is the default but 15528 // is listed to be explicit.) 15529 PreferServerCipherSuites: false, 15530 }, 15531 flags: []string{ 15532 "-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15533 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15534 }, 15535 }) 15536} 15537 15538func addPeekTests() { 15539 // Test SSL_peek works, including on empty records. 15540 testCases = append(testCases, testCase{ 15541 name: "Peek-Basic", 15542 sendEmptyRecords: 1, 15543 flags: []string{"-peek-then-read"}, 15544 }) 15545 15546 // Test SSL_peek can drive the initial handshake. 15547 testCases = append(testCases, testCase{ 15548 name: "Peek-ImplicitHandshake", 15549 flags: []string{ 15550 "-peek-then-read", 15551 "-implicit-handshake", 15552 }, 15553 }) 15554 15555 // Test SSL_peek can discover and drive a renegotiation. 15556 testCases = append(testCases, testCase{ 15557 name: "Peek-Renegotiate", 15558 config: Config{ 15559 MaxVersion: VersionTLS12, 15560 }, 15561 renegotiate: 1, 15562 flags: []string{ 15563 "-peek-then-read", 15564 "-renegotiate-freely", 15565 "-expect-total-renegotiations", "1", 15566 }, 15567 }) 15568 15569 // Test SSL_peek can discover a close_notify. 15570 testCases = append(testCases, testCase{ 15571 name: "Peek-Shutdown", 15572 config: Config{ 15573 Bugs: ProtocolBugs{ 15574 ExpectCloseNotify: true, 15575 }, 15576 }, 15577 flags: []string{ 15578 "-peek-then-read", 15579 "-check-close-notify", 15580 }, 15581 }) 15582 15583 // Test SSL_peek can discover an alert. 15584 testCases = append(testCases, testCase{ 15585 name: "Peek-Alert", 15586 config: Config{ 15587 Bugs: ProtocolBugs{ 15588 SendSpuriousAlert: alertRecordOverflow, 15589 }, 15590 }, 15591 flags: []string{"-peek-then-read"}, 15592 shouldFail: true, 15593 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 15594 }) 15595 15596 // Test SSL_peek can handle KeyUpdate. 15597 testCases = append(testCases, testCase{ 15598 name: "Peek-KeyUpdate", 15599 config: Config{ 15600 MaxVersion: VersionTLS13, 15601 }, 15602 sendKeyUpdates: 1, 15603 keyUpdateRequest: keyUpdateNotRequested, 15604 flags: []string{"-peek-then-read"}, 15605 }) 15606} 15607 15608func addRecordVersionTests() { 15609 for _, ver := range tlsVersions { 15610 // Test that the record version is enforced. 15611 testCases = append(testCases, testCase{ 15612 name: "CheckRecordVersion-" + ver.name, 15613 config: Config{ 15614 MinVersion: ver.version, 15615 MaxVersion: ver.version, 15616 Bugs: ProtocolBugs{ 15617 SendRecordVersion: 0x03ff, 15618 }, 15619 }, 15620 shouldFail: true, 15621 expectedError: ":WRONG_VERSION_NUMBER:", 15622 }) 15623 15624 // Test that the ClientHello may use any record version, for 15625 // compatibility reasons. 15626 testCases = append(testCases, testCase{ 15627 testType: serverTest, 15628 name: "LooseInitialRecordVersion-" + ver.name, 15629 config: Config{ 15630 MinVersion: ver.version, 15631 MaxVersion: ver.version, 15632 Bugs: ProtocolBugs{ 15633 SendInitialRecordVersion: 0x03ff, 15634 }, 15635 }, 15636 }) 15637 15638 // Test that garbage ClientHello record versions are rejected. 15639 testCases = append(testCases, testCase{ 15640 testType: serverTest, 15641 name: "GarbageInitialRecordVersion-" + ver.name, 15642 config: Config{ 15643 MinVersion: ver.version, 15644 MaxVersion: ver.version, 15645 Bugs: ProtocolBugs{ 15646 SendInitialRecordVersion: 0xffff, 15647 }, 15648 }, 15649 shouldFail: true, 15650 expectedError: ":WRONG_VERSION_NUMBER:", 15651 }) 15652 } 15653} 15654 15655func addCertificateTests() { 15656 for _, ver := range tlsVersions { 15657 // Test that a certificate chain with intermediate may be sent 15658 // and received as both client and server. 15659 testCases = append(testCases, testCase{ 15660 testType: clientTest, 15661 name: "SendReceiveIntermediate-Client-" + ver.name, 15662 config: Config{ 15663 MinVersion: ver.version, 15664 MaxVersion: ver.version, 15665 Credential: &rsaChainCertificate, 15666 ClientAuth: RequireAnyClientCert, 15667 }, 15668 expectations: connectionExpectations{ 15669 peerCertificate: &rsaChainCertificate, 15670 }, 15671 shimCertificate: &rsaChainCertificate, 15672 flags: []string{ 15673 "-expect-peer-cert-file", rsaChainCertificate.ChainPath, 15674 }, 15675 }) 15676 15677 testCases = append(testCases, testCase{ 15678 testType: serverTest, 15679 name: "SendReceiveIntermediate-Server-" + ver.name, 15680 config: Config{ 15681 MinVersion: ver.version, 15682 MaxVersion: ver.version, 15683 Credential: &rsaChainCertificate, 15684 }, 15685 expectations: connectionExpectations{ 15686 peerCertificate: &rsaChainCertificate, 15687 }, 15688 shimCertificate: &rsaChainCertificate, 15689 flags: []string{ 15690 "-require-any-client-certificate", 15691 "-expect-peer-cert-file", rsaChainCertificate.ChainPath, 15692 }, 15693 }) 15694 15695 // Test that garbage leaf certificates are properly rejected. 15696 testCases = append(testCases, testCase{ 15697 testType: clientTest, 15698 name: "GarbageCertificate-Client-" + ver.name, 15699 config: Config{ 15700 MinVersion: ver.version, 15701 MaxVersion: ver.version, 15702 Credential: &garbageCertificate, 15703 }, 15704 shouldFail: true, 15705 expectedError: ":CANNOT_PARSE_LEAF_CERT:", 15706 expectedLocalError: "remote error: error decoding message", 15707 }) 15708 15709 testCases = append(testCases, testCase{ 15710 testType: serverTest, 15711 name: "GarbageCertificate-Server-" + ver.name, 15712 config: Config{ 15713 MinVersion: ver.version, 15714 MaxVersion: ver.version, 15715 Credential: &garbageCertificate, 15716 }, 15717 flags: []string{"-require-any-client-certificate"}, 15718 shouldFail: true, 15719 expectedError: ":CANNOT_PARSE_LEAF_CERT:", 15720 expectedLocalError: "remote error: error decoding message", 15721 }) 15722 } 15723} 15724 15725func addRetainOnlySHA256ClientCertTests() { 15726 for _, ver := range tlsVersions { 15727 // Test that enabling 15728 // SSL_CTX_set_retain_only_sha256_of_client_certs without 15729 // actually requesting a client certificate is a no-op. 15730 testCases = append(testCases, testCase{ 15731 testType: serverTest, 15732 name: "RetainOnlySHA256-NoCert-" + ver.name, 15733 config: Config{ 15734 MinVersion: ver.version, 15735 MaxVersion: ver.version, 15736 }, 15737 flags: []string{ 15738 "-on-initial-retain-only-sha256-client-cert", 15739 "-on-resume-retain-only-sha256-client-cert", 15740 }, 15741 resumeSession: true, 15742 }) 15743 15744 // Test that when retaining only a SHA-256 certificate is 15745 // enabled, the hash appears as expected. 15746 testCases = append(testCases, testCase{ 15747 testType: serverTest, 15748 name: "RetainOnlySHA256-Cert-" + ver.name, 15749 config: Config{ 15750 MinVersion: ver.version, 15751 MaxVersion: ver.version, 15752 Credential: &rsaCertificate, 15753 }, 15754 flags: []string{ 15755 "-verify-peer", 15756 "-on-initial-retain-only-sha256-client-cert", 15757 "-on-resume-retain-only-sha256-client-cert", 15758 "-on-initial-expect-sha256-client-cert", 15759 "-on-resume-expect-sha256-client-cert", 15760 }, 15761 resumeSession: true, 15762 }) 15763 15764 // Test that when the config changes from on to off, a 15765 // resumption is rejected because the server now wants the full 15766 // certificate chain. 15767 testCases = append(testCases, testCase{ 15768 testType: serverTest, 15769 name: "RetainOnlySHA256-OnOff-" + ver.name, 15770 config: Config{ 15771 MinVersion: ver.version, 15772 MaxVersion: ver.version, 15773 Credential: &rsaCertificate, 15774 }, 15775 flags: []string{ 15776 "-verify-peer", 15777 "-on-initial-retain-only-sha256-client-cert", 15778 "-on-initial-expect-sha256-client-cert", 15779 }, 15780 resumeSession: true, 15781 expectResumeRejected: true, 15782 }) 15783 15784 // Test that when the config changes from off to on, a 15785 // resumption is rejected because the server now wants just the 15786 // hash. 15787 testCases = append(testCases, testCase{ 15788 testType: serverTest, 15789 name: "RetainOnlySHA256-OffOn-" + ver.name, 15790 config: Config{ 15791 MinVersion: ver.version, 15792 MaxVersion: ver.version, 15793 Credential: &rsaCertificate, 15794 }, 15795 flags: []string{ 15796 "-verify-peer", 15797 "-on-resume-retain-only-sha256-client-cert", 15798 "-on-resume-expect-sha256-client-cert", 15799 }, 15800 resumeSession: true, 15801 expectResumeRejected: true, 15802 }) 15803 } 15804} 15805 15806func addECDSAKeyUsageTests() { 15807 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 15808 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 15809 if err != nil { 15810 panic(err) 15811 } 15812 15813 template := &x509.Certificate{ 15814 SerialNumber: serialNumber, 15815 Subject: pkix.Name{ 15816 Organization: []string{"Acme Co"}, 15817 }, 15818 NotBefore: time.Now(), 15819 NotAfter: time.Now(), 15820 15821 // An ECC certificate with only the keyAgreement key usgae may 15822 // be used with ECDH, but not ECDSA. 15823 KeyUsage: x509.KeyUsageKeyAgreement, 15824 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 15825 BasicConstraintsValid: true, 15826 } 15827 15828 cert := generateSingleCertChain(template, &ecdsaP256Key) 15829 15830 for _, ver := range tlsVersions { 15831 if ver.version < VersionTLS12 { 15832 continue 15833 } 15834 15835 testCases = append(testCases, testCase{ 15836 testType: clientTest, 15837 name: "ECDSAKeyUsage-Client-" + ver.name, 15838 config: Config{ 15839 MinVersion: ver.version, 15840 MaxVersion: ver.version, 15841 Credential: &cert, 15842 }, 15843 shouldFail: true, 15844 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15845 }) 15846 15847 testCases = append(testCases, testCase{ 15848 testType: serverTest, 15849 name: "ECDSAKeyUsage-Server-" + ver.name, 15850 config: Config{ 15851 MinVersion: ver.version, 15852 MaxVersion: ver.version, 15853 Credential: &cert, 15854 }, 15855 flags: []string{"-require-any-client-certificate"}, 15856 shouldFail: true, 15857 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15858 }) 15859 } 15860} 15861 15862func addRSAKeyUsageTests() { 15863 priv := rsaCertificate.PrivateKey.(*rsa.PrivateKey) 15864 15865 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 15866 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 15867 if err != nil { 15868 panic(err) 15869 } 15870 15871 dsTemplate := x509.Certificate{ 15872 SerialNumber: serialNumber, 15873 Subject: pkix.Name{ 15874 Organization: []string{"Acme Co"}, 15875 }, 15876 NotBefore: time.Now(), 15877 NotAfter: time.Now(), 15878 15879 KeyUsage: x509.KeyUsageDigitalSignature, 15880 BasicConstraintsValid: true, 15881 } 15882 15883 encTemplate := x509.Certificate{ 15884 SerialNumber: serialNumber, 15885 Subject: pkix.Name{ 15886 Organization: []string{"Acme Co"}, 15887 }, 15888 NotBefore: time.Now(), 15889 NotAfter: time.Now(), 15890 15891 KeyUsage: x509.KeyUsageKeyEncipherment, 15892 BasicConstraintsValid: true, 15893 } 15894 15895 dsCert := generateSingleCertChain(&dsTemplate, priv) 15896 15897 encCert := generateSingleCertChain(&encTemplate, priv) 15898 15899 dsSuites := []uint16{ 15900 TLS_AES_128_GCM_SHA256, 15901 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 15902 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 15903 } 15904 encSuites := []uint16{ 15905 TLS_RSA_WITH_AES_128_GCM_SHA256, 15906 TLS_RSA_WITH_AES_128_CBC_SHA, 15907 } 15908 15909 for _, ver := range tlsVersions { 15910 testCases = append(testCases, testCase{ 15911 testType: clientTest, 15912 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-" + ver.name, 15913 config: Config{ 15914 MinVersion: ver.version, 15915 MaxVersion: ver.version, 15916 Credential: &encCert, 15917 CipherSuites: dsSuites, 15918 }, 15919 shouldFail: true, 15920 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15921 }) 15922 15923 testCases = append(testCases, testCase{ 15924 testType: clientTest, 15925 name: "RSAKeyUsage-Client-WantSignature-GotSignature-" + ver.name, 15926 config: Config{ 15927 MinVersion: ver.version, 15928 MaxVersion: ver.version, 15929 Credential: &dsCert, 15930 CipherSuites: dsSuites, 15931 }, 15932 }) 15933 15934 // TLS 1.3 removes the encipherment suites. 15935 if ver.version < VersionTLS13 { 15936 testCases = append(testCases, testCase{ 15937 testType: clientTest, 15938 name: "RSAKeyUsage-Client-WantEncipherment-GotEncipherment" + ver.name, 15939 config: Config{ 15940 MinVersion: ver.version, 15941 MaxVersion: ver.version, 15942 Credential: &encCert, 15943 CipherSuites: encSuites, 15944 }, 15945 }) 15946 15947 testCases = append(testCases, testCase{ 15948 testType: clientTest, 15949 name: "RSAKeyUsage-Client-WantEncipherment-GotSignature-" + ver.name, 15950 config: Config{ 15951 MinVersion: ver.version, 15952 MaxVersion: ver.version, 15953 Credential: &dsCert, 15954 CipherSuites: encSuites, 15955 }, 15956 shouldFail: true, 15957 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15958 }) 15959 15960 // In 1.2 and below, we should not enforce without the enforce-rsa-key-usage flag. 15961 testCases = append(testCases, testCase{ 15962 testType: clientTest, 15963 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-Unenforced-" + ver.name, 15964 config: Config{ 15965 MinVersion: ver.version, 15966 MaxVersion: ver.version, 15967 Credential: &dsCert, 15968 CipherSuites: encSuites, 15969 }, 15970 flags: []string{"-expect-key-usage-invalid", "-ignore-rsa-key-usage"}, 15971 }) 15972 15973 testCases = append(testCases, testCase{ 15974 testType: clientTest, 15975 name: "RSAKeyUsage-Client-WantEncipherment-GotSignature-Unenforced-" + ver.name, 15976 config: Config{ 15977 MinVersion: ver.version, 15978 MaxVersion: ver.version, 15979 Credential: &encCert, 15980 CipherSuites: dsSuites, 15981 }, 15982 flags: []string{"-expect-key-usage-invalid", "-ignore-rsa-key-usage"}, 15983 }) 15984 } 15985 15986 if ver.version >= VersionTLS13 { 15987 // In 1.3 and above, we enforce keyUsage even when disabled. 15988 testCases = append(testCases, testCase{ 15989 testType: clientTest, 15990 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-AlwaysEnforced-" + ver.name, 15991 config: Config{ 15992 MinVersion: ver.version, 15993 MaxVersion: ver.version, 15994 Credential: &encCert, 15995 CipherSuites: dsSuites, 15996 }, 15997 flags: []string{"-ignore-rsa-key-usage"}, 15998 shouldFail: true, 15999 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 16000 }) 16001 } 16002 16003 // The server only uses signatures and always enforces it. 16004 testCases = append(testCases, testCase{ 16005 testType: serverTest, 16006 name: "RSAKeyUsage-Server-WantSignature-GotEncipherment-" + ver.name, 16007 config: Config{ 16008 MinVersion: ver.version, 16009 MaxVersion: ver.version, 16010 Credential: &encCert, 16011 }, 16012 shouldFail: true, 16013 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 16014 flags: []string{"-require-any-client-certificate"}, 16015 }) 16016 16017 testCases = append(testCases, testCase{ 16018 testType: serverTest, 16019 name: "RSAKeyUsage-Server-WantSignature-GotSignature-" + ver.name, 16020 config: Config{ 16021 MinVersion: ver.version, 16022 MaxVersion: ver.version, 16023 Credential: &dsCert, 16024 }, 16025 flags: []string{"-require-any-client-certificate"}, 16026 }) 16027 16028 } 16029} 16030 16031func addExtraHandshakeTests() { 16032 // An extra SSL_do_handshake is normally a no-op. These tests use -async 16033 // to ensure there is no transport I/O. 16034 testCases = append(testCases, testCase{ 16035 testType: clientTest, 16036 name: "ExtraHandshake-Client-TLS12", 16037 config: Config{ 16038 MinVersion: VersionTLS12, 16039 MaxVersion: VersionTLS12, 16040 }, 16041 flags: []string{ 16042 "-async", 16043 "-no-op-extra-handshake", 16044 }, 16045 }) 16046 testCases = append(testCases, testCase{ 16047 testType: serverTest, 16048 name: "ExtraHandshake-Server-TLS12", 16049 config: Config{ 16050 MinVersion: VersionTLS12, 16051 MaxVersion: VersionTLS12, 16052 }, 16053 flags: []string{ 16054 "-async", 16055 "-no-op-extra-handshake", 16056 }, 16057 }) 16058 testCases = append(testCases, testCase{ 16059 testType: clientTest, 16060 name: "ExtraHandshake-Client-TLS13", 16061 config: Config{ 16062 MinVersion: VersionTLS13, 16063 MaxVersion: VersionTLS13, 16064 }, 16065 flags: []string{ 16066 "-async", 16067 "-no-op-extra-handshake", 16068 }, 16069 }) 16070 testCases = append(testCases, testCase{ 16071 testType: serverTest, 16072 name: "ExtraHandshake-Server-TLS13", 16073 config: Config{ 16074 MinVersion: VersionTLS13, 16075 MaxVersion: VersionTLS13, 16076 }, 16077 flags: []string{ 16078 "-async", 16079 "-no-op-extra-handshake", 16080 }, 16081 }) 16082 16083 // An extra SSL_do_handshake is a no-op in server 0-RTT. 16084 testCases = append(testCases, testCase{ 16085 testType: serverTest, 16086 name: "ExtraHandshake-Server-EarlyData-TLS13", 16087 config: Config{ 16088 MaxVersion: VersionTLS13, 16089 MinVersion: VersionTLS13, 16090 }, 16091 messageCount: 2, 16092 resumeSession: true, 16093 earlyData: true, 16094 flags: []string{ 16095 "-async", 16096 "-no-op-extra-handshake", 16097 }, 16098 }) 16099 16100 // An extra SSL_do_handshake drives the handshake to completion in False 16101 // Start. We test this by handshaking twice and asserting the False 16102 // Start does not appear to happen. See AlertBeforeFalseStartTest for 16103 // how the test works. 16104 testCases = append(testCases, testCase{ 16105 testType: clientTest, 16106 name: "ExtraHandshake-FalseStart", 16107 config: Config{ 16108 MaxVersion: VersionTLS12, 16109 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 16110 NextProtos: []string{"foo"}, 16111 Bugs: ProtocolBugs{ 16112 ExpectFalseStart: true, 16113 AlertBeforeFalseStartTest: alertAccessDenied, 16114 }, 16115 }, 16116 flags: []string{ 16117 "-handshake-twice", 16118 "-false-start", 16119 "-advertise-alpn", "\x03foo", 16120 "-expect-alpn", "foo", 16121 }, 16122 shimWritesFirst: true, 16123 shouldFail: true, 16124 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 16125 expectedLocalError: "tls: peer did not false start: EOF", 16126 }) 16127} 16128 16129// Test that omitted and empty extensions blocks are tolerated. 16130func addOmitExtensionsTests() { 16131 // Check the ExpectOmitExtensions setting works. 16132 testCases = append(testCases, testCase{ 16133 testType: serverTest, 16134 name: "ExpectOmitExtensions", 16135 config: Config{ 16136 MinVersion: VersionTLS12, 16137 MaxVersion: VersionTLS12, 16138 Bugs: ProtocolBugs{ 16139 ExpectOmitExtensions: true, 16140 }, 16141 }, 16142 shouldFail: true, 16143 expectedLocalError: "tls: ServerHello did not omit extensions", 16144 }) 16145 16146 for _, ver := range tlsVersions { 16147 if ver.version > VersionTLS12 { 16148 continue 16149 } 16150 16151 testCases = append(testCases, testCase{ 16152 testType: serverTest, 16153 name: "OmitExtensions-ClientHello-" + ver.name, 16154 config: Config{ 16155 MinVersion: ver.version, 16156 MaxVersion: ver.version, 16157 SessionTicketsDisabled: true, 16158 Bugs: ProtocolBugs{ 16159 OmitExtensions: true, 16160 // With no client extensions, the ServerHello must not have 16161 // extensions. It should then omit the extensions field. 16162 ExpectOmitExtensions: true, 16163 }, 16164 }, 16165 }) 16166 16167 testCases = append(testCases, testCase{ 16168 testType: serverTest, 16169 name: "EmptyExtensions-ClientHello-" + ver.name, 16170 config: Config{ 16171 MinVersion: ver.version, 16172 MaxVersion: ver.version, 16173 SessionTicketsDisabled: true, 16174 Bugs: ProtocolBugs{ 16175 EmptyExtensions: true, 16176 // With no client extensions, the ServerHello must not have 16177 // extensions. It should then omit the extensions field. 16178 ExpectOmitExtensions: true, 16179 }, 16180 }, 16181 }) 16182 16183 testCases = append(testCases, testCase{ 16184 testType: clientTest, 16185 name: "OmitExtensions-ServerHello-" + ver.name, 16186 config: Config{ 16187 MinVersion: ver.version, 16188 MaxVersion: ver.version, 16189 SessionTicketsDisabled: true, 16190 Bugs: ProtocolBugs{ 16191 OmitExtensions: true, 16192 // Disable all ServerHello extensions so 16193 // OmitExtensions works. 16194 NoExtendedMasterSecret: true, 16195 NoRenegotiationInfo: true, 16196 NoOCSPStapling: true, 16197 NoSignedCertificateTimestamps: true, 16198 }, 16199 }, 16200 }) 16201 16202 testCases = append(testCases, testCase{ 16203 testType: clientTest, 16204 name: "EmptyExtensions-ServerHello-" + ver.name, 16205 config: Config{ 16206 MinVersion: ver.version, 16207 MaxVersion: ver.version, 16208 SessionTicketsDisabled: true, 16209 Bugs: ProtocolBugs{ 16210 EmptyExtensions: true, 16211 // Disable all ServerHello extensions so 16212 // EmptyExtensions works. 16213 NoExtendedMasterSecret: true, 16214 NoRenegotiationInfo: true, 16215 NoOCSPStapling: true, 16216 NoSignedCertificateTimestamps: true, 16217 }, 16218 }, 16219 }) 16220 } 16221} 16222 16223const ( 16224 shrinkingCompressionAlgID = 0xff01 16225 expandingCompressionAlgID = 0xff02 16226 randomCompressionAlgID = 0xff03 16227) 16228 16229var ( 16230 // shrinkingPrefix is the first two bytes of a Certificate message. 16231 shrinkingPrefix = []byte{0, 0} 16232 // expandingPrefix is just some arbitrary byte string. This has to match the 16233 // value in the shim. 16234 expandingPrefix = []byte{1, 2, 3, 4} 16235) 16236 16237var shrinkingCompression = CertCompressionAlg{ 16238 Compress: func(uncompressed []byte) []byte { 16239 if !bytes.HasPrefix(uncompressed, shrinkingPrefix) { 16240 panic(fmt.Sprintf("cannot compress certificate message %x", uncompressed)) 16241 } 16242 return uncompressed[len(shrinkingPrefix):] 16243 }, 16244 Decompress: func(out []byte, compressed []byte) bool { 16245 if len(out) != len(shrinkingPrefix)+len(compressed) { 16246 return false 16247 } 16248 16249 copy(out, shrinkingPrefix) 16250 copy(out[len(shrinkingPrefix):], compressed) 16251 return true 16252 }, 16253} 16254 16255var expandingCompression = CertCompressionAlg{ 16256 Compress: func(uncompressed []byte) []byte { 16257 ret := make([]byte, 0, len(expandingPrefix)+len(uncompressed)) 16258 ret = append(ret, expandingPrefix...) 16259 return append(ret, uncompressed...) 16260 }, 16261 Decompress: func(out []byte, compressed []byte) bool { 16262 if !bytes.HasPrefix(compressed, expandingPrefix) { 16263 return false 16264 } 16265 copy(out, compressed[len(expandingPrefix):]) 16266 return true 16267 }, 16268} 16269 16270var randomCompression = CertCompressionAlg{ 16271 Compress: func(uncompressed []byte) []byte { 16272 ret := make([]byte, 1+len(uncompressed)) 16273 if _, err := rand.Read(ret[:1]); err != nil { 16274 panic(err) 16275 } 16276 copy(ret[1:], uncompressed) 16277 return ret 16278 }, 16279 Decompress: func(out []byte, compressed []byte) bool { 16280 if len(compressed) != 1+len(out) { 16281 return false 16282 } 16283 copy(out, compressed[1:]) 16284 return true 16285 }, 16286} 16287 16288func addCertCompressionTests() { 16289 for _, ver := range tlsVersions { 16290 if ver.version < VersionTLS12 { 16291 continue 16292 } 16293 16294 // Duplicate compression algorithms is an error, even if nothing is 16295 // configured. 16296 testCases = append(testCases, testCase{ 16297 testType: serverTest, 16298 name: "DuplicateCertCompressionExt-" + ver.name, 16299 config: Config{ 16300 MinVersion: ver.version, 16301 MaxVersion: ver.version, 16302 Bugs: ProtocolBugs{ 16303 DuplicateCompressedCertAlgs: true, 16304 }, 16305 }, 16306 shouldFail: true, 16307 expectedError: ":ERROR_PARSING_EXTENSION:", 16308 }) 16309 16310 // With compression algorithms configured, an duplicate values should still 16311 // be an error. 16312 testCases = append(testCases, testCase{ 16313 testType: serverTest, 16314 name: "DuplicateCertCompressionExt2-" + ver.name, 16315 flags: []string{"-install-cert-compression-algs"}, 16316 config: Config{ 16317 MinVersion: ver.version, 16318 MaxVersion: ver.version, 16319 Bugs: ProtocolBugs{ 16320 DuplicateCompressedCertAlgs: true, 16321 }, 16322 }, 16323 shouldFail: true, 16324 expectedError: ":ERROR_PARSING_EXTENSION:", 16325 }) 16326 16327 if ver.version < VersionTLS13 { 16328 testCases = append(testCases, testCase{ 16329 testType: serverTest, 16330 name: "CertCompressionIgnoredBefore13-" + ver.name, 16331 flags: []string{"-install-cert-compression-algs"}, 16332 config: Config{ 16333 MinVersion: ver.version, 16334 MaxVersion: ver.version, 16335 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16336 expandingCompressionAlgID: expandingCompression, 16337 }, 16338 }, 16339 }) 16340 16341 continue 16342 } 16343 16344 testCases = append(testCases, testCase{ 16345 testType: serverTest, 16346 name: "CertCompressionExpands-" + ver.name, 16347 flags: []string{"-install-cert-compression-algs"}, 16348 config: Config{ 16349 MinVersion: ver.version, 16350 MaxVersion: ver.version, 16351 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16352 expandingCompressionAlgID: expandingCompression, 16353 }, 16354 Bugs: ProtocolBugs{ 16355 ExpectedCompressedCert: expandingCompressionAlgID, 16356 }, 16357 }, 16358 }) 16359 16360 testCases = append(testCases, testCase{ 16361 testType: serverTest, 16362 name: "CertCompressionShrinks-" + ver.name, 16363 flags: []string{"-install-cert-compression-algs"}, 16364 config: Config{ 16365 MinVersion: ver.version, 16366 MaxVersion: ver.version, 16367 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16368 shrinkingCompressionAlgID: shrinkingCompression, 16369 }, 16370 Bugs: ProtocolBugs{ 16371 ExpectedCompressedCert: shrinkingCompressionAlgID, 16372 }, 16373 }, 16374 }) 16375 16376 // Test that the shim behaves consistently if the compression function 16377 // is non-deterministic. This is intended to model version differences 16378 // between the shim and handshaker with handshake hints, but it is also 16379 // useful in confirming we only call the callbacks once. 16380 testCases = append(testCases, testCase{ 16381 testType: serverTest, 16382 name: "CertCompressionRandom-" + ver.name, 16383 flags: []string{"-install-cert-compression-algs"}, 16384 config: Config{ 16385 MinVersion: ver.version, 16386 MaxVersion: ver.version, 16387 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16388 randomCompressionAlgID: randomCompression, 16389 }, 16390 Bugs: ProtocolBugs{ 16391 ExpectedCompressedCert: randomCompressionAlgID, 16392 }, 16393 }, 16394 }) 16395 16396 // With both algorithms configured, the server should pick its most 16397 // preferable. (Which is expandingCompressionAlgID.) 16398 testCases = append(testCases, testCase{ 16399 testType: serverTest, 16400 name: "CertCompressionPriority-" + ver.name, 16401 flags: []string{"-install-cert-compression-algs"}, 16402 config: Config{ 16403 MinVersion: ver.version, 16404 MaxVersion: ver.version, 16405 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16406 shrinkingCompressionAlgID: shrinkingCompression, 16407 expandingCompressionAlgID: expandingCompression, 16408 }, 16409 Bugs: ProtocolBugs{ 16410 ExpectedCompressedCert: expandingCompressionAlgID, 16411 }, 16412 }, 16413 }) 16414 16415 // With no common algorithms configured, the server should decline 16416 // compression. 16417 testCases = append(testCases, testCase{ 16418 testType: serverTest, 16419 name: "CertCompressionNoCommonAlgs-" + ver.name, 16420 flags: []string{"-install-one-cert-compression-alg", strconv.Itoa(shrinkingCompressionAlgID)}, 16421 config: Config{ 16422 MinVersion: ver.version, 16423 MaxVersion: ver.version, 16424 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16425 expandingCompressionAlgID: expandingCompression, 16426 }, 16427 Bugs: ProtocolBugs{ 16428 ExpectUncompressedCert: true, 16429 }, 16430 }, 16431 }) 16432 16433 testCases = append(testCases, testCase{ 16434 testType: clientTest, 16435 name: "CertCompressionExpandsClient-" + ver.name, 16436 flags: []string{"-install-cert-compression-algs"}, 16437 config: Config{ 16438 MinVersion: ver.version, 16439 MaxVersion: ver.version, 16440 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16441 expandingCompressionAlgID: expandingCompression, 16442 }, 16443 Bugs: ProtocolBugs{ 16444 ExpectedCompressedCert: expandingCompressionAlgID, 16445 }, 16446 }, 16447 }) 16448 16449 testCases = append(testCases, testCase{ 16450 testType: clientTest, 16451 name: "CertCompressionShrinksClient-" + ver.name, 16452 flags: []string{"-install-cert-compression-algs"}, 16453 config: Config{ 16454 MinVersion: ver.version, 16455 MaxVersion: ver.version, 16456 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16457 shrinkingCompressionAlgID: shrinkingCompression, 16458 }, 16459 Bugs: ProtocolBugs{ 16460 ExpectedCompressedCert: shrinkingCompressionAlgID, 16461 }, 16462 }, 16463 }) 16464 16465 testCases = append(testCases, testCase{ 16466 testType: clientTest, 16467 name: "CertCompressionBadAlgIDClient-" + ver.name, 16468 flags: []string{"-install-cert-compression-algs"}, 16469 config: Config{ 16470 MinVersion: ver.version, 16471 MaxVersion: ver.version, 16472 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16473 shrinkingCompressionAlgID: shrinkingCompression, 16474 }, 16475 Bugs: ProtocolBugs{ 16476 ExpectedCompressedCert: shrinkingCompressionAlgID, 16477 SendCertCompressionAlgID: 1234, 16478 }, 16479 }, 16480 shouldFail: true, 16481 expectedError: ":UNKNOWN_CERT_COMPRESSION_ALG:", 16482 }) 16483 16484 testCases = append(testCases, testCase{ 16485 testType: clientTest, 16486 name: "CertCompressionTooSmallClient-" + ver.name, 16487 flags: []string{"-install-cert-compression-algs"}, 16488 config: Config{ 16489 MinVersion: ver.version, 16490 MaxVersion: ver.version, 16491 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16492 shrinkingCompressionAlgID: shrinkingCompression, 16493 }, 16494 Bugs: ProtocolBugs{ 16495 ExpectedCompressedCert: shrinkingCompressionAlgID, 16496 SendCertUncompressedLength: 12, 16497 }, 16498 }, 16499 shouldFail: true, 16500 expectedError: ":CERT_DECOMPRESSION_FAILED:", 16501 }) 16502 16503 testCases = append(testCases, testCase{ 16504 testType: clientTest, 16505 name: "CertCompressionTooLargeClient-" + ver.name, 16506 flags: []string{"-install-cert-compression-algs"}, 16507 config: Config{ 16508 MinVersion: ver.version, 16509 MaxVersion: ver.version, 16510 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16511 shrinkingCompressionAlgID: shrinkingCompression, 16512 }, 16513 Bugs: ProtocolBugs{ 16514 ExpectedCompressedCert: shrinkingCompressionAlgID, 16515 SendCertUncompressedLength: 1 << 20, 16516 }, 16517 }, 16518 shouldFail: true, 16519 expectedError: ":UNCOMPRESSED_CERT_TOO_LARGE:", 16520 }) 16521 } 16522} 16523 16524func addJDK11WorkaroundTests() { 16525 // Test the client treats the JDK 11 downgrade random like the usual one. 16526 testCases = append(testCases, testCase{ 16527 testType: clientTest, 16528 name: "Client-RejectJDK11DowngradeRandom", 16529 config: Config{ 16530 MaxVersion: VersionTLS12, 16531 Bugs: ProtocolBugs{ 16532 SendJDK11DowngradeRandom: true, 16533 }, 16534 }, 16535 shouldFail: true, 16536 expectedError: ":TLS13_DOWNGRADE:", 16537 expectedLocalError: "remote error: illegal parameter", 16538 }) 16539 testCases = append(testCases, testCase{ 16540 testType: clientTest, 16541 name: "Client-AcceptJDK11DowngradeRandom", 16542 config: Config{ 16543 MaxVersion: VersionTLS12, 16544 Bugs: ProtocolBugs{ 16545 SendJDK11DowngradeRandom: true, 16546 }, 16547 }, 16548 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 16549 }) 16550 16551 var clientHelloTests = []struct { 16552 clientHello []byte 16553 isJDK11 bool 16554 }{ 16555 { 16556 // A default JDK 11 ClientHello. 16557 decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"), 16558 true, 16559 }, 16560 { 16561 // The above with supported_versions and 16562 // psk_key_exchange_modes in the wrong order. 16563 decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002d00020101002b00090803040303030203010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"), 16564 false, 16565 }, 16566 { 16567 // The above with a padding extension added at the end. 16568 decodeHexOrPanic("010001b4030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000111000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b50015000700000000000000"), 16569 false, 16570 }, 16571 { 16572 // A JDK 11 ClientHello offering a TLS 1.3 PSK. 16573 decodeHexOrPanic("0100024c0303a8d71b20f060545a398226e807d21371a7a02b7ca2f96f476c2dea7e5860c5a400005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010001c9000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104aaec585ea9e121b24710a23560571322b2cf8ab8cd14e5762ef0486d8a6d0ecd721d8f2abda2eb8ed5ab7195505660450f49bba94bbf0c3f0070a531d9a1be4f002900cb00a600a0e6f7586d9a2bf64a54c1adf55a2f76657047e8e88e26629e2e7b9d630941e06fd87792770f6834e159a70b252157a9b4b082183f24629c8ff5049088b07ce37c49de8cf752a2ed7a545aff63bdc7a1b18e1bc201f23f159ee75d4987a04e00f840824f764691ab83a20e3032646e793065874cdb46138a52f50ed71406f399f96f9309eba4e5b1966148c22a63dc4aa1364269dd41dd5cc0e848d07af0095622c52cfcfc00212009cc315259e2328d65ad17a3de7c182c7874140a9356fecdd4614657806cd659"), 16574 true, 16575 }, 16576 { 16577 // A JDK 11 ClientHello offering a TLS 1.2 session. 16578 decodeHexOrPanic("010001a903038cdec49f4836d064a75046c93f22d0b9c2cf4900917332e6f0e1f41d692d3146201a3e99047492285ec65ab4e0eeee59f8f9d1eb7687398887bcd7b81353e93923005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d0002010100330047004500170041041c83c42fcd8fc06265b9f6e4f076f7e7ee17ace915c587845c0e1bc8cd177f904befeb611b682cae4702509a5f5d0c7162a282b8152d843169b91136e7c6f3e7"), 16579 true, 16580 }, 16581 { 16582 // A JDK 11 ClientHello with EMS disabled. 16583 decodeHexOrPanic("010001a50303323a857c324a9ef57d6e2544d129073830385cb1dc75ea79f6a2ec8ae09d2e7320f85fdd081678874c67ebab235e6d6a81d947f690bc0af9be4d39854ed67d9ef9005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000102000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200110009000702000400000000002b0009080304030303020301002d0002010100330047004500170041049c904c4850b495d75522f955d79e9cabea065c90279d6037a101a4c4ee712afc93ad0df5d12d287d53e458c7075d9a3ce3969c939bb62222bda779cecf54a603"), 16584 true, 16585 }, 16586 { 16587 // A JDK 11 ClientHello with OCSP stapling disabled. 16588 decodeHexOrPanic("0100019303038a50481dc85ee4f6581670821c50f2b3d34ac3251dc6e9b751bfd2521ab47ab02069a963c5486034c37ae0577ddb4c2db28cab592380ef8e4599d1305148712112005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010000f0000000080006000003736e69000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200170000002b0009080304030303020301002d00020101003300470045001700410438a97824f842c549e3c339322d8b2dbaa85d10bd7bca9c969376cb0c60b1e929eb4d13db38dcb0082ad8c637b24f55466a9acbb0b63634c1f431ec8342cf720d"), 16589 true, 16590 }, 16591 { 16592 // A JDK 11 ClientHello configured with a smaller set of 16593 // ciphers. 16594 decodeHexOrPanic("0100015603036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16595 true, 16596 }, 16597 { 16598 // The above with TLS_CHACHA20_POLY1305_SHA256 added, 16599 // which JDK 11 does not support. 16600 decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f48118000813011303c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16601 false, 16602 }, 16603 { 16604 // The above with X25519 added, which JDK 11 does not 16605 // support. 16606 decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000109000000080006000003736e69000500050100000000000a00220020001d0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16607 false, 16608 }, 16609 { 16610 // A JDK 11 ClientHello with ALPN protocols configured. 16611 decodeHexOrPanic("010001bb0303c0e0ea707b00c5311eb09cabd58626692cebfaefaef7265637e4550811dae16220da86d6eea04e214e873675223f08a6926bcf79f16d866280bdbab85e9e09c3ff005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000118000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020010000e000c02683208687474702f312e310011000900070200040000000000170000002b0009080304030303020301002d00020101003300470045001700410416def07c1d66ddde5fc9dcc328c8e77022d321c590c0d30cb41d515b38dca34540819a216c6c053bd47b9068f4f6b960f03647de4e36e8b7ffeea78f7252e3d9"), 16612 true, 16613 }, 16614 } 16615 for i, t := range clientHelloTests { 16616 expectedVersion := uint16(VersionTLS13) 16617 if t.isJDK11 { 16618 expectedVersion = VersionTLS12 16619 } 16620 16621 // In each of these tests, we set DefaultCurves to P-256 to 16622 // match the test inputs. SendClientHelloWithFixes requires the 16623 // key_shares extension to match in type. 16624 16625 // With the workaround enabled, we should negotiate TLS 1.2 on 16626 // JDK 11 ClientHellos. 16627 testCases = append(testCases, testCase{ 16628 testType: serverTest, 16629 name: fmt.Sprintf("Server-JDK11-%d", i), 16630 config: Config{ 16631 MaxVersion: VersionTLS13, 16632 DefaultCurves: []CurveID{CurveP256}, 16633 Bugs: ProtocolBugs{ 16634 SendClientHelloWithFixes: t.clientHello, 16635 ExpectJDK11DowngradeRandom: t.isJDK11, 16636 }, 16637 }, 16638 expectations: connectionExpectations{ 16639 version: expectedVersion, 16640 }, 16641 flags: []string{"-jdk11-workaround"}, 16642 }) 16643 16644 // With the workaround disabled, we always negotiate TLS 1.3. 16645 testCases = append(testCases, testCase{ 16646 testType: serverTest, 16647 name: fmt.Sprintf("Server-JDK11-NoWorkaround-%d", i), 16648 config: Config{ 16649 MaxVersion: VersionTLS13, 16650 DefaultCurves: []CurveID{CurveP256}, 16651 Bugs: ProtocolBugs{ 16652 SendClientHelloWithFixes: t.clientHello, 16653 ExpectJDK11DowngradeRandom: false, 16654 }, 16655 }, 16656 expectations: connectionExpectations{ 16657 version: VersionTLS13, 16658 }, 16659 }) 16660 16661 // If the server does not support TLS 1.3, the workaround should 16662 // be a no-op. In particular, it should not send the downgrade 16663 // signal. 16664 testCases = append(testCases, testCase{ 16665 testType: serverTest, 16666 name: fmt.Sprintf("Server-JDK11-TLS12-%d", i), 16667 config: Config{ 16668 MaxVersion: VersionTLS13, 16669 DefaultCurves: []CurveID{CurveP256}, 16670 Bugs: ProtocolBugs{ 16671 SendClientHelloWithFixes: t.clientHello, 16672 ExpectJDK11DowngradeRandom: false, 16673 }, 16674 }, 16675 expectations: connectionExpectations{ 16676 version: VersionTLS12, 16677 }, 16678 flags: []string{ 16679 "-jdk11-workaround", 16680 "-max-version", strconv.Itoa(VersionTLS12), 16681 }, 16682 }) 16683 } 16684} 16685 16686func addDelegatedCredentialTests() { 16687 p256DC := createDelegatedCredential(&rsaCertificate, delegatedCredentialConfig{ 16688 dcAlgo: signatureECDSAWithP256AndSHA256, 16689 algo: signatureRSAPSSWithSHA256, 16690 }) 16691 16692 testCases = append(testCases, testCase{ 16693 testType: serverTest, 16694 name: "DelegatedCredentials-NoClientSupport", 16695 config: Config{ 16696 MinVersion: VersionTLS13, 16697 MaxVersion: VersionTLS13, 16698 }, 16699 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16700 flags: []string{"-expect-selected-credential", "1"}, 16701 expectations: connectionExpectations{ 16702 peerCertificate: &rsaCertificate, 16703 }, 16704 }) 16705 16706 testCases = append(testCases, testCase{ 16707 testType: serverTest, 16708 name: "DelegatedCredentials-Basic", 16709 config: Config{ 16710 MinVersion: VersionTLS13, 16711 MaxVersion: VersionTLS13, 16712 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 16713 }, 16714 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16715 flags: []string{"-expect-selected-credential", "0"}, 16716 expectations: connectionExpectations{ 16717 peerCertificate: p256DC, 16718 }, 16719 }) 16720 16721 testCases = append(testCases, testCase{ 16722 testType: serverTest, 16723 name: "DelegatedCredentials-ExactAlgorithmMatch", 16724 config: Config{ 16725 MinVersion: VersionTLS13, 16726 MaxVersion: VersionTLS13, 16727 // Test that the server doesn't mix up the two signature algorithm 16728 // fields. These options are a match because the signature_algorithms 16729 // extension matches against the signature on the delegated 16730 // credential, while the delegated_credential extension matches 16731 // against the signature made by the delegated credential. 16732 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 16733 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 16734 }, 16735 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16736 flags: []string{"-expect-selected-credential", "0"}, 16737 expectations: connectionExpectations{ 16738 peerCertificate: p256DC, 16739 }, 16740 }) 16741 16742 testCases = append(testCases, testCase{ 16743 testType: serverTest, 16744 name: "DelegatedCredentials-SigAlgoMissing", 16745 config: Config{ 16746 MinVersion: VersionTLS13, 16747 MaxVersion: VersionTLS13, 16748 // If the client doesn't support the signature in the delegated credential, 16749 // the server should not use delegated credentials. 16750 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA384}, 16751 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 16752 }, 16753 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16754 flags: []string{"-expect-selected-credential", "1"}, 16755 expectations: connectionExpectations{ 16756 peerCertificate: &rsaCertificate, 16757 }, 16758 }) 16759 16760 testCases = append(testCases, testCase{ 16761 testType: serverTest, 16762 name: "DelegatedCredentials-CertVerifySigAlgoMissing", 16763 config: Config{ 16764 MinVersion: VersionTLS13, 16765 MaxVersion: VersionTLS13, 16766 // If the client doesn't support the delegated credential's 16767 // CertificateVerify algorithm, the server should not use delegated 16768 // credentials. 16769 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 16770 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP384AndSHA384}, 16771 }, 16772 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16773 flags: []string{"-expect-selected-credential", "1"}, 16774 expectations: connectionExpectations{ 16775 peerCertificate: &rsaCertificate, 16776 }, 16777 }) 16778 16779 // Delegated credentials are not supported at TLS 1.2, even if the client 16780 // sends the extension. 16781 testCases = append(testCases, testCase{ 16782 testType: serverTest, 16783 name: "DelegatedCredentials-TLS12-Forbidden", 16784 config: Config{ 16785 MinVersion: VersionTLS12, 16786 MaxVersion: VersionTLS12, 16787 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 16788 }, 16789 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16790 flags: []string{"-expect-selected-credential", "1"}, 16791 expectations: connectionExpectations{ 16792 peerCertificate: &rsaCertificate, 16793 }, 16794 }) 16795 16796 // Generate another delegated credential, so we can get the keys out of sync. 16797 dcWrongKey := createDelegatedCredential(&rsaCertificate, delegatedCredentialConfig{ 16798 algo: signatureRSAPSSWithSHA256, 16799 }) 16800 dcWrongKey.DelegatedCredential = p256DC.DelegatedCredential 16801 testCases = append(testCases, testCase{ 16802 testType: serverTest, 16803 name: "DelegatedCredentials-KeyMismatch", 16804 // The handshake hints version of the test will, as a side effect, use a 16805 // custom private key. Custom private keys can't be checked for key 16806 // mismatches. 16807 skipHints: true, 16808 shimCredentials: []*Credential{dcWrongKey}, 16809 shouldFail: true, 16810 expectedError: ":KEY_VALUES_MISMATCH:", 16811 }) 16812 16813 // RSA delegated credentials should be rejected at configuration time. 16814 rsaDC := createDelegatedCredential(&rsaCertificate, delegatedCredentialConfig{ 16815 algo: signatureRSAPSSWithSHA256, 16816 dcAlgo: signatureRSAPSSWithSHA256, 16817 }) 16818 testCases = append(testCases, testCase{ 16819 testType: serverTest, 16820 name: "DelegatedCredentials-NoRSA", 16821 shimCredentials: []*Credential{rsaDC}, 16822 shouldFail: true, 16823 expectedError: ":INVALID_SIGNATURE_ALGORITHM:", 16824 }) 16825 16826 // If configured with multiple delegated credentials, the server can cleanly 16827 // select the first one that works. 16828 p384DC := createDelegatedCredential(&rsaCertificate, delegatedCredentialConfig{ 16829 dcAlgo: signatureECDSAWithP384AndSHA384, 16830 algo: signatureRSAPSSWithSHA256, 16831 }) 16832 testCases = append(testCases, testCase{ 16833 testType: serverTest, 16834 name: "DelegatedCredentials-Multiple", 16835 config: Config{ 16836 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP384AndSHA384}, 16837 }, 16838 shimCredentials: []*Credential{p256DC, p384DC}, 16839 flags: []string{"-expect-selected-credential", "1"}, 16840 expectations: connectionExpectations{ 16841 peerCertificate: p384DC, 16842 }, 16843 }) 16844} 16845 16846type echCipher struct { 16847 name string 16848 cipher HPKECipherSuite 16849} 16850 16851var echCiphers = []echCipher{ 16852 { 16853 name: "HKDF-SHA256-AES-128-GCM", 16854 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.AES128GCM}, 16855 }, 16856 { 16857 name: "HKDF-SHA256-AES-256-GCM", 16858 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.AES256GCM}, 16859 }, { 16860 name: "HKDF-SHA256-ChaCha20-Poly1305", 16861 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.ChaCha20Poly1305}, 16862 }, 16863} 16864 16865// generateServerECHConfig constructs a ServerECHConfig with a fresh X25519 16866// keypair and using |template| as a template for the ECHConfig. If fields are 16867// omitted, defaults are used. 16868func generateServerECHConfig(template *ECHConfig) ServerECHConfig { 16869 publicKey, secretKey, err := hpke.GenerateKeyPairX25519() 16870 if err != nil { 16871 panic(err) 16872 } 16873 templateCopy := *template 16874 if templateCopy.KEM == 0 { 16875 templateCopy.KEM = hpke.X25519WithHKDFSHA256 16876 } 16877 if len(templateCopy.PublicKey) == 0 { 16878 templateCopy.PublicKey = publicKey 16879 } 16880 if len(templateCopy.CipherSuites) == 0 { 16881 templateCopy.CipherSuites = make([]HPKECipherSuite, len(echCiphers)) 16882 for i, cipher := range echCiphers { 16883 templateCopy.CipherSuites[i] = cipher.cipher 16884 } 16885 } 16886 if len(templateCopy.PublicName) == 0 { 16887 templateCopy.PublicName = "public.example" 16888 } 16889 if templateCopy.MaxNameLen == 0 { 16890 templateCopy.MaxNameLen = 64 16891 } 16892 return ServerECHConfig{ECHConfig: CreateECHConfig(&templateCopy), Key: secretKey} 16893} 16894 16895func addEncryptedClientHelloTests() { 16896 // echConfig's ConfigID should match the one used in ssl/test/fuzzer.h. 16897 echConfig := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 16898 echConfig1 := generateServerECHConfig(&ECHConfig{ConfigID: 43}) 16899 echConfig2 := generateServerECHConfig(&ECHConfig{ConfigID: 44}) 16900 echConfig3 := generateServerECHConfig(&ECHConfig{ConfigID: 45}) 16901 echConfigRepeatID := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 16902 16903 echSecretCertificate := generateSingleCertChain(&x509.Certificate{ 16904 SerialNumber: big.NewInt(57005), 16905 Subject: pkix.Name{ 16906 CommonName: "test cert", 16907 }, 16908 NotBefore: time.Now().Add(-time.Hour), 16909 NotAfter: time.Now().Add(time.Hour), 16910 DNSNames: []string{"secret.example"}, 16911 IsCA: true, 16912 BasicConstraintsValid: true, 16913 }, &rsa2048Key) 16914 echPublicCertificate := generateSingleCertChain(&x509.Certificate{ 16915 SerialNumber: big.NewInt(57005), 16916 Subject: pkix.Name{ 16917 CommonName: "test cert", 16918 }, 16919 NotBefore: time.Now().Add(-time.Hour), 16920 NotAfter: time.Now().Add(time.Hour), 16921 DNSNames: []string{"public.example"}, 16922 IsCA: true, 16923 BasicConstraintsValid: true, 16924 }, &rsa2048Key) 16925 echLongNameCertificate := generateSingleCertChain(&x509.Certificate{ 16926 SerialNumber: big.NewInt(57005), 16927 Subject: pkix.Name{ 16928 CommonName: "test cert", 16929 }, 16930 NotBefore: time.Now().Add(-time.Hour), 16931 NotAfter: time.Now().Add(time.Hour), 16932 DNSNames: []string{"test0123456789.example"}, 16933 IsCA: true, 16934 BasicConstraintsValid: true, 16935 }, &ecdsaP256Key) 16936 16937 for _, protocol := range []protocol{tls, quic} { 16938 prefix := protocol.String() + "-" 16939 16940 // There are two ClientHellos, so many of our tests have 16941 // HelloRetryRequest variations. 16942 for _, hrr := range []bool{false, true} { 16943 var suffix string 16944 var defaultCurves []CurveID 16945 if hrr { 16946 suffix = "-HelloRetryRequest" 16947 // Require a HelloRetryRequest for every curve. 16948 defaultCurves = []CurveID{} 16949 } 16950 16951 // Test the server can accept ECH. 16952 testCases = append(testCases, testCase{ 16953 testType: serverTest, 16954 protocol: protocol, 16955 name: prefix + "ECH-Server" + suffix, 16956 config: Config{ 16957 ServerName: "secret.example", 16958 ClientECHConfig: echConfig.ECHConfig, 16959 DefaultCurves: defaultCurves, 16960 }, 16961 resumeSession: true, 16962 flags: []string{ 16963 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16964 "-ech-server-key", base64FlagValue(echConfig.Key), 16965 "-ech-is-retry-config", "1", 16966 "-expect-server-name", "secret.example", 16967 "-expect-ech-accept", 16968 }, 16969 expectations: connectionExpectations{ 16970 echAccepted: true, 16971 }, 16972 }) 16973 16974 // Test the server can accept ECH with a minimal ClientHelloOuter. 16975 // This confirms that the server does not unexpectedly pick up 16976 // fields from the wrong ClientHello. 16977 testCases = append(testCases, testCase{ 16978 testType: serverTest, 16979 protocol: protocol, 16980 name: prefix + "ECH-Server-MinimalClientHelloOuter" + suffix, 16981 config: Config{ 16982 ServerName: "secret.example", 16983 ClientECHConfig: echConfig.ECHConfig, 16984 DefaultCurves: defaultCurves, 16985 Bugs: ProtocolBugs{ 16986 MinimalClientHelloOuter: true, 16987 }, 16988 }, 16989 resumeSession: true, 16990 flags: []string{ 16991 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16992 "-ech-server-key", base64FlagValue(echConfig.Key), 16993 "-ech-is-retry-config", "1", 16994 "-expect-server-name", "secret.example", 16995 "-expect-ech-accept", 16996 }, 16997 expectations: connectionExpectations{ 16998 echAccepted: true, 16999 }, 17000 }) 17001 17002 // Test that the server can decline ECH. In particular, it must send 17003 // retry configs. 17004 testCases = append(testCases, testCase{ 17005 testType: serverTest, 17006 protocol: protocol, 17007 name: prefix + "ECH-Server-Decline" + suffix, 17008 config: Config{ 17009 ServerName: "secret.example", 17010 DefaultCurves: defaultCurves, 17011 // The client uses an ECHConfig that the server does not understand 17012 // so we can observe which retry configs the server sends back. 17013 ClientECHConfig: echConfig.ECHConfig, 17014 Bugs: ProtocolBugs{ 17015 OfferSessionInClientHelloOuter: true, 17016 ExpectECHRetryConfigs: CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw), 17017 }, 17018 }, 17019 resumeSession: true, 17020 flags: []string{ 17021 // Configure three ECHConfigs on the shim, only two of which 17022 // should be sent in retry configs. 17023 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 17024 "-ech-server-key", base64FlagValue(echConfig1.Key), 17025 "-ech-is-retry-config", "0", 17026 "-ech-server-config", base64FlagValue(echConfig2.ECHConfig.Raw), 17027 "-ech-server-key", base64FlagValue(echConfig2.Key), 17028 "-ech-is-retry-config", "1", 17029 "-ech-server-config", base64FlagValue(echConfig3.ECHConfig.Raw), 17030 "-ech-server-key", base64FlagValue(echConfig3.Key), 17031 "-ech-is-retry-config", "1", 17032 "-expect-server-name", "public.example", 17033 }, 17034 }) 17035 17036 // Test that the server considers a ClientHelloInner indicating TLS 17037 // 1.2 to be a fatal error. 17038 testCases = append(testCases, testCase{ 17039 testType: serverTest, 17040 protocol: protocol, 17041 name: prefix + "ECH-Server-TLS12InInner" + suffix, 17042 config: Config{ 17043 ServerName: "secret.example", 17044 DefaultCurves: defaultCurves, 17045 ClientECHConfig: echConfig.ECHConfig, 17046 Bugs: ProtocolBugs{ 17047 AllowTLS12InClientHelloInner: true, 17048 }, 17049 }, 17050 flags: []string{ 17051 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17052 "-ech-server-key", base64FlagValue(echConfig.Key), 17053 "-ech-is-retry-config", "1"}, 17054 shouldFail: true, 17055 expectedLocalError: "remote error: illegal parameter", 17056 expectedError: ":INVALID_CLIENT_HELLO_INNER:", 17057 }) 17058 17059 // When inner ECH extension is absent from the ClientHelloInner, the 17060 // server should fail the connection. 17061 testCases = append(testCases, testCase{ 17062 testType: serverTest, 17063 protocol: protocol, 17064 name: prefix + "ECH-Server-MissingECHInner" + suffix, 17065 config: Config{ 17066 ServerName: "secret.example", 17067 DefaultCurves: defaultCurves, 17068 ClientECHConfig: echConfig.ECHConfig, 17069 Bugs: ProtocolBugs{ 17070 OmitECHInner: !hrr, 17071 OmitSecondECHInner: hrr, 17072 }, 17073 }, 17074 flags: []string{ 17075 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17076 "-ech-server-key", base64FlagValue(echConfig.Key), 17077 "-ech-is-retry-config", "1", 17078 }, 17079 shouldFail: true, 17080 expectedLocalError: "remote error: illegal parameter", 17081 expectedError: ":INVALID_CLIENT_HELLO_INNER:", 17082 }) 17083 17084 // Test that the server can decode ech_outer_extensions. 17085 testCases = append(testCases, testCase{ 17086 testType: serverTest, 17087 protocol: protocol, 17088 name: prefix + "ECH-Server-OuterExtensions" + suffix, 17089 config: Config{ 17090 ServerName: "secret.example", 17091 DefaultCurves: defaultCurves, 17092 ClientECHConfig: echConfig.ECHConfig, 17093 ECHOuterExtensions: []uint16{ 17094 extensionKeyShare, 17095 extensionSupportedCurves, 17096 // Include a custom extension, to test that unrecognized 17097 // extensions are also decoded. 17098 extensionCustom, 17099 }, 17100 Bugs: ProtocolBugs{ 17101 CustomExtension: "test", 17102 OnlyCompressSecondClientHelloInner: hrr, 17103 }, 17104 }, 17105 flags: []string{ 17106 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17107 "-ech-server-key", base64FlagValue(echConfig.Key), 17108 "-ech-is-retry-config", "1", 17109 "-expect-server-name", "secret.example", 17110 "-expect-ech-accept", 17111 }, 17112 expectations: connectionExpectations{ 17113 echAccepted: true, 17114 }, 17115 }) 17116 17117 // Test that the server allows referenced ClientHelloOuter 17118 // extensions to be interleaved with other extensions. Only the 17119 // relative order must match. 17120 testCases = append(testCases, testCase{ 17121 testType: serverTest, 17122 protocol: protocol, 17123 name: prefix + "ECH-Server-OuterExtensions-Interleaved" + suffix, 17124 config: Config{ 17125 ServerName: "secret.example", 17126 DefaultCurves: defaultCurves, 17127 ClientECHConfig: echConfig.ECHConfig, 17128 ECHOuterExtensions: []uint16{ 17129 extensionKeyShare, 17130 extensionSupportedCurves, 17131 extensionCustom, 17132 }, 17133 Bugs: ProtocolBugs{ 17134 CustomExtension: "test", 17135 OnlyCompressSecondClientHelloInner: hrr, 17136 ECHOuterExtensionOrder: []uint16{ 17137 extensionServerName, 17138 extensionKeyShare, 17139 extensionSupportedVersions, 17140 extensionPSKKeyExchangeModes, 17141 extensionSupportedCurves, 17142 extensionSignatureAlgorithms, 17143 extensionCustom, 17144 }, 17145 }, 17146 }, 17147 flags: []string{ 17148 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17149 "-ech-server-key", base64FlagValue(echConfig.Key), 17150 "-ech-is-retry-config", "1", 17151 "-expect-server-name", "secret.example", 17152 "-expect-ech-accept", 17153 }, 17154 expectations: connectionExpectations{ 17155 echAccepted: true, 17156 }, 17157 }) 17158 17159 // Test that the server rejects references to extensions in the 17160 // wrong order. 17161 testCases = append(testCases, testCase{ 17162 testType: serverTest, 17163 protocol: protocol, 17164 name: prefix + "ECH-Server-OuterExtensions-WrongOrder" + suffix, 17165 config: Config{ 17166 ServerName: "secret.example", 17167 DefaultCurves: defaultCurves, 17168 ClientECHConfig: echConfig.ECHConfig, 17169 ECHOuterExtensions: []uint16{ 17170 extensionKeyShare, 17171 extensionSupportedCurves, 17172 }, 17173 Bugs: ProtocolBugs{ 17174 CustomExtension: "test", 17175 OnlyCompressSecondClientHelloInner: hrr, 17176 ECHOuterExtensionOrder: []uint16{ 17177 extensionSupportedCurves, 17178 extensionKeyShare, 17179 }, 17180 }, 17181 }, 17182 flags: []string{ 17183 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17184 "-ech-server-key", base64FlagValue(echConfig.Key), 17185 "-ech-is-retry-config", "1", 17186 "-expect-server-name", "secret.example", 17187 }, 17188 shouldFail: true, 17189 expectedLocalError: "remote error: illegal parameter", 17190 expectedError: ":INVALID_OUTER_EXTENSION:", 17191 }) 17192 17193 // Test that the server rejects duplicated values in ech_outer_extensions. 17194 // Besides causing the server to reconstruct an invalid ClientHelloInner 17195 // with duplicated extensions, this behavior would be vulnerable to DoS 17196 // attacks. 17197 testCases = append(testCases, testCase{ 17198 testType: serverTest, 17199 protocol: protocol, 17200 name: prefix + "ECH-Server-OuterExtensions-Duplicate" + suffix, 17201 config: Config{ 17202 ServerName: "secret.example", 17203 DefaultCurves: defaultCurves, 17204 ClientECHConfig: echConfig.ECHConfig, 17205 ECHOuterExtensions: []uint16{ 17206 extensionSupportedCurves, 17207 extensionSupportedCurves, 17208 }, 17209 Bugs: ProtocolBugs{ 17210 OnlyCompressSecondClientHelloInner: hrr, 17211 // Don't duplicate the extension in ClientHelloOuter. 17212 ECHOuterExtensionOrder: []uint16{ 17213 extensionSupportedCurves, 17214 }, 17215 }, 17216 }, 17217 flags: []string{ 17218 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17219 "-ech-server-key", base64FlagValue(echConfig.Key), 17220 "-ech-is-retry-config", "1", 17221 }, 17222 shouldFail: true, 17223 expectedLocalError: "remote error: illegal parameter", 17224 expectedError: ":INVALID_OUTER_EXTENSION:", 17225 }) 17226 17227 // Test that the server rejects references to missing extensions in 17228 // ech_outer_extensions. 17229 testCases = append(testCases, testCase{ 17230 testType: serverTest, 17231 protocol: protocol, 17232 name: prefix + "ECH-Server-OuterExtensions-Missing" + suffix, 17233 config: Config{ 17234 ServerName: "secret.example", 17235 DefaultCurves: defaultCurves, 17236 ClientECHConfig: echConfig.ECHConfig, 17237 ECHOuterExtensions: []uint16{ 17238 extensionCustom, 17239 }, 17240 Bugs: ProtocolBugs{ 17241 OnlyCompressSecondClientHelloInner: hrr, 17242 }, 17243 }, 17244 flags: []string{ 17245 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17246 "-ech-server-key", base64FlagValue(echConfig.Key), 17247 "-ech-is-retry-config", "1", 17248 "-expect-server-name", "secret.example", 17249 "-expect-ech-accept", 17250 }, 17251 shouldFail: true, 17252 expectedLocalError: "remote error: illegal parameter", 17253 expectedError: ":INVALID_OUTER_EXTENSION:", 17254 }) 17255 17256 // Test that the server rejects a references to the ECH extension in 17257 // ech_outer_extensions. The ECH extension is not authenticated in the 17258 // AAD and would result in an invalid ClientHelloInner. 17259 testCases = append(testCases, testCase{ 17260 testType: serverTest, 17261 protocol: protocol, 17262 name: prefix + "ECH-Server-OuterExtensions-SelfReference" + suffix, 17263 config: Config{ 17264 ServerName: "secret.example", 17265 DefaultCurves: defaultCurves, 17266 ClientECHConfig: echConfig.ECHConfig, 17267 ECHOuterExtensions: []uint16{ 17268 extensionEncryptedClientHello, 17269 }, 17270 Bugs: ProtocolBugs{ 17271 OnlyCompressSecondClientHelloInner: hrr, 17272 }, 17273 }, 17274 flags: []string{ 17275 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17276 "-ech-server-key", base64FlagValue(echConfig.Key), 17277 "-ech-is-retry-config", "1", 17278 }, 17279 shouldFail: true, 17280 expectedLocalError: "remote error: illegal parameter", 17281 expectedError: ":INVALID_OUTER_EXTENSION:", 17282 }) 17283 17284 // Test the message callback is correctly reported with ECH. 17285 clientAndServerHello := "read hs 1\nread clienthelloinner\nwrite hs 2\n" 17286 expectMsgCallback := clientAndServerHello + "write ccs\n" 17287 if hrr { 17288 expectMsgCallback += clientAndServerHello 17289 } 17290 // EncryptedExtensions onwards. 17291 expectMsgCallback += `write hs 8 17292write hs 11 17293write hs 15 17294write hs 20 17295read hs 20 17296write hs 4 17297write hs 4 17298` 17299 testCases = append(testCases, testCase{ 17300 testType: serverTest, 17301 protocol: protocol, 17302 name: prefix + "ECH-Server-MessageCallback" + suffix, 17303 config: Config{ 17304 ServerName: "secret.example", 17305 ClientECHConfig: echConfig.ECHConfig, 17306 DefaultCurves: defaultCurves, 17307 Bugs: ProtocolBugs{ 17308 NoCloseNotify: true, // Align QUIC and TCP traces. 17309 }, 17310 }, 17311 flags: []string{ 17312 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17313 "-ech-server-key", base64FlagValue(echConfig.Key), 17314 "-ech-is-retry-config", "1", 17315 "-expect-ech-accept", 17316 "-expect-msg-callback", expectMsgCallback, 17317 }, 17318 expectations: connectionExpectations{ 17319 echAccepted: true, 17320 }, 17321 }) 17322 } 17323 17324 // Test that ECH, which runs before an async early callback, interacts 17325 // correctly in the state machine. 17326 testCases = append(testCases, testCase{ 17327 testType: serverTest, 17328 protocol: protocol, 17329 name: prefix + "ECH-Server-AsyncEarlyCallback", 17330 config: Config{ 17331 ServerName: "secret.example", 17332 ClientECHConfig: echConfig.ECHConfig, 17333 }, 17334 flags: []string{ 17335 "-async", 17336 "-use-early-callback", 17337 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17338 "-ech-server-key", base64FlagValue(echConfig.Key), 17339 "-ech-is-retry-config", "1", 17340 "-expect-server-name", "secret.example", 17341 "-expect-ech-accept", 17342 }, 17343 expectations: connectionExpectations{ 17344 echAccepted: true, 17345 }, 17346 }) 17347 17348 // Test that we successfully rewind the TLS state machine and disable ECH in the 17349 // case that the select_cert_cb signals that ECH is not possible for the SNI in 17350 // ClientHelloInner. 17351 testCases = append(testCases, testCase{ 17352 testType: serverTest, 17353 protocol: protocol, 17354 name: prefix + "ECH-Server-FailCallbackNeedRewind", 17355 config: Config{ 17356 ServerName: "secret.example", 17357 ClientECHConfig: echConfig.ECHConfig, 17358 }, 17359 flags: []string{ 17360 "-async", 17361 "-fail-early-callback-ech-rewind", 17362 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17363 "-ech-server-key", base64FlagValue(echConfig.Key), 17364 "-ech-is-retry-config", "1", 17365 "-expect-server-name", "public.example", 17366 }, 17367 expectations: connectionExpectations{ 17368 echAccepted: false, 17369 }, 17370 }) 17371 17372 // Test that we correctly handle falling back to a ClientHelloOuter with 17373 // no SNI (public name). 17374 testCases = append(testCases, testCase{ 17375 testType: serverTest, 17376 protocol: protocol, 17377 name: prefix + "ECH-Server-RewindWithNoPublicName", 17378 config: Config{ 17379 ServerName: "secret.example", 17380 ClientECHConfig: echConfig.ECHConfig, 17381 Bugs: ProtocolBugs{ 17382 OmitPublicName: true, 17383 }, 17384 }, 17385 flags: []string{ 17386 "-async", 17387 "-fail-early-callback-ech-rewind", 17388 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17389 "-ech-server-key", base64FlagValue(echConfig.Key), 17390 "-ech-is-retry-config", "1", 17391 "-expect-no-server-name", 17392 }, 17393 expectations: connectionExpectations{ 17394 echAccepted: false, 17395 }, 17396 }) 17397 17398 // Test ECH-enabled server with two ECHConfigs can decrypt client's ECH when 17399 // it uses the second ECHConfig. 17400 testCases = append(testCases, testCase{ 17401 testType: serverTest, 17402 protocol: protocol, 17403 name: prefix + "ECH-Server-SecondECHConfig", 17404 config: Config{ 17405 ServerName: "secret.example", 17406 ClientECHConfig: echConfig1.ECHConfig, 17407 }, 17408 flags: []string{ 17409 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17410 "-ech-server-key", base64FlagValue(echConfig.Key), 17411 "-ech-is-retry-config", "1", 17412 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 17413 "-ech-server-key", base64FlagValue(echConfig1.Key), 17414 "-ech-is-retry-config", "1", 17415 "-expect-server-name", "secret.example", 17416 "-expect-ech-accept", 17417 }, 17418 expectations: connectionExpectations{ 17419 echAccepted: true, 17420 }, 17421 }) 17422 17423 // Test ECH-enabled server with two ECHConfigs that have the same config 17424 // ID can decrypt client's ECH when it uses the second ECHConfig. 17425 testCases = append(testCases, testCase{ 17426 testType: serverTest, 17427 protocol: protocol, 17428 name: prefix + "ECH-Server-RepeatedConfigID", 17429 config: Config{ 17430 ServerName: "secret.example", 17431 ClientECHConfig: echConfigRepeatID.ECHConfig, 17432 }, 17433 flags: []string{ 17434 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17435 "-ech-server-key", base64FlagValue(echConfig.Key), 17436 "-ech-is-retry-config", "1", 17437 "-ech-server-config", base64FlagValue(echConfigRepeatID.ECHConfig.Raw), 17438 "-ech-server-key", base64FlagValue(echConfigRepeatID.Key), 17439 "-ech-is-retry-config", "1", 17440 "-expect-server-name", "secret.example", 17441 "-expect-ech-accept", 17442 }, 17443 expectations: connectionExpectations{ 17444 echAccepted: true, 17445 }, 17446 }) 17447 17448 // Test all supported ECH cipher suites. 17449 for i, cipher := range echCiphers { 17450 otherCipher := echCiphers[(i+1)%len(echCiphers)] 17451 17452 // Test the ECH server can handle the specified cipher. 17453 testCases = append(testCases, testCase{ 17454 testType: serverTest, 17455 protocol: protocol, 17456 name: prefix + "ECH-Server-Cipher-" + cipher.name, 17457 config: Config{ 17458 ServerName: "secret.example", 17459 ClientECHConfig: echConfig.ECHConfig, 17460 ECHCipherSuites: []HPKECipherSuite{cipher.cipher}, 17461 }, 17462 flags: []string{ 17463 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17464 "-ech-server-key", base64FlagValue(echConfig.Key), 17465 "-ech-is-retry-config", "1", 17466 "-expect-server-name", "secret.example", 17467 "-expect-ech-accept", 17468 }, 17469 expectations: connectionExpectations{ 17470 echAccepted: true, 17471 }, 17472 }) 17473 17474 // Test that client can offer the specified cipher and skip over 17475 // unrecognized ones. 17476 cipherConfig := generateServerECHConfig(&ECHConfig{ 17477 ConfigID: 42, 17478 CipherSuites: []HPKECipherSuite{ 17479 {KDF: 0x1111, AEAD: 0x2222}, 17480 {KDF: cipher.cipher.KDF, AEAD: 0x2222}, 17481 {KDF: 0x1111, AEAD: cipher.cipher.AEAD}, 17482 cipher.cipher, 17483 }, 17484 }) 17485 testCases = append(testCases, testCase{ 17486 testType: clientTest, 17487 protocol: protocol, 17488 name: prefix + "ECH-Client-Cipher-" + cipher.name, 17489 config: Config{ 17490 ServerECHConfigs: []ServerECHConfig{cipherConfig}, 17491 Credential: &echSecretCertificate, 17492 }, 17493 flags: []string{ 17494 "-ech-config-list", base64FlagValue(CreateECHConfigList(cipherConfig.ECHConfig.Raw)), 17495 "-host-name", "secret.example", 17496 "-expect-ech-accept", 17497 }, 17498 expectations: connectionExpectations{ 17499 echAccepted: true, 17500 }, 17501 }) 17502 17503 // Test that the ECH server rejects the specified cipher if not 17504 // listed in its ECHConfig. 17505 otherCipherConfig := generateServerECHConfig(&ECHConfig{ 17506 ConfigID: 42, 17507 CipherSuites: []HPKECipherSuite{otherCipher.cipher}, 17508 }) 17509 testCases = append(testCases, testCase{ 17510 testType: serverTest, 17511 protocol: protocol, 17512 name: prefix + "ECH-Server-DisabledCipher-" + cipher.name, 17513 config: Config{ 17514 ServerName: "secret.example", 17515 ClientECHConfig: echConfig.ECHConfig, 17516 ECHCipherSuites: []HPKECipherSuite{cipher.cipher}, 17517 Bugs: ProtocolBugs{ 17518 ExpectECHRetryConfigs: CreateECHConfigList(otherCipherConfig.ECHConfig.Raw), 17519 }, 17520 }, 17521 flags: []string{ 17522 "-ech-server-config", base64FlagValue(otherCipherConfig.ECHConfig.Raw), 17523 "-ech-server-key", base64FlagValue(otherCipherConfig.Key), 17524 "-ech-is-retry-config", "1", 17525 "-expect-server-name", "public.example", 17526 }, 17527 }) 17528 } 17529 17530 // Test that the ECH server handles a short enc value by falling back to 17531 // ClientHelloOuter. 17532 testCases = append(testCases, testCase{ 17533 testType: serverTest, 17534 protocol: protocol, 17535 name: prefix + "ECH-Server-ShortEnc", 17536 config: Config{ 17537 ServerName: "secret.example", 17538 ClientECHConfig: echConfig.ECHConfig, 17539 Bugs: ProtocolBugs{ 17540 ExpectECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw), 17541 TruncateClientECHEnc: true, 17542 }, 17543 }, 17544 flags: []string{ 17545 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17546 "-ech-server-key", base64FlagValue(echConfig.Key), 17547 "-ech-is-retry-config", "1", 17548 "-expect-server-name", "public.example", 17549 }, 17550 }) 17551 17552 // Test that the server handles decryption failure by falling back to 17553 // ClientHelloOuter. 17554 testCases = append(testCases, testCase{ 17555 testType: serverTest, 17556 protocol: protocol, 17557 name: prefix + "ECH-Server-CorruptEncryptedClientHello", 17558 config: Config{ 17559 ServerName: "secret.example", 17560 ClientECHConfig: echConfig.ECHConfig, 17561 Bugs: ProtocolBugs{ 17562 ExpectECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw), 17563 CorruptEncryptedClientHello: true, 17564 }, 17565 }, 17566 flags: []string{ 17567 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17568 "-ech-server-key", base64FlagValue(echConfig.Key), 17569 "-ech-is-retry-config", "1", 17570 }, 17571 }) 17572 17573 // Test that the server treats decryption failure in the second 17574 // ClientHello as fatal. 17575 testCases = append(testCases, testCase{ 17576 testType: serverTest, 17577 protocol: protocol, 17578 name: prefix + "ECH-Server-CorruptSecondEncryptedClientHello", 17579 config: Config{ 17580 ServerName: "secret.example", 17581 ClientECHConfig: echConfig.ECHConfig, 17582 // Force a HelloRetryRequest. 17583 DefaultCurves: []CurveID{}, 17584 Bugs: ProtocolBugs{ 17585 CorruptSecondEncryptedClientHello: true, 17586 }, 17587 }, 17588 flags: []string{ 17589 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17590 "-ech-server-key", base64FlagValue(echConfig.Key), 17591 "-ech-is-retry-config", "1", 17592 }, 17593 shouldFail: true, 17594 expectedError: ":DECRYPTION_FAILED:", 17595 expectedLocalError: "remote error: error decrypting message", 17596 }) 17597 17598 // Test that the server treats a missing second ECH extension as fatal. 17599 testCases = append(testCases, testCase{ 17600 testType: serverTest, 17601 protocol: protocol, 17602 name: prefix + "ECH-Server-OmitSecondEncryptedClientHello", 17603 config: Config{ 17604 ServerName: "secret.example", 17605 ClientECHConfig: echConfig.ECHConfig, 17606 // Force a HelloRetryRequest. 17607 DefaultCurves: []CurveID{}, 17608 Bugs: ProtocolBugs{ 17609 OmitSecondEncryptedClientHello: true, 17610 }, 17611 }, 17612 flags: []string{ 17613 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17614 "-ech-server-key", base64FlagValue(echConfig.Key), 17615 "-ech-is-retry-config", "1", 17616 }, 17617 shouldFail: true, 17618 expectedError: ":MISSING_EXTENSION:", 17619 expectedLocalError: "remote error: missing extension", 17620 }) 17621 17622 // Test that the server treats a mismatched config ID in the second ClientHello as fatal. 17623 testCases = append(testCases, testCase{ 17624 testType: serverTest, 17625 protocol: protocol, 17626 name: prefix + "ECH-Server-DifferentConfigIDSecondClientHello", 17627 config: Config{ 17628 ServerName: "secret.example", 17629 ClientECHConfig: echConfig.ECHConfig, 17630 // Force a HelloRetryRequest. 17631 DefaultCurves: []CurveID{}, 17632 Bugs: ProtocolBugs{ 17633 CorruptSecondEncryptedClientHelloConfigID: true, 17634 }, 17635 }, 17636 flags: []string{ 17637 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17638 "-ech-server-key", base64FlagValue(echConfig.Key), 17639 "-ech-is-retry-config", "1", 17640 }, 17641 shouldFail: true, 17642 expectedError: ":DECODE_ERROR:", 17643 expectedLocalError: "remote error: illegal parameter", 17644 }) 17645 17646 // Test early data works with ECH, in both accept and reject cases. 17647 testCases = append(testCases, testCase{ 17648 testType: serverTest, 17649 protocol: protocol, 17650 name: prefix + "ECH-Server-EarlyData", 17651 config: Config{ 17652 ServerName: "secret.example", 17653 ClientECHConfig: echConfig.ECHConfig, 17654 }, 17655 resumeSession: true, 17656 earlyData: true, 17657 flags: []string{ 17658 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17659 "-ech-server-key", base64FlagValue(echConfig.Key), 17660 "-ech-is-retry-config", "1", 17661 "-expect-ech-accept", 17662 }, 17663 expectations: connectionExpectations{ 17664 echAccepted: true, 17665 }, 17666 }) 17667 testCases = append(testCases, testCase{ 17668 testType: serverTest, 17669 protocol: protocol, 17670 name: prefix + "ECH-Server-EarlyDataRejected", 17671 config: Config{ 17672 ServerName: "secret.example", 17673 ClientECHConfig: echConfig.ECHConfig, 17674 Bugs: ProtocolBugs{ 17675 // Cause the server to reject 0-RTT with a bad ticket age. 17676 SendTicketAge: 1 * time.Hour, 17677 }, 17678 }, 17679 resumeSession: true, 17680 earlyData: true, 17681 expectEarlyDataRejected: true, 17682 flags: []string{ 17683 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17684 "-ech-server-key", base64FlagValue(echConfig.Key), 17685 "-ech-is-retry-config", "1", 17686 "-expect-ech-accept", 17687 }, 17688 expectations: connectionExpectations{ 17689 echAccepted: true, 17690 }, 17691 }) 17692 17693 // Test servers with ECH disabled correctly ignore the extension and 17694 // handshake with the ClientHelloOuter. 17695 testCases = append(testCases, testCase{ 17696 testType: serverTest, 17697 protocol: protocol, 17698 name: prefix + "ECH-Server-Disabled", 17699 config: Config{ 17700 ServerName: "secret.example", 17701 ClientECHConfig: echConfig.ECHConfig, 17702 }, 17703 flags: []string{ 17704 "-expect-server-name", "public.example", 17705 }, 17706 }) 17707 17708 // Test that ECH can be used with client certificates. In particular, 17709 // the name override logic should not interfere with the server. 17710 // Test the server can accept ECH. 17711 testCases = append(testCases, testCase{ 17712 testType: serverTest, 17713 protocol: protocol, 17714 name: prefix + "ECH-Server-ClientAuth", 17715 config: Config{ 17716 Credential: &rsaCertificate, 17717 ClientECHConfig: echConfig.ECHConfig, 17718 }, 17719 flags: []string{ 17720 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17721 "-ech-server-key", base64FlagValue(echConfig.Key), 17722 "-ech-is-retry-config", "1", 17723 "-expect-ech-accept", 17724 "-require-any-client-certificate", 17725 }, 17726 expectations: connectionExpectations{ 17727 echAccepted: true, 17728 }, 17729 }) 17730 testCases = append(testCases, testCase{ 17731 testType: serverTest, 17732 protocol: protocol, 17733 name: prefix + "ECH-Server-Decline-ClientAuth", 17734 config: Config{ 17735 Credential: &rsaCertificate, 17736 ClientECHConfig: echConfig.ECHConfig, 17737 Bugs: ProtocolBugs{ 17738 ExpectECHRetryConfigs: CreateECHConfigList(echConfig1.ECHConfig.Raw), 17739 }, 17740 }, 17741 flags: []string{ 17742 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 17743 "-ech-server-key", base64FlagValue(echConfig1.Key), 17744 "-ech-is-retry-config", "1", 17745 "-require-any-client-certificate", 17746 }, 17747 }) 17748 17749 // Test that the server accepts padding. 17750 testCases = append(testCases, testCase{ 17751 testType: serverTest, 17752 protocol: protocol, 17753 name: prefix + "ECH-Server-Padding", 17754 config: Config{ 17755 ClientECHConfig: echConfig.ECHConfig, 17756 Bugs: ProtocolBugs{ 17757 ClientECHPadding: 10, 17758 }, 17759 }, 17760 flags: []string{ 17761 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17762 "-ech-server-key", base64FlagValue(echConfig.Key), 17763 "-ech-is-retry-config", "1", 17764 "-expect-ech-accept", 17765 }, 17766 expectations: connectionExpectations{ 17767 echAccepted: true, 17768 }, 17769 }) 17770 17771 // Test that the server rejects bad padding. 17772 testCases = append(testCases, testCase{ 17773 testType: serverTest, 17774 protocol: protocol, 17775 name: prefix + "ECH-Server-BadPadding", 17776 config: Config{ 17777 ClientECHConfig: echConfig.ECHConfig, 17778 Bugs: ProtocolBugs{ 17779 ClientECHPadding: 10, 17780 BadClientECHPadding: true, 17781 }, 17782 }, 17783 flags: []string{ 17784 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17785 "-ech-server-key", base64FlagValue(echConfig.Key), 17786 "-ech-is-retry-config", "1", 17787 "-expect-ech-accept", 17788 }, 17789 expectations: connectionExpectations{ 17790 echAccepted: true, 17791 }, 17792 shouldFail: true, 17793 expectedError: ":DECODE_ERROR", 17794 expectedLocalError: "remote error: illegal parameter", 17795 }) 17796 17797 // Test the client's behavior when the server ignores ECH GREASE. 17798 testCases = append(testCases, testCase{ 17799 testType: clientTest, 17800 protocol: protocol, 17801 name: prefix + "ECH-GREASE-Client-TLS13", 17802 config: Config{ 17803 MinVersion: VersionTLS13, 17804 MaxVersion: VersionTLS13, 17805 Bugs: ProtocolBugs{ 17806 ExpectClientECH: true, 17807 }, 17808 }, 17809 flags: []string{"-enable-ech-grease"}, 17810 }) 17811 17812 // Test the client's ECH GREASE behavior when responding to server's 17813 // HelloRetryRequest. This test implicitly checks that the first and second 17814 // ClientHello messages have identical ECH extensions. 17815 testCases = append(testCases, testCase{ 17816 testType: clientTest, 17817 protocol: protocol, 17818 name: prefix + "ECH-GREASE-Client-TLS13-HelloRetryRequest", 17819 config: Config{ 17820 MaxVersion: VersionTLS13, 17821 MinVersion: VersionTLS13, 17822 // P-384 requires a HelloRetryRequest against BoringSSL's default 17823 // configuration. Assert this with ExpectMissingKeyShare. 17824 CurvePreferences: []CurveID{CurveP384}, 17825 Bugs: ProtocolBugs{ 17826 ExpectMissingKeyShare: true, 17827 ExpectClientECH: true, 17828 }, 17829 }, 17830 flags: []string{"-enable-ech-grease", "-expect-hrr"}, 17831 }) 17832 17833 unsupportedVersion := []byte{ 17834 // version 17835 0xba, 0xdd, 17836 // length 17837 0x00, 0x05, 17838 // contents 17839 0x05, 0x04, 0x03, 0x02, 0x01, 17840 } 17841 17842 // Test that the client accepts a well-formed encrypted_client_hello 17843 // extension in response to ECH GREASE. The response includes one ECHConfig 17844 // with a supported version and one with an unsupported version. 17845 testCases = append(testCases, testCase{ 17846 testType: clientTest, 17847 protocol: protocol, 17848 name: prefix + "ECH-GREASE-Client-TLS13-Retry-Configs", 17849 config: Config{ 17850 MinVersion: VersionTLS13, 17851 MaxVersion: VersionTLS13, 17852 Bugs: ProtocolBugs{ 17853 ExpectClientECH: true, 17854 // Include an additional well-formed ECHConfig with an 17855 // unsupported version. This ensures the client can skip 17856 // unsupported configs. 17857 SendECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw, unsupportedVersion), 17858 }, 17859 }, 17860 flags: []string{"-enable-ech-grease"}, 17861 }) 17862 17863 // TLS 1.2 ServerHellos cannot contain retry configs. 17864 if protocol != quic { 17865 testCases = append(testCases, testCase{ 17866 testType: clientTest, 17867 protocol: protocol, 17868 name: prefix + "ECH-GREASE-Client-TLS12-RejectRetryConfigs", 17869 config: Config{ 17870 MinVersion: VersionTLS12, 17871 MaxVersion: VersionTLS12, 17872 ServerECHConfigs: []ServerECHConfig{echConfig}, 17873 Bugs: ProtocolBugs{ 17874 ExpectClientECH: true, 17875 AlwaysSendECHRetryConfigs: true, 17876 }, 17877 }, 17878 flags: []string{"-enable-ech-grease"}, 17879 shouldFail: true, 17880 expectedLocalError: "remote error: unsupported extension", 17881 expectedError: ":UNEXPECTED_EXTENSION:", 17882 }) 17883 testCases = append(testCases, testCase{ 17884 testType: clientTest, 17885 protocol: protocol, 17886 name: prefix + "ECH-Client-TLS12-RejectRetryConfigs", 17887 config: Config{ 17888 MinVersion: VersionTLS12, 17889 MaxVersion: VersionTLS12, 17890 ServerECHConfigs: []ServerECHConfig{echConfig}, 17891 Bugs: ProtocolBugs{ 17892 ExpectClientECH: true, 17893 AlwaysSendECHRetryConfigs: true, 17894 }, 17895 }, 17896 flags: []string{ 17897 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig1.ECHConfig.Raw)), 17898 }, 17899 shouldFail: true, 17900 expectedLocalError: "remote error: unsupported extension", 17901 expectedError: ":UNEXPECTED_EXTENSION:", 17902 }) 17903 } 17904 17905 // Retry configs must be rejected when ECH is accepted. 17906 testCases = append(testCases, testCase{ 17907 testType: clientTest, 17908 protocol: protocol, 17909 name: prefix + "ECH-Client-Accept-RejectRetryConfigs", 17910 config: Config{ 17911 ServerECHConfigs: []ServerECHConfig{echConfig}, 17912 Bugs: ProtocolBugs{ 17913 ExpectClientECH: true, 17914 AlwaysSendECHRetryConfigs: true, 17915 }, 17916 }, 17917 flags: []string{ 17918 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17919 }, 17920 shouldFail: true, 17921 expectedLocalError: "remote error: unsupported extension", 17922 expectedError: ":UNEXPECTED_EXTENSION:", 17923 }) 17924 17925 // Unsolicited ECH HelloRetryRequest extensions should be rejected. 17926 testCases = append(testCases, testCase{ 17927 testType: clientTest, 17928 protocol: protocol, 17929 name: prefix + "ECH-Client-UnsolictedHRRExtension", 17930 config: Config{ 17931 ServerECHConfigs: []ServerECHConfig{echConfig}, 17932 CurvePreferences: []CurveID{CurveP384}, 17933 Bugs: ProtocolBugs{ 17934 AlwaysSendECHHelloRetryRequest: true, 17935 ExpectMissingKeyShare: true, // Check we triggered HRR. 17936 }, 17937 }, 17938 shouldFail: true, 17939 expectedLocalError: "remote error: unsupported extension", 17940 expectedError: ":UNEXPECTED_EXTENSION:", 17941 }) 17942 17943 // GREASE should ignore ECH HelloRetryRequest extensions. 17944 testCases = append(testCases, testCase{ 17945 testType: clientTest, 17946 protocol: protocol, 17947 name: prefix + "ECH-Client-GREASE-IgnoreHRRExtension", 17948 config: Config{ 17949 CurvePreferences: []CurveID{CurveP384}, 17950 Bugs: ProtocolBugs{ 17951 AlwaysSendECHHelloRetryRequest: true, 17952 ExpectMissingKeyShare: true, // Check we triggered HRR. 17953 }, 17954 }, 17955 flags: []string{"-enable-ech-grease"}, 17956 }) 17957 17958 // Random ECH HelloRetryRequest extensions also signal ECH reject. 17959 testCases = append(testCases, testCase{ 17960 testType: clientTest, 17961 protocol: protocol, 17962 name: prefix + "ECH-Client-Reject-RandomHRRExtension", 17963 config: Config{ 17964 CurvePreferences: []CurveID{CurveP384}, 17965 Bugs: ProtocolBugs{ 17966 AlwaysSendECHHelloRetryRequest: true, 17967 ExpectMissingKeyShare: true, // Check we triggered HRR. 17968 }, 17969 Credential: &echPublicCertificate, 17970 }, 17971 flags: []string{ 17972 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17973 }, 17974 shouldFail: true, 17975 expectedLocalError: "remote error: ECH required", 17976 expectedError: ":ECH_REJECTED:", 17977 }) 17978 17979 // Test that the client aborts with a decode_error alert when it receives a 17980 // syntactically-invalid encrypted_client_hello extension from the server. 17981 testCases = append(testCases, testCase{ 17982 testType: clientTest, 17983 protocol: protocol, 17984 name: prefix + "ECH-GREASE-Client-TLS13-Invalid-Retry-Configs", 17985 config: Config{ 17986 MinVersion: VersionTLS13, 17987 MaxVersion: VersionTLS13, 17988 Bugs: ProtocolBugs{ 17989 ExpectClientECH: true, 17990 SendECHRetryConfigs: []byte{0xba, 0xdd, 0xec, 0xcc}, 17991 }, 17992 }, 17993 flags: []string{"-enable-ech-grease"}, 17994 shouldFail: true, 17995 expectedLocalError: "remote error: error decoding message", 17996 expectedError: ":ERROR_PARSING_EXTENSION:", 17997 }) 17998 17999 // Test that the server responds to an inner ECH extension with the 18000 // acceptance confirmation. 18001 testCases = append(testCases, testCase{ 18002 testType: serverTest, 18003 protocol: protocol, 18004 name: prefix + "ECH-Server-ECHInner", 18005 config: Config{ 18006 MinVersion: VersionTLS13, 18007 MaxVersion: VersionTLS13, 18008 Bugs: ProtocolBugs{ 18009 AlwaysSendECHInner: true, 18010 }, 18011 }, 18012 resumeSession: true, 18013 }) 18014 testCases = append(testCases, testCase{ 18015 testType: serverTest, 18016 protocol: protocol, 18017 name: prefix + "ECH-Server-ECHInner-HelloRetryRequest", 18018 config: Config{ 18019 MinVersion: VersionTLS13, 18020 MaxVersion: VersionTLS13, 18021 // Force a HelloRetryRequest. 18022 DefaultCurves: []CurveID{}, 18023 Bugs: ProtocolBugs{ 18024 AlwaysSendECHInner: true, 18025 }, 18026 }, 18027 resumeSession: true, 18028 }) 18029 18030 // Test that server fails the handshake when it sees a non-empty 18031 // inner ECH extension. 18032 testCases = append(testCases, testCase{ 18033 testType: serverTest, 18034 protocol: protocol, 18035 name: prefix + "ECH-Server-ECHInner-NotEmpty", 18036 config: Config{ 18037 MinVersion: VersionTLS13, 18038 MaxVersion: VersionTLS13, 18039 Bugs: ProtocolBugs{ 18040 AlwaysSendECHInner: true, 18041 SendInvalidECHInner: []byte{42, 42, 42}, 18042 }, 18043 }, 18044 shouldFail: true, 18045 expectedLocalError: "remote error: error decoding message", 18046 expectedError: ":ERROR_PARSING_EXTENSION:", 18047 }) 18048 18049 // Test that a TLS 1.3 server that receives an inner ECH extension can 18050 // negotiate TLS 1.2 without clobbering the downgrade signal. 18051 if protocol != quic { 18052 testCases = append(testCases, testCase{ 18053 testType: serverTest, 18054 protocol: protocol, 18055 name: prefix + "ECH-Server-ECHInner-Absent-TLS12", 18056 config: Config{ 18057 MinVersion: VersionTLS12, 18058 MaxVersion: VersionTLS13, 18059 Bugs: ProtocolBugs{ 18060 // Omit supported_versions extension so the server negotiates 18061 // TLS 1.2. 18062 OmitSupportedVersions: true, 18063 AlwaysSendECHInner: true, 18064 }, 18065 }, 18066 // Check that the client sees the TLS 1.3 downgrade signal in 18067 // ServerHello.random. 18068 shouldFail: true, 18069 expectedLocalError: "tls: downgrade from TLS 1.3 detected", 18070 }) 18071 } 18072 18073 // Test the client can negotiate ECH, with and without HelloRetryRequest. 18074 testCases = append(testCases, testCase{ 18075 testType: clientTest, 18076 protocol: protocol, 18077 name: prefix + "ECH-Client", 18078 config: Config{ 18079 MinVersion: VersionTLS13, 18080 MaxVersion: VersionTLS13, 18081 ServerECHConfigs: []ServerECHConfig{echConfig}, 18082 Bugs: ProtocolBugs{ 18083 ExpectServerName: "secret.example", 18084 ExpectOuterServerName: "public.example", 18085 }, 18086 Credential: &echSecretCertificate, 18087 }, 18088 flags: []string{ 18089 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18090 "-host-name", "secret.example", 18091 "-expect-ech-accept", 18092 }, 18093 resumeSession: true, 18094 expectations: connectionExpectations{echAccepted: true}, 18095 }) 18096 testCases = append(testCases, testCase{ 18097 testType: clientTest, 18098 protocol: protocol, 18099 name: prefix + "ECH-Client-HelloRetryRequest", 18100 config: Config{ 18101 MinVersion: VersionTLS13, 18102 MaxVersion: VersionTLS13, 18103 CurvePreferences: []CurveID{CurveP384}, 18104 ServerECHConfigs: []ServerECHConfig{echConfig}, 18105 Bugs: ProtocolBugs{ 18106 ExpectServerName: "secret.example", 18107 ExpectOuterServerName: "public.example", 18108 ExpectMissingKeyShare: true, // Check we triggered HRR. 18109 }, 18110 Credential: &echSecretCertificate, 18111 }, 18112 resumeSession: true, 18113 flags: []string{ 18114 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18115 "-host-name", "secret.example", 18116 "-expect-ech-accept", 18117 "-expect-hrr", // Check we triggered HRR. 18118 }, 18119 expectations: connectionExpectations{echAccepted: true}, 18120 }) 18121 18122 // Test the client can negotiate ECH with early data. 18123 testCases = append(testCases, testCase{ 18124 testType: clientTest, 18125 protocol: protocol, 18126 name: prefix + "ECH-Client-EarlyData", 18127 config: Config{ 18128 MinVersion: VersionTLS13, 18129 MaxVersion: VersionTLS13, 18130 ServerECHConfigs: []ServerECHConfig{echConfig}, 18131 Bugs: ProtocolBugs{ 18132 ExpectServerName: "secret.example", 18133 }, 18134 Credential: &echSecretCertificate, 18135 }, 18136 flags: []string{ 18137 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18138 "-host-name", "secret.example", 18139 "-expect-ech-accept", 18140 }, 18141 resumeSession: true, 18142 earlyData: true, 18143 expectations: connectionExpectations{echAccepted: true}, 18144 }) 18145 testCases = append(testCases, testCase{ 18146 testType: clientTest, 18147 protocol: protocol, 18148 name: prefix + "ECH-Client-EarlyDataRejected", 18149 config: Config{ 18150 MinVersion: VersionTLS13, 18151 MaxVersion: VersionTLS13, 18152 ServerECHConfigs: []ServerECHConfig{echConfig}, 18153 Bugs: ProtocolBugs{ 18154 ExpectServerName: "secret.example", 18155 AlwaysRejectEarlyData: true, 18156 }, 18157 Credential: &echSecretCertificate, 18158 }, 18159 flags: []string{ 18160 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18161 "-host-name", "secret.example", 18162 "-expect-ech-accept", 18163 }, 18164 resumeSession: true, 18165 earlyData: true, 18166 expectEarlyDataRejected: true, 18167 expectations: connectionExpectations{echAccepted: true}, 18168 }) 18169 18170 if protocol != quic { 18171 // Test that an ECH client does not offer a TLS 1.2 session. 18172 testCases = append(testCases, testCase{ 18173 testType: clientTest, 18174 protocol: protocol, 18175 name: prefix + "ECH-Client-TLS12SessionID", 18176 config: Config{ 18177 MaxVersion: VersionTLS12, 18178 SessionTicketsDisabled: true, 18179 }, 18180 resumeConfig: &Config{ 18181 ServerECHConfigs: []ServerECHConfig{echConfig}, 18182 Bugs: ProtocolBugs{ 18183 ExpectNoTLS12Session: true, 18184 }, 18185 }, 18186 flags: []string{ 18187 "-on-resume-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18188 "-on-resume-expect-ech-accept", 18189 }, 18190 resumeSession: true, 18191 expectResumeRejected: true, 18192 resumeExpectations: &connectionExpectations{echAccepted: true}, 18193 }) 18194 testCases = append(testCases, testCase{ 18195 testType: clientTest, 18196 protocol: protocol, 18197 name: prefix + "ECH-Client-TLS12SessionTicket", 18198 config: Config{ 18199 MaxVersion: VersionTLS12, 18200 }, 18201 resumeConfig: &Config{ 18202 ServerECHConfigs: []ServerECHConfig{echConfig}, 18203 Bugs: ProtocolBugs{ 18204 ExpectNoTLS12Session: true, 18205 }, 18206 }, 18207 flags: []string{ 18208 "-on-resume-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18209 "-on-resume-expect-ech-accept", 18210 }, 18211 resumeSession: true, 18212 expectResumeRejected: true, 18213 resumeExpectations: &connectionExpectations{echAccepted: true}, 18214 }) 18215 } 18216 18217 // ClientHelloInner should not include NPN, which is a TLS 1.2-only 18218 // extensions. The Go server will enforce this, so this test only needs 18219 // to configure the feature on the shim. Other application extensions 18220 // are sent implicitly. 18221 testCases = append(testCases, testCase{ 18222 testType: clientTest, 18223 protocol: protocol, 18224 name: prefix + "ECH-Client-NoNPN", 18225 config: Config{ 18226 ServerECHConfigs: []ServerECHConfig{echConfig}, 18227 }, 18228 flags: []string{ 18229 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18230 "-expect-ech-accept", 18231 // Enable NPN. 18232 "-select-next-proto", "foo", 18233 }, 18234 expectations: connectionExpectations{echAccepted: true}, 18235 }) 18236 18237 // Test that the client iterates over configurations in the 18238 // ECHConfigList and selects the first with supported parameters. 18239 unsupportedKEM := generateServerECHConfig(&ECHConfig{ 18240 KEM: 0x6666, 18241 PublicKey: []byte{1, 2, 3, 4}, 18242 }).ECHConfig 18243 unsupportedCipherSuites := generateServerECHConfig(&ECHConfig{ 18244 CipherSuites: []HPKECipherSuite{{0x1111, 0x2222}}, 18245 }).ECHConfig 18246 unsupportedMandatoryExtension := generateServerECHConfig(&ECHConfig{ 18247 UnsupportedMandatoryExtension: true, 18248 }).ECHConfig 18249 testCases = append(testCases, testCase{ 18250 testType: clientTest, 18251 protocol: protocol, 18252 name: prefix + "ECH-Client-SelectECHConfig", 18253 config: Config{ 18254 ServerECHConfigs: []ServerECHConfig{echConfig}, 18255 }, 18256 flags: []string{ 18257 "-ech-config-list", base64FlagValue(CreateECHConfigList( 18258 unsupportedVersion, 18259 unsupportedKEM.Raw, 18260 unsupportedCipherSuites.Raw, 18261 unsupportedMandatoryExtension.Raw, 18262 echConfig.ECHConfig.Raw, 18263 // |echConfig1| is also supported, but the client should 18264 // select the first one. 18265 echConfig1.ECHConfig.Raw, 18266 )), 18267 "-expect-ech-accept", 18268 }, 18269 expectations: connectionExpectations{ 18270 echAccepted: true, 18271 }, 18272 }) 18273 18274 // Test that the client skips sending ECH if all ECHConfigs are 18275 // unsupported. 18276 testCases = append(testCases, testCase{ 18277 testType: clientTest, 18278 protocol: protocol, 18279 name: prefix + "ECH-Client-NoSupportedConfigs", 18280 config: Config{ 18281 Bugs: ProtocolBugs{ 18282 ExpectNoClientECH: true, 18283 }, 18284 }, 18285 flags: []string{ 18286 "-ech-config-list", base64FlagValue(CreateECHConfigList( 18287 unsupportedVersion, 18288 unsupportedKEM.Raw, 18289 unsupportedCipherSuites.Raw, 18290 unsupportedMandatoryExtension.Raw, 18291 )), 18292 }, 18293 }) 18294 18295 // If ECH GREASE is enabled, the client should send ECH GREASE when no 18296 // configured ECHConfig is suitable. 18297 testCases = append(testCases, testCase{ 18298 testType: clientTest, 18299 protocol: protocol, 18300 name: prefix + "ECH-Client-NoSupportedConfigs-GREASE", 18301 config: Config{ 18302 Bugs: ProtocolBugs{ 18303 ExpectClientECH: true, 18304 }, 18305 }, 18306 flags: []string{ 18307 "-ech-config-list", base64FlagValue(CreateECHConfigList( 18308 unsupportedVersion, 18309 unsupportedKEM.Raw, 18310 unsupportedCipherSuites.Raw, 18311 unsupportedMandatoryExtension.Raw, 18312 )), 18313 "-enable-ech-grease", 18314 }, 18315 }) 18316 18317 // If both ECH GREASE and suitable ECHConfigs are available, the 18318 // client should send normal ECH. 18319 testCases = append(testCases, testCase{ 18320 testType: clientTest, 18321 protocol: protocol, 18322 name: prefix + "ECH-Client-GREASE", 18323 config: Config{ 18324 ServerECHConfigs: []ServerECHConfig{echConfig}, 18325 }, 18326 flags: []string{ 18327 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18328 "-expect-ech-accept", 18329 }, 18330 resumeSession: true, 18331 expectations: connectionExpectations{echAccepted: true}, 18332 }) 18333 18334 // Test that GREASE extensions correctly interact with ECH. Both the 18335 // inner and outer ClientHellos should include GREASE extensions. 18336 testCases = append(testCases, testCase{ 18337 testType: clientTest, 18338 protocol: protocol, 18339 name: prefix + "ECH-Client-GREASEExtensions", 18340 config: Config{ 18341 ServerECHConfigs: []ServerECHConfig{echConfig}, 18342 Bugs: ProtocolBugs{ 18343 ExpectGREASE: true, 18344 }, 18345 }, 18346 flags: []string{ 18347 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18348 "-expect-ech-accept", 18349 "-enable-grease", 18350 }, 18351 resumeSession: true, 18352 expectations: connectionExpectations{echAccepted: true}, 18353 }) 18354 18355 // Test that the client tolerates unsupported extensions if the 18356 // mandatory bit is not set. 18357 unsupportedExtension := generateServerECHConfig(&ECHConfig{UnsupportedExtension: true}) 18358 testCases = append(testCases, testCase{ 18359 testType: clientTest, 18360 protocol: protocol, 18361 name: prefix + "ECH-Client-UnsupportedExtension", 18362 config: Config{ 18363 ServerECHConfigs: []ServerECHConfig{unsupportedExtension}, 18364 }, 18365 flags: []string{ 18366 "-ech-config-list", base64FlagValue(CreateECHConfigList(unsupportedExtension.ECHConfig.Raw)), 18367 "-expect-ech-accept", 18368 }, 18369 expectations: connectionExpectations{echAccepted: true}, 18370 }) 18371 18372 // Syntax errors in the ECHConfigList should be rejected. 18373 testCases = append(testCases, testCase{ 18374 testType: clientTest, 18375 protocol: protocol, 18376 name: prefix + "ECH-Client-InvalidECHConfigList", 18377 flags: []string{ 18378 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw[1:])), 18379 }, 18380 shouldFail: true, 18381 expectedError: ":INVALID_ECH_CONFIG_LIST:", 18382 }) 18383 18384 // If the ClientHelloInner has no server_name extension, while the 18385 // ClientHelloOuter has one, the client must check for unsolicited 18386 // extensions based on the selected ClientHello. 18387 testCases = append(testCases, testCase{ 18388 testType: clientTest, 18389 protocol: protocol, 18390 name: prefix + "ECH-Client-UnsolicitedInnerServerNameAck", 18391 config: Config{ 18392 ServerECHConfigs: []ServerECHConfig{echConfig}, 18393 Bugs: ProtocolBugs{ 18394 // ClientHelloOuter should have a server name. 18395 ExpectOuterServerName: "public.example", 18396 // The server will acknowledge the server_name extension. 18397 // This option runs whether or not the client requested the 18398 // extension. 18399 SendServerNameAck: true, 18400 }, 18401 }, 18402 flags: []string{ 18403 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18404 // No -host-name flag. 18405 "-expect-ech-accept", 18406 }, 18407 shouldFail: true, 18408 expectedError: ":UNEXPECTED_EXTENSION:", 18409 expectedLocalError: "remote error: unsupported extension", 18410 expectations: connectionExpectations{echAccepted: true}, 18411 }) 18412 18413 // Most extensions are the same between ClientHelloInner and 18414 // ClientHelloOuter and can be compressed. 18415 testCases = append(testCases, testCase{ 18416 testType: clientTest, 18417 protocol: protocol, 18418 name: prefix + "ECH-Client-ExpectECHOuterExtensions", 18419 config: Config{ 18420 ServerECHConfigs: []ServerECHConfig{echConfig}, 18421 NextProtos: []string{"proto"}, 18422 Bugs: ProtocolBugs{ 18423 ExpectECHOuterExtensions: []uint16{ 18424 extensionALPN, 18425 extensionKeyShare, 18426 extensionPSKKeyExchangeModes, 18427 extensionSignatureAlgorithms, 18428 extensionSupportedCurves, 18429 }, 18430 }, 18431 Credential: &echSecretCertificate, 18432 }, 18433 flags: []string{ 18434 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18435 "-expect-ech-accept", 18436 "-advertise-alpn", "\x05proto", 18437 "-expect-alpn", "proto", 18438 "-host-name", "secret.example", 18439 }, 18440 expectations: connectionExpectations{ 18441 echAccepted: true, 18442 nextProto: "proto", 18443 }, 18444 skipQUICALPNConfig: true, 18445 }) 18446 18447 // If the server name happens to match the public name, it still should 18448 // not be compressed. It is not publicly known that they match. 18449 testCases = append(testCases, testCase{ 18450 testType: clientTest, 18451 protocol: protocol, 18452 name: prefix + "ECH-Client-NeverCompressServerName", 18453 config: Config{ 18454 ServerECHConfigs: []ServerECHConfig{echConfig}, 18455 NextProtos: []string{"proto"}, 18456 Bugs: ProtocolBugs{ 18457 ExpectECHUncompressedExtensions: []uint16{extensionServerName}, 18458 ExpectServerName: "public.example", 18459 ExpectOuterServerName: "public.example", 18460 }, 18461 Credential: &echPublicCertificate, 18462 }, 18463 flags: []string{ 18464 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18465 "-expect-ech-accept", 18466 "-host-name", "public.example", 18467 }, 18468 expectations: connectionExpectations{echAccepted: true}, 18469 }) 18470 18471 // If the ClientHelloOuter disables TLS 1.3, e.g. in QUIC, the client 18472 // should also compress supported_versions. 18473 testCases = append(testCases, testCase{ 18474 testType: clientTest, 18475 protocol: protocol, 18476 name: prefix + "ECH-Client-CompressSupportedVersions", 18477 config: Config{ 18478 ServerECHConfigs: []ServerECHConfig{echConfig}, 18479 Bugs: ProtocolBugs{ 18480 ExpectECHOuterExtensions: []uint16{ 18481 extensionSupportedVersions, 18482 }, 18483 }, 18484 Credential: &echSecretCertificate, 18485 }, 18486 flags: []string{ 18487 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18488 "-host-name", "secret.example", 18489 "-expect-ech-accept", 18490 "-min-version", strconv.Itoa(int(VersionTLS13)), 18491 }, 18492 expectations: connectionExpectations{echAccepted: true}, 18493 }) 18494 18495 // Test that the client can still offer server names that exceed the 18496 // maximum name length. It is only a padding hint. 18497 maxNameLen10 := generateServerECHConfig(&ECHConfig{MaxNameLen: 10}) 18498 testCases = append(testCases, testCase{ 18499 testType: clientTest, 18500 protocol: protocol, 18501 name: prefix + "ECH-Client-NameTooLong", 18502 config: Config{ 18503 ServerECHConfigs: []ServerECHConfig{maxNameLen10}, 18504 Bugs: ProtocolBugs{ 18505 ExpectServerName: "test0123456789.example", 18506 }, 18507 Credential: &echLongNameCertificate, 18508 }, 18509 flags: []string{ 18510 "-ech-config-list", base64FlagValue(CreateECHConfigList(maxNameLen10.ECHConfig.Raw)), 18511 "-host-name", "test0123456789.example", 18512 "-expect-ech-accept", 18513 }, 18514 expectations: connectionExpectations{echAccepted: true}, 18515 }) 18516 18517 // Test the client can recognize when ECH is rejected. 18518 testCases = append(testCases, testCase{ 18519 testType: clientTest, 18520 protocol: protocol, 18521 name: prefix + "ECH-Client-Reject", 18522 config: Config{ 18523 ServerECHConfigs: []ServerECHConfig{echConfig2, echConfig3}, 18524 Bugs: ProtocolBugs{ 18525 ExpectServerName: "public.example", 18526 }, 18527 Credential: &echPublicCertificate, 18528 }, 18529 flags: []string{ 18530 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18531 "-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw)), 18532 }, 18533 shouldFail: true, 18534 expectedLocalError: "remote error: ECH required", 18535 expectedError: ":ECH_REJECTED:", 18536 }) 18537 testCases = append(testCases, testCase{ 18538 testType: clientTest, 18539 protocol: protocol, 18540 name: prefix + "ECH-Client-Reject-HelloRetryRequest", 18541 config: Config{ 18542 ServerECHConfigs: []ServerECHConfig{echConfig2, echConfig3}, 18543 CurvePreferences: []CurveID{CurveP384}, 18544 Bugs: ProtocolBugs{ 18545 ExpectServerName: "public.example", 18546 ExpectMissingKeyShare: true, // Check we triggered HRR. 18547 }, 18548 Credential: &echPublicCertificate, 18549 }, 18550 flags: []string{ 18551 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18552 "-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw)), 18553 "-expect-hrr", // Check we triggered HRR. 18554 }, 18555 shouldFail: true, 18556 expectedLocalError: "remote error: ECH required", 18557 expectedError: ":ECH_REJECTED:", 18558 }) 18559 testCases = append(testCases, testCase{ 18560 testType: clientTest, 18561 protocol: protocol, 18562 name: prefix + "ECH-Client-Reject-NoRetryConfigs", 18563 config: Config{ 18564 Bugs: ProtocolBugs{ 18565 ExpectServerName: "public.example", 18566 }, 18567 Credential: &echPublicCertificate, 18568 }, 18569 flags: []string{ 18570 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18571 "-expect-no-ech-retry-configs", 18572 }, 18573 shouldFail: true, 18574 expectedLocalError: "remote error: ECH required", 18575 expectedError: ":ECH_REJECTED:", 18576 }) 18577 if protocol != quic { 18578 testCases = append(testCases, testCase{ 18579 testType: clientTest, 18580 protocol: protocol, 18581 name: prefix + "ECH-Client-Reject-TLS12", 18582 config: Config{ 18583 MaxVersion: VersionTLS12, 18584 Bugs: ProtocolBugs{ 18585 ExpectServerName: "public.example", 18586 }, 18587 Credential: &echPublicCertificate, 18588 }, 18589 flags: []string{ 18590 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18591 // TLS 1.2 cannot provide retry configs. 18592 "-expect-no-ech-retry-configs", 18593 }, 18594 shouldFail: true, 18595 expectedLocalError: "remote error: ECH required", 18596 expectedError: ":ECH_REJECTED:", 18597 }) 18598 18599 // Test that the client disables False Start when ECH is rejected. 18600 testCases = append(testCases, testCase{ 18601 name: prefix + "ECH-Client-Reject-TLS12-NoFalseStart", 18602 config: Config{ 18603 MaxVersion: VersionTLS12, 18604 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 18605 NextProtos: []string{"foo"}, 18606 Bugs: ProtocolBugs{ 18607 // The options below cause the server to, immediately 18608 // after client Finished, send an alert and try to read 18609 // application data without sending server Finished. 18610 ExpectFalseStart: true, 18611 AlertBeforeFalseStartTest: alertAccessDenied, 18612 }, 18613 Credential: &echPublicCertificate, 18614 }, 18615 flags: []string{ 18616 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18617 "-false-start", 18618 "-advertise-alpn", "\x03foo", 18619 "-expect-alpn", "foo", 18620 }, 18621 shimWritesFirst: true, 18622 shouldFail: true, 18623 // Ensure the client does not send application data at the False 18624 // Start point. EOF comes from the client closing the connection 18625 // in response ot the alert. 18626 expectedLocalError: "tls: peer did not false start: EOF", 18627 // Ensures the client picks up the alert before reporting an 18628 // authenticated |SSL_R_ECH_REJECTED|. 18629 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 18630 }) 18631 } 18632 18633 // Test that unsupported retry configs in a valid ECHConfigList are 18634 // allowed. They will be skipped when configured in the retry. 18635 retryConfigs := CreateECHConfigList( 18636 unsupportedVersion, 18637 unsupportedKEM.Raw, 18638 unsupportedCipherSuites.Raw, 18639 unsupportedMandatoryExtension.Raw, 18640 echConfig2.ECHConfig.Raw) 18641 testCases = append(testCases, testCase{ 18642 testType: clientTest, 18643 protocol: protocol, 18644 name: prefix + "ECH-Client-Reject-UnsupportedRetryConfigs", 18645 config: Config{ 18646 Bugs: ProtocolBugs{ 18647 SendECHRetryConfigs: retryConfigs, 18648 ExpectServerName: "public.example", 18649 }, 18650 Credential: &echPublicCertificate, 18651 }, 18652 flags: []string{ 18653 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18654 "-expect-ech-retry-configs", base64FlagValue(retryConfigs), 18655 }, 18656 shouldFail: true, 18657 expectedLocalError: "remote error: ECH required", 18658 expectedError: ":ECH_REJECTED:", 18659 }) 18660 18661 // Test that the client rejects ClientHelloOuter handshakes that attempt 18662 // to resume the ClientHelloInner's ticket, at TLS 1.2 and TLS 1.3. 18663 testCases = append(testCases, testCase{ 18664 testType: clientTest, 18665 protocol: protocol, 18666 name: prefix + "ECH-Client-Reject-ResumeInnerSession-TLS13", 18667 config: Config{ 18668 ServerECHConfigs: []ServerECHConfig{echConfig}, 18669 Bugs: ProtocolBugs{ 18670 ExpectServerName: "secret.example", 18671 }, 18672 Credential: &echSecretCertificate, 18673 }, 18674 resumeConfig: &Config{ 18675 MaxVersion: VersionTLS13, 18676 ServerECHConfigs: []ServerECHConfig{echConfig}, 18677 Bugs: ProtocolBugs{ 18678 ExpectServerName: "public.example", 18679 UseInnerSessionWithClientHelloOuter: true, 18680 }, 18681 Credential: &echPublicCertificate, 18682 }, 18683 resumeSession: true, 18684 flags: []string{ 18685 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18686 "-host-name", "secret.example", 18687 "-on-initial-expect-ech-accept", 18688 }, 18689 shouldFail: true, 18690 expectedError: ":UNEXPECTED_EXTENSION:", 18691 expectations: connectionExpectations{echAccepted: true}, 18692 resumeExpectations: &connectionExpectations{echAccepted: false}, 18693 }) 18694 if protocol != quic { 18695 testCases = append(testCases, testCase{ 18696 testType: clientTest, 18697 protocol: protocol, 18698 name: prefix + "ECH-Client-Reject-ResumeInnerSession-TLS12", 18699 config: Config{ 18700 ServerECHConfigs: []ServerECHConfig{echConfig}, 18701 Bugs: ProtocolBugs{ 18702 ExpectServerName: "secret.example", 18703 }, 18704 Credential: &echSecretCertificate, 18705 }, 18706 resumeConfig: &Config{ 18707 MinVersion: VersionTLS12, 18708 MaxVersion: VersionTLS12, 18709 ServerECHConfigs: []ServerECHConfig{echConfig}, 18710 Bugs: ProtocolBugs{ 18711 ExpectServerName: "public.example", 18712 UseInnerSessionWithClientHelloOuter: true, 18713 // The client only ever offers TLS 1.3 sessions in 18714 // ClientHelloInner. AcceptAnySession allows them to be 18715 // resumed at TLS 1.2. 18716 AcceptAnySession: true, 18717 }, 18718 Credential: &echPublicCertificate, 18719 }, 18720 resumeSession: true, 18721 flags: []string{ 18722 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18723 "-host-name", "secret.example", 18724 "-on-initial-expect-ech-accept", 18725 }, 18726 // From the client's perspective, the server echoed a session ID to 18727 // signal resumption, but the selected ClientHello had nothing to 18728 // resume. 18729 shouldFail: true, 18730 expectedError: ":SERVER_ECHOED_INVALID_SESSION_ID:", 18731 expectedLocalError: "remote error: illegal parameter", 18732 expectations: connectionExpectations{echAccepted: true}, 18733 resumeExpectations: &connectionExpectations{echAccepted: false}, 18734 }) 18735 } 18736 18737 // Test that the client can process ECH rejects after an early data reject. 18738 testCases = append(testCases, testCase{ 18739 testType: clientTest, 18740 protocol: protocol, 18741 name: prefix + "ECH-Client-Reject-EarlyDataRejected", 18742 config: Config{ 18743 ServerECHConfigs: []ServerECHConfig{echConfig}, 18744 Bugs: ProtocolBugs{ 18745 ExpectServerName: "secret.example", 18746 }, 18747 Credential: &echSecretCertificate, 18748 }, 18749 resumeConfig: &Config{ 18750 ServerECHConfigs: []ServerECHConfig{echConfig2}, 18751 Bugs: ProtocolBugs{ 18752 ExpectServerName: "public.example", 18753 }, 18754 Credential: &echPublicCertificate, 18755 }, 18756 flags: []string{ 18757 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18758 "-host-name", "secret.example", 18759 // Although the resumption connection does not accept ECH, the 18760 // API will report ECH was accepted at the 0-RTT point. 18761 "-expect-ech-accept", 18762 // -on-retry refers to the retried handshake after 0-RTT reject, 18763 // while ech-retry-configs refers to the ECHConfigs to use in 18764 // the next connection attempt. 18765 "-on-retry-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw)), 18766 }, 18767 resumeSession: true, 18768 expectResumeRejected: true, 18769 earlyData: true, 18770 expectEarlyDataRejected: true, 18771 expectations: connectionExpectations{echAccepted: true}, 18772 resumeExpectations: &connectionExpectations{echAccepted: false}, 18773 shouldFail: true, 18774 expectedLocalError: "remote error: ECH required", 18775 expectedError: ":ECH_REJECTED:", 18776 }) 18777 if protocol != quic { 18778 testCases = append(testCases, testCase{ 18779 testType: clientTest, 18780 protocol: protocol, 18781 name: prefix + "ECH-Client-Reject-EarlyDataRejected-TLS12", 18782 config: Config{ 18783 ServerECHConfigs: []ServerECHConfig{echConfig}, 18784 Bugs: ProtocolBugs{ 18785 ExpectServerName: "secret.example", 18786 }, 18787 Credential: &echSecretCertificate, 18788 }, 18789 resumeConfig: &Config{ 18790 MaxVersion: VersionTLS12, 18791 Bugs: ProtocolBugs{ 18792 ExpectServerName: "public.example", 18793 }, 18794 Credential: &echPublicCertificate, 18795 }, 18796 flags: []string{ 18797 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18798 "-host-name", "secret.example", 18799 // Although the resumption connection does not accept ECH, the 18800 // API will report ECH was accepted at the 0-RTT point. 18801 "-expect-ech-accept", 18802 }, 18803 resumeSession: true, 18804 expectResumeRejected: true, 18805 earlyData: true, 18806 expectEarlyDataRejected: true, 18807 expectations: connectionExpectations{echAccepted: true}, 18808 resumeExpectations: &connectionExpectations{echAccepted: false}, 18809 // ClientHellos with early data cannot negotiate TLS 1.2, with 18810 // or without ECH. The shim should first report 18811 // |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. The caller will then 18812 // repair the first error by retrying without early data. That 18813 // will look like ECH-Client-Reject-TLS12 and select TLS 1.2 18814 // and ClientHelloOuter. The caller will then trigger a third 18815 // attempt, which will succeed. 18816 shouldFail: true, 18817 expectedError: ":WRONG_VERSION_ON_EARLY_DATA:", 18818 }) 18819 } 18820 18821 // Test that the client ignores ECHConfigs with invalid public names. 18822 invalidPublicName := generateServerECHConfig(&ECHConfig{PublicName: "dns_names_have_no_underscores.example"}) 18823 testCases = append(testCases, testCase{ 18824 testType: clientTest, 18825 protocol: protocol, 18826 name: prefix + "ECH-Client-SkipInvalidPublicName", 18827 config: Config{ 18828 Bugs: ProtocolBugs{ 18829 // No ECHConfigs are supported, so the client should fall 18830 // back to cleartext. 18831 ExpectNoClientECH: true, 18832 ExpectServerName: "secret.example", 18833 }, 18834 Credential: &echSecretCertificate, 18835 }, 18836 flags: []string{ 18837 "-ech-config-list", base64FlagValue(CreateECHConfigList(invalidPublicName.ECHConfig.Raw)), 18838 "-host-name", "secret.example", 18839 }, 18840 }) 18841 testCases = append(testCases, testCase{ 18842 testType: clientTest, 18843 protocol: protocol, 18844 name: prefix + "ECH-Client-SkipInvalidPublicName-2", 18845 config: Config{ 18846 // The client should skip |invalidPublicName| and use |echConfig|. 18847 ServerECHConfigs: []ServerECHConfig{echConfig}, 18848 Bugs: ProtocolBugs{ 18849 ExpectOuterServerName: "public.example", 18850 ExpectServerName: "secret.example", 18851 }, 18852 Credential: &echSecretCertificate, 18853 }, 18854 flags: []string{ 18855 "-ech-config-list", base64FlagValue(CreateECHConfigList(invalidPublicName.ECHConfig.Raw, echConfig.ECHConfig.Raw)), 18856 "-host-name", "secret.example", 18857 "-expect-ech-accept", 18858 }, 18859 expectations: connectionExpectations{echAccepted: true}, 18860 }) 18861 18862 // Test both sync and async mode, to test both with and without the 18863 // client certificate callback. 18864 for _, async := range []bool{false, true} { 18865 var flags []string 18866 var suffix string 18867 if async { 18868 flags = []string{"-async"} 18869 suffix = "-Async" 18870 } 18871 18872 // Test that ECH and client certificates can be used together. 18873 testCases = append(testCases, testCase{ 18874 testType: clientTest, 18875 protocol: protocol, 18876 name: prefix + "ECH-Client-ClientCertificate" + suffix, 18877 config: Config{ 18878 ServerECHConfigs: []ServerECHConfig{echConfig}, 18879 ClientAuth: RequireAnyClientCert, 18880 }, 18881 shimCertificate: &rsaCertificate, 18882 flags: append([]string{ 18883 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18884 "-expect-ech-accept", 18885 }, flags...), 18886 expectations: connectionExpectations{echAccepted: true}, 18887 }) 18888 18889 // Test that, when ECH is rejected, the client does not send a client 18890 // certificate. 18891 testCases = append(testCases, testCase{ 18892 testType: clientTest, 18893 protocol: protocol, 18894 name: prefix + "ECH-Client-Reject-NoClientCertificate-TLS13" + suffix, 18895 config: Config{ 18896 MinVersion: VersionTLS13, 18897 MaxVersion: VersionTLS13, 18898 ClientAuth: RequireAnyClientCert, 18899 Credential: &echPublicCertificate, 18900 }, 18901 shimCertificate: &rsaCertificate, 18902 flags: append([]string{ 18903 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18904 }, flags...), 18905 shouldFail: true, 18906 expectedLocalError: "tls: client didn't provide a certificate", 18907 }) 18908 if protocol != quic { 18909 testCases = append(testCases, testCase{ 18910 testType: clientTest, 18911 protocol: protocol, 18912 name: prefix + "ECH-Client-Reject-NoClientCertificate-TLS12" + suffix, 18913 config: Config{ 18914 MinVersion: VersionTLS12, 18915 MaxVersion: VersionTLS12, 18916 ClientAuth: RequireAnyClientCert, 18917 Credential: &echPublicCertificate, 18918 }, 18919 shimCertificate: &rsaCertificate, 18920 flags: append([]string{ 18921 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18922 }, flags...), 18923 shouldFail: true, 18924 expectedLocalError: "tls: client didn't provide a certificate", 18925 }) 18926 } 18927 } 18928 18929 // Test that ECH and Channel ID can be used together. 18930 testCases = append(testCases, testCase{ 18931 testType: clientTest, 18932 protocol: protocol, 18933 name: prefix + "ECH-Client-ChannelID", 18934 config: Config{ 18935 ServerECHConfigs: []ServerECHConfig{echConfig}, 18936 RequestChannelID: true, 18937 }, 18938 flags: []string{ 18939 "-send-channel-id", channelIDKeyPath, 18940 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18941 "-expect-ech-accept", 18942 }, 18943 resumeSession: true, 18944 expectations: connectionExpectations{ 18945 channelID: true, 18946 echAccepted: true, 18947 }, 18948 }) 18949 18950 // Handshakes where ECH is rejected do not offer or accept Channel ID. 18951 testCases = append(testCases, testCase{ 18952 testType: clientTest, 18953 protocol: protocol, 18954 name: prefix + "ECH-Client-Reject-NoChannelID-TLS13", 18955 config: Config{ 18956 MinVersion: VersionTLS13, 18957 MaxVersion: VersionTLS13, 18958 Bugs: ProtocolBugs{ 18959 AlwaysNegotiateChannelID: true, 18960 }, 18961 Credential: &echPublicCertificate, 18962 }, 18963 flags: []string{ 18964 "-send-channel-id", channelIDKeyPath, 18965 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18966 }, 18967 shouldFail: true, 18968 expectedLocalError: "remote error: unsupported extension", 18969 expectedError: ":UNEXPECTED_EXTENSION:", 18970 }) 18971 if protocol != quic { 18972 testCases = append(testCases, testCase{ 18973 testType: clientTest, 18974 protocol: protocol, 18975 name: prefix + "ECH-Client-Reject-NoChannelID-TLS12", 18976 config: Config{ 18977 MinVersion: VersionTLS12, 18978 MaxVersion: VersionTLS12, 18979 Bugs: ProtocolBugs{ 18980 AlwaysNegotiateChannelID: true, 18981 }, 18982 Credential: &echPublicCertificate, 18983 }, 18984 flags: []string{ 18985 "-send-channel-id", channelIDKeyPath, 18986 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18987 }, 18988 shouldFail: true, 18989 expectedLocalError: "remote error: unsupported extension", 18990 expectedError: ":UNEXPECTED_EXTENSION:", 18991 }) 18992 } 18993 18994 // Test that ECH correctly overrides the host name for certificate 18995 // verification. 18996 testCases = append(testCases, testCase{ 18997 testType: clientTest, 18998 protocol: protocol, 18999 name: prefix + "ECH-Client-NotOffered-NoOverrideName", 19000 flags: []string{ 19001 "-verify-peer", 19002 "-use-custom-verify-callback", 19003 // When not offering ECH, verify the usual name in both full 19004 // and resumption handshakes. 19005 "-reverify-on-resume", 19006 "-expect-no-ech-name-override", 19007 }, 19008 resumeSession: true, 19009 }) 19010 testCases = append(testCases, testCase{ 19011 testType: clientTest, 19012 protocol: protocol, 19013 name: prefix + "ECH-Client-GREASE-NoOverrideName", 19014 flags: []string{ 19015 "-verify-peer", 19016 "-use-custom-verify-callback", 19017 "-enable-ech-grease", 19018 // When offering ECH GREASE, verify the usual name in both full 19019 // and resumption handshakes. 19020 "-reverify-on-resume", 19021 "-expect-no-ech-name-override", 19022 }, 19023 resumeSession: true, 19024 }) 19025 if protocol != quic { 19026 testCases = append(testCases, testCase{ 19027 testType: clientTest, 19028 protocol: protocol, 19029 name: prefix + "ECH-Client-Rejected-OverrideName-TLS12", 19030 config: Config{ 19031 MinVersion: VersionTLS12, 19032 MaxVersion: VersionTLS12, 19033 }, 19034 flags: []string{ 19035 "-verify-peer", 19036 "-use-custom-verify-callback", 19037 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 19038 // When ECH is rejected, verify the public name. This can 19039 // only happen in full handshakes. 19040 "-expect-ech-name-override", "public.example", 19041 }, 19042 shouldFail: true, 19043 expectedError: ":ECH_REJECTED:", 19044 expectedLocalError: "remote error: ECH required", 19045 }) 19046 } 19047 testCases = append(testCases, testCase{ 19048 testType: clientTest, 19049 protocol: protocol, 19050 name: prefix + "ECH-Client-Reject-OverrideName-TLS13", 19051 config: Config{ 19052 MinVersion: VersionTLS13, 19053 MaxVersion: VersionTLS13, 19054 Credential: &echPublicCertificate, 19055 }, 19056 flags: []string{ 19057 "-verify-peer", 19058 "-use-custom-verify-callback", 19059 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 19060 // When ECH is rejected, verify the public name. This can 19061 // only happen in full handshakes. 19062 "-expect-ech-name-override", "public.example", 19063 }, 19064 shouldFail: true, 19065 expectedError: ":ECH_REJECTED:", 19066 expectedLocalError: "remote error: ECH required", 19067 }) 19068 testCases = append(testCases, testCase{ 19069 testType: clientTest, 19070 protocol: protocol, 19071 name: prefix + "ECH-Client-Accept-NoOverrideName", 19072 config: Config{ 19073 ServerECHConfigs: []ServerECHConfig{echConfig}, 19074 }, 19075 flags: []string{ 19076 "-verify-peer", 19077 "-use-custom-verify-callback", 19078 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 19079 "-expect-ech-accept", 19080 // When ECH is accepted, verify the usual name in both full and 19081 // resumption handshakes. 19082 "-reverify-on-resume", 19083 "-expect-no-ech-name-override", 19084 }, 19085 resumeSession: true, 19086 expectations: connectionExpectations{echAccepted: true}, 19087 }) 19088 testCases = append(testCases, testCase{ 19089 testType: clientTest, 19090 protocol: protocol, 19091 name: prefix + "ECH-Client-Reject-EarlyDataRejected-OverrideNameOnRetry", 19092 config: Config{ 19093 ServerECHConfigs: []ServerECHConfig{echConfig}, 19094 Credential: &echPublicCertificate, 19095 }, 19096 resumeConfig: &Config{ 19097 Credential: &echPublicCertificate, 19098 }, 19099 flags: []string{ 19100 "-verify-peer", 19101 "-use-custom-verify-callback", 19102 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 19103 // Although the resumption connection does not accept ECH, the 19104 // API will report ECH was accepted at the 0-RTT point. 19105 "-expect-ech-accept", 19106 // The resumption connection verifies certificates twice. First, 19107 // if reverification is enabled, we verify the 0-RTT certificate 19108 // as if ECH as accepted. There should be no name override. 19109 // Next, on the post-0-RTT-rejection retry, we verify the new 19110 // server certificate. This picks up the ECH reject, so it 19111 // should use public.example. 19112 "-reverify-on-resume", 19113 "-on-resume-expect-no-ech-name-override", 19114 "-on-retry-expect-ech-name-override", "public.example", 19115 }, 19116 resumeSession: true, 19117 expectResumeRejected: true, 19118 earlyData: true, 19119 expectEarlyDataRejected: true, 19120 expectations: connectionExpectations{echAccepted: true}, 19121 resumeExpectations: &connectionExpectations{echAccepted: false}, 19122 shouldFail: true, 19123 expectedError: ":ECH_REJECTED:", 19124 expectedLocalError: "remote error: ECH required", 19125 }) 19126 19127 // Test that the client checks both HelloRetryRequest and ServerHello 19128 // for a confirmation signal. 19129 testCases = append(testCases, testCase{ 19130 testType: clientTest, 19131 protocol: protocol, 19132 name: prefix + "ECH-Client-HelloRetryRequest-MissingServerHelloConfirmation", 19133 config: Config{ 19134 MinVersion: VersionTLS13, 19135 MaxVersion: VersionTLS13, 19136 CurvePreferences: []CurveID{CurveP384}, 19137 ServerECHConfigs: []ServerECHConfig{echConfig}, 19138 Bugs: ProtocolBugs{ 19139 ExpectMissingKeyShare: true, // Check we triggered HRR. 19140 OmitServerHelloECHConfirmation: true, 19141 }, 19142 }, 19143 resumeSession: true, 19144 flags: []string{ 19145 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 19146 "-expect-hrr", // Check we triggered HRR. 19147 }, 19148 shouldFail: true, 19149 expectedError: ":INCONSISTENT_ECH_NEGOTIATION:", 19150 }) 19151 19152 // Test the message callback is correctly reported, with and without 19153 // HelloRetryRequest. 19154 clientAndServerHello := "write clienthelloinner\nwrite hs 1\nread hs 2\n" 19155 // EncryptedExtensions onwards. 19156 finishHandshake := `read hs 8 19157read hs 11 19158read hs 15 19159read hs 20 19160write hs 20 19161read hs 4 19162read hs 4 19163` 19164 testCases = append(testCases, testCase{ 19165 testType: clientTest, 19166 protocol: protocol, 19167 name: prefix + "ECH-Client-MessageCallback", 19168 config: Config{ 19169 MinVersion: VersionTLS13, 19170 MaxVersion: VersionTLS13, 19171 ServerECHConfigs: []ServerECHConfig{echConfig}, 19172 Bugs: ProtocolBugs{ 19173 NoCloseNotify: true, // Align QUIC and TCP traces. 19174 }, 19175 }, 19176 flags: []string{ 19177 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 19178 "-expect-ech-accept", 19179 "-expect-msg-callback", clientAndServerHello + "write ccs\n" + finishHandshake, 19180 }, 19181 expectations: connectionExpectations{echAccepted: true}, 19182 }) 19183 testCases = append(testCases, testCase{ 19184 testType: clientTest, 19185 protocol: protocol, 19186 name: prefix + "ECH-Client-MessageCallback-HelloRetryRequest", 19187 config: Config{ 19188 MinVersion: VersionTLS13, 19189 MaxVersion: VersionTLS13, 19190 CurvePreferences: []CurveID{CurveP384}, 19191 ServerECHConfigs: []ServerECHConfig{echConfig}, 19192 Bugs: ProtocolBugs{ 19193 ExpectMissingKeyShare: true, // Check we triggered HRR. 19194 NoCloseNotify: true, // Align QUIC and TCP traces. 19195 }, 19196 }, 19197 flags: []string{ 19198 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 19199 "-expect-ech-accept", 19200 "-expect-hrr", // Check we triggered HRR. 19201 "-expect-msg-callback", clientAndServerHello + "write ccs\n" + clientAndServerHello + finishHandshake, 19202 }, 19203 expectations: connectionExpectations{echAccepted: true}, 19204 }) 19205 } 19206} 19207 19208func addHintMismatchTests() { 19209 // Each of these tests skips split handshakes because split handshakes does 19210 // not handle a mismatch between shim and handshaker. Handshake hints, 19211 // however, are designed to tolerate the mismatch. 19212 // 19213 // Note also these tests do not specify -handshake-hints directly. Instead, 19214 // we define normal tests, that run even without a handshaker, and rely on 19215 // convertToSplitHandshakeTests to generate a handshaker hints variant. This 19216 // avoids repeating the -is-handshaker-supported and -handshaker-path logic. 19217 // (While not useful, the tests will still pass without a handshaker.) 19218 for _, protocol := range []protocol{tls, quic} { 19219 // If the signing payload is different, the handshake still completes 19220 // successfully. Different ALPN preferences will trigger a mismatch. 19221 testCases = append(testCases, testCase{ 19222 name: protocol.String() + "-HintMismatch-SignatureInput", 19223 testType: serverTest, 19224 protocol: protocol, 19225 skipSplitHandshake: true, 19226 config: Config{ 19227 MinVersion: VersionTLS13, 19228 MaxVersion: VersionTLS13, 19229 NextProtos: []string{"foo", "bar"}, 19230 }, 19231 flags: []string{ 19232 "-allow-hint-mismatch", 19233 "-on-shim-select-alpn", "foo", 19234 "-on-handshaker-select-alpn", "bar", 19235 }, 19236 expectations: connectionExpectations{ 19237 nextProto: "foo", 19238 nextProtoType: alpn, 19239 }, 19240 }) 19241 19242 // The shim and handshaker may have different curve preferences. 19243 testCases = append(testCases, testCase{ 19244 name: protocol.String() + "-HintMismatch-KeyShare", 19245 testType: serverTest, 19246 protocol: protocol, 19247 skipSplitHandshake: true, 19248 config: Config{ 19249 MinVersion: VersionTLS13, 19250 MaxVersion: VersionTLS13, 19251 // Send both curves in the key share list, to avoid getting 19252 // mixed up with HelloRetryRequest. 19253 DefaultCurves: []CurveID{CurveX25519, CurveP256}, 19254 }, 19255 flags: []string{ 19256 "-allow-hint-mismatch", 19257 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 19258 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 19259 }, 19260 expectations: connectionExpectations{ 19261 curveID: CurveX25519, 19262 }, 19263 }) 19264 if protocol != quic { 19265 testCases = append(testCases, testCase{ 19266 name: protocol.String() + "-HintMismatch-ECDHE-Group", 19267 testType: serverTest, 19268 protocol: protocol, 19269 skipSplitHandshake: true, 19270 config: Config{ 19271 MinVersion: VersionTLS12, 19272 MaxVersion: VersionTLS12, 19273 DefaultCurves: []CurveID{CurveX25519, CurveP256}, 19274 }, 19275 flags: []string{ 19276 "-allow-hint-mismatch", 19277 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 19278 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 19279 }, 19280 expectations: connectionExpectations{ 19281 curveID: CurveX25519, 19282 }, 19283 }) 19284 } 19285 19286 // If the handshaker does HelloRetryRequest, it will omit most hints. 19287 // The shim should still work. 19288 testCases = append(testCases, testCase{ 19289 name: protocol.String() + "-HintMismatch-HandshakerHelloRetryRequest", 19290 testType: serverTest, 19291 protocol: protocol, 19292 skipSplitHandshake: true, 19293 config: Config{ 19294 MinVersion: VersionTLS13, 19295 MaxVersion: VersionTLS13, 19296 DefaultCurves: []CurveID{CurveX25519}, 19297 }, 19298 flags: []string{ 19299 "-allow-hint-mismatch", 19300 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 19301 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 19302 }, 19303 expectations: connectionExpectations{ 19304 curveID: CurveX25519, 19305 }, 19306 }) 19307 19308 // If the shim does HelloRetryRequest, the hints from the handshaker 19309 // will be ignored. This is not reported as a mismatch because hints 19310 // would not have helped the shim anyway. 19311 testCases = append(testCases, testCase{ 19312 name: protocol.String() + "-HintMismatch-ShimHelloRetryRequest", 19313 testType: serverTest, 19314 protocol: protocol, 19315 skipSplitHandshake: true, 19316 config: Config{ 19317 MinVersion: VersionTLS13, 19318 MaxVersion: VersionTLS13, 19319 DefaultCurves: []CurveID{CurveX25519}, 19320 }, 19321 flags: []string{ 19322 "-on-shim-curves", strconv.Itoa(int(CurveP256)), 19323 "-on-handshaker-curves", strconv.Itoa(int(CurveX25519)), 19324 }, 19325 expectations: connectionExpectations{ 19326 curveID: CurveP256, 19327 }, 19328 }) 19329 19330 // The shim and handshaker may have different signature algorithm 19331 // preferences. 19332 testCases = append(testCases, testCase{ 19333 name: protocol.String() + "-HintMismatch-SignatureAlgorithm-TLS13", 19334 testType: serverTest, 19335 protocol: protocol, 19336 skipSplitHandshake: true, 19337 config: Config{ 19338 MinVersion: VersionTLS13, 19339 MaxVersion: VersionTLS13, 19340 VerifySignatureAlgorithms: []signatureAlgorithm{ 19341 signatureRSAPSSWithSHA256, 19342 signatureRSAPSSWithSHA384, 19343 }, 19344 }, 19345 shimCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 19346 handshakerCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA384), 19347 flags: []string{"-allow-hint-mismatch"}, 19348 expectations: connectionExpectations{ 19349 peerSignatureAlgorithm: signatureRSAPSSWithSHA256, 19350 }, 19351 }) 19352 if protocol != quic { 19353 testCases = append(testCases, testCase{ 19354 name: protocol.String() + "-HintMismatch-SignatureAlgorithm-TLS12", 19355 testType: serverTest, 19356 protocol: protocol, 19357 skipSplitHandshake: true, 19358 config: Config{ 19359 MinVersion: VersionTLS12, 19360 MaxVersion: VersionTLS12, 19361 VerifySignatureAlgorithms: []signatureAlgorithm{ 19362 signatureRSAPSSWithSHA256, 19363 signatureRSAPSSWithSHA384, 19364 }, 19365 }, 19366 shimCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 19367 handshakerCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA384), 19368 flags: []string{"-allow-hint-mismatch"}, 19369 expectations: connectionExpectations{ 19370 peerSignatureAlgorithm: signatureRSAPSSWithSHA256, 19371 }, 19372 }) 19373 } 19374 19375 // The shim and handshaker may use different certificates. In TLS 1.3, 19376 // the signature input includes the certificate, so we do not need to 19377 // explicitly check for a public key match. In TLS 1.2, it does not. 19378 ecdsaP256Certificate2 := generateSingleCertChain(nil, &channelIDKey) 19379 testCases = append(testCases, testCase{ 19380 name: protocol.String() + "-HintMismatch-Certificate-TLS13", 19381 testType: serverTest, 19382 protocol: protocol, 19383 skipSplitHandshake: true, 19384 config: Config{ 19385 MinVersion: VersionTLS13, 19386 MaxVersion: VersionTLS13, 19387 }, 19388 shimCertificate: &ecdsaP256Certificate, 19389 handshakerCertificate: &ecdsaP256Certificate2, 19390 flags: []string{"-allow-hint-mismatch"}, 19391 expectations: connectionExpectations{ 19392 peerCertificate: &ecdsaP256Certificate, 19393 }, 19394 }) 19395 if protocol != quic { 19396 testCases = append(testCases, testCase{ 19397 name: protocol.String() + "-HintMismatch-Certificate-TLS12", 19398 testType: serverTest, 19399 protocol: protocol, 19400 skipSplitHandshake: true, 19401 config: Config{ 19402 MinVersion: VersionTLS12, 19403 MaxVersion: VersionTLS12, 19404 }, 19405 shimCertificate: &ecdsaP256Certificate, 19406 handshakerCertificate: &ecdsaP256Certificate2, 19407 flags: []string{"-allow-hint-mismatch"}, 19408 expectations: connectionExpectations{ 19409 peerCertificate: &ecdsaP256Certificate, 19410 }, 19411 }) 19412 } 19413 19414 // The shim and handshaker may disagree on whether resumption is allowed. 19415 // We run the first connection with tickets enabled, so the client is 19416 // issued a ticket, then disable tickets on the second connection. 19417 testCases = append(testCases, testCase{ 19418 name: protocol.String() + "-HintMismatch-NoTickets1-TLS13", 19419 testType: serverTest, 19420 protocol: protocol, 19421 skipSplitHandshake: true, 19422 config: Config{ 19423 MinVersion: VersionTLS13, 19424 MaxVersion: VersionTLS13, 19425 }, 19426 flags: []string{ 19427 "-on-resume-allow-hint-mismatch", 19428 "-on-shim-on-resume-no-ticket", 19429 }, 19430 resumeSession: true, 19431 expectResumeRejected: true, 19432 }) 19433 testCases = append(testCases, testCase{ 19434 name: protocol.String() + "-HintMismatch-NoTickets2-TLS13", 19435 testType: serverTest, 19436 protocol: protocol, 19437 skipSplitHandshake: true, 19438 config: Config{ 19439 MinVersion: VersionTLS13, 19440 MaxVersion: VersionTLS13, 19441 }, 19442 flags: []string{ 19443 "-on-resume-allow-hint-mismatch", 19444 "-on-handshaker-on-resume-no-ticket", 19445 }, 19446 resumeSession: true, 19447 }) 19448 if protocol != quic { 19449 testCases = append(testCases, testCase{ 19450 name: protocol.String() + "-HintMismatch-NoTickets1-TLS12", 19451 testType: serverTest, 19452 protocol: protocol, 19453 skipSplitHandshake: true, 19454 config: Config{ 19455 MinVersion: VersionTLS12, 19456 MaxVersion: VersionTLS12, 19457 }, 19458 flags: []string{ 19459 "-on-resume-allow-hint-mismatch", 19460 "-on-shim-on-resume-no-ticket", 19461 }, 19462 resumeSession: true, 19463 expectResumeRejected: true, 19464 }) 19465 testCases = append(testCases, testCase{ 19466 name: protocol.String() + "-HintMismatch-NoTickets2-TLS12", 19467 testType: serverTest, 19468 protocol: protocol, 19469 skipSplitHandshake: true, 19470 config: Config{ 19471 MinVersion: VersionTLS12, 19472 MaxVersion: VersionTLS12, 19473 }, 19474 flags: []string{ 19475 "-on-resume-allow-hint-mismatch", 19476 "-on-handshaker-on-resume-no-ticket", 19477 }, 19478 resumeSession: true, 19479 }) 19480 } 19481 19482 // The shim and handshaker may disagree on whether to request a client 19483 // certificate. 19484 testCases = append(testCases, testCase{ 19485 name: protocol.String() + "-HintMismatch-CertificateRequest", 19486 testType: serverTest, 19487 protocol: protocol, 19488 skipSplitHandshake: true, 19489 config: Config{ 19490 MinVersion: VersionTLS13, 19491 MaxVersion: VersionTLS13, 19492 Credential: &rsaCertificate, 19493 }, 19494 flags: []string{ 19495 "-allow-hint-mismatch", 19496 "-on-shim-require-any-client-certificate", 19497 }, 19498 }) 19499 19500 // The shim and handshaker may negotiate different versions altogether. 19501 if protocol != quic { 19502 testCases = append(testCases, testCase{ 19503 name: protocol.String() + "-HintMismatch-Version1", 19504 testType: serverTest, 19505 protocol: protocol, 19506 skipSplitHandshake: true, 19507 config: Config{ 19508 MinVersion: VersionTLS12, 19509 MaxVersion: VersionTLS13, 19510 }, 19511 flags: []string{ 19512 "-allow-hint-mismatch", 19513 "-on-shim-max-version", strconv.Itoa(VersionTLS12), 19514 "-on-handshaker-max-version", strconv.Itoa(VersionTLS13), 19515 }, 19516 expectations: connectionExpectations{ 19517 version: VersionTLS12, 19518 }, 19519 }) 19520 testCases = append(testCases, testCase{ 19521 name: protocol.String() + "-HintMismatch-Version2", 19522 testType: serverTest, 19523 protocol: protocol, 19524 skipSplitHandshake: true, 19525 config: Config{ 19526 MinVersion: VersionTLS12, 19527 MaxVersion: VersionTLS13, 19528 }, 19529 flags: []string{ 19530 "-allow-hint-mismatch", 19531 "-on-shim-max-version", strconv.Itoa(VersionTLS13), 19532 "-on-handshaker-max-version", strconv.Itoa(VersionTLS12), 19533 }, 19534 expectations: connectionExpectations{ 19535 version: VersionTLS13, 19536 }, 19537 }) 19538 } 19539 19540 // The shim and handshaker may disagree on the certificate compression 19541 // algorithm, whether to enable certificate compression, or certificate 19542 // compression inputs. 19543 testCases = append(testCases, testCase{ 19544 name: protocol.String() + "-HintMismatch-CertificateCompression-ShimOnly", 19545 testType: serverTest, 19546 protocol: protocol, 19547 skipSplitHandshake: true, 19548 config: Config{ 19549 MinVersion: VersionTLS13, 19550 MaxVersion: VersionTLS13, 19551 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19552 shrinkingCompressionAlgID: shrinkingCompression, 19553 }, 19554 Bugs: ProtocolBugs{ 19555 ExpectedCompressedCert: shrinkingCompressionAlgID, 19556 }, 19557 }, 19558 flags: []string{ 19559 "-allow-hint-mismatch", 19560 "-on-shim-install-cert-compression-algs", 19561 }, 19562 }) 19563 testCases = append(testCases, testCase{ 19564 name: protocol.String() + "-HintMismatch-CertificateCompression-HandshakerOnly", 19565 testType: serverTest, 19566 protocol: protocol, 19567 skipSplitHandshake: true, 19568 config: Config{ 19569 MinVersion: VersionTLS13, 19570 MaxVersion: VersionTLS13, 19571 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19572 shrinkingCompressionAlgID: shrinkingCompression, 19573 }, 19574 Bugs: ProtocolBugs{ 19575 ExpectUncompressedCert: true, 19576 }, 19577 }, 19578 flags: []string{ 19579 "-allow-hint-mismatch", 19580 "-on-handshaker-install-cert-compression-algs", 19581 }, 19582 }) 19583 testCases = append(testCases, testCase{ 19584 testType: serverTest, 19585 name: protocol.String() + "-HintMismatch-CertificateCompression-AlgorithmMismatch", 19586 protocol: protocol, 19587 skipSplitHandshake: true, 19588 config: Config{ 19589 MinVersion: VersionTLS13, 19590 MaxVersion: VersionTLS13, 19591 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19592 shrinkingCompressionAlgID: shrinkingCompression, 19593 expandingCompressionAlgID: expandingCompression, 19594 }, 19595 Bugs: ProtocolBugs{ 19596 // The shim's preferences should take effect. 19597 ExpectedCompressedCert: shrinkingCompressionAlgID, 19598 }, 19599 }, 19600 flags: []string{ 19601 "-allow-hint-mismatch", 19602 "-on-shim-install-one-cert-compression-alg", strconv.Itoa(shrinkingCompressionAlgID), 19603 "-on-handshaker-install-one-cert-compression-alg", strconv.Itoa(expandingCompressionAlgID), 19604 }, 19605 }) 19606 testCases = append(testCases, testCase{ 19607 testType: serverTest, 19608 name: protocol.String() + "-HintMismatch-CertificateCompression-InputMismatch", 19609 protocol: protocol, 19610 skipSplitHandshake: true, 19611 config: Config{ 19612 MinVersion: VersionTLS13, 19613 MaxVersion: VersionTLS13, 19614 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19615 shrinkingCompressionAlgID: shrinkingCompression, 19616 }, 19617 Bugs: ProtocolBugs{ 19618 ExpectedCompressedCert: shrinkingCompressionAlgID, 19619 }, 19620 }, 19621 // Configure the shim and handshaker with different OCSP responses, 19622 // so the compression inputs do not match. 19623 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 19624 handshakerCertificate: rsaCertificate.WithOCSP(testOCSPResponse2), 19625 flags: []string{ 19626 "-allow-hint-mismatch", 19627 "-install-cert-compression-algs", 19628 }, 19629 expectations: connectionExpectations{ 19630 // The shim's configuration should take precendence. 19631 peerCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 19632 }, 19633 }) 19634 19635 // The shim and handshaker may disagree on cipher suite, to the point 19636 // that one selects RSA key exchange (no applicable hint) and the other 19637 // selects ECDHE_RSA (hints are useful). 19638 if protocol != quic { 19639 testCases = append(testCases, testCase{ 19640 testType: serverTest, 19641 name: protocol.String() + "-HintMismatch-CipherMismatch1", 19642 protocol: protocol, 19643 skipSplitHandshake: true, 19644 config: Config{ 19645 MinVersion: VersionTLS12, 19646 MaxVersion: VersionTLS12, 19647 }, 19648 flags: []string{ 19649 "-allow-hint-mismatch", 19650 "-on-shim-cipher", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 19651 "-on-handshaker-cipher", "TLS_RSA_WITH_AES_128_GCM_SHA256", 19652 }, 19653 expectations: connectionExpectations{ 19654 cipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 19655 }, 19656 }) 19657 testCases = append(testCases, testCase{ 19658 testType: serverTest, 19659 name: protocol.String() + "-HintMismatch-CipherMismatch2", 19660 protocol: protocol, 19661 skipSplitHandshake: true, 19662 config: Config{ 19663 MinVersion: VersionTLS12, 19664 MaxVersion: VersionTLS12, 19665 }, 19666 flags: []string{ 19667 // There is no need to pass -allow-hint-mismatch. The 19668 // handshaker will unnecessarily generate a signature hints. 19669 // This is not reported as a mismatch because hints would 19670 // not have helped the shim anyway. 19671 "-on-shim-cipher", "TLS_RSA_WITH_AES_128_GCM_SHA256", 19672 "-on-handshaker-cipher", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 19673 }, 19674 expectations: connectionExpectations{ 19675 cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, 19676 }, 19677 }) 19678 } 19679 } 19680} 19681 19682func addCompliancePolicyTests() { 19683 for _, protocol := range []protocol{tls, quic} { 19684 for _, suite := range testCipherSuites { 19685 var isFIPSCipherSuite bool 19686 switch suite.id { 19687 case TLS_AES_128_GCM_SHA256, 19688 TLS_AES_256_GCM_SHA384, 19689 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 19690 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 19691 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 19692 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: 19693 isFIPSCipherSuite = true 19694 } 19695 19696 var isWPACipherSuite bool 19697 switch suite.id { 19698 case TLS_AES_256_GCM_SHA384, 19699 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 19700 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: 19701 isWPACipherSuite = true 19702 } 19703 19704 var cert Credential 19705 if hasComponent(suite.name, "ECDSA") { 19706 cert = ecdsaP384Certificate 19707 } else { 19708 cert = rsaCertificate 19709 } 19710 19711 maxVersion := uint16(VersionTLS13) 19712 if !isTLS13Suite(suite.name) { 19713 if protocol == quic { 19714 continue 19715 } 19716 maxVersion = VersionTLS12 19717 } 19718 19719 policies := []struct { 19720 flag string 19721 cipherSuiteOk bool 19722 }{ 19723 {"-fips-202205", isFIPSCipherSuite}, 19724 {"-wpa-202304", isWPACipherSuite}, 19725 } 19726 19727 for _, policy := range policies { 19728 testCases = append(testCases, testCase{ 19729 testType: serverTest, 19730 protocol: protocol, 19731 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + suite.name, 19732 config: Config{ 19733 MinVersion: VersionTLS12, 19734 MaxVersion: maxVersion, 19735 CipherSuites: []uint16{suite.id}, 19736 }, 19737 shimCertificate: &cert, 19738 flags: []string{ 19739 policy.flag, 19740 }, 19741 shouldFail: !policy.cipherSuiteOk, 19742 }) 19743 19744 testCases = append(testCases, testCase{ 19745 testType: clientTest, 19746 protocol: protocol, 19747 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + suite.name, 19748 config: Config{ 19749 MinVersion: VersionTLS12, 19750 MaxVersion: maxVersion, 19751 CipherSuites: []uint16{suite.id}, 19752 Credential: &cert, 19753 }, 19754 flags: []string{ 19755 policy.flag, 19756 }, 19757 shouldFail: !policy.cipherSuiteOk, 19758 }) 19759 } 19760 } 19761 19762 // Check that a TLS 1.3 client won't accept ChaCha20 even if the server 19763 // picks it without it being in the client's cipher list. 19764 testCases = append(testCases, testCase{ 19765 testType: clientTest, 19766 protocol: protocol, 19767 name: "Compliance-fips202205-" + protocol.String() + "-Client-ReallyWontAcceptChaCha", 19768 config: Config{ 19769 MinVersion: VersionTLS12, 19770 MaxVersion: maxVersion, 19771 Bugs: ProtocolBugs{ 19772 SendCipherSuite: TLS_CHACHA20_POLY1305_SHA256, 19773 }, 19774 }, 19775 flags: []string{ 19776 "-fips-202205", 19777 }, 19778 shouldFail: true, 19779 expectedError: ":WRONG_CIPHER_RETURNED:", 19780 }) 19781 19782 for _, curve := range testCurves { 19783 var isFIPSCurve bool 19784 switch curve.id { 19785 case CurveP256, CurveP384: 19786 isFIPSCurve = true 19787 } 19788 19789 var isWPACurve bool 19790 switch curve.id { 19791 case CurveP384: 19792 isWPACurve = true 19793 } 19794 19795 policies := []struct { 19796 flag string 19797 curveOk bool 19798 }{ 19799 {"-fips-202205", isFIPSCurve}, 19800 {"-wpa-202304", isWPACurve}, 19801 } 19802 19803 for _, policy := range policies { 19804 testCases = append(testCases, testCase{ 19805 testType: serverTest, 19806 protocol: protocol, 19807 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + curve.name, 19808 config: Config{ 19809 MinVersion: VersionTLS12, 19810 MaxVersion: VersionTLS13, 19811 CurvePreferences: []CurveID{curve.id}, 19812 }, 19813 flags: []string{ 19814 policy.flag, 19815 }, 19816 shouldFail: !policy.curveOk, 19817 }) 19818 19819 testCases = append(testCases, testCase{ 19820 testType: clientTest, 19821 protocol: protocol, 19822 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + curve.name, 19823 config: Config{ 19824 MinVersion: VersionTLS12, 19825 MaxVersion: VersionTLS13, 19826 CurvePreferences: []CurveID{curve.id}, 19827 }, 19828 flags: []string{ 19829 policy.flag, 19830 }, 19831 shouldFail: !policy.curveOk, 19832 }) 19833 } 19834 } 19835 19836 for _, sigalg := range testSignatureAlgorithms { 19837 // The TLS 1.0 and TLS 1.1 default signature algorithm does not 19838 // apply to these tests. 19839 if sigalg.id == 0 { 19840 continue 19841 } 19842 19843 var isFIPSSigAlg bool 19844 switch sigalg.id { 19845 case signatureRSAPKCS1WithSHA256, 19846 signatureRSAPKCS1WithSHA384, 19847 signatureRSAPKCS1WithSHA512, 19848 signatureECDSAWithP256AndSHA256, 19849 signatureECDSAWithP384AndSHA384, 19850 signatureRSAPSSWithSHA256, 19851 signatureRSAPSSWithSHA384, 19852 signatureRSAPSSWithSHA512: 19853 isFIPSSigAlg = true 19854 } 19855 19856 var isWPASigAlg bool 19857 switch sigalg.id { 19858 case signatureRSAPKCS1WithSHA384, 19859 signatureRSAPKCS1WithSHA512, 19860 signatureECDSAWithP384AndSHA384, 19861 signatureRSAPSSWithSHA384, 19862 signatureRSAPSSWithSHA512: 19863 isWPASigAlg = true 19864 } 19865 19866 if sigalg.curve == CurveP224 { 19867 // This can work in TLS 1.2, but not with TLS 1.3. 19868 // For consistency it's not permitted in FIPS mode. 19869 isFIPSSigAlg = false 19870 } 19871 19872 maxVersion := uint16(VersionTLS13) 19873 if hasComponent(sigalg.name, "PKCS1") { 19874 if protocol == quic { 19875 continue 19876 } 19877 maxVersion = VersionTLS12 19878 } 19879 19880 policies := []struct { 19881 flag string 19882 sigAlgOk bool 19883 }{ 19884 {"-fips-202205", isFIPSSigAlg}, 19885 {"-wpa-202304", isWPASigAlg}, 19886 } 19887 19888 cert := sigalg.baseCert.WithSignatureAlgorithms(sigalg.id) 19889 for _, policy := range policies { 19890 testCases = append(testCases, testCase{ 19891 testType: serverTest, 19892 protocol: protocol, 19893 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + sigalg.name, 19894 config: Config{ 19895 MinVersion: VersionTLS12, 19896 MaxVersion: maxVersion, 19897 VerifySignatureAlgorithms: []signatureAlgorithm{sigalg.id}, 19898 }, 19899 // Use the base certificate. We wish to pick up the signature algorithm 19900 // preferences from the FIPS policy. 19901 shimCertificate: sigalg.baseCert, 19902 flags: []string{policy.flag}, 19903 shouldFail: !policy.sigAlgOk, 19904 }) 19905 19906 testCases = append(testCases, testCase{ 19907 testType: clientTest, 19908 protocol: protocol, 19909 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + sigalg.name, 19910 config: Config{ 19911 MinVersion: VersionTLS12, 19912 MaxVersion: maxVersion, 19913 Credential: cert, 19914 }, 19915 flags: []string{ 19916 policy.flag, 19917 }, 19918 shouldFail: !policy.sigAlgOk, 19919 }) 19920 } 19921 } 19922 } 19923} 19924 19925func addCertificateSelectionTests() { 19926 // Combinatorially test each selection criteria at different versions, 19927 // protocols, and with the matching certificate before and after the 19928 // mismatching one. 19929 type certSelectTest struct { 19930 name string 19931 testType testType 19932 minVersion uint16 19933 maxVersion uint16 19934 config Config 19935 match *Credential 19936 mismatch *Credential 19937 flags []string 19938 expectedError string 19939 } 19940 certSelectTests := []certSelectTest{ 19941 // TLS 1.0 through TLS 1.2 servers should incorporate TLS cipher suites 19942 // into certificate selection. 19943 { 19944 name: "Server-CipherSuite-ECDHE_ECDSA", 19945 testType: serverTest, 19946 maxVersion: VersionTLS12, 19947 config: Config{ 19948 CipherSuites: []uint16{ 19949 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 19950 }, 19951 }, 19952 match: &ecdsaP256Certificate, 19953 mismatch: &rsaCertificate, 19954 expectedError: ":NO_SHARED_CIPHER:", 19955 }, 19956 { 19957 name: "Server-CipherSuite-ECDHE_RSA", 19958 testType: serverTest, 19959 maxVersion: VersionTLS12, 19960 config: Config{ 19961 CipherSuites: []uint16{ 19962 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 19963 }, 19964 }, 19965 match: &rsaCertificate, 19966 mismatch: &ecdsaP256Certificate, 19967 expectedError: ":NO_SHARED_CIPHER:", 19968 }, 19969 { 19970 name: "Server-CipherSuite-RSA", 19971 testType: serverTest, 19972 maxVersion: VersionTLS12, 19973 config: Config{ 19974 CipherSuites: []uint16{ 19975 TLS_RSA_WITH_AES_128_CBC_SHA, 19976 }, 19977 }, 19978 match: &rsaCertificate, 19979 mismatch: &ecdsaP256Certificate, 19980 expectedError: ":NO_SHARED_CIPHER:", 19981 }, 19982 19983 // Ed25519 counts as ECDSA for purposes of cipher suite matching. 19984 { 19985 name: "Server-CipherSuite-ECDHE_ECDSA-Ed25519", 19986 testType: serverTest, 19987 minVersion: VersionTLS12, 19988 maxVersion: VersionTLS12, 19989 config: Config{ 19990 CipherSuites: []uint16{ 19991 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 19992 }, 19993 }, 19994 match: &ed25519Certificate, 19995 mismatch: &rsaCertificate, 19996 expectedError: ":NO_SHARED_CIPHER:", 19997 }, 19998 { 19999 name: "Server-CipherSuite-ECDHE_RSA-Ed25519", 20000 testType: serverTest, 20001 minVersion: VersionTLS12, 20002 maxVersion: VersionTLS12, 20003 config: Config{ 20004 CipherSuites: []uint16{ 20005 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 20006 }, 20007 }, 20008 match: &rsaCertificate, 20009 mismatch: &ed25519Certificate, 20010 expectedError: ":NO_SHARED_CIPHER:", 20011 }, 20012 20013 // If there is no ECDHE curve match, ECDHE cipher suites are 20014 // disqualified in TLS 1.2 and below. This, in turn, impacts the 20015 // available cipher suites for each credential. 20016 { 20017 name: "Server-CipherSuite-NoECDHE", 20018 testType: serverTest, 20019 maxVersion: VersionTLS12, 20020 config: Config{ 20021 CurvePreferences: []CurveID{CurveP256}, 20022 }, 20023 flags: []string{"-curves", strconv.Itoa(int(CurveX25519))}, 20024 match: &rsaCertificate, 20025 mismatch: &ecdsaP256Certificate, 20026 expectedError: ":NO_SHARED_CIPHER:", 20027 }, 20028 20029 // If the client offered a cipher that would allow a certificate, but it 20030 // wasn't one of the ones we configured, the certificate should be 20031 // skipped in favor of another one. 20032 { 20033 name: "Server-CipherSuite-Prefs", 20034 testType: serverTest, 20035 maxVersion: VersionTLS12, 20036 config: Config{ 20037 CipherSuites: []uint16{ 20038 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 20039 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 20040 }, 20041 }, 20042 flags: []string{"-cipher", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"}, 20043 match: &rsaCertificate, 20044 mismatch: &ecdsaP256Certificate, 20045 expectedError: ":NO_SHARED_CIPHER:", 20046 }, 20047 20048 // TLS 1.0 through 1.2 servers should incorporate the curve list into 20049 // ECDSA certificate selection. 20050 { 20051 name: "Server-Curve", 20052 testType: serverTest, 20053 maxVersion: VersionTLS12, 20054 config: Config{ 20055 CurvePreferences: []CurveID{CurveP256}, 20056 }, 20057 match: &ecdsaP256Certificate, 20058 mismatch: &ecdsaP384Certificate, 20059 expectedError: ":WRONG_CURVE:", 20060 }, 20061 20062 // TLS 1.3 servers ignore the curve list. ECDSA certificate selection is 20063 // solely determined by the signature algorithm list. 20064 { 20065 name: "Server-IgnoreCurve", 20066 testType: serverTest, 20067 minVersion: VersionTLS13, 20068 config: Config{ 20069 CurvePreferences: []CurveID{CurveP256}, 20070 }, 20071 match: &ecdsaP384Certificate, 20072 }, 20073 20074 // TLS 1.2 servers also ignore the curve list for Ed25519. The signature 20075 // algorithm list is sufficient for Ed25519. 20076 { 20077 name: "Server-IgnoreCurveEd25519", 20078 testType: serverTest, 20079 minVersion: VersionTLS12, 20080 config: Config{ 20081 CurvePreferences: []CurveID{CurveP256}, 20082 }, 20083 match: &ed25519Certificate, 20084 }, 20085 20086 // Without signature algorithm negotiation, Ed25519 is not usable in TLS 20087 // 1.1 and below. 20088 { 20089 name: "Server-NoEd25519", 20090 testType: serverTest, 20091 maxVersion: VersionTLS11, 20092 match: &rsaCertificate, 20093 mismatch: &ed25519Certificate, 20094 }, 20095 20096 // TLS 1.2 and up should incorporate the signature algorithm list into 20097 // certificate selection. 20098 { 20099 name: "Server-SignatureAlgorithm", 20100 testType: serverTest, 20101 minVersion: VersionTLS12, 20102 maxVersion: VersionTLS12, 20103 config: Config{ 20104 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20105 CipherSuites: []uint16{ 20106 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 20107 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 20108 }, 20109 }, 20110 match: &ecdsaP256Certificate, 20111 mismatch: &rsaCertificate, 20112 expectedError: ":NO_SHARED_CIPHER:", 20113 }, 20114 { 20115 name: "Server-SignatureAlgorithm", 20116 testType: serverTest, 20117 minVersion: VersionTLS13, 20118 config: Config{ 20119 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20120 }, 20121 match: &ecdsaP256Certificate, 20122 mismatch: &rsaCertificate, 20123 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 20124 }, 20125 20126 // TLS 1.2's use of the signature algorithm list only disables the 20127 // signing-based algorithms. If an RSA key exchange cipher suite is 20128 // eligible, that is fine. (This is not a realistic configuration, 20129 // however. No one would configure RSA before ECDSA.) 20130 { 20131 name: "Server-SignatureAlgorithmImpactsECDHEOnly", 20132 testType: serverTest, 20133 minVersion: VersionTLS12, 20134 maxVersion: VersionTLS12, 20135 config: Config{ 20136 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20137 CipherSuites: []uint16{ 20138 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 20139 TLS_RSA_WITH_AES_128_CBC_SHA, 20140 }, 20141 }, 20142 match: &rsaCertificate, 20143 }, 20144 20145 // TLS 1.3's use of the signature algorithm looks at the ECDSA curve 20146 // embedded in the signature algorithm. 20147 { 20148 name: "Server-SignatureAlgorithmECDSACurve", 20149 testType: serverTest, 20150 minVersion: VersionTLS13, 20151 config: Config{ 20152 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20153 }, 20154 match: &ecdsaP256Certificate, 20155 mismatch: &ecdsaP384Certificate, 20156 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 20157 }, 20158 20159 // TLS 1.2's use does not. 20160 { 20161 name: "Server-SignatureAlgorithmECDSACurve", 20162 testType: serverTest, 20163 minVersion: VersionTLS12, 20164 maxVersion: VersionTLS12, 20165 config: Config{ 20166 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20167 }, 20168 match: &ecdsaP384Certificate, 20169 }, 20170 20171 // TLS 1.0 and 1.1 do not look at the signature algorithm. 20172 { 20173 name: "Server-IgnoreSignatureAlgorithm", 20174 testType: serverTest, 20175 maxVersion: VersionTLS11, 20176 config: Config{ 20177 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20178 }, 20179 match: &rsaCertificate, 20180 }, 20181 20182 // Signature algorithm matches take preferences on the keys into 20183 // consideration. 20184 { 20185 name: "Server-SignatureAlgorithmKeyPrefs", 20186 testType: serverTest, 20187 minVersion: VersionTLS12, 20188 maxVersion: VersionTLS12, 20189 config: Config{ 20190 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 20191 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 20192 }, 20193 match: rsaChainCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 20194 mismatch: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA384), 20195 expectedError: ":NO_SHARED_CIPHER:", 20196 }, 20197 { 20198 name: "Server-SignatureAlgorithmKeyPrefs", 20199 testType: serverTest, 20200 minVersion: VersionTLS13, 20201 config: Config{ 20202 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 20203 }, 20204 match: rsaChainCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 20205 mismatch: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA384), 20206 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 20207 }, 20208 20209 // TLS 1.2 clients and below check the certificate against the old 20210 // client certificate types field. 20211 { 20212 name: "Client-ClientCertificateTypes-RSA", 20213 testType: clientTest, 20214 maxVersion: VersionTLS12, 20215 config: Config{ 20216 ClientAuth: RequestClientCert, 20217 ClientCertificateTypes: []uint8{CertTypeRSASign}, 20218 }, 20219 match: &rsaCertificate, 20220 mismatch: &ecdsaP256Certificate, 20221 expectedError: ":UNKNOWN_CERTIFICATE_TYPE:", 20222 }, 20223 { 20224 name: "Client-ClientCertificateTypes-ECDSA", 20225 testType: clientTest, 20226 maxVersion: VersionTLS12, 20227 config: Config{ 20228 ClientAuth: RequestClientCert, 20229 ClientCertificateTypes: []uint8{CertTypeECDSASign}, 20230 }, 20231 match: &ecdsaP256Certificate, 20232 mismatch: &rsaCertificate, 20233 expectedError: ":UNKNOWN_CERTIFICATE_TYPE:", 20234 }, 20235 20236 // Ed25519 is considered ECDSA for purposes of client certificate types. 20237 { 20238 name: "Client-ClientCertificateTypes-RSA-Ed25519", 20239 testType: clientTest, 20240 minVersion: VersionTLS12, 20241 maxVersion: VersionTLS12, 20242 config: Config{ 20243 ClientAuth: RequestClientCert, 20244 ClientCertificateTypes: []uint8{CertTypeRSASign}, 20245 }, 20246 match: &rsaCertificate, 20247 mismatch: &ed25519Certificate, 20248 expectedError: ":UNKNOWN_CERTIFICATE_TYPE:", 20249 }, 20250 { 20251 name: "Client-ClientCertificateTypes-ECDSA-Ed25519", 20252 testType: clientTest, 20253 minVersion: VersionTLS12, 20254 maxVersion: VersionTLS12, 20255 config: Config{ 20256 ClientAuth: RequestClientCert, 20257 ClientCertificateTypes: []uint8{CertTypeECDSASign}, 20258 }, 20259 match: &ed25519Certificate, 20260 mismatch: &rsaCertificate, 20261 expectedError: ":UNKNOWN_CERTIFICATE_TYPE:", 20262 }, 20263 20264 // TLS 1.2 and up should incorporate the signature algorithm list into 20265 // certificate selection. (There is no signature algorithm list to look 20266 // at in TLS 1.0 and 1.1.) 20267 { 20268 name: "Client-SignatureAlgorithm", 20269 testType: clientTest, 20270 minVersion: VersionTLS12, 20271 config: Config{ 20272 ClientAuth: RequestClientCert, 20273 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20274 }, 20275 match: &ecdsaP256Certificate, 20276 mismatch: &rsaCertificate, 20277 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 20278 }, 20279 20280 // TLS 1.3's use of the signature algorithm looks at the ECDSA curve 20281 // embedded in the signature algorithm. 20282 { 20283 name: "Client-SignatureAlgorithmECDSACurve", 20284 testType: clientTest, 20285 minVersion: VersionTLS13, 20286 config: Config{ 20287 ClientAuth: RequestClientCert, 20288 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20289 }, 20290 match: &ecdsaP256Certificate, 20291 mismatch: &ecdsaP384Certificate, 20292 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 20293 }, 20294 20295 // TLS 1.2's use does not. It is not possible to determine what ECDSA 20296 // curves are allowed by the server. 20297 { 20298 name: "Client-SignatureAlgorithmECDSACurve", 20299 testType: clientTest, 20300 minVersion: VersionTLS12, 20301 maxVersion: VersionTLS12, 20302 config: Config{ 20303 ClientAuth: RequestClientCert, 20304 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20305 }, 20306 match: &ecdsaP384Certificate, 20307 }, 20308 20309 // Signature algorithm matches take preferences on the keys into 20310 // consideration. 20311 { 20312 name: "Client-SignatureAlgorithmKeyPrefs", 20313 testType: clientTest, 20314 minVersion: VersionTLS12, 20315 config: Config{ 20316 ClientAuth: RequestClientCert, 20317 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 20318 }, 20319 match: rsaChainCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 20320 mismatch: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA384), 20321 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 20322 }, 20323 } 20324 20325 for _, protocol := range []protocol{tls, dtls} { 20326 for _, vers := range allVersions(protocol) { 20327 suffix := fmt.Sprintf("%s-%s", protocol, vers) 20328 20329 // Test that the credential list is interpreted in preference order, 20330 // with the default credential, if any, at the end. 20331 testCases = append(testCases, testCase{ 20332 name: fmt.Sprintf("CertificateSelection-Client-PreferenceOrder-%s", suffix), 20333 testType: clientTest, 20334 protocol: protocol, 20335 config: Config{ 20336 MinVersion: vers.version, 20337 MaxVersion: vers.version, 20338 ClientAuth: RequestClientCert, 20339 }, 20340 shimCredentials: []*Credential{&ecdsaP256Certificate, &ecdsaP384Certificate}, 20341 shimCertificate: &rsaCertificate, 20342 flags: []string{"-expect-selected-credential", "0"}, 20343 expectations: connectionExpectations{peerCertificate: &ecdsaP256Certificate}, 20344 }) 20345 testCases = append(testCases, testCase{ 20346 name: fmt.Sprintf("CertificateSelection-Server-PreferenceOrder-%s", suffix), 20347 testType: serverTest, 20348 protocol: protocol, 20349 config: Config{ 20350 MinVersion: vers.version, 20351 MaxVersion: vers.version, 20352 }, 20353 shimCredentials: []*Credential{&ecdsaP256Certificate, &ecdsaP384Certificate}, 20354 shimCertificate: &rsaCertificate, 20355 flags: []string{"-expect-selected-credential", "0"}, 20356 expectations: connectionExpectations{peerCertificate: &ecdsaP256Certificate}, 20357 }) 20358 20359 // Test that the selected credential contributes the certificate chain, OCSP response, 20360 // and SCT list. 20361 testCases = append(testCases, testCase{ 20362 name: fmt.Sprintf("CertificateSelection-Server-OCSP-SCT-%s", suffix), 20363 testType: serverTest, 20364 protocol: protocol, 20365 config: Config{ 20366 MinVersion: vers.version, 20367 MaxVersion: vers.version, 20368 // Configure enough options so that, at all TLS versions, only an RSA 20369 // certificate will be accepted. 20370 CipherSuites: []uint16{ 20371 TLS_AES_128_GCM_SHA256, 20372 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 20373 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 20374 }, 20375 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 20376 }, 20377 shimCredentials: []*Credential{ 20378 ecdsaP256Certificate.WithOCSP(testOCSPResponse2).WithSCTList(testSCTList2), 20379 rsaChainCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 20380 }, 20381 shimCertificate: ecdsaP384Certificate.WithOCSP(testOCSPResponse2).WithSCTList(testSCTList2), 20382 flags: []string{"-expect-selected-credential", "1"}, 20383 expectations: connectionExpectations{ 20384 peerCertificate: rsaChainCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 20385 }, 20386 }) 20387 20388 // Test that the credentials API works asynchronously. This tests both deferring the 20389 // configuration to the certificate callback, and using a custom, async private key. 20390 testCases = append(testCases, testCase{ 20391 name: fmt.Sprintf("CertificateSelection-Client-Async-%s", suffix), 20392 testType: clientTest, 20393 protocol: protocol, 20394 config: Config{ 20395 MinVersion: vers.version, 20396 MaxVersion: vers.version, 20397 ClientAuth: RequestClientCert, 20398 }, 20399 shimCredentials: []*Credential{&ecdsaP256Certificate}, 20400 shimCertificate: &rsaCertificate, 20401 flags: []string{"-async", "-expect-selected-credential", "0"}, 20402 expectations: connectionExpectations{peerCertificate: &ecdsaP256Certificate}, 20403 }) 20404 testCases = append(testCases, testCase{ 20405 name: fmt.Sprintf("CertificateSelection-Server-Async-%s", suffix), 20406 testType: serverTest, 20407 protocol: protocol, 20408 config: Config{ 20409 MinVersion: vers.version, 20410 MaxVersion: vers.version, 20411 }, 20412 shimCredentials: []*Credential{&ecdsaP256Certificate}, 20413 shimCertificate: &rsaCertificate, 20414 flags: []string{"-async", "-expect-selected-credential", "0"}, 20415 expectations: connectionExpectations{peerCertificate: &ecdsaP256Certificate}, 20416 }) 20417 20418 for _, test := range certSelectTests { 20419 if test.minVersion != 0 && vers.version < test.minVersion { 20420 continue 20421 } 20422 if test.maxVersion != 0 && vers.version > test.maxVersion { 20423 continue 20424 } 20425 20426 config := test.config 20427 config.MinVersion = vers.version 20428 config.MaxVersion = vers.version 20429 20430 // If the mismatch field is omitted, this is a positive test, 20431 // just to confirm that the selection logic does not block a 20432 // particular certificate. 20433 if test.mismatch == nil { 20434 testCases = append(testCases, testCase{ 20435 name: fmt.Sprintf("CertificateSelection-%s-%s", test.name, suffix), 20436 protocol: protocol, 20437 testType: test.testType, 20438 config: config, 20439 shimCredentials: []*Credential{test.match}, 20440 flags: append([]string{"-expect-selected-credential", "0"}, test.flags...), 20441 expectations: connectionExpectations{peerCertificate: test.match}, 20442 }) 20443 continue 20444 } 20445 20446 testCases = append(testCases, testCase{ 20447 name: fmt.Sprintf("CertificateSelection-%s-MatchFirst-%s", test.name, suffix), 20448 protocol: protocol, 20449 testType: test.testType, 20450 config: config, 20451 shimCredentials: []*Credential{test.match, test.mismatch}, 20452 flags: append([]string{"-expect-selected-credential", "0"}, test.flags...), 20453 expectations: connectionExpectations{peerCertificate: test.match}, 20454 }) 20455 testCases = append(testCases, testCase{ 20456 name: fmt.Sprintf("CertificateSelection-%s-MatchSecond-%s", test.name, suffix), 20457 protocol: protocol, 20458 testType: test.testType, 20459 config: config, 20460 shimCredentials: []*Credential{test.mismatch, test.match}, 20461 flags: append([]string{"-expect-selected-credential", "1"}, test.flags...), 20462 expectations: connectionExpectations{peerCertificate: test.match}, 20463 }) 20464 testCases = append(testCases, testCase{ 20465 name: fmt.Sprintf("CertificateSelection-%s-MatchDefault-%s", test.name, suffix), 20466 protocol: protocol, 20467 testType: test.testType, 20468 config: config, 20469 shimCredentials: []*Credential{test.mismatch}, 20470 shimCertificate: test.match, 20471 flags: append([]string{"-expect-selected-credential", "-1"}, test.flags...), 20472 expectations: connectionExpectations{peerCertificate: test.match}, 20473 }) 20474 testCases = append(testCases, testCase{ 20475 name: fmt.Sprintf("CertificateSelection-%s-MatchNone-%s", test.name, suffix), 20476 protocol: protocol, 20477 testType: test.testType, 20478 config: config, 20479 shimCredentials: []*Credential{test.mismatch, test.mismatch, test.mismatch}, 20480 flags: test.flags, 20481 shouldFail: true, 20482 expectedLocalError: "remote error: handshake failure", 20483 expectedError: test.expectedError, 20484 }) 20485 } 20486 } 20487 } 20488} 20489 20490func worker(dispatcher *shimDispatcher, statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { 20491 defer wg.Done() 20492 20493 for test := range c { 20494 var err error 20495 20496 if *mallocTest >= 0 { 20497 for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ { 20498 statusChan <- statusMsg{test: test, statusType: statusStarted} 20499 if err = runTest(dispatcher, statusChan, test, shimPath, mallocNumToFail); err != errMoreMallocs { 20500 if err != nil { 20501 fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err) 20502 } 20503 break 20504 } 20505 } 20506 } else if *repeatUntilFailure { 20507 for err == nil { 20508 statusChan <- statusMsg{test: test, statusType: statusStarted} 20509 err = runTest(dispatcher, statusChan, test, shimPath, -1) 20510 } 20511 } else { 20512 statusChan <- statusMsg{test: test, statusType: statusStarted} 20513 err = runTest(dispatcher, statusChan, test, shimPath, -1) 20514 } 20515 statusChan <- statusMsg{test: test, statusType: statusDone, err: err} 20516 } 20517} 20518 20519type statusType int 20520 20521const ( 20522 statusStarted statusType = iota 20523 statusShimStarted 20524 statusDone 20525) 20526 20527type statusMsg struct { 20528 test *testCase 20529 statusType statusType 20530 pid int 20531 err error 20532} 20533 20534func statusPrinter(doneChan chan *testresult.Results, statusChan chan statusMsg, total int) { 20535 var started, done, failed, unimplemented, lineLen int 20536 20537 testOutput := testresult.NewResults() 20538 for msg := range statusChan { 20539 if !*pipe { 20540 // Erase the previous status line. 20541 var erase string 20542 for i := 0; i < lineLen; i++ { 20543 erase += "\b \b" 20544 } 20545 fmt.Print(erase) 20546 } 20547 20548 if msg.statusType == statusStarted { 20549 started++ 20550 } else if msg.statusType == statusDone { 20551 done++ 20552 20553 if msg.err != nil { 20554 if msg.err == errUnimplemented { 20555 if *pipe { 20556 // Print each test instead of a status line. 20557 fmt.Printf("UNIMPLEMENTED (%s)\n", msg.test.name) 20558 } 20559 unimplemented++ 20560 if *allowUnimplemented { 20561 testOutput.AddSkip(msg.test.name) 20562 } else { 20563 testOutput.AddResult(msg.test.name, "SKIP", nil) 20564 } 20565 } else { 20566 fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err) 20567 failed++ 20568 testOutput.AddResult(msg.test.name, "FAIL", msg.err) 20569 } 20570 } else { 20571 if *pipe { 20572 // Print each test instead of a status line. 20573 fmt.Printf("PASSED (%s)\n", msg.test.name) 20574 } 20575 testOutput.AddResult(msg.test.name, "PASS", nil) 20576 } 20577 } 20578 20579 if !*pipe { 20580 // Print a new status line. 20581 line := fmt.Sprintf("%d/%d/%d/%d/%d", failed, unimplemented, done, started, total) 20582 if msg.statusType == statusShimStarted && *waitForDebugger { 20583 // Note -wait-for-debugger limits the test to one worker, 20584 // otherwise some output would be skipped. 20585 line += fmt.Sprintf(" (%s: attach to process %d to continue)", msg.test.name, msg.pid) 20586 } 20587 lineLen = len(line) 20588 os.Stdout.WriteString(line) 20589 } 20590 } 20591 20592 doneChan <- testOutput 20593} 20594 20595func match(oneOfPatternIfAny []string, noneOfPattern []string, candidate string) (matched bool, err error) { 20596 matched = len(oneOfPatternIfAny) == 0 20597 20598 var didMatch bool 20599 for _, pattern := range oneOfPatternIfAny { 20600 didMatch, err = filepath.Match(pattern, candidate) 20601 if err != nil { 20602 return false, err 20603 } 20604 20605 matched = didMatch || matched 20606 } 20607 20608 for _, pattern := range noneOfPattern { 20609 didMatch, err = filepath.Match(pattern, candidate) 20610 if err != nil { 20611 return false, err 20612 } 20613 20614 matched = !didMatch && matched 20615 } 20616 20617 return matched, nil 20618} 20619 20620func checkTests() { 20621 for _, test := range testCases { 20622 if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) { 20623 panic("Error expected without shouldFail in " + test.name) 20624 } 20625 20626 if test.expectResumeRejected && !test.resumeSession { 20627 panic("expectResumeRejected without resumeSession in " + test.name) 20628 } 20629 20630 if !test.skipVersionNameCheck { 20631 for _, ver := range tlsVersions { 20632 if !strings.Contains("-"+test.name+"-", "-"+ver.name+"-") { 20633 continue 20634 } 20635 20636 found := test.config.MaxVersion == ver.version || test.config.MinVersion == ver.version || test.expectations.version == ver.version 20637 if test.resumeConfig != nil { 20638 found = found || test.resumeConfig.MaxVersion == ver.version || test.resumeConfig.MinVersion == ver.version 20639 } 20640 if test.resumeExpectations != nil { 20641 found = found || test.resumeExpectations.version == ver.version 20642 } 20643 shimFlag := ver.shimFlag(test.protocol) 20644 for _, flag := range test.flags { 20645 if flag == shimFlag { 20646 found = true 20647 break 20648 } 20649 } 20650 if !found { 20651 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)) 20652 } 20653 } 20654 } 20655 20656 for _, protocol := range []protocol{tls, dtls, quic} { 20657 if strings.Contains("-"+test.name+"-", "-"+protocol.String()+"-") && test.protocol != protocol { 20658 panic(fmt.Sprintf("The name of test %q suggests that it tests %q, but the test does not reference it", test.name, protocol)) 20659 } 20660 } 20661 } 20662} 20663 20664func main() { 20665 flag.Parse() 20666 var err error 20667 if tmpDir, err = os.MkdirTemp("", "testing-certs"); err != nil { 20668 fmt.Fprintf(os.Stderr, "failed to make temporary directory: %s", err) 20669 os.Exit(1) 20670 } 20671 defer os.RemoveAll(tmpDir) 20672 initKeys() 20673 initCertificates() 20674 20675 if len(*shimConfigFile) != 0 { 20676 encoded, err := os.ReadFile(*shimConfigFile) 20677 if err != nil { 20678 fmt.Fprintf(os.Stderr, "Couldn't read config file %q: %s\n", *shimConfigFile, err) 20679 os.Exit(1) 20680 } 20681 20682 if err := json.Unmarshal(encoded, &shimConfig); err != nil { 20683 fmt.Fprintf(os.Stderr, "Couldn't decode config file %q: %s\n", *shimConfigFile, err) 20684 os.Exit(1) 20685 } 20686 } 20687 20688 if shimConfig.AllCurves == nil { 20689 for _, curve := range testCurves { 20690 shimConfig.AllCurves = append(shimConfig.AllCurves, int(curve.id)) 20691 } 20692 } 20693 20694 addBasicTests() 20695 addCipherSuiteTests() 20696 addBadECDSASignatureTests() 20697 addCBCPaddingTests() 20698 addCBCSplittingTests() 20699 addClientAuthTests() 20700 addDDoSCallbackTests() 20701 addVersionNegotiationTests() 20702 addMinimumVersionTests() 20703 addExtensionTests() 20704 addResumptionVersionTests() 20705 addExtendedMasterSecretTests() 20706 addRenegotiationTests() 20707 addDTLSReplayTests() 20708 addSignatureAlgorithmTests() 20709 addDTLSRetransmitTests() 20710 addExportKeyingMaterialTests() 20711 addExportTrafficSecretsTests() 20712 addTLSUniqueTests() 20713 addCustomExtensionTests() 20714 addRSAClientKeyExchangeTests() 20715 addCurveTests() 20716 addSessionTicketTests() 20717 addTLS13RecordTests() 20718 addAllStateMachineCoverageTests() 20719 addChangeCipherSpecTests() 20720 addEndOfFlightTests() 20721 addWrongMessageTypeTests() 20722 addTrailingMessageDataTests() 20723 addTLS13HandshakeTests() 20724 addTLS13CipherPreferenceTests() 20725 addPeekTests() 20726 addRecordVersionTests() 20727 addCertificateTests() 20728 addRetainOnlySHA256ClientCertTests() 20729 addECDSAKeyUsageTests() 20730 addRSAKeyUsageTests() 20731 addExtraHandshakeTests() 20732 addOmitExtensionsTests() 20733 addCertCompressionTests() 20734 addJDK11WorkaroundTests() 20735 addDelegatedCredentialTests() 20736 addEncryptedClientHelloTests() 20737 addHintMismatchTests() 20738 addCompliancePolicyTests() 20739 addCertificateSelectionTests() 20740 20741 toAppend, err := convertToSplitHandshakeTests(testCases) 20742 if err != nil { 20743 fmt.Fprintf(os.Stderr, "Error making split handshake tests: %s", err) 20744 os.Exit(1) 20745 } 20746 testCases = append(testCases, toAppend...) 20747 20748 checkTests() 20749 20750 dispatcher, err := newShimDispatcher() 20751 if err != nil { 20752 fmt.Fprintf(os.Stderr, "Error opening socket: %s", err) 20753 os.Exit(1) 20754 } 20755 defer dispatcher.Close() 20756 20757 numWorkers := *numWorkersFlag 20758 if useDebugger() { 20759 numWorkers = 1 20760 } 20761 20762 statusChan := make(chan statusMsg, numWorkers) 20763 testChan := make(chan *testCase, numWorkers) 20764 doneChan := make(chan *testresult.Results) 20765 20766 go statusPrinter(doneChan, statusChan, len(testCases)) 20767 20768 var wg sync.WaitGroup 20769 for i := 0; i < numWorkers; i++ { 20770 wg.Add(1) 20771 go worker(dispatcher, statusChan, testChan, *shimPath, &wg) 20772 } 20773 20774 var oneOfPatternIfAny, noneOfPattern []string 20775 if len(*testToRun) > 0 { 20776 oneOfPatternIfAny = strings.Split(*testToRun, ";") 20777 } 20778 if len(*skipTest) > 0 { 20779 noneOfPattern = strings.Split(*skipTest, ";") 20780 } 20781 20782 shardIndex, shardTotal, err := getSharding() 20783 if err != nil { 20784 fmt.Fprintln(os.Stderr, err) 20785 os.Exit(1) 20786 } 20787 20788 if shardTotal > 0 { 20789 fmt.Printf("This is shard %d of 0..%d (inclusive)\n", shardIndex, shardTotal-1) 20790 } 20791 20792 var foundTest bool 20793 for i := range testCases { 20794 if shardTotal > 0 && i%shardTotal != shardIndex { 20795 continue 20796 } 20797 20798 matched, err := match(oneOfPatternIfAny, noneOfPattern, testCases[i].name) 20799 if err != nil { 20800 fmt.Fprintf(os.Stderr, "Error matching pattern: %s\n", err) 20801 os.Exit(1) 20802 } 20803 20804 if !*includeDisabled { 20805 for pattern := range shimConfig.DisabledTests { 20806 isDisabled, err := filepath.Match(pattern, testCases[i].name) 20807 if err != nil { 20808 fmt.Fprintf(os.Stderr, "Error matching pattern %q from config file: %s\n", pattern, err) 20809 os.Exit(1) 20810 } 20811 20812 if isDisabled { 20813 matched = false 20814 break 20815 } 20816 } 20817 } 20818 20819 if matched { 20820 if foundTest && *useRR { 20821 fmt.Fprintf(os.Stderr, "Too many matching tests. Only one test can run when RR is enabled.\n") 20822 os.Exit(1) 20823 } 20824 20825 foundTest = true 20826 testChan <- &testCases[i] 20827 20828 // Only run one test if repeating until failure. 20829 if *repeatUntilFailure { 20830 break 20831 } 20832 } 20833 } 20834 20835 if !foundTest && shardTotal == 0 { 20836 fmt.Fprintf(os.Stderr, "No tests run\n") 20837 os.Exit(1) 20838 } 20839 20840 close(testChan) 20841 wg.Wait() 20842 close(statusChan) 20843 testOutput := <-doneChan 20844 20845 fmt.Printf("\n") 20846 20847 if *jsonOutput != "" { 20848 if err := testOutput.WriteToFile(*jsonOutput); err != nil { 20849 fmt.Fprintf(os.Stderr, "Error: %s\n", err) 20850 } 20851 } 20852 20853 if *useRR { 20854 fmt.Println("RR trace recorded. Replay with `rr replay`.") 20855 } 20856 20857 if !testOutput.HasUnexpectedResults() { 20858 os.Exit(1) 20859 } 20860} 20861