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(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 = "unexpected success" 1742 case failed && !correctFailure: 1743 msg = "bad error (wanted '" + 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 '%s', child error '%s', 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-handshake 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 // Client does False Start and negotiates NPN. 5719 tests = append(tests, testCase{ 5720 name: "FalseStart", 5721 config: Config{ 5722 MaxVersion: VersionTLS12, 5723 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5724 NextProtos: []string{"foo"}, 5725 Bugs: ProtocolBugs{ 5726 ExpectFalseStart: true, 5727 }, 5728 }, 5729 flags: []string{ 5730 "-false-start", 5731 "-select-next-proto", "foo", 5732 }, 5733 shimWritesFirst: true, 5734 resumeSession: true, 5735 }) 5736 5737 // Client does False Start and negotiates ALPN. 5738 tests = append(tests, testCase{ 5739 name: "FalseStart-ALPN", 5740 config: Config{ 5741 MaxVersion: VersionTLS12, 5742 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5743 NextProtos: []string{"foo"}, 5744 Bugs: ProtocolBugs{ 5745 ExpectFalseStart: true, 5746 }, 5747 }, 5748 flags: []string{ 5749 "-false-start", 5750 "-advertise-alpn", "\x03foo", 5751 "-expect-alpn", "foo", 5752 }, 5753 shimWritesFirst: true, 5754 resumeSession: true, 5755 }) 5756 5757 // False Start without session tickets. 5758 tests = append(tests, testCase{ 5759 name: "FalseStart-SessionTicketsDisabled", 5760 config: Config{ 5761 MaxVersion: VersionTLS12, 5762 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 5763 NextProtos: []string{"foo"}, 5764 SessionTicketsDisabled: true, 5765 Bugs: ProtocolBugs{ 5766 ExpectFalseStart: true, 5767 }, 5768 }, 5769 flags: []string{ 5770 "-false-start", 5771 "-select-next-proto", "foo", 5772 }, 5773 shimWritesFirst: true, 5774 }) 5775 5776 // Server parses a V2ClientHello. Test different lengths for the 5777 // challenge field. 5778 for _, challengeLength := range []int{16, 31, 32, 33, 48} { 5779 tests = append(tests, testCase{ 5780 testType: serverTest, 5781 name: fmt.Sprintf("SendV2ClientHello-%d", challengeLength), 5782 config: Config{ 5783 // Choose a cipher suite that does not involve 5784 // elliptic curves, so no extensions are 5785 // involved. 5786 MaxVersion: VersionTLS12, 5787 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 5788 Bugs: ProtocolBugs{ 5789 SendV2ClientHello: true, 5790 V2ClientHelloChallengeLength: challengeLength, 5791 }, 5792 }, 5793 flags: []string{ 5794 "-expect-msg-callback", 5795 `read v2clienthello 5796write hs 2 5797write hs 11 5798write hs 14 5799read hs 16 5800read ccs 5801read hs 20 5802write ccs 5803write hs 20 5804read alert 1 0 5805`, 5806 }, 5807 }) 5808 } 5809 5810 // Channel ID and NPN at the same time, to ensure their relative 5811 // ordering is correct. 5812 tests = append(tests, testCase{ 5813 name: "ChannelID-NPN-Client", 5814 config: Config{ 5815 MaxVersion: VersionTLS12, 5816 RequestChannelID: true, 5817 NextProtos: []string{"foo"}, 5818 }, 5819 flags: []string{ 5820 "-send-channel-id", channelIDKeyPath, 5821 "-select-next-proto", "foo", 5822 }, 5823 resumeSession: true, 5824 expectations: connectionExpectations{ 5825 channelID: true, 5826 nextProto: "foo", 5827 nextProtoType: npn, 5828 }, 5829 }) 5830 tests = append(tests, testCase{ 5831 testType: serverTest, 5832 name: "ChannelID-NPN-Server", 5833 config: Config{ 5834 MaxVersion: VersionTLS12, 5835 ChannelID: &channelIDKey, 5836 NextProtos: []string{"bar"}, 5837 }, 5838 flags: []string{ 5839 "-expect-channel-id", 5840 base64FlagValue(channelIDBytes), 5841 "-advertise-npn", "\x03foo\x03bar\x03baz", 5842 "-expect-next-proto", "bar", 5843 }, 5844 resumeSession: true, 5845 expectations: connectionExpectations{ 5846 channelID: true, 5847 nextProto: "bar", 5848 nextProtoType: npn, 5849 }, 5850 }) 5851 5852 // Bidirectional shutdown with the runner initiating. 5853 tests = append(tests, testCase{ 5854 name: "Shutdown-Runner", 5855 config: Config{ 5856 Bugs: ProtocolBugs{ 5857 ExpectCloseNotify: true, 5858 }, 5859 }, 5860 flags: []string{"-check-close-notify"}, 5861 }) 5862 } 5863 if config.protocol != dtls { 5864 // Test Channel ID 5865 for _, ver := range allVersions(config.protocol) { 5866 if ver.version < VersionTLS10 { 5867 continue 5868 } 5869 // Client sends a Channel ID. 5870 tests = append(tests, testCase{ 5871 name: "ChannelID-Client-" + ver.name, 5872 config: Config{ 5873 MaxVersion: ver.version, 5874 RequestChannelID: true, 5875 }, 5876 flags: []string{"-send-channel-id", channelIDKeyPath}, 5877 resumeSession: true, 5878 expectations: connectionExpectations{ 5879 channelID: true, 5880 }, 5881 }) 5882 5883 // Server accepts a Channel ID. 5884 tests = append(tests, testCase{ 5885 testType: serverTest, 5886 name: "ChannelID-Server-" + ver.name, 5887 config: Config{ 5888 MaxVersion: ver.version, 5889 ChannelID: &channelIDKey, 5890 }, 5891 flags: []string{ 5892 "-expect-channel-id", 5893 base64FlagValue(channelIDBytes), 5894 }, 5895 resumeSession: true, 5896 expectations: connectionExpectations{ 5897 channelID: true, 5898 }, 5899 }) 5900 5901 tests = append(tests, testCase{ 5902 testType: serverTest, 5903 name: "InvalidChannelIDSignature-" + ver.name, 5904 config: Config{ 5905 MaxVersion: ver.version, 5906 ChannelID: &channelIDKey, 5907 Bugs: ProtocolBugs{ 5908 InvalidChannelIDSignature: true, 5909 }, 5910 }, 5911 flags: []string{"-enable-channel-id"}, 5912 shouldFail: true, 5913 expectedError: ":CHANNEL_ID_SIGNATURE_INVALID:", 5914 }) 5915 5916 if ver.version < VersionTLS13 { 5917 // Channel ID requires ECDHE ciphers. 5918 tests = append(tests, testCase{ 5919 testType: serverTest, 5920 name: "ChannelID-NoECDHE-" + ver.name, 5921 config: Config{ 5922 MaxVersion: ver.version, 5923 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 5924 ChannelID: &channelIDKey, 5925 }, 5926 expectations: connectionExpectations{ 5927 channelID: false, 5928 }, 5929 flags: []string{"-enable-channel-id"}, 5930 }) 5931 5932 // Sanity-check setting expectations.channelID false works. 5933 tests = append(tests, testCase{ 5934 testType: serverTest, 5935 name: "ChannelID-ECDHE-" + ver.name, 5936 config: Config{ 5937 MaxVersion: ver.version, 5938 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, 5939 ChannelID: &channelIDKey, 5940 }, 5941 expectations: connectionExpectations{ 5942 channelID: false, 5943 }, 5944 flags: []string{"-enable-channel-id"}, 5945 shouldFail: true, 5946 expectedLocalError: "channel ID unexpectedly negotiated", 5947 }) 5948 } 5949 } 5950 5951 if !config.implicitHandshake { 5952 // Bidirectional shutdown with the shim initiating. The runner, 5953 // in the meantime, sends garbage before the close_notify which 5954 // the shim must ignore. This test is disabled under implicit 5955 // handshake tests because the shim never reads or writes. 5956 5957 // Tests that require checking for a close notify alert don't work with 5958 // QUIC because alerts are handled outside of the TLS stack in QUIC. 5959 if config.protocol != quic { 5960 tests = append(tests, testCase{ 5961 name: "Shutdown-Shim", 5962 config: Config{ 5963 MaxVersion: VersionTLS12, 5964 Bugs: ProtocolBugs{ 5965 ExpectCloseNotify: true, 5966 }, 5967 }, 5968 shimShutsDown: true, 5969 sendEmptyRecords: 1, 5970 sendWarningAlerts: 1, 5971 flags: []string{"-check-close-notify"}, 5972 }) 5973 5974 // The shim should reject unexpected application data 5975 // when shutting down. 5976 tests = append(tests, testCase{ 5977 name: "Shutdown-Shim-ApplicationData", 5978 config: Config{ 5979 MaxVersion: VersionTLS12, 5980 Bugs: ProtocolBugs{ 5981 ExpectCloseNotify: true, 5982 }, 5983 }, 5984 shimShutsDown: true, 5985 messageCount: 1, 5986 sendEmptyRecords: 1, 5987 sendWarningAlerts: 1, 5988 flags: []string{"-check-close-notify"}, 5989 shouldFail: true, 5990 expectedError: ":APPLICATION_DATA_ON_SHUTDOWN:", 5991 }) 5992 5993 // Test that SSL_shutdown still processes KeyUpdate. 5994 tests = append(tests, testCase{ 5995 name: "Shutdown-Shim-KeyUpdate", 5996 config: Config{ 5997 MinVersion: VersionTLS13, 5998 MaxVersion: VersionTLS13, 5999 Bugs: ProtocolBugs{ 6000 ExpectCloseNotify: true, 6001 }, 6002 }, 6003 shimShutsDown: true, 6004 sendKeyUpdates: 1, 6005 keyUpdateRequest: keyUpdateRequested, 6006 flags: []string{"-check-close-notify"}, 6007 }) 6008 6009 // Test that SSL_shutdown processes HelloRequest 6010 // correctly. 6011 tests = append(tests, testCase{ 6012 name: "Shutdown-Shim-HelloRequest-Ignore", 6013 config: Config{ 6014 MinVersion: VersionTLS12, 6015 MaxVersion: VersionTLS12, 6016 Bugs: ProtocolBugs{ 6017 SendHelloRequestBeforeEveryAppDataRecord: true, 6018 ExpectCloseNotify: true, 6019 }, 6020 }, 6021 shimShutsDown: true, 6022 flags: []string{ 6023 "-renegotiate-ignore", 6024 "-check-close-notify", 6025 }, 6026 }) 6027 tests = append(tests, testCase{ 6028 name: "Shutdown-Shim-HelloRequest-Reject", 6029 config: Config{ 6030 MinVersion: VersionTLS12, 6031 MaxVersion: VersionTLS12, 6032 Bugs: ProtocolBugs{ 6033 ExpectCloseNotify: true, 6034 }, 6035 }, 6036 shimShutsDown: true, 6037 renegotiate: 1, 6038 shouldFail: true, 6039 expectedError: ":NO_RENEGOTIATION:", 6040 flags: []string{"-check-close-notify"}, 6041 }) 6042 tests = append(tests, testCase{ 6043 name: "Shutdown-Shim-HelloRequest-CannotHandshake", 6044 config: Config{ 6045 MinVersion: VersionTLS12, 6046 MaxVersion: VersionTLS12, 6047 Bugs: ProtocolBugs{ 6048 ExpectCloseNotify: true, 6049 }, 6050 }, 6051 shimShutsDown: true, 6052 renegotiate: 1, 6053 shouldFail: true, 6054 expectedError: ":NO_RENEGOTIATION:", 6055 flags: []string{ 6056 "-check-close-notify", 6057 "-renegotiate-freely", 6058 }, 6059 }) 6060 6061 tests = append(tests, testCase{ 6062 testType: serverTest, 6063 name: "Shutdown-Shim-Renegotiate-Server-Forbidden", 6064 config: Config{ 6065 MaxVersion: VersionTLS12, 6066 Bugs: ProtocolBugs{ 6067 ExpectCloseNotify: true, 6068 }, 6069 }, 6070 shimShutsDown: true, 6071 renegotiate: 1, 6072 shouldFail: true, 6073 expectedError: ":NO_RENEGOTIATION:", 6074 flags: []string{ 6075 "-check-close-notify", 6076 }, 6077 }) 6078 } 6079 } 6080 } 6081 if config.protocol == dtls { 6082 // TODO(davidben): DTLS 1.3 will want a similar thing for 6083 // HelloRetryRequest. 6084 tests = append(tests, testCase{ 6085 name: "SkipHelloVerifyRequest", 6086 config: Config{ 6087 MaxVersion: VersionTLS12, 6088 Bugs: ProtocolBugs{ 6089 SkipHelloVerifyRequest: true, 6090 }, 6091 }, 6092 }) 6093 } 6094 6095 for _, test := range tests { 6096 test.protocol = config.protocol 6097 test.name += "-" + config.protocol.String() 6098 if config.async { 6099 test.name += "-Async" 6100 test.flags = append(test.flags, "-async") 6101 } else { 6102 test.name += "-Sync" 6103 } 6104 if config.splitHandshake { 6105 test.name += "-SplitHandshakeRecords" 6106 test.config.Bugs.MaxHandshakeRecordLength = 1 6107 if config.protocol == dtls { 6108 test.config.Bugs.MaxPacketLength = 256 6109 test.flags = append(test.flags, "-mtu", "256") 6110 } 6111 } 6112 if config.packHandshake { 6113 test.name += "-PackHandshake" 6114 if config.protocol == dtls { 6115 test.config.Bugs.MaxHandshakeRecordLength = 2 6116 test.config.Bugs.PackHandshakeFragments = 20 6117 test.config.Bugs.PackHandshakeRecords = 1500 6118 test.config.Bugs.PackAppDataWithHandshake = true 6119 } else { 6120 test.config.Bugs.PackHandshakeFlight = true 6121 } 6122 } 6123 if config.implicitHandshake { 6124 test.name += "-ImplicitHandshake" 6125 test.flags = append(test.flags, "-implicit-handshake") 6126 } 6127 testCases = append(testCases, test) 6128 } 6129} 6130 6131func addDDoSCallbackTests() { 6132 // DDoS callback. 6133 for _, resume := range []bool{false, true} { 6134 suffix := "Resume" 6135 if resume { 6136 suffix = "No" + suffix 6137 } 6138 6139 testCases = append(testCases, testCase{ 6140 testType: serverTest, 6141 name: "Server-DDoS-OK-" + suffix, 6142 config: Config{ 6143 MaxVersion: VersionTLS12, 6144 }, 6145 flags: []string{"-install-ddos-callback"}, 6146 resumeSession: resume, 6147 }) 6148 testCases = append(testCases, testCase{ 6149 testType: serverTest, 6150 name: "Server-DDoS-OK-" + suffix + "-TLS13", 6151 config: Config{ 6152 MaxVersion: VersionTLS13, 6153 }, 6154 flags: []string{"-install-ddos-callback"}, 6155 resumeSession: resume, 6156 }) 6157 6158 failFlag := "-fail-ddos-callback" 6159 if resume { 6160 failFlag = "-on-resume-fail-ddos-callback" 6161 } 6162 testCases = append(testCases, testCase{ 6163 testType: serverTest, 6164 name: "Server-DDoS-Reject-" + suffix, 6165 config: Config{ 6166 MaxVersion: VersionTLS12, 6167 }, 6168 flags: []string{"-install-ddos-callback", failFlag}, 6169 resumeSession: resume, 6170 shouldFail: true, 6171 expectedError: ":CONNECTION_REJECTED:", 6172 expectedLocalError: "remote error: internal error", 6173 }) 6174 testCases = append(testCases, testCase{ 6175 testType: serverTest, 6176 name: "Server-DDoS-Reject-" + suffix + "-TLS13", 6177 config: Config{ 6178 MaxVersion: VersionTLS13, 6179 }, 6180 flags: []string{"-install-ddos-callback", failFlag}, 6181 resumeSession: resume, 6182 shouldFail: true, 6183 expectedError: ":CONNECTION_REJECTED:", 6184 expectedLocalError: "remote error: internal error", 6185 }) 6186 } 6187} 6188 6189func addVersionNegotiationTests() { 6190 for _, protocol := range []protocol{tls, dtls, quic} { 6191 for _, shimVers := range allVersions(protocol) { 6192 // Assemble flags to disable all newer versions on the shim. 6193 var flags []string 6194 for _, vers := range allVersions(protocol) { 6195 if vers.version > shimVers.version { 6196 flags = append(flags, vers.excludeFlag) 6197 } 6198 } 6199 6200 flags2 := []string{"-max-version", shimVers.shimFlag(protocol)} 6201 6202 // Test configuring the runner's maximum version. 6203 for _, runnerVers := range allVersions(protocol) { 6204 expectedVersion := shimVers.version 6205 if runnerVers.version < shimVers.version { 6206 expectedVersion = runnerVers.version 6207 } 6208 6209 suffix := shimVers.name + "-" + runnerVers.name 6210 suffix += "-" + protocol.String() 6211 6212 // Determine the expected initial record-layer versions. 6213 clientVers := shimVers.version 6214 if clientVers > VersionTLS10 { 6215 clientVers = VersionTLS10 6216 } 6217 clientVers = recordVersionToWire(clientVers, protocol) 6218 serverVers := expectedVersion 6219 if expectedVersion >= VersionTLS13 { 6220 serverVers = VersionTLS12 6221 } 6222 serverVers = recordVersionToWire(serverVers, protocol) 6223 6224 testCases = append(testCases, testCase{ 6225 protocol: protocol, 6226 testType: clientTest, 6227 name: "VersionNegotiation-Client-" + suffix, 6228 config: Config{ 6229 MaxVersion: runnerVers.version, 6230 Bugs: ProtocolBugs{ 6231 ExpectInitialRecordVersion: clientVers, 6232 }, 6233 }, 6234 flags: flags, 6235 expectations: connectionExpectations{ 6236 version: expectedVersion, 6237 }, 6238 // The version name check does not recognize the 6239 // |excludeFlag| construction in |flags|. 6240 skipVersionNameCheck: true, 6241 }) 6242 testCases = append(testCases, testCase{ 6243 protocol: protocol, 6244 testType: clientTest, 6245 name: "VersionNegotiation-Client2-" + suffix, 6246 config: Config{ 6247 MaxVersion: runnerVers.version, 6248 Bugs: ProtocolBugs{ 6249 ExpectInitialRecordVersion: clientVers, 6250 }, 6251 }, 6252 flags: flags2, 6253 expectations: connectionExpectations{ 6254 version: expectedVersion, 6255 }, 6256 }) 6257 6258 testCases = append(testCases, testCase{ 6259 protocol: protocol, 6260 testType: serverTest, 6261 name: "VersionNegotiation-Server-" + suffix, 6262 config: Config{ 6263 MaxVersion: runnerVers.version, 6264 Bugs: ProtocolBugs{ 6265 ExpectInitialRecordVersion: serverVers, 6266 }, 6267 }, 6268 flags: flags, 6269 expectations: connectionExpectations{ 6270 version: expectedVersion, 6271 }, 6272 // The version name check does not recognize the 6273 // |excludeFlag| construction in |flags|. 6274 skipVersionNameCheck: true, 6275 }) 6276 testCases = append(testCases, testCase{ 6277 protocol: protocol, 6278 testType: serverTest, 6279 name: "VersionNegotiation-Server2-" + suffix, 6280 config: Config{ 6281 MaxVersion: runnerVers.version, 6282 Bugs: ProtocolBugs{ 6283 ExpectInitialRecordVersion: serverVers, 6284 }, 6285 }, 6286 flags: flags2, 6287 expectations: connectionExpectations{ 6288 version: expectedVersion, 6289 }, 6290 }) 6291 } 6292 } 6293 } 6294 6295 // Test the version extension at all versions. 6296 for _, protocol := range []protocol{tls, dtls, quic} { 6297 for _, vers := range allVersions(protocol) { 6298 suffix := vers.name + "-" + protocol.String() 6299 6300 testCases = append(testCases, testCase{ 6301 protocol: protocol, 6302 testType: serverTest, 6303 name: "VersionNegotiationExtension-" + suffix, 6304 config: Config{ 6305 Bugs: ProtocolBugs{ 6306 SendSupportedVersions: []uint16{0x1111, vers.wire(protocol), 0x2222}, 6307 IgnoreTLS13DowngradeRandom: true, 6308 }, 6309 }, 6310 expectations: connectionExpectations{ 6311 version: vers.version, 6312 }, 6313 }) 6314 } 6315 } 6316 6317 // If all versions are unknown, negotiation fails. 6318 testCases = append(testCases, testCase{ 6319 testType: serverTest, 6320 name: "NoSupportedVersions", 6321 config: Config{ 6322 Bugs: ProtocolBugs{ 6323 SendSupportedVersions: []uint16{0x1111}, 6324 }, 6325 }, 6326 shouldFail: true, 6327 expectedError: ":UNSUPPORTED_PROTOCOL:", 6328 }) 6329 testCases = append(testCases, testCase{ 6330 protocol: dtls, 6331 testType: serverTest, 6332 name: "NoSupportedVersions-DTLS", 6333 config: Config{ 6334 Bugs: ProtocolBugs{ 6335 SendSupportedVersions: []uint16{0x1111}, 6336 }, 6337 }, 6338 shouldFail: true, 6339 expectedError: ":UNSUPPORTED_PROTOCOL:", 6340 }) 6341 6342 testCases = append(testCases, testCase{ 6343 testType: serverTest, 6344 name: "ClientHelloVersionTooHigh", 6345 config: Config{ 6346 MaxVersion: VersionTLS13, 6347 Bugs: ProtocolBugs{ 6348 SendClientVersion: 0x0304, 6349 OmitSupportedVersions: true, 6350 IgnoreTLS13DowngradeRandom: true, 6351 }, 6352 }, 6353 expectations: connectionExpectations{ 6354 version: VersionTLS12, 6355 }, 6356 }) 6357 6358 testCases = append(testCases, testCase{ 6359 testType: serverTest, 6360 name: "ConflictingVersionNegotiation", 6361 config: Config{ 6362 Bugs: ProtocolBugs{ 6363 SendClientVersion: VersionTLS12, 6364 SendSupportedVersions: []uint16{VersionTLS11}, 6365 IgnoreTLS13DowngradeRandom: true, 6366 }, 6367 }, 6368 // The extension takes precedence over the ClientHello version. 6369 expectations: connectionExpectations{ 6370 version: VersionTLS11, 6371 }, 6372 }) 6373 6374 testCases = append(testCases, testCase{ 6375 testType: serverTest, 6376 name: "ConflictingVersionNegotiation-2", 6377 config: Config{ 6378 Bugs: ProtocolBugs{ 6379 SendClientVersion: VersionTLS11, 6380 SendSupportedVersions: []uint16{VersionTLS12}, 6381 IgnoreTLS13DowngradeRandom: true, 6382 }, 6383 }, 6384 // The extension takes precedence over the ClientHello version. 6385 expectations: connectionExpectations{ 6386 version: VersionTLS12, 6387 }, 6388 }) 6389 6390 // Test that TLS 1.2 isn't negotiated by the supported_versions extension in 6391 // the ServerHello. 6392 testCases = append(testCases, testCase{ 6393 testType: clientTest, 6394 name: "SupportedVersionSelection-TLS12", 6395 config: Config{ 6396 MaxVersion: VersionTLS12, 6397 Bugs: ProtocolBugs{ 6398 SendServerSupportedVersionExtension: VersionTLS12, 6399 }, 6400 }, 6401 shouldFail: true, 6402 expectedError: ":UNEXPECTED_EXTENSION:", 6403 }) 6404 6405 // Test that the maximum version is selected regardless of the 6406 // client-sent order. 6407 testCases = append(testCases, testCase{ 6408 testType: serverTest, 6409 name: "IgnoreClientVersionOrder", 6410 config: Config{ 6411 Bugs: ProtocolBugs{ 6412 SendSupportedVersions: []uint16{VersionTLS12, VersionTLS13}, 6413 }, 6414 }, 6415 expectations: connectionExpectations{ 6416 version: VersionTLS13, 6417 }, 6418 }) 6419 6420 // Test for version tolerance. 6421 testCases = append(testCases, testCase{ 6422 testType: serverTest, 6423 name: "MinorVersionTolerance", 6424 config: Config{ 6425 Bugs: ProtocolBugs{ 6426 SendClientVersion: 0x03ff, 6427 OmitSupportedVersions: true, 6428 IgnoreTLS13DowngradeRandom: true, 6429 }, 6430 }, 6431 expectations: connectionExpectations{ 6432 version: VersionTLS12, 6433 }, 6434 }) 6435 testCases = append(testCases, testCase{ 6436 testType: serverTest, 6437 name: "MajorVersionTolerance", 6438 config: Config{ 6439 Bugs: ProtocolBugs{ 6440 SendClientVersion: 0x0400, 6441 OmitSupportedVersions: true, 6442 IgnoreTLS13DowngradeRandom: true, 6443 }, 6444 }, 6445 // TLS 1.3 must be negotiated with the supported_versions 6446 // extension, not ClientHello.version. 6447 expectations: connectionExpectations{ 6448 version: VersionTLS12, 6449 }, 6450 }) 6451 testCases = append(testCases, testCase{ 6452 testType: serverTest, 6453 name: "VersionTolerance-TLS13", 6454 config: Config{ 6455 Bugs: ProtocolBugs{ 6456 // Although TLS 1.3 does not use 6457 // ClientHello.version, it still tolerates high 6458 // values there. 6459 SendClientVersion: 0x0400, 6460 }, 6461 }, 6462 expectations: connectionExpectations{ 6463 version: VersionTLS13, 6464 }, 6465 }) 6466 6467 testCases = append(testCases, testCase{ 6468 protocol: dtls, 6469 testType: serverTest, 6470 name: "MinorVersionTolerance-DTLS", 6471 config: Config{ 6472 Bugs: ProtocolBugs{ 6473 SendClientVersion: 0xfe00, 6474 OmitSupportedVersions: true, 6475 }, 6476 }, 6477 expectations: connectionExpectations{ 6478 version: VersionTLS12, 6479 }, 6480 }) 6481 testCases = append(testCases, testCase{ 6482 protocol: dtls, 6483 testType: serverTest, 6484 name: "MajorVersionTolerance-DTLS", 6485 config: Config{ 6486 Bugs: ProtocolBugs{ 6487 SendClientVersion: 0xfdff, 6488 OmitSupportedVersions: true, 6489 }, 6490 }, 6491 expectations: connectionExpectations{ 6492 version: VersionTLS12, 6493 }, 6494 }) 6495 6496 // Test that versions below 3.0 are rejected. 6497 testCases = append(testCases, testCase{ 6498 testType: serverTest, 6499 name: "VersionTooLow", 6500 config: Config{ 6501 Bugs: ProtocolBugs{ 6502 SendClientVersion: 0x0200, 6503 OmitSupportedVersions: true, 6504 }, 6505 }, 6506 shouldFail: true, 6507 expectedError: ":UNSUPPORTED_PROTOCOL:", 6508 }) 6509 testCases = append(testCases, testCase{ 6510 protocol: dtls, 6511 testType: serverTest, 6512 name: "VersionTooLow-DTLS", 6513 config: Config{ 6514 Bugs: ProtocolBugs{ 6515 SendClientVersion: 0xffff, 6516 }, 6517 }, 6518 shouldFail: true, 6519 expectedError: ":UNSUPPORTED_PROTOCOL:", 6520 }) 6521 6522 testCases = append(testCases, testCase{ 6523 name: "ServerBogusVersion", 6524 config: Config{ 6525 Bugs: ProtocolBugs{ 6526 SendServerHelloVersion: 0x1234, 6527 }, 6528 }, 6529 shouldFail: true, 6530 expectedError: ":UNSUPPORTED_PROTOCOL:", 6531 }) 6532 6533 // Test TLS 1.3's downgrade signal. 6534 var downgradeTests = []struct { 6535 name string 6536 version uint16 6537 clientShimError string 6538 }{ 6539 {"TLS12", VersionTLS12, "tls: downgrade from TLS 1.3 detected"}, 6540 {"TLS11", VersionTLS11, "tls: downgrade from TLS 1.2 detected"}, 6541 // TLS 1.0 does not have a dedicated value. 6542 {"TLS10", VersionTLS10, "tls: downgrade from TLS 1.2 detected"}, 6543 } 6544 6545 for _, test := range downgradeTests { 6546 // The client should enforce the downgrade sentinel. 6547 testCases = append(testCases, testCase{ 6548 name: "Downgrade-" + test.name + "-Client", 6549 config: Config{ 6550 Bugs: ProtocolBugs{ 6551 NegotiateVersion: test.version, 6552 }, 6553 }, 6554 expectations: connectionExpectations{ 6555 version: test.version, 6556 }, 6557 shouldFail: true, 6558 expectedError: ":TLS13_DOWNGRADE:", 6559 expectedLocalError: "remote error: illegal parameter", 6560 }) 6561 6562 // The server should emit the downgrade signal. 6563 testCases = append(testCases, testCase{ 6564 testType: serverTest, 6565 name: "Downgrade-" + test.name + "-Server", 6566 config: Config{ 6567 Bugs: ProtocolBugs{ 6568 SendSupportedVersions: []uint16{test.version}, 6569 }, 6570 }, 6571 expectations: connectionExpectations{ 6572 version: test.version, 6573 }, 6574 shouldFail: true, 6575 expectedLocalError: test.clientShimError, 6576 }) 6577 } 6578 6579 // SSL 3.0 support has been removed. Test that the shim does not 6580 // support it. 6581 testCases = append(testCases, testCase{ 6582 name: "NoSSL3-Client", 6583 config: Config{ 6584 MinVersion: VersionSSL30, 6585 MaxVersion: VersionSSL30, 6586 }, 6587 shouldFail: true, 6588 expectedLocalError: "tls: client did not offer any supported protocol versions", 6589 }) 6590 testCases = append(testCases, testCase{ 6591 name: "NoSSL3-Client-Unsolicited", 6592 config: Config{ 6593 MinVersion: VersionSSL30, 6594 MaxVersion: VersionSSL30, 6595 Bugs: ProtocolBugs{ 6596 // The above test asserts the client does not 6597 // offer SSL 3.0 in the supported_versions 6598 // list. Additionally assert that it rejects an 6599 // unsolicited SSL 3.0 ServerHello. 6600 NegotiateVersion: VersionSSL30, 6601 }, 6602 }, 6603 shouldFail: true, 6604 expectedError: ":UNSUPPORTED_PROTOCOL:", 6605 expectedLocalError: "remote error: protocol version not supported", 6606 }) 6607 testCases = append(testCases, testCase{ 6608 testType: serverTest, 6609 name: "NoSSL3-Server", 6610 config: Config{ 6611 MinVersion: VersionSSL30, 6612 MaxVersion: VersionSSL30, 6613 }, 6614 shouldFail: true, 6615 expectedError: ":UNSUPPORTED_PROTOCOL:", 6616 expectedLocalError: "remote error: protocol version not supported", 6617 }) 6618} 6619 6620func addMinimumVersionTests() { 6621 for _, protocol := range []protocol{tls, dtls, quic} { 6622 for _, shimVers := range allVersions(protocol) { 6623 // Assemble flags to disable all older versions on the shim. 6624 var flags []string 6625 for _, vers := range allVersions(protocol) { 6626 if vers.version < shimVers.version { 6627 flags = append(flags, vers.excludeFlag) 6628 } 6629 } 6630 6631 flags2 := []string{"-min-version", shimVers.shimFlag(protocol)} 6632 6633 for _, runnerVers := range allVersions(protocol) { 6634 suffix := shimVers.name + "-" + runnerVers.name 6635 suffix += "-" + protocol.String() 6636 6637 var expectedVersion uint16 6638 var shouldFail bool 6639 var expectedError, expectedLocalError string 6640 if runnerVers.version >= shimVers.version { 6641 expectedVersion = runnerVers.version 6642 } else { 6643 shouldFail = true 6644 expectedError = ":UNSUPPORTED_PROTOCOL:" 6645 expectedLocalError = "remote error: protocol version not supported" 6646 } 6647 6648 testCases = append(testCases, testCase{ 6649 protocol: protocol, 6650 testType: clientTest, 6651 name: "MinimumVersion-Client-" + suffix, 6652 config: Config{ 6653 MaxVersion: runnerVers.version, 6654 Bugs: ProtocolBugs{ 6655 // Ensure the server does not decline to 6656 // select a version (versions extension) or 6657 // cipher (some ciphers depend on versions). 6658 NegotiateVersion: runnerVers.wire(protocol), 6659 IgnorePeerCipherPreferences: shouldFail, 6660 }, 6661 }, 6662 flags: flags, 6663 expectations: connectionExpectations{ 6664 version: expectedVersion, 6665 }, 6666 shouldFail: shouldFail, 6667 expectedError: expectedError, 6668 expectedLocalError: expectedLocalError, 6669 // The version name check does not recognize the 6670 // |excludeFlag| construction in |flags|. 6671 skipVersionNameCheck: true, 6672 }) 6673 testCases = append(testCases, testCase{ 6674 protocol: protocol, 6675 testType: clientTest, 6676 name: "MinimumVersion-Client2-" + suffix, 6677 config: Config{ 6678 MaxVersion: runnerVers.version, 6679 Bugs: ProtocolBugs{ 6680 // Ensure the server does not decline to 6681 // select a version (versions extension) or 6682 // cipher (some ciphers depend on versions). 6683 NegotiateVersion: runnerVers.wire(protocol), 6684 IgnorePeerCipherPreferences: shouldFail, 6685 }, 6686 }, 6687 flags: flags2, 6688 expectations: connectionExpectations{ 6689 version: expectedVersion, 6690 }, 6691 shouldFail: shouldFail, 6692 expectedError: expectedError, 6693 expectedLocalError: expectedLocalError, 6694 }) 6695 6696 testCases = append(testCases, testCase{ 6697 protocol: protocol, 6698 testType: serverTest, 6699 name: "MinimumVersion-Server-" + suffix, 6700 config: Config{ 6701 MaxVersion: runnerVers.version, 6702 }, 6703 flags: flags, 6704 expectations: connectionExpectations{ 6705 version: expectedVersion, 6706 }, 6707 shouldFail: shouldFail, 6708 expectedError: expectedError, 6709 expectedLocalError: expectedLocalError, 6710 // The version name check does not recognize the 6711 // |excludeFlag| construction in |flags|. 6712 skipVersionNameCheck: true, 6713 }) 6714 testCases = append(testCases, testCase{ 6715 protocol: protocol, 6716 testType: serverTest, 6717 name: "MinimumVersion-Server2-" + suffix, 6718 config: Config{ 6719 MaxVersion: runnerVers.version, 6720 }, 6721 flags: flags2, 6722 expectations: connectionExpectations{ 6723 version: expectedVersion, 6724 }, 6725 shouldFail: shouldFail, 6726 expectedError: expectedError, 6727 expectedLocalError: expectedLocalError, 6728 }) 6729 } 6730 } 6731 } 6732} 6733 6734func addExtensionTests() { 6735 exampleCertificate := generateSingleCertChain(&x509.Certificate{ 6736 SerialNumber: big.NewInt(57005), 6737 Subject: pkix.Name{ 6738 CommonName: "test cert", 6739 }, 6740 NotBefore: time.Now().Add(-time.Hour), 6741 NotAfter: time.Now().Add(time.Hour), 6742 DNSNames: []string{"example.com"}, 6743 IsCA: true, 6744 BasicConstraintsValid: true, 6745 }, &ecdsaP256Key) 6746 6747 // Repeat extensions tests at all versions. 6748 for _, protocol := range []protocol{tls, dtls, quic} { 6749 for _, ver := range allVersions(protocol) { 6750 suffix := fmt.Sprintf("%s-%s", protocol.String(), ver.name) 6751 6752 // Test that duplicate extensions are rejected. 6753 testCases = append(testCases, testCase{ 6754 protocol: protocol, 6755 testType: clientTest, 6756 name: "DuplicateExtensionClient-" + suffix, 6757 config: Config{ 6758 MaxVersion: ver.version, 6759 Bugs: ProtocolBugs{ 6760 DuplicateExtension: true, 6761 }, 6762 }, 6763 shouldFail: true, 6764 expectedLocalError: "remote error: error decoding message", 6765 }) 6766 testCases = append(testCases, testCase{ 6767 protocol: protocol, 6768 testType: serverTest, 6769 name: "DuplicateExtensionServer-" + suffix, 6770 config: Config{ 6771 MaxVersion: ver.version, 6772 Bugs: ProtocolBugs{ 6773 DuplicateExtension: true, 6774 }, 6775 }, 6776 shouldFail: true, 6777 expectedLocalError: "remote error: error decoding message", 6778 }) 6779 6780 // Test SNI. 6781 testCases = append(testCases, testCase{ 6782 protocol: protocol, 6783 testType: clientTest, 6784 name: "ServerNameExtensionClient-" + suffix, 6785 config: Config{ 6786 MaxVersion: ver.version, 6787 Bugs: ProtocolBugs{ 6788 ExpectServerName: "example.com", 6789 }, 6790 Credential: &exampleCertificate, 6791 }, 6792 flags: []string{"-host-name", "example.com"}, 6793 }) 6794 testCases = append(testCases, testCase{ 6795 protocol: protocol, 6796 testType: clientTest, 6797 name: "ServerNameExtensionClientMismatch-" + suffix, 6798 config: Config{ 6799 MaxVersion: ver.version, 6800 Bugs: ProtocolBugs{ 6801 ExpectServerName: "mismatch.com", 6802 }, 6803 }, 6804 flags: []string{"-host-name", "example.com"}, 6805 shouldFail: true, 6806 expectedLocalError: "tls: unexpected server name", 6807 }) 6808 testCases = append(testCases, testCase{ 6809 protocol: protocol, 6810 testType: clientTest, 6811 name: "ServerNameExtensionClientMissing-" + suffix, 6812 config: Config{ 6813 MaxVersion: ver.version, 6814 Bugs: ProtocolBugs{ 6815 ExpectServerName: "missing.com", 6816 }, 6817 }, 6818 shouldFail: true, 6819 expectedLocalError: "tls: unexpected server name", 6820 }) 6821 testCases = append(testCases, testCase{ 6822 protocol: protocol, 6823 testType: clientTest, 6824 name: "TolerateServerNameAck-" + suffix, 6825 config: Config{ 6826 MaxVersion: ver.version, 6827 Bugs: ProtocolBugs{ 6828 SendServerNameAck: true, 6829 }, 6830 Credential: &exampleCertificate, 6831 }, 6832 flags: []string{"-host-name", "example.com"}, 6833 resumeSession: true, 6834 }) 6835 testCases = append(testCases, testCase{ 6836 protocol: protocol, 6837 testType: clientTest, 6838 name: "UnsolicitedServerNameAck-" + suffix, 6839 config: Config{ 6840 MaxVersion: ver.version, 6841 Bugs: ProtocolBugs{ 6842 SendServerNameAck: true, 6843 }, 6844 }, 6845 shouldFail: true, 6846 expectedError: ":UNEXPECTED_EXTENSION:", 6847 expectedLocalError: "remote error: unsupported extension", 6848 }) 6849 testCases = append(testCases, testCase{ 6850 protocol: protocol, 6851 testType: serverTest, 6852 name: "ServerNameExtensionServer-" + suffix, 6853 config: Config{ 6854 MaxVersion: ver.version, 6855 ServerName: "example.com", 6856 }, 6857 flags: []string{"-expect-server-name", "example.com"}, 6858 resumeSession: true, 6859 }) 6860 6861 // Test ALPN. 6862 testCases = append(testCases, testCase{ 6863 protocol: protocol, 6864 testType: clientTest, 6865 skipQUICALPNConfig: true, 6866 name: "ALPNClient-" + suffix, 6867 config: Config{ 6868 MaxVersion: ver.version, 6869 NextProtos: []string{"foo"}, 6870 }, 6871 flags: []string{ 6872 "-advertise-alpn", "\x03foo\x03bar\x03baz", 6873 "-expect-alpn", "foo", 6874 }, 6875 expectations: connectionExpectations{ 6876 nextProto: "foo", 6877 nextProtoType: alpn, 6878 }, 6879 resumeSession: true, 6880 }) 6881 testCases = append(testCases, testCase{ 6882 protocol: protocol, 6883 testType: clientTest, 6884 skipQUICALPNConfig: true, 6885 name: "ALPNClient-RejectUnknown-" + suffix, 6886 config: Config{ 6887 MaxVersion: ver.version, 6888 Bugs: ProtocolBugs{ 6889 SendALPN: "baz", 6890 }, 6891 }, 6892 flags: []string{ 6893 "-advertise-alpn", "\x03foo\x03bar", 6894 }, 6895 shouldFail: true, 6896 expectedError: ":INVALID_ALPN_PROTOCOL:", 6897 expectedLocalError: "remote error: illegal parameter", 6898 }) 6899 testCases = append(testCases, testCase{ 6900 protocol: protocol, 6901 testType: clientTest, 6902 skipQUICALPNConfig: true, 6903 name: "ALPNClient-AllowUnknown-" + suffix, 6904 config: Config{ 6905 MaxVersion: ver.version, 6906 Bugs: ProtocolBugs{ 6907 SendALPN: "baz", 6908 }, 6909 }, 6910 flags: []string{ 6911 "-advertise-alpn", "\x03foo\x03bar", 6912 "-allow-unknown-alpn-protos", 6913 "-expect-alpn", "baz", 6914 }, 6915 }) 6916 testCases = append(testCases, testCase{ 6917 protocol: protocol, 6918 testType: serverTest, 6919 skipQUICALPNConfig: true, 6920 name: "ALPNServer-" + suffix, 6921 config: Config{ 6922 MaxVersion: ver.version, 6923 NextProtos: []string{"foo", "bar", "baz"}, 6924 }, 6925 flags: []string{ 6926 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 6927 "-select-alpn", "foo", 6928 }, 6929 expectations: connectionExpectations{ 6930 nextProto: "foo", 6931 nextProtoType: alpn, 6932 }, 6933 resumeSession: true, 6934 }) 6935 6936 var shouldDeclineALPNFail bool 6937 var declineALPNError, declineALPNLocalError string 6938 if protocol == quic { 6939 // ALPN is mandatory in QUIC. 6940 shouldDeclineALPNFail = true 6941 declineALPNError = ":NO_APPLICATION_PROTOCOL:" 6942 declineALPNLocalError = "remote error: no application protocol" 6943 } 6944 testCases = append(testCases, testCase{ 6945 protocol: protocol, 6946 testType: serverTest, 6947 skipQUICALPNConfig: true, 6948 name: "ALPNServer-Decline-" + suffix, 6949 config: Config{ 6950 MaxVersion: ver.version, 6951 NextProtos: []string{"foo", "bar", "baz"}, 6952 }, 6953 flags: []string{"-decline-alpn"}, 6954 expectations: connectionExpectations{ 6955 noNextProto: true, 6956 }, 6957 resumeSession: true, 6958 shouldFail: shouldDeclineALPNFail, 6959 expectedError: declineALPNError, 6960 expectedLocalError: declineALPNLocalError, 6961 }) 6962 6963 testCases = append(testCases, testCase{ 6964 protocol: protocol, 6965 testType: serverTest, 6966 skipQUICALPNConfig: true, 6967 name: "ALPNServer-Reject-" + suffix, 6968 config: Config{ 6969 MaxVersion: ver.version, 6970 NextProtos: []string{"foo", "bar", "baz"}, 6971 }, 6972 flags: []string{"-reject-alpn"}, 6973 shouldFail: true, 6974 expectedError: ":NO_APPLICATION_PROTOCOL:", 6975 expectedLocalError: "remote error: no application protocol", 6976 }) 6977 6978 // Test that the server implementation catches itself if the 6979 // callback tries to return an invalid empty ALPN protocol. 6980 testCases = append(testCases, testCase{ 6981 protocol: protocol, 6982 testType: serverTest, 6983 skipQUICALPNConfig: true, 6984 name: "ALPNServer-SelectEmpty-" + suffix, 6985 config: Config{ 6986 MaxVersion: ver.version, 6987 NextProtos: []string{"foo", "bar", "baz"}, 6988 }, 6989 flags: []string{ 6990 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 6991 "-select-empty-alpn", 6992 }, 6993 shouldFail: true, 6994 expectedLocalError: "remote error: internal error", 6995 expectedError: ":INVALID_ALPN_PROTOCOL:", 6996 }) 6997 6998 // Test ALPN in async mode as well to ensure that extensions callbacks are only 6999 // called once. 7000 testCases = append(testCases, testCase{ 7001 protocol: protocol, 7002 testType: serverTest, 7003 skipQUICALPNConfig: true, 7004 name: "ALPNServer-Async-" + suffix, 7005 config: Config{ 7006 MaxVersion: ver.version, 7007 NextProtos: []string{"foo", "bar", "baz"}, 7008 // Prior to TLS 1.3, exercise the asynchronous session callback. 7009 SessionTicketsDisabled: ver.version < VersionTLS13, 7010 }, 7011 flags: []string{ 7012 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7013 "-select-alpn", "foo", 7014 "-async", 7015 }, 7016 expectations: connectionExpectations{ 7017 nextProto: "foo", 7018 nextProtoType: alpn, 7019 }, 7020 resumeSession: true, 7021 }) 7022 7023 var emptyString string 7024 testCases = append(testCases, testCase{ 7025 protocol: protocol, 7026 testType: clientTest, 7027 skipQUICALPNConfig: true, 7028 name: "ALPNClient-EmptyProtocolName-" + suffix, 7029 config: Config{ 7030 MaxVersion: ver.version, 7031 NextProtos: []string{""}, 7032 Bugs: ProtocolBugs{ 7033 // A server returning an empty ALPN protocol 7034 // should be rejected. 7035 ALPNProtocol: &emptyString, 7036 }, 7037 }, 7038 flags: []string{ 7039 "-advertise-alpn", "\x03foo", 7040 }, 7041 shouldFail: true, 7042 expectedError: ":PARSE_TLSEXT:", 7043 }) 7044 testCases = append(testCases, testCase{ 7045 protocol: protocol, 7046 testType: serverTest, 7047 skipQUICALPNConfig: true, 7048 name: "ALPNServer-EmptyProtocolName-" + suffix, 7049 config: Config{ 7050 MaxVersion: ver.version, 7051 // A ClientHello containing an empty ALPN protocol 7052 // should be rejected. 7053 NextProtos: []string{"foo", "", "baz"}, 7054 }, 7055 flags: []string{ 7056 "-select-alpn", "foo", 7057 }, 7058 shouldFail: true, 7059 expectedError: ":PARSE_TLSEXT:", 7060 }) 7061 7062 // Test NPN and the interaction with ALPN. 7063 if ver.version < VersionTLS13 && protocol == tls { 7064 // Test that the server prefers ALPN over NPN. 7065 testCases = append(testCases, testCase{ 7066 protocol: protocol, 7067 testType: serverTest, 7068 name: "ALPNServer-Preferred-" + suffix, 7069 config: Config{ 7070 MaxVersion: ver.version, 7071 NextProtos: []string{"foo", "bar", "baz"}, 7072 }, 7073 flags: []string{ 7074 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7075 "-select-alpn", "foo", 7076 "-advertise-npn", "\x03foo\x03bar\x03baz", 7077 }, 7078 expectations: connectionExpectations{ 7079 nextProto: "foo", 7080 nextProtoType: alpn, 7081 }, 7082 resumeSession: true, 7083 }) 7084 testCases = append(testCases, testCase{ 7085 protocol: protocol, 7086 testType: serverTest, 7087 name: "ALPNServer-Preferred-Swapped-" + suffix, 7088 config: Config{ 7089 MaxVersion: ver.version, 7090 NextProtos: []string{"foo", "bar", "baz"}, 7091 Bugs: ProtocolBugs{ 7092 SwapNPNAndALPN: true, 7093 }, 7094 }, 7095 flags: []string{ 7096 "-expect-advertised-alpn", "\x03foo\x03bar\x03baz", 7097 "-select-alpn", "foo", 7098 "-advertise-npn", "\x03foo\x03bar\x03baz", 7099 }, 7100 expectations: connectionExpectations{ 7101 nextProto: "foo", 7102 nextProtoType: alpn, 7103 }, 7104 resumeSession: true, 7105 }) 7106 7107 // Test that negotiating both NPN and ALPN is forbidden. 7108 testCases = append(testCases, testCase{ 7109 protocol: protocol, 7110 name: "NegotiateALPNAndNPN-" + suffix, 7111 config: Config{ 7112 MaxVersion: ver.version, 7113 NextProtos: []string{"foo", "bar", "baz"}, 7114 Bugs: ProtocolBugs{ 7115 NegotiateALPNAndNPN: true, 7116 }, 7117 }, 7118 flags: []string{ 7119 "-advertise-alpn", "\x03foo", 7120 "-select-next-proto", "foo", 7121 }, 7122 shouldFail: true, 7123 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:", 7124 }) 7125 testCases = append(testCases, testCase{ 7126 protocol: protocol, 7127 name: "NegotiateALPNAndNPN-Swapped-" + suffix, 7128 config: Config{ 7129 MaxVersion: ver.version, 7130 NextProtos: []string{"foo", "bar", "baz"}, 7131 Bugs: ProtocolBugs{ 7132 NegotiateALPNAndNPN: true, 7133 SwapNPNAndALPN: true, 7134 }, 7135 }, 7136 flags: []string{ 7137 "-advertise-alpn", "\x03foo", 7138 "-select-next-proto", "foo", 7139 }, 7140 shouldFail: true, 7141 expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:", 7142 }) 7143 } 7144 7145 // Test missing ALPN in QUIC 7146 if protocol == quic { 7147 testCases = append(testCases, testCase{ 7148 testType: clientTest, 7149 protocol: protocol, 7150 name: "Client-ALPNMissingFromConfig-" + suffix, 7151 config: Config{ 7152 MinVersion: ver.version, 7153 MaxVersion: ver.version, 7154 }, 7155 skipQUICALPNConfig: true, 7156 shouldFail: true, 7157 expectedError: ":NO_APPLICATION_PROTOCOL:", 7158 }) 7159 testCases = append(testCases, testCase{ 7160 testType: clientTest, 7161 protocol: protocol, 7162 name: "Client-ALPNMissing-" + suffix, 7163 config: Config{ 7164 MinVersion: ver.version, 7165 MaxVersion: ver.version, 7166 }, 7167 flags: []string{ 7168 "-advertise-alpn", "\x03foo", 7169 }, 7170 skipQUICALPNConfig: true, 7171 shouldFail: true, 7172 expectedError: ":NO_APPLICATION_PROTOCOL:", 7173 expectedLocalError: "remote error: no application protocol", 7174 }) 7175 testCases = append(testCases, testCase{ 7176 testType: serverTest, 7177 protocol: protocol, 7178 name: "Server-ALPNMissing-" + suffix, 7179 config: Config{ 7180 MinVersion: ver.version, 7181 MaxVersion: ver.version, 7182 }, 7183 skipQUICALPNConfig: true, 7184 shouldFail: true, 7185 expectedError: ":NO_APPLICATION_PROTOCOL:", 7186 expectedLocalError: "remote error: no application protocol", 7187 }) 7188 testCases = append(testCases, testCase{ 7189 testType: serverTest, 7190 protocol: protocol, 7191 name: "Server-ALPNMismatch-" + suffix, 7192 config: Config{ 7193 MinVersion: ver.version, 7194 MaxVersion: ver.version, 7195 NextProtos: []string{"foo"}, 7196 }, 7197 flags: []string{ 7198 "-decline-alpn", 7199 }, 7200 skipQUICALPNConfig: true, 7201 shouldFail: true, 7202 expectedError: ":NO_APPLICATION_PROTOCOL:", 7203 expectedLocalError: "remote error: no application protocol", 7204 }) 7205 } 7206 7207 // Test ALPS. 7208 if ver.version >= VersionTLS13 { 7209 // Test basic client with different ALPS codepoint. 7210 for _, alpsCodePoint := range []ALPSUseCodepoint{ALPSUseCodepointNew, ALPSUseCodepointOld} { 7211 flags := []string{} 7212 expectations := connectionExpectations{ 7213 peerApplicationSettingsOld: []byte("shim1"), 7214 } 7215 resumeExpectations := &connectionExpectations{ 7216 peerApplicationSettingsOld: []byte("shim2"), 7217 } 7218 7219 if alpsCodePoint == ALPSUseCodepointNew { 7220 flags = append(flags, "-alps-use-new-codepoint") 7221 expectations = connectionExpectations{ 7222 peerApplicationSettings: []byte("shim1"), 7223 } 7224 resumeExpectations = &connectionExpectations{ 7225 peerApplicationSettings: []byte("shim2"), 7226 } 7227 } 7228 7229 flags = append(flags, 7230 "-advertise-alpn", "\x05proto", 7231 "-expect-alpn", "proto", 7232 "-on-initial-application-settings", "proto,shim1", 7233 "-on-initial-expect-peer-application-settings", "runner1", 7234 "-on-resume-application-settings", "proto,shim2", 7235 "-on-resume-expect-peer-application-settings", "runner2") 7236 7237 // Test that server can negotiate ALPS, including different values 7238 // on resumption. 7239 testCases = append(testCases, testCase{ 7240 protocol: protocol, 7241 testType: clientTest, 7242 name: fmt.Sprintf("ALPS-Basic-Client-%s-%s", alpsCodePoint, suffix), 7243 skipQUICALPNConfig: true, 7244 config: Config{ 7245 MaxVersion: ver.version, 7246 NextProtos: []string{"proto"}, 7247 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7248 ALPSUseNewCodepoint: alpsCodePoint, 7249 }, 7250 resumeConfig: &Config{ 7251 MaxVersion: ver.version, 7252 NextProtos: []string{"proto"}, 7253 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7254 ALPSUseNewCodepoint: alpsCodePoint, 7255 }, 7256 resumeSession: true, 7257 expectations: expectations, 7258 resumeExpectations: resumeExpectations, 7259 flags: flags, 7260 }) 7261 7262 // Test basic server with different ALPS codepoint. 7263 flags = []string{} 7264 expectations = connectionExpectations{ 7265 peerApplicationSettingsOld: []byte("shim1"), 7266 } 7267 resumeExpectations = &connectionExpectations{ 7268 peerApplicationSettingsOld: []byte("shim2"), 7269 } 7270 7271 if alpsCodePoint == ALPSUseCodepointNew { 7272 flags = append(flags, "-alps-use-new-codepoint") 7273 expectations = connectionExpectations{ 7274 peerApplicationSettings: []byte("shim1"), 7275 } 7276 resumeExpectations = &connectionExpectations{ 7277 peerApplicationSettings: []byte("shim2"), 7278 } 7279 } 7280 7281 flags = append(flags, 7282 "-select-alpn", "proto", 7283 "-on-initial-application-settings", "proto,shim1", 7284 "-on-initial-expect-peer-application-settings", "runner1", 7285 "-on-resume-application-settings", "proto,shim2", 7286 "-on-resume-expect-peer-application-settings", "runner2") 7287 7288 // Test that server can negotiate ALPS, including different values 7289 // on resumption. 7290 testCases = append(testCases, testCase{ 7291 protocol: protocol, 7292 testType: serverTest, 7293 name: fmt.Sprintf("ALPS-Basic-Server-%s-%s", alpsCodePoint, suffix), 7294 skipQUICALPNConfig: true, 7295 config: Config{ 7296 MaxVersion: ver.version, 7297 NextProtos: []string{"proto"}, 7298 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7299 ALPSUseNewCodepoint: alpsCodePoint, 7300 }, 7301 resumeConfig: &Config{ 7302 MaxVersion: ver.version, 7303 NextProtos: []string{"proto"}, 7304 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7305 ALPSUseNewCodepoint: alpsCodePoint, 7306 }, 7307 resumeSession: true, 7308 expectations: expectations, 7309 resumeExpectations: resumeExpectations, 7310 flags: flags, 7311 }) 7312 7313 // Try different ALPS codepoint for all the existing tests. 7314 alpsFlags := []string{} 7315 expectations = connectionExpectations{ 7316 peerApplicationSettingsOld: []byte("shim1"), 7317 } 7318 resumeExpectations = &connectionExpectations{ 7319 peerApplicationSettingsOld: []byte("shim2"), 7320 } 7321 if alpsCodePoint == ALPSUseCodepointNew { 7322 alpsFlags = append(alpsFlags, "-alps-use-new-codepoint") 7323 expectations = connectionExpectations{ 7324 peerApplicationSettings: []byte("shim1"), 7325 } 7326 resumeExpectations = &connectionExpectations{ 7327 peerApplicationSettings: []byte("shim2"), 7328 } 7329 } 7330 7331 // Test that the server can defer its ALPS configuration to the ALPN 7332 // selection callback. 7333 testCases = append(testCases, testCase{ 7334 protocol: protocol, 7335 testType: serverTest, 7336 name: fmt.Sprintf("ALPS-Basic-Server-Defer-%s-%s", alpsCodePoint, suffix), 7337 skipQUICALPNConfig: true, 7338 config: Config{ 7339 MaxVersion: ver.version, 7340 NextProtos: []string{"proto"}, 7341 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7342 ALPSUseNewCodepoint: alpsCodePoint, 7343 }, 7344 resumeConfig: &Config{ 7345 MaxVersion: ver.version, 7346 NextProtos: []string{"proto"}, 7347 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7348 ALPSUseNewCodepoint: alpsCodePoint, 7349 }, 7350 resumeSession: true, 7351 expectations: expectations, 7352 resumeExpectations: resumeExpectations, 7353 flags: append([]string{ 7354 "-select-alpn", "proto", 7355 "-defer-alps", 7356 "-on-initial-application-settings", "proto,shim1", 7357 "-on-initial-expect-peer-application-settings", "runner1", 7358 "-on-resume-application-settings", "proto,shim2", 7359 "-on-resume-expect-peer-application-settings", "runner2", 7360 }, alpsFlags...), 7361 }) 7362 7363 expectations = connectionExpectations{ 7364 peerApplicationSettingsOld: []byte{}, 7365 } 7366 if alpsCodePoint == ALPSUseCodepointNew { 7367 expectations = connectionExpectations{ 7368 peerApplicationSettings: []byte{}, 7369 } 7370 } 7371 // Test the client and server correctly handle empty settings. 7372 testCases = append(testCases, testCase{ 7373 protocol: protocol, 7374 testType: clientTest, 7375 name: fmt.Sprintf("ALPS-Empty-Client-%s-%s", alpsCodePoint, suffix), 7376 skipQUICALPNConfig: true, 7377 config: Config{ 7378 MaxVersion: ver.version, 7379 NextProtos: []string{"proto"}, 7380 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7381 ALPSUseNewCodepoint: alpsCodePoint, 7382 }, 7383 resumeSession: true, 7384 expectations: expectations, 7385 flags: append([]string{ 7386 "-advertise-alpn", "\x05proto", 7387 "-expect-alpn", "proto", 7388 "-application-settings", "proto,", 7389 "-expect-peer-application-settings", "", 7390 }, alpsFlags...), 7391 }) 7392 testCases = append(testCases, testCase{ 7393 protocol: protocol, 7394 testType: serverTest, 7395 name: fmt.Sprintf("ALPS-Empty-Server-%s-%s", alpsCodePoint, suffix), 7396 skipQUICALPNConfig: true, 7397 config: Config{ 7398 MaxVersion: ver.version, 7399 NextProtos: []string{"proto"}, 7400 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7401 ALPSUseNewCodepoint: alpsCodePoint, 7402 }, 7403 resumeSession: true, 7404 expectations: expectations, 7405 flags: append([]string{ 7406 "-select-alpn", "proto", 7407 "-application-settings", "proto,", 7408 "-expect-peer-application-settings", "", 7409 }, alpsFlags...), 7410 }) 7411 7412 bugs := ProtocolBugs{ 7413 AlwaysNegotiateApplicationSettingsOld: true, 7414 } 7415 if alpsCodePoint == ALPSUseCodepointNew { 7416 bugs = ProtocolBugs{ 7417 AlwaysNegotiateApplicationSettingsNew: true, 7418 } 7419 } 7420 // Test the client rejects application settings from the server on 7421 // protocols it doesn't have them. 7422 testCases = append(testCases, testCase{ 7423 protocol: protocol, 7424 testType: clientTest, 7425 name: fmt.Sprintf("ALPS-UnsupportedProtocol-Client-%s-%s", alpsCodePoint, suffix), 7426 skipQUICALPNConfig: true, 7427 config: Config{ 7428 MaxVersion: ver.version, 7429 NextProtos: []string{"proto1"}, 7430 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7431 Bugs: bugs, 7432 ALPSUseNewCodepoint: alpsCodePoint, 7433 }, 7434 // The client supports ALPS with "proto2", but not "proto1". 7435 flags: append([]string{ 7436 "-advertise-alpn", "\x06proto1\x06proto2", 7437 "-application-settings", "proto2,shim", 7438 "-expect-alpn", "proto1", 7439 }, alpsFlags...), 7440 // The server sends ALPS with "proto1", which is invalid. 7441 shouldFail: true, 7442 expectedError: ":INVALID_ALPN_PROTOCOL:", 7443 expectedLocalError: "remote error: illegal parameter", 7444 }) 7445 7446 // Test client rejects application settings from the server when 7447 // server sends the wrong ALPS codepoint. 7448 bugs = ProtocolBugs{ 7449 AlwaysNegotiateApplicationSettingsOld: true, 7450 } 7451 if alpsCodePoint == ALPSUseCodepointOld { 7452 bugs = ProtocolBugs{ 7453 AlwaysNegotiateApplicationSettingsNew: true, 7454 } 7455 } 7456 7457 testCases = append(testCases, testCase{ 7458 protocol: protocol, 7459 testType: clientTest, 7460 name: fmt.Sprintf("ALPS-WrongServerCodepoint-Client-%s-%s", alpsCodePoint, suffix), 7461 skipQUICALPNConfig: true, 7462 config: Config{ 7463 MaxVersion: ver.version, 7464 NextProtos: []string{"proto"}, 7465 ApplicationSettings: map[string][]byte{"proto": []byte{}}, 7466 Bugs: bugs, 7467 ALPSUseNewCodepoint: alpsCodePoint, 7468 }, 7469 flags: append([]string{ 7470 "-advertise-alpn", "\x05proto", 7471 "-expect-alpn", "proto", 7472 "-application-settings", "proto,", 7473 "-expect-peer-application-settings", "", 7474 }, alpsFlags...), 7475 shouldFail: true, 7476 expectedError: ":UNEXPECTED_EXTENSION:", 7477 expectedLocalError: "remote error: unsupported extension", 7478 }) 7479 7480 // Test server ignore wrong codepoint from client. 7481 clientSends := ALPSUseCodepointNew 7482 if alpsCodePoint == ALPSUseCodepointNew { 7483 clientSends = ALPSUseCodepointOld 7484 } 7485 7486 testCases = append(testCases, testCase{ 7487 protocol: protocol, 7488 testType: serverTest, 7489 name: fmt.Sprintf("ALPS-IgnoreClientWrongCodepoint-Server-%s-%s", alpsCodePoint, suffix), 7490 skipQUICALPNConfig: true, 7491 config: Config{ 7492 MaxVersion: ver.version, 7493 NextProtos: []string{"proto"}, 7494 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 7495 ALPSUseNewCodepoint: clientSends, 7496 }, 7497 resumeConfig: &Config{ 7498 MaxVersion: ver.version, 7499 NextProtos: []string{"proto"}, 7500 ApplicationSettings: map[string][]byte{"proto": []byte("runner2")}, 7501 ALPSUseNewCodepoint: clientSends, 7502 }, 7503 resumeSession: true, 7504 flags: append([]string{ 7505 "-select-alpn", "proto", 7506 "-on-initial-application-settings", "proto,shim1", 7507 "-on-resume-application-settings", "proto,shim2", 7508 }, alpsFlags...), 7509 }) 7510 7511 // Test the server declines ALPS if it doesn't support it for the 7512 // specified protocol. 7513 testCases = append(testCases, testCase{ 7514 protocol: protocol, 7515 testType: serverTest, 7516 name: fmt.Sprintf("ALPS-UnsupportedProtocol-Server-%s-%s", alpsCodePoint, suffix), 7517 skipQUICALPNConfig: true, 7518 config: Config{ 7519 MaxVersion: ver.version, 7520 NextProtos: []string{"proto1"}, 7521 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7522 ALPSUseNewCodepoint: alpsCodePoint, 7523 }, 7524 // The server supports ALPS with "proto2", but not "proto1". 7525 flags: append([]string{ 7526 "-select-alpn", "proto1", 7527 "-application-settings", "proto2,shim", 7528 }, alpsFlags...), 7529 }) 7530 7531 // Test the client rejects application settings from the server when 7532 // it always negotiate both codepoint. 7533 testCases = append(testCases, testCase{ 7534 protocol: protocol, 7535 testType: clientTest, 7536 name: fmt.Sprintf("ALPS-UnsupportedProtocol-Client-ServerBoth-%s-%s", alpsCodePoint, suffix), 7537 skipQUICALPNConfig: true, 7538 config: Config{ 7539 MaxVersion: ver.version, 7540 NextProtos: []string{"proto1"}, 7541 ApplicationSettings: map[string][]byte{"proto1": []byte("runner")}, 7542 Bugs: ProtocolBugs{ 7543 AlwaysNegotiateApplicationSettingsBoth: true, 7544 }, 7545 ALPSUseNewCodepoint: alpsCodePoint, 7546 }, 7547 flags: append([]string{ 7548 "-advertise-alpn", "\x06proto1\x06proto2", 7549 "-application-settings", "proto1,shim", 7550 "-expect-alpn", "proto1", 7551 }, alpsFlags...), 7552 // The server sends ALPS with both application settings, which is invalid. 7553 shouldFail: true, 7554 expectedError: ":UNEXPECTED_EXTENSION:", 7555 expectedLocalError: "remote error: unsupported extension", 7556 }) 7557 7558 expectations = connectionExpectations{ 7559 peerApplicationSettingsOld: []byte("shim"), 7560 } 7561 if alpsCodePoint == ALPSUseCodepointNew { 7562 expectations = connectionExpectations{ 7563 peerApplicationSettings: []byte("shim"), 7564 } 7565 } 7566 7567 // Test that the server rejects a missing application_settings extension. 7568 testCases = append(testCases, testCase{ 7569 protocol: protocol, 7570 testType: serverTest, 7571 name: fmt.Sprintf("ALPS-OmitClientApplicationSettings-%s-%s", alpsCodePoint, suffix), 7572 skipQUICALPNConfig: true, 7573 config: Config{ 7574 MaxVersion: ver.version, 7575 NextProtos: []string{"proto"}, 7576 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7577 Bugs: ProtocolBugs{ 7578 OmitClientApplicationSettings: true, 7579 }, 7580 ALPSUseNewCodepoint: alpsCodePoint, 7581 }, 7582 flags: append([]string{ 7583 "-select-alpn", "proto", 7584 "-application-settings", "proto,shim", 7585 }, alpsFlags...), 7586 // The runner is a client, so it only processes the shim's alert 7587 // after checking connection state. 7588 expectations: expectations, 7589 shouldFail: true, 7590 expectedError: ":MISSING_EXTENSION:", 7591 expectedLocalError: "remote error: missing extension", 7592 }) 7593 7594 // Test that the server rejects a missing EncryptedExtensions message. 7595 testCases = append(testCases, testCase{ 7596 protocol: protocol, 7597 testType: serverTest, 7598 name: fmt.Sprintf("ALPS-OmitClientEncryptedExtensions-%s-%s", alpsCodePoint, suffix), 7599 skipQUICALPNConfig: true, 7600 config: Config{ 7601 MaxVersion: ver.version, 7602 NextProtos: []string{"proto"}, 7603 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7604 Bugs: ProtocolBugs{ 7605 OmitClientEncryptedExtensions: true, 7606 }, 7607 ALPSUseNewCodepoint: alpsCodePoint, 7608 }, 7609 flags: append([]string{ 7610 "-select-alpn", "proto", 7611 "-application-settings", "proto,shim", 7612 }, alpsFlags...), 7613 // The runner is a client, so it only processes the shim's alert 7614 // after checking connection state. 7615 expectations: expectations, 7616 shouldFail: true, 7617 expectedError: ":UNEXPECTED_MESSAGE:", 7618 expectedLocalError: "remote error: unexpected message", 7619 }) 7620 7621 // Test that the server rejects an unexpected EncryptedExtensions message. 7622 testCases = append(testCases, testCase{ 7623 protocol: protocol, 7624 testType: serverTest, 7625 name: fmt.Sprintf("UnexpectedClientEncryptedExtensions-%s-%s", alpsCodePoint, suffix), 7626 config: Config{ 7627 MaxVersion: ver.version, 7628 Bugs: ProtocolBugs{ 7629 AlwaysSendClientEncryptedExtensions: true, 7630 }, 7631 ALPSUseNewCodepoint: alpsCodePoint, 7632 }, 7633 shouldFail: true, 7634 expectedError: ":UNEXPECTED_MESSAGE:", 7635 expectedLocalError: "remote error: unexpected message", 7636 }) 7637 7638 // Test that the server rejects an unexpected extension in an 7639 // expected EncryptedExtensions message. 7640 testCases = append(testCases, testCase{ 7641 protocol: protocol, 7642 testType: serverTest, 7643 name: fmt.Sprintf("ExtraClientEncryptedExtension-%s-%s", alpsCodePoint, suffix), 7644 skipQUICALPNConfig: true, 7645 config: Config{ 7646 MaxVersion: ver.version, 7647 NextProtos: []string{"proto"}, 7648 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7649 Bugs: ProtocolBugs{ 7650 SendExtraClientEncryptedExtension: true, 7651 }, 7652 ALPSUseNewCodepoint: alpsCodePoint, 7653 }, 7654 flags: append([]string{ 7655 "-select-alpn", "proto", 7656 "-application-settings", "proto,shim", 7657 }, alpsFlags...), 7658 // The runner is a client, so it only processes the shim's alert 7659 // after checking connection state. 7660 expectations: expectations, 7661 shouldFail: true, 7662 expectedError: ":UNEXPECTED_EXTENSION:", 7663 expectedLocalError: "remote error: unsupported extension", 7664 }) 7665 7666 // Test that ALPS is carried over on 0-RTT. 7667 for _, empty := range []bool{false, true} { 7668 maybeEmpty := "" 7669 runnerSettings := "runner" 7670 shimSettings := "shim" 7671 if empty { 7672 maybeEmpty = "Empty-" 7673 runnerSettings = "" 7674 shimSettings = "" 7675 } 7676 7677 expectations = connectionExpectations{ 7678 peerApplicationSettingsOld: []byte(shimSettings), 7679 } 7680 if alpsCodePoint == ALPSUseCodepointNew { 7681 expectations = connectionExpectations{ 7682 peerApplicationSettings: []byte(shimSettings), 7683 } 7684 } 7685 testCases = append(testCases, testCase{ 7686 protocol: protocol, 7687 testType: clientTest, 7688 name: fmt.Sprintf("ALPS-EarlyData-Client-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7689 skipQUICALPNConfig: true, 7690 config: Config{ 7691 MaxVersion: ver.version, 7692 NextProtos: []string{"proto"}, 7693 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7694 ALPSUseNewCodepoint: alpsCodePoint, 7695 }, 7696 resumeSession: true, 7697 earlyData: true, 7698 flags: append([]string{ 7699 "-advertise-alpn", "\x05proto", 7700 "-expect-alpn", "proto", 7701 "-application-settings", "proto," + shimSettings, 7702 "-expect-peer-application-settings", runnerSettings, 7703 }, alpsFlags...), 7704 expectations: expectations, 7705 }) 7706 testCases = append(testCases, testCase{ 7707 protocol: protocol, 7708 testType: serverTest, 7709 name: fmt.Sprintf("ALPS-EarlyData-Server-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7710 skipQUICALPNConfig: true, 7711 config: Config{ 7712 MaxVersion: ver.version, 7713 NextProtos: []string{"proto"}, 7714 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7715 ALPSUseNewCodepoint: alpsCodePoint, 7716 }, 7717 resumeSession: true, 7718 earlyData: true, 7719 flags: append([]string{ 7720 "-select-alpn", "proto", 7721 "-application-settings", "proto," + shimSettings, 7722 "-expect-peer-application-settings", runnerSettings, 7723 }, alpsFlags...), 7724 expectations: expectations, 7725 }) 7726 7727 // Sending application settings in 0-RTT handshakes is forbidden. 7728 testCases = append(testCases, testCase{ 7729 protocol: protocol, 7730 testType: clientTest, 7731 name: fmt.Sprintf("ALPS-EarlyData-SendApplicationSettingsWithEarlyData-Client-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7732 skipQUICALPNConfig: true, 7733 config: Config{ 7734 MaxVersion: ver.version, 7735 NextProtos: []string{"proto"}, 7736 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7737 Bugs: ProtocolBugs{ 7738 SendApplicationSettingsWithEarlyData: true, 7739 }, 7740 ALPSUseNewCodepoint: alpsCodePoint, 7741 }, 7742 resumeSession: true, 7743 earlyData: true, 7744 flags: append([]string{ 7745 "-advertise-alpn", "\x05proto", 7746 "-expect-alpn", "proto", 7747 "-application-settings", "proto," + shimSettings, 7748 "-expect-peer-application-settings", runnerSettings, 7749 }, alpsFlags...), 7750 expectations: expectations, 7751 shouldFail: true, 7752 expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:", 7753 expectedLocalError: "remote error: illegal parameter", 7754 }) 7755 testCases = append(testCases, testCase{ 7756 protocol: protocol, 7757 testType: serverTest, 7758 name: fmt.Sprintf("ALPS-EarlyData-SendApplicationSettingsWithEarlyData-Server-%s-%s-%s", alpsCodePoint, maybeEmpty, suffix), 7759 skipQUICALPNConfig: true, 7760 config: Config{ 7761 MaxVersion: ver.version, 7762 NextProtos: []string{"proto"}, 7763 ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)}, 7764 Bugs: ProtocolBugs{ 7765 SendApplicationSettingsWithEarlyData: true, 7766 }, 7767 ALPSUseNewCodepoint: alpsCodePoint, 7768 }, 7769 resumeSession: true, 7770 earlyData: true, 7771 flags: append([]string{ 7772 "-select-alpn", "proto", 7773 "-application-settings", "proto," + shimSettings, 7774 "-expect-peer-application-settings", runnerSettings, 7775 }, alpsFlags...), 7776 expectations: expectations, 7777 shouldFail: true, 7778 expectedError: ":UNEXPECTED_MESSAGE:", 7779 expectedLocalError: "remote error: unexpected message", 7780 }) 7781 } 7782 7783 // Test that the client and server each decline early data if local 7784 // ALPS preferences has changed for the current connection. 7785 alpsMismatchTests := []struct { 7786 name string 7787 initialSettings, resumeSettings []byte 7788 }{ 7789 {"DifferentValues", []byte("settings1"), []byte("settings2")}, 7790 {"OnOff", []byte("settings"), nil}, 7791 {"OffOn", nil, []byte("settings")}, 7792 // The empty settings value should not be mistaken for ALPS not 7793 // being negotiated. 7794 {"OnEmpty", []byte("settings"), []byte{}}, 7795 {"EmptyOn", []byte{}, []byte("settings")}, 7796 {"EmptyOff", []byte{}, nil}, 7797 {"OffEmpty", nil, []byte{}}, 7798 } 7799 for _, test := range alpsMismatchTests { 7800 flags := []string{"-on-resume-expect-early-data-reason", "alps_mismatch"} 7801 flags = append(flags, alpsFlags...) 7802 if test.initialSettings != nil { 7803 flags = append(flags, "-on-initial-application-settings", "proto,"+string(test.initialSettings)) 7804 flags = append(flags, "-on-initial-expect-peer-application-settings", "runner") 7805 } 7806 if test.resumeSettings != nil { 7807 flags = append(flags, "-on-resume-application-settings", "proto,"+string(test.resumeSettings)) 7808 flags = append(flags, "-on-resume-expect-peer-application-settings", "runner") 7809 } 7810 7811 expectations = connectionExpectations{ 7812 peerApplicationSettingsOld: test.initialSettings, 7813 } 7814 resumeExpectations = &connectionExpectations{ 7815 peerApplicationSettingsOld: test.resumeSettings, 7816 } 7817 if alpsCodePoint == ALPSUseCodepointNew { 7818 expectations = connectionExpectations{ 7819 peerApplicationSettings: test.initialSettings, 7820 } 7821 resumeExpectations = &connectionExpectations{ 7822 peerApplicationSettings: test.resumeSettings, 7823 } 7824 } 7825 // The client should not offer early data if the session is 7826 // inconsistent with the new configuration. Note that if 7827 // the session did not negotiate ALPS (test.initialSettings 7828 // is nil), the client always offers early data. 7829 if test.initialSettings != nil { 7830 testCases = append(testCases, testCase{ 7831 protocol: protocol, 7832 testType: clientTest, 7833 name: fmt.Sprintf("ALPS-EarlyData-Mismatch-%s-Client-%s-%s", test.name, alpsCodePoint, suffix), 7834 skipQUICALPNConfig: true, 7835 config: Config{ 7836 MaxVersion: ver.version, 7837 MaxEarlyDataSize: 16384, 7838 NextProtos: []string{"proto"}, 7839 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7840 ALPSUseNewCodepoint: alpsCodePoint, 7841 }, 7842 resumeSession: true, 7843 flags: append([]string{ 7844 "-enable-early-data", 7845 "-expect-ticket-supports-early-data", 7846 "-expect-no-offer-early-data", 7847 "-advertise-alpn", "\x05proto", 7848 "-expect-alpn", "proto", 7849 }, flags...), 7850 expectations: expectations, 7851 resumeExpectations: resumeExpectations, 7852 }) 7853 } 7854 7855 // The server should reject early data if the session is 7856 // inconsistent with the new selection. 7857 testCases = append(testCases, testCase{ 7858 protocol: protocol, 7859 testType: serverTest, 7860 name: fmt.Sprintf("ALPS-EarlyData-Mismatch-%s-Server-%s-%s", test.name, alpsCodePoint, suffix), 7861 skipQUICALPNConfig: true, 7862 config: Config{ 7863 MaxVersion: ver.version, 7864 NextProtos: []string{"proto"}, 7865 ApplicationSettings: map[string][]byte{"proto": []byte("runner")}, 7866 ALPSUseNewCodepoint: alpsCodePoint, 7867 }, 7868 resumeSession: true, 7869 earlyData: true, 7870 expectEarlyDataRejected: true, 7871 flags: append([]string{ 7872 "-select-alpn", "proto", 7873 }, flags...), 7874 expectations: expectations, 7875 resumeExpectations: resumeExpectations, 7876 }) 7877 } 7878 7879 // Test that 0-RTT continues working when the shim configures 7880 // ALPS but the peer does not. 7881 testCases = append(testCases, testCase{ 7882 protocol: protocol, 7883 testType: clientTest, 7884 name: fmt.Sprintf("ALPS-EarlyData-Client-ServerDecline-%s-%s", alpsCodePoint, suffix), 7885 skipQUICALPNConfig: true, 7886 config: Config{ 7887 MaxVersion: ver.version, 7888 NextProtos: []string{"proto"}, 7889 ALPSUseNewCodepoint: alpsCodePoint, 7890 }, 7891 resumeSession: true, 7892 earlyData: true, 7893 flags: append([]string{ 7894 "-advertise-alpn", "\x05proto", 7895 "-expect-alpn", "proto", 7896 "-application-settings", "proto,shim", 7897 }, alpsFlags...), 7898 }) 7899 testCases = append(testCases, testCase{ 7900 protocol: protocol, 7901 testType: serverTest, 7902 name: fmt.Sprintf("ALPS-EarlyData-Server-ClientNoOffe-%s-%s", alpsCodePoint, suffix), 7903 skipQUICALPNConfig: true, 7904 config: Config{ 7905 MaxVersion: ver.version, 7906 NextProtos: []string{"proto"}, 7907 ALPSUseNewCodepoint: alpsCodePoint, 7908 }, 7909 resumeSession: true, 7910 earlyData: true, 7911 flags: append([]string{ 7912 "-select-alpn", "proto", 7913 "-application-settings", "proto,shim", 7914 }, alpsFlags...), 7915 }) 7916 } 7917 } else { 7918 // Test the client rejects the ALPS extension if the server 7919 // negotiated TLS 1.2 or below. 7920 for _, alpsCodePoint := range []ALPSUseCodepoint{ALPSUseCodepointNew, ALPSUseCodepointOld} { 7921 flags := []string{ 7922 "-advertise-alpn", "\x03foo", 7923 "-expect-alpn", "foo", 7924 "-application-settings", "foo,shim", 7925 } 7926 bugs := ProtocolBugs{ 7927 AlwaysNegotiateApplicationSettingsOld: true, 7928 } 7929 if alpsCodePoint == ALPSUseCodepointNew { 7930 flags = append(flags, "-alps-use-new-codepoint") 7931 bugs = ProtocolBugs{ 7932 AlwaysNegotiateApplicationSettingsNew: true, 7933 } 7934 } 7935 testCases = append(testCases, testCase{ 7936 protocol: protocol, 7937 testType: clientTest, 7938 name: fmt.Sprintf("ALPS-Reject-Client-%s-%s", alpsCodePoint, suffix), 7939 config: Config{ 7940 MaxVersion: ver.version, 7941 NextProtos: []string{"foo"}, 7942 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 7943 Bugs: bugs, 7944 ALPSUseNewCodepoint: alpsCodePoint, 7945 }, 7946 flags: flags, 7947 shouldFail: true, 7948 expectedError: ":UNEXPECTED_EXTENSION:", 7949 expectedLocalError: "remote error: unsupported extension", 7950 }) 7951 7952 flags = []string{ 7953 "-on-resume-advertise-alpn", "\x03foo", 7954 "-on-resume-expect-alpn", "foo", 7955 "-on-resume-application-settings", "foo,shim", 7956 } 7957 bugs = ProtocolBugs{ 7958 AlwaysNegotiateApplicationSettingsOld: true, 7959 } 7960 if alpsCodePoint == ALPSUseCodepointNew { 7961 flags = append(flags, "-alps-use-new-codepoint") 7962 bugs = ProtocolBugs{ 7963 AlwaysNegotiateApplicationSettingsNew: true, 7964 } 7965 } 7966 testCases = append(testCases, testCase{ 7967 protocol: protocol, 7968 testType: clientTest, 7969 name: fmt.Sprintf("ALPS-Reject-Client-Resume-%s-%s", alpsCodePoint, suffix), 7970 config: Config{ 7971 MaxVersion: ver.version, 7972 }, 7973 resumeConfig: &Config{ 7974 MaxVersion: ver.version, 7975 NextProtos: []string{"foo"}, 7976 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 7977 Bugs: bugs, 7978 ALPSUseNewCodepoint: alpsCodePoint, 7979 }, 7980 resumeSession: true, 7981 flags: flags, 7982 shouldFail: true, 7983 expectedError: ":UNEXPECTED_EXTENSION:", 7984 expectedLocalError: "remote error: unsupported extension", 7985 }) 7986 7987 // Test the server declines ALPS if it negotiates TLS 1.2 or below. 7988 flags = []string{ 7989 "-select-alpn", "foo", 7990 "-application-settings", "foo,shim", 7991 } 7992 if alpsCodePoint == ALPSUseCodepointNew { 7993 flags = append(flags, "-alps-use-new-codepoint") 7994 } 7995 testCases = append(testCases, testCase{ 7996 protocol: protocol, 7997 testType: serverTest, 7998 name: fmt.Sprintf("ALPS-Decline-Server-%s-%s", alpsCodePoint, suffix), 7999 config: Config{ 8000 MaxVersion: ver.version, 8001 NextProtos: []string{"foo"}, 8002 ApplicationSettings: map[string][]byte{"foo": []byte("runner")}, 8003 ALPSUseNewCodepoint: alpsCodePoint, 8004 }, 8005 // Test both TLS 1.2 full and resumption handshakes. 8006 resumeSession: true, 8007 flags: flags, 8008 // If not specified, runner and shim both implicitly expect ALPS 8009 // is not negotiated. 8010 }) 8011 } 8012 } 8013 8014 // Test QUIC transport params 8015 if protocol == quic { 8016 // Client sends params 8017 for _, clientConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8018 for _, serverSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 8019 useCodepointFlag := "0" 8020 if clientConfig == QUICUseCodepointLegacy { 8021 useCodepointFlag = "1" 8022 } 8023 flags := []string{ 8024 "-quic-transport-params", 8025 base64FlagValue([]byte{1, 2}), 8026 "-quic-use-legacy-codepoint", useCodepointFlag, 8027 } 8028 expectations := connectionExpectations{ 8029 quicTransportParams: []byte{1, 2}, 8030 } 8031 shouldFail := false 8032 expectedError := "" 8033 expectedLocalError := "" 8034 if clientConfig == QUICUseCodepointLegacy { 8035 expectations = connectionExpectations{ 8036 quicTransportParamsLegacy: []byte{1, 2}, 8037 } 8038 } 8039 if serverSends != clientConfig { 8040 expectations = connectionExpectations{} 8041 shouldFail = true 8042 if serverSends == QUICUseCodepointNeither { 8043 expectedError = ":MISSING_EXTENSION:" 8044 } else { 8045 expectedLocalError = "remote error: unsupported extension" 8046 } 8047 } else { 8048 flags = append(flags, 8049 "-expect-quic-transport-params", 8050 base64FlagValue([]byte{3, 4})) 8051 } 8052 testCases = append(testCases, testCase{ 8053 testType: clientTest, 8054 protocol: protocol, 8055 name: fmt.Sprintf("QUICTransportParams-Client-Client%s-Server%s-%s", clientConfig, serverSends, suffix), 8056 config: Config{ 8057 MinVersion: ver.version, 8058 MaxVersion: ver.version, 8059 QUICTransportParams: []byte{3, 4}, 8060 QUICTransportParamsUseLegacyCodepoint: serverSends, 8061 }, 8062 flags: flags, 8063 expectations: expectations, 8064 shouldFail: shouldFail, 8065 expectedError: expectedError, 8066 expectedLocalError: expectedLocalError, 8067 skipTransportParamsConfig: true, 8068 }) 8069 } 8070 } 8071 // Server sends params 8072 for _, clientSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 8073 for _, serverConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8074 expectations := connectionExpectations{ 8075 quicTransportParams: []byte{3, 4}, 8076 } 8077 shouldFail := false 8078 expectedError := "" 8079 useCodepointFlag := "0" 8080 if serverConfig == QUICUseCodepointLegacy { 8081 useCodepointFlag = "1" 8082 expectations = connectionExpectations{ 8083 quicTransportParamsLegacy: []byte{3, 4}, 8084 } 8085 } 8086 flags := []string{ 8087 "-quic-transport-params", 8088 base64FlagValue([]byte{3, 4}), 8089 "-quic-use-legacy-codepoint", useCodepointFlag, 8090 } 8091 if clientSends != QUICUseCodepointBoth && clientSends != serverConfig { 8092 expectations = connectionExpectations{} 8093 shouldFail = true 8094 expectedError = ":MISSING_EXTENSION:" 8095 } else { 8096 flags = append(flags, 8097 "-expect-quic-transport-params", 8098 base64FlagValue([]byte{1, 2}), 8099 ) 8100 } 8101 testCases = append(testCases, testCase{ 8102 testType: serverTest, 8103 protocol: protocol, 8104 name: fmt.Sprintf("QUICTransportParams-Server-Client%s-Server%s-%s", clientSends, serverConfig, suffix), 8105 config: Config{ 8106 MinVersion: ver.version, 8107 MaxVersion: ver.version, 8108 QUICTransportParams: []byte{1, 2}, 8109 QUICTransportParamsUseLegacyCodepoint: clientSends, 8110 }, 8111 flags: flags, 8112 expectations: expectations, 8113 shouldFail: shouldFail, 8114 expectedError: expectedError, 8115 skipTransportParamsConfig: true, 8116 }) 8117 } 8118 } 8119 } else { 8120 // Ensure non-QUIC client doesn't send QUIC transport parameters. 8121 for _, clientConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8122 useCodepointFlag := "0" 8123 if clientConfig == QUICUseCodepointLegacy { 8124 useCodepointFlag = "1" 8125 } 8126 testCases = append(testCases, testCase{ 8127 protocol: protocol, 8128 testType: clientTest, 8129 name: fmt.Sprintf("QUICTransportParams-Client-NotSentInNonQUIC-%s-%s", clientConfig, suffix), 8130 config: Config{ 8131 MinVersion: ver.version, 8132 MaxVersion: ver.version, 8133 QUICTransportParamsUseLegacyCodepoint: clientConfig, 8134 }, 8135 flags: []string{ 8136 "-max-version", 8137 strconv.Itoa(int(ver.versionWire)), 8138 "-quic-transport-params", 8139 base64FlagValue([]byte{3, 4}), 8140 "-quic-use-legacy-codepoint", useCodepointFlag, 8141 }, 8142 shouldFail: true, 8143 expectedError: ":QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED:", 8144 skipTransportParamsConfig: true, 8145 }) 8146 } 8147 // Ensure non-QUIC server rejects codepoint 57 but ignores legacy 0xffa5. 8148 for _, clientSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} { 8149 for _, serverConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} { 8150 shouldFail := false 8151 expectedLocalError := "" 8152 useCodepointFlag := "0" 8153 if serverConfig == QUICUseCodepointLegacy { 8154 useCodepointFlag = "1" 8155 } 8156 if clientSends == QUICUseCodepointStandard || clientSends == QUICUseCodepointBoth { 8157 shouldFail = true 8158 expectedLocalError = "remote error: unsupported extension" 8159 } 8160 testCases = append(testCases, testCase{ 8161 protocol: protocol, 8162 testType: serverTest, 8163 name: fmt.Sprintf("QUICTransportParams-NonQUICServer-Client%s-Server%s-%s", clientSends, serverConfig, suffix), 8164 config: Config{ 8165 MinVersion: ver.version, 8166 MaxVersion: ver.version, 8167 QUICTransportParams: []byte{1, 2}, 8168 QUICTransportParamsUseLegacyCodepoint: clientSends, 8169 }, 8170 flags: []string{ 8171 "-quic-use-legacy-codepoint", useCodepointFlag, 8172 }, 8173 shouldFail: shouldFail, 8174 expectedLocalError: expectedLocalError, 8175 skipTransportParamsConfig: true, 8176 }) 8177 } 8178 } 8179 8180 } 8181 8182 // Test ticket behavior. 8183 8184 // Resume with a corrupt ticket. 8185 testCases = append(testCases, testCase{ 8186 protocol: protocol, 8187 testType: serverTest, 8188 name: "CorruptTicket-" + suffix, 8189 config: Config{ 8190 MaxVersion: ver.version, 8191 Bugs: ProtocolBugs{ 8192 FilterTicket: func(in []byte) ([]byte, error) { 8193 in[len(in)-1] ^= 1 8194 return in, nil 8195 }, 8196 }, 8197 }, 8198 resumeSession: true, 8199 expectResumeRejected: true, 8200 }) 8201 // Test the ticket callback, with and without renewal. 8202 testCases = append(testCases, testCase{ 8203 protocol: protocol, 8204 testType: serverTest, 8205 name: "TicketCallback-" + suffix, 8206 config: Config{ 8207 MaxVersion: ver.version, 8208 }, 8209 resumeSession: true, 8210 flags: []string{"-use-ticket-callback"}, 8211 }) 8212 testCases = append(testCases, testCase{ 8213 protocol: protocol, 8214 testType: serverTest, 8215 name: "TicketCallback-Renew-" + suffix, 8216 config: Config{ 8217 MaxVersion: ver.version, 8218 Bugs: ProtocolBugs{ 8219 ExpectNewTicket: true, 8220 }, 8221 }, 8222 flags: []string{"-use-ticket-callback", "-renew-ticket"}, 8223 resumeSession: true, 8224 }) 8225 8226 // Test that the ticket callback is only called once when everything before 8227 // it in the ClientHello is asynchronous. This corrupts the ticket so 8228 // certificate selection callbacks run. 8229 testCases = append(testCases, testCase{ 8230 protocol: protocol, 8231 testType: serverTest, 8232 name: "TicketCallback-SingleCall-" + suffix, 8233 config: Config{ 8234 MaxVersion: ver.version, 8235 Bugs: ProtocolBugs{ 8236 FilterTicket: func(in []byte) ([]byte, error) { 8237 in[len(in)-1] ^= 1 8238 return in, nil 8239 }, 8240 }, 8241 }, 8242 resumeSession: true, 8243 expectResumeRejected: true, 8244 flags: []string{ 8245 "-use-ticket-callback", 8246 "-async", 8247 }, 8248 }) 8249 8250 // Resume with various lengths of ticket session id. 8251 if ver.version < VersionTLS13 { 8252 testCases = append(testCases, testCase{ 8253 protocol: protocol, 8254 testType: serverTest, 8255 name: "TicketSessionIDLength-0-" + suffix, 8256 config: Config{ 8257 MaxVersion: ver.version, 8258 Bugs: ProtocolBugs{ 8259 EmptyTicketSessionID: true, 8260 }, 8261 }, 8262 resumeSession: true, 8263 }) 8264 testCases = append(testCases, testCase{ 8265 protocol: protocol, 8266 testType: serverTest, 8267 name: "TicketSessionIDLength-16-" + suffix, 8268 config: Config{ 8269 MaxVersion: ver.version, 8270 Bugs: ProtocolBugs{ 8271 TicketSessionIDLength: 16, 8272 }, 8273 }, 8274 resumeSession: true, 8275 }) 8276 testCases = append(testCases, testCase{ 8277 protocol: protocol, 8278 testType: serverTest, 8279 name: "TicketSessionIDLength-32-" + suffix, 8280 config: Config{ 8281 MaxVersion: ver.version, 8282 Bugs: ProtocolBugs{ 8283 TicketSessionIDLength: 32, 8284 }, 8285 }, 8286 resumeSession: true, 8287 }) 8288 testCases = append(testCases, testCase{ 8289 protocol: protocol, 8290 testType: serverTest, 8291 name: "TicketSessionIDLength-33-" + suffix, 8292 config: Config{ 8293 MaxVersion: ver.version, 8294 Bugs: ProtocolBugs{ 8295 TicketSessionIDLength: 33, 8296 }, 8297 }, 8298 resumeSession: true, 8299 shouldFail: true, 8300 // The maximum session ID length is 32. 8301 expectedError: ":DECODE_ERROR:", 8302 }) 8303 } 8304 8305 // Basic DTLS-SRTP tests. Include fake profiles to ensure they 8306 // are ignored. 8307 if protocol == dtls { 8308 testCases = append(testCases, testCase{ 8309 protocol: protocol, 8310 name: "SRTP-Client-" + suffix, 8311 config: Config{ 8312 MaxVersion: ver.version, 8313 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8314 }, 8315 flags: []string{ 8316 "-srtp-profiles", 8317 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8318 }, 8319 expectations: connectionExpectations{ 8320 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8321 }, 8322 }) 8323 testCases = append(testCases, testCase{ 8324 protocol: protocol, 8325 testType: serverTest, 8326 name: "SRTP-Server-" + suffix, 8327 config: Config{ 8328 MaxVersion: ver.version, 8329 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8330 }, 8331 flags: []string{ 8332 "-srtp-profiles", 8333 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8334 }, 8335 expectations: connectionExpectations{ 8336 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8337 }, 8338 }) 8339 // Test that the MKI is ignored. 8340 testCases = append(testCases, testCase{ 8341 protocol: protocol, 8342 testType: serverTest, 8343 name: "SRTP-Server-IgnoreMKI-" + suffix, 8344 config: Config{ 8345 MaxVersion: ver.version, 8346 SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80}, 8347 Bugs: ProtocolBugs{ 8348 SRTPMasterKeyIdentifier: "bogus", 8349 }, 8350 }, 8351 flags: []string{ 8352 "-srtp-profiles", 8353 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8354 }, 8355 expectations: connectionExpectations{ 8356 srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80, 8357 }, 8358 }) 8359 // Test that SRTP isn't negotiated on the server if there were 8360 // no matching profiles. 8361 testCases = append(testCases, testCase{ 8362 protocol: protocol, 8363 testType: serverTest, 8364 name: "SRTP-Server-NoMatch-" + suffix, 8365 config: Config{ 8366 MaxVersion: ver.version, 8367 SRTPProtectionProfiles: []uint16{100, 101, 102}, 8368 }, 8369 flags: []string{ 8370 "-srtp-profiles", 8371 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8372 }, 8373 expectations: connectionExpectations{ 8374 srtpProtectionProfile: 0, 8375 }, 8376 }) 8377 // Test that the server returning an invalid SRTP profile is 8378 // flagged as an error by the client. 8379 testCases = append(testCases, testCase{ 8380 protocol: protocol, 8381 name: "SRTP-Client-NoMatch-" + suffix, 8382 config: Config{ 8383 MaxVersion: ver.version, 8384 Bugs: ProtocolBugs{ 8385 SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32, 8386 }, 8387 }, 8388 flags: []string{ 8389 "-srtp-profiles", 8390 "SRTP_AES128_CM_SHA1_80", 8391 }, 8392 shouldFail: true, 8393 expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:", 8394 }) 8395 } else { 8396 // DTLS-SRTP is not defined for other protocols. Configuring it 8397 // on the client and server should ignore the extension. 8398 testCases = append(testCases, testCase{ 8399 protocol: protocol, 8400 name: "SRTP-Client-Ignore-" + suffix, 8401 config: Config{ 8402 MaxVersion: ver.version, 8403 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8404 }, 8405 flags: []string{ 8406 "-srtp-profiles", 8407 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8408 }, 8409 expectations: connectionExpectations{ 8410 srtpProtectionProfile: 0, 8411 }, 8412 }) 8413 testCases = append(testCases, testCase{ 8414 protocol: protocol, 8415 testType: serverTest, 8416 name: "SRTP-Server-Ignore-" + suffix, 8417 config: Config{ 8418 MaxVersion: ver.version, 8419 SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42}, 8420 }, 8421 flags: []string{ 8422 "-srtp-profiles", 8423 "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32", 8424 }, 8425 expectations: connectionExpectations{ 8426 srtpProtectionProfile: 0, 8427 }, 8428 }) 8429 } 8430 8431 // Test SCT list. 8432 testCases = append(testCases, testCase{ 8433 protocol: protocol, 8434 name: "SignedCertificateTimestampList-Client-" + suffix, 8435 testType: clientTest, 8436 config: Config{ 8437 MaxVersion: ver.version, 8438 Credential: rsaCertificate.WithSCTList(testSCTList), 8439 }, 8440 flags: []string{ 8441 "-enable-signed-cert-timestamps", 8442 "-expect-signed-cert-timestamps", 8443 base64FlagValue(testSCTList), 8444 }, 8445 resumeSession: true, 8446 }) 8447 8448 var differentSCTList []byte 8449 differentSCTList = append(differentSCTList, testSCTList...) 8450 differentSCTList[len(differentSCTList)-1] ^= 1 8451 8452 // The SCT extension did not specify that it must only be sent on resumption as it 8453 // should have, so test that we tolerate but ignore it. 8454 testCases = append(testCases, testCase{ 8455 protocol: protocol, 8456 name: "SendSCTListOnResume-" + suffix, 8457 config: Config{ 8458 MaxVersion: ver.version, 8459 Credential: rsaCertificate.WithSCTList(testSCTList), 8460 Bugs: ProtocolBugs{ 8461 SendSCTListOnResume: differentSCTList, 8462 }, 8463 }, 8464 flags: []string{ 8465 "-enable-signed-cert-timestamps", 8466 "-expect-signed-cert-timestamps", 8467 base64FlagValue(testSCTList), 8468 }, 8469 resumeSession: true, 8470 }) 8471 8472 testCases = append(testCases, testCase{ 8473 protocol: protocol, 8474 name: "SignedCertificateTimestampList-Server-" + suffix, 8475 testType: serverTest, 8476 config: Config{ 8477 MaxVersion: ver.version, 8478 }, 8479 shimCertificate: rsaCertificate.WithSCTList(testSCTList), 8480 expectations: connectionExpectations{ 8481 peerCertificate: rsaCertificate.WithSCTList(testSCTList), 8482 }, 8483 resumeSession: true, 8484 }) 8485 8486 // Test empty SCT list. 8487 testCases = append(testCases, testCase{ 8488 protocol: protocol, 8489 name: "SignedCertificateTimestampListEmpty-Client-" + suffix, 8490 testType: clientTest, 8491 config: Config{ 8492 MaxVersion: ver.version, 8493 Credential: rsaCertificate.WithSCTList([]byte{0, 0}), 8494 }, 8495 flags: []string{ 8496 "-enable-signed-cert-timestamps", 8497 }, 8498 shouldFail: true, 8499 expectedError: ":ERROR_PARSING_EXTENSION:", 8500 }) 8501 8502 // Test empty SCT in non-empty list. 8503 testCases = append(testCases, testCase{ 8504 protocol: protocol, 8505 name: "SignedCertificateTimestampListEmptySCT-Client-" + suffix, 8506 testType: clientTest, 8507 config: Config{ 8508 MaxVersion: ver.version, 8509 Credential: rsaCertificate.WithSCTList([]byte{0, 6, 0, 2, 1, 2, 0, 0}), 8510 }, 8511 flags: []string{ 8512 "-enable-signed-cert-timestamps", 8513 }, 8514 shouldFail: true, 8515 expectedError: ":ERROR_PARSING_EXTENSION:", 8516 }) 8517 8518 // Test that certificate-related extensions are not sent unsolicited. 8519 testCases = append(testCases, testCase{ 8520 protocol: protocol, 8521 testType: serverTest, 8522 name: "UnsolicitedCertificateExtensions-" + suffix, 8523 config: Config{ 8524 MaxVersion: ver.version, 8525 Bugs: ProtocolBugs{ 8526 NoOCSPStapling: true, 8527 NoSignedCertificateTimestamps: true, 8528 }, 8529 }, 8530 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8531 }) 8532 8533 // Extension permutation should interact correctly with other extensions, 8534 // HelloVerifyRequest, HelloRetryRequest, and ECH. SSLTest.PermuteExtensions 8535 // in ssl_test.cc tests that the extensions are actually permuted. This 8536 // tests the handshake still works. 8537 // 8538 // This test also tests that all our extensions interact with each other. 8539 for _, ech := range []bool{false, true} { 8540 if ech && ver.version < VersionTLS13 { 8541 continue 8542 } 8543 8544 test := testCase{ 8545 protocol: protocol, 8546 name: "AllExtensions-Client-Permute", 8547 skipQUICALPNConfig: true, 8548 config: Config{ 8549 MinVersion: ver.version, 8550 MaxVersion: ver.version, 8551 Credential: rsaCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8552 NextProtos: []string{"proto"}, 8553 ApplicationSettings: map[string][]byte{"proto": []byte("runner1")}, 8554 Bugs: ProtocolBugs{ 8555 SendServerNameAck: true, 8556 ExpectServerName: "example.com", 8557 ExpectGREASE: true, 8558 }, 8559 }, 8560 resumeSession: true, 8561 flags: []string{ 8562 "-permute-extensions", 8563 "-enable-grease", 8564 "-enable-ocsp-stapling", 8565 "-enable-signed-cert-timestamps", 8566 "-advertise-alpn", "\x05proto", 8567 "-expect-alpn", "proto", 8568 "-host-name", "example.com", 8569 }, 8570 } 8571 8572 if ech { 8573 test.name += "-ECH" 8574 echConfig := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 8575 test.config.ServerECHConfigs = []ServerECHConfig{echConfig} 8576 test.flags = append(test.flags, 8577 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 8578 "-expect-ech-accept", 8579 ) 8580 test.expectations.echAccepted = true 8581 } 8582 8583 if ver.version >= VersionTLS13 { 8584 // Trigger a HelloRetryRequest to test both ClientHellos. Note 8585 // our DTLS tests always enable HelloVerifyRequest. 8586 test.name += "-HelloRetryRequest" 8587 8588 // ALPS is only available on TLS 1.3. 8589 test.config.ApplicationSettings = map[string][]byte{"proto": []byte("runner")} 8590 test.flags = append(test.flags, 8591 "-application-settings", "proto,shim", 8592 "-alps-use-new-codepoint", 8593 "-expect-peer-application-settings", "runner") 8594 test.expectations.peerApplicationSettings = []byte("shim") 8595 } 8596 8597 if protocol == dtls { 8598 test.config.SRTPProtectionProfiles = []uint16{SRTP_AES128_CM_HMAC_SHA1_80} 8599 test.flags = append(test.flags, "-srtp-profiles", "SRTP_AES128_CM_SHA1_80") 8600 test.expectations.srtpProtectionProfile = SRTP_AES128_CM_HMAC_SHA1_80 8601 } 8602 8603 test.name += "-" + suffix 8604 testCases = append(testCases, test) 8605 } 8606 } 8607 } 8608 8609 testCases = append(testCases, testCase{ 8610 testType: clientTest, 8611 name: "ClientHelloPadding", 8612 config: Config{ 8613 Bugs: ProtocolBugs{ 8614 RequireClientHelloSize: 512, 8615 }, 8616 }, 8617 // This hostname just needs to be long enough to push the 8618 // ClientHello into F5's danger zone between 256 and 511 bytes 8619 // long. 8620 flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"}, 8621 }) 8622 8623 // Test that illegal extensions in TLS 1.3 are rejected by the client if 8624 // in ServerHello. 8625 testCases = append(testCases, testCase{ 8626 name: "NPN-Forbidden-TLS13", 8627 config: Config{ 8628 MaxVersion: VersionTLS13, 8629 NextProtos: []string{"foo"}, 8630 Bugs: ProtocolBugs{ 8631 NegotiateNPNAtAllVersions: true, 8632 }, 8633 }, 8634 flags: []string{"-select-next-proto", "foo"}, 8635 shouldFail: true, 8636 expectedError: ":ERROR_PARSING_EXTENSION:", 8637 }) 8638 testCases = append(testCases, testCase{ 8639 name: "EMS-Forbidden-TLS13", 8640 config: Config{ 8641 MaxVersion: VersionTLS13, 8642 Bugs: ProtocolBugs{ 8643 NegotiateEMSAtAllVersions: true, 8644 }, 8645 }, 8646 shouldFail: true, 8647 expectedError: ":ERROR_PARSING_EXTENSION:", 8648 }) 8649 testCases = append(testCases, testCase{ 8650 name: "RenegotiationInfo-Forbidden-TLS13", 8651 config: Config{ 8652 MaxVersion: VersionTLS13, 8653 Bugs: ProtocolBugs{ 8654 NegotiateRenegotiationInfoAtAllVersions: true, 8655 }, 8656 }, 8657 shouldFail: true, 8658 expectedError: ":ERROR_PARSING_EXTENSION:", 8659 }) 8660 testCases = append(testCases, testCase{ 8661 name: "Ticket-Forbidden-TLS13", 8662 config: Config{ 8663 MaxVersion: VersionTLS12, 8664 }, 8665 resumeConfig: &Config{ 8666 MaxVersion: VersionTLS13, 8667 Bugs: ProtocolBugs{ 8668 AdvertiseTicketExtension: true, 8669 }, 8670 }, 8671 resumeSession: true, 8672 shouldFail: true, 8673 expectedError: ":ERROR_PARSING_EXTENSION:", 8674 }) 8675 8676 // Test that illegal extensions in TLS 1.3 are declined by the server if 8677 // offered in ClientHello. The runner's server will fail if this occurs, 8678 // so we exercise the offering path. (EMS and Renegotiation Info are 8679 // implicit in every test.) 8680 testCases = append(testCases, testCase{ 8681 testType: serverTest, 8682 name: "NPN-Declined-TLS13", 8683 config: Config{ 8684 MaxVersion: VersionTLS13, 8685 NextProtos: []string{"bar"}, 8686 }, 8687 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"}, 8688 }) 8689 8690 // OpenSSL sends the status_request extension on resumption in TLS 1.2. Test that this is 8691 // tolerated. 8692 testCases = append(testCases, testCase{ 8693 name: "SendOCSPResponseOnResume-TLS12", 8694 config: Config{ 8695 MaxVersion: VersionTLS12, 8696 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 8697 Bugs: ProtocolBugs{ 8698 SendOCSPResponseOnResume: []byte("bogus"), 8699 }, 8700 }, 8701 flags: []string{ 8702 "-enable-ocsp-stapling", 8703 "-expect-ocsp-response", 8704 base64FlagValue(testOCSPResponse), 8705 }, 8706 resumeSession: true, 8707 }) 8708 8709 testCases = append(testCases, testCase{ 8710 name: "SendUnsolicitedOCSPOnCertificate-TLS13", 8711 config: Config{ 8712 MaxVersion: VersionTLS13, 8713 Bugs: ProtocolBugs{ 8714 SendExtensionOnCertificate: testOCSPExtension, 8715 }, 8716 }, 8717 shouldFail: true, 8718 expectedError: ":UNEXPECTED_EXTENSION:", 8719 }) 8720 8721 testCases = append(testCases, testCase{ 8722 name: "SendUnsolicitedSCTOnCertificate-TLS13", 8723 config: Config{ 8724 MaxVersion: VersionTLS13, 8725 Bugs: ProtocolBugs{ 8726 SendExtensionOnCertificate: testSCTExtension, 8727 }, 8728 }, 8729 shouldFail: true, 8730 expectedError: ":UNEXPECTED_EXTENSION:", 8731 }) 8732 8733 // Test that extensions on client certificates are never accepted. 8734 testCases = append(testCases, testCase{ 8735 name: "SendExtensionOnClientCertificate-TLS13", 8736 testType: serverTest, 8737 config: Config{ 8738 MaxVersion: VersionTLS13, 8739 Credential: &rsaCertificate, 8740 Bugs: ProtocolBugs{ 8741 SendExtensionOnCertificate: testOCSPExtension, 8742 }, 8743 }, 8744 flags: []string{ 8745 "-enable-ocsp-stapling", 8746 "-require-any-client-certificate", 8747 }, 8748 shouldFail: true, 8749 expectedError: ":UNEXPECTED_EXTENSION:", 8750 }) 8751 8752 testCases = append(testCases, testCase{ 8753 name: "SendUnknownExtensionOnCertificate-TLS13", 8754 config: Config{ 8755 MaxVersion: VersionTLS13, 8756 Bugs: ProtocolBugs{ 8757 SendExtensionOnCertificate: []byte{0x00, 0x7f, 0, 0}, 8758 }, 8759 }, 8760 shouldFail: true, 8761 expectedError: ":UNEXPECTED_EXTENSION:", 8762 }) 8763 8764 // Test that extensions on intermediates are allowed but ignored. 8765 testCases = append(testCases, testCase{ 8766 name: "IgnoreExtensionsOnIntermediates-TLS13", 8767 config: Config{ 8768 MaxVersion: VersionTLS13, 8769 Credential: rsaChainCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8770 Bugs: ProtocolBugs{ 8771 // Send different values on the intermediate. This tests 8772 // the intermediate's extensions do not override the 8773 // leaf's. 8774 SendOCSPOnIntermediates: testOCSPResponse2, 8775 SendSCTOnIntermediates: testSCTList2, 8776 }, 8777 }, 8778 flags: []string{ 8779 "-enable-ocsp-stapling", 8780 "-expect-ocsp-response", 8781 base64FlagValue(testOCSPResponse), 8782 "-enable-signed-cert-timestamps", 8783 "-expect-signed-cert-timestamps", 8784 base64FlagValue(testSCTList), 8785 }, 8786 resumeSession: true, 8787 }) 8788 8789 // Test that extensions are not sent on intermediates when configured 8790 // only for a leaf. 8791 testCases = append(testCases, testCase{ 8792 testType: serverTest, 8793 name: "SendNoExtensionsOnIntermediate-TLS13", 8794 config: Config{ 8795 MaxVersion: VersionTLS13, 8796 Bugs: ProtocolBugs{ 8797 ExpectNoExtensionsOnIntermediate: true, 8798 }, 8799 }, 8800 shimCertificate: rsaChainCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8801 }) 8802 8803 // Test that extensions are not sent on client certificates. 8804 testCases = append(testCases, testCase{ 8805 name: "SendNoClientCertificateExtensions-TLS13", 8806 config: Config{ 8807 MaxVersion: VersionTLS13, 8808 ClientAuth: RequireAnyClientCert, 8809 }, 8810 shimCertificate: rsaChainCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8811 }) 8812 8813 testCases = append(testCases, testCase{ 8814 name: "SendDuplicateExtensionsOnCerts-TLS13", 8815 config: Config{ 8816 MaxVersion: VersionTLS13, 8817 Credential: rsaCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 8818 Bugs: ProtocolBugs{ 8819 SendDuplicateCertExtensions: true, 8820 }, 8821 }, 8822 flags: []string{ 8823 "-enable-ocsp-stapling", 8824 "-enable-signed-cert-timestamps", 8825 }, 8826 resumeSession: true, 8827 shouldFail: true, 8828 expectedError: ":DUPLICATE_EXTENSION:", 8829 }) 8830 8831 testCases = append(testCases, testCase{ 8832 name: "SignedCertificateTimestampListInvalid-Server", 8833 testType: serverTest, 8834 shimCertificate: rsaCertificate.WithSCTList([]byte{0, 0}), 8835 shouldFail: true, 8836 expectedError: ":INVALID_SCT_LIST:", 8837 }) 8838} 8839 8840func addResumptionVersionTests() { 8841 for _, sessionVers := range tlsVersions { 8842 for _, resumeVers := range tlsVersions { 8843 protocols := []protocol{tls} 8844 if sessionVers.hasDTLS && resumeVers.hasDTLS { 8845 protocols = append(protocols, dtls) 8846 } 8847 if sessionVers.hasQUIC && resumeVers.hasQUIC { 8848 protocols = append(protocols, quic) 8849 } 8850 for _, protocol := range protocols { 8851 suffix := "-" + sessionVers.name + "-" + resumeVers.name 8852 suffix += "-" + protocol.String() 8853 8854 if sessionVers.version == resumeVers.version { 8855 testCases = append(testCases, testCase{ 8856 protocol: protocol, 8857 name: "Resume-Client" + suffix, 8858 resumeSession: true, 8859 config: Config{ 8860 MaxVersion: sessionVers.version, 8861 Bugs: ProtocolBugs{ 8862 ExpectNoTLS13PSK: sessionVers.version < VersionTLS13, 8863 }, 8864 }, 8865 expectations: connectionExpectations{ 8866 version: sessionVers.version, 8867 }, 8868 resumeExpectations: &connectionExpectations{ 8869 version: resumeVers.version, 8870 }, 8871 }) 8872 } else { 8873 testCases = append(testCases, testCase{ 8874 protocol: protocol, 8875 name: "Resume-Client-Mismatch" + suffix, 8876 resumeSession: true, 8877 config: Config{ 8878 MaxVersion: sessionVers.version, 8879 }, 8880 expectations: connectionExpectations{ 8881 version: sessionVers.version, 8882 }, 8883 resumeConfig: &Config{ 8884 MaxVersion: resumeVers.version, 8885 Bugs: ProtocolBugs{ 8886 AcceptAnySession: true, 8887 }, 8888 }, 8889 resumeExpectations: &connectionExpectations{ 8890 version: resumeVers.version, 8891 }, 8892 shouldFail: true, 8893 expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:", 8894 }) 8895 } 8896 8897 testCases = append(testCases, testCase{ 8898 protocol: protocol, 8899 name: "Resume-Client-NoResume" + suffix, 8900 resumeSession: true, 8901 config: Config{ 8902 MaxVersion: sessionVers.version, 8903 }, 8904 expectations: connectionExpectations{ 8905 version: sessionVers.version, 8906 }, 8907 resumeConfig: &Config{ 8908 MaxVersion: resumeVers.version, 8909 }, 8910 newSessionsOnResume: true, 8911 expectResumeRejected: true, 8912 resumeExpectations: &connectionExpectations{ 8913 version: resumeVers.version, 8914 }, 8915 }) 8916 8917 testCases = append(testCases, testCase{ 8918 protocol: protocol, 8919 testType: serverTest, 8920 name: "Resume-Server" + suffix, 8921 resumeSession: true, 8922 config: Config{ 8923 MaxVersion: sessionVers.version, 8924 }, 8925 expectations: connectionExpectations{ 8926 version: sessionVers.version, 8927 }, 8928 expectResumeRejected: sessionVers != resumeVers, 8929 resumeConfig: &Config{ 8930 MaxVersion: resumeVers.version, 8931 Bugs: ProtocolBugs{ 8932 SendBothTickets: true, 8933 }, 8934 }, 8935 resumeExpectations: &connectionExpectations{ 8936 version: resumeVers.version, 8937 }, 8938 }) 8939 8940 // Repeat the test using session IDs, rather than tickets. 8941 if sessionVers.version < VersionTLS13 && resumeVers.version < VersionTLS13 { 8942 testCases = append(testCases, testCase{ 8943 protocol: protocol, 8944 testType: serverTest, 8945 name: "Resume-Server-NoTickets" + suffix, 8946 resumeSession: true, 8947 config: Config{ 8948 MaxVersion: sessionVers.version, 8949 SessionTicketsDisabled: true, 8950 }, 8951 expectations: connectionExpectations{ 8952 version: sessionVers.version, 8953 }, 8954 expectResumeRejected: sessionVers != resumeVers, 8955 resumeConfig: &Config{ 8956 MaxVersion: resumeVers.version, 8957 SessionTicketsDisabled: true, 8958 }, 8959 resumeExpectations: &connectionExpectations{ 8960 version: resumeVers.version, 8961 }, 8962 }) 8963 } 8964 } 8965 } 8966 } 8967 8968 // Make sure shim ticket mutations are functional. 8969 testCases = append(testCases, testCase{ 8970 testType: serverTest, 8971 name: "ShimTicketRewritable", 8972 resumeSession: true, 8973 config: Config{ 8974 MaxVersion: VersionTLS12, 8975 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 8976 Bugs: ProtocolBugs{ 8977 FilterTicket: func(in []byte) ([]byte, error) { 8978 in, err := SetShimTicketVersion(in, VersionTLS12) 8979 if err != nil { 8980 return nil, err 8981 } 8982 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) 8983 }, 8984 }, 8985 }, 8986 flags: []string{ 8987 "-ticket-key", 8988 base64FlagValue(TestShimTicketKey), 8989 }, 8990 }) 8991 8992 // Resumptions are declined if the version does not match. 8993 testCases = append(testCases, testCase{ 8994 testType: serverTest, 8995 name: "Resume-Server-DeclineCrossVersion", 8996 resumeSession: true, 8997 config: Config{ 8998 MaxVersion: VersionTLS12, 8999 Bugs: ProtocolBugs{ 9000 ExpectNewTicket: true, 9001 FilterTicket: func(in []byte) ([]byte, error) { 9002 return SetShimTicketVersion(in, VersionTLS13) 9003 }, 9004 }, 9005 }, 9006 flags: []string{ 9007 "-ticket-key", 9008 base64FlagValue(TestShimTicketKey), 9009 }, 9010 expectResumeRejected: true, 9011 }) 9012 9013 testCases = append(testCases, testCase{ 9014 testType: serverTest, 9015 name: "Resume-Server-DeclineCrossVersion-TLS13", 9016 resumeSession: true, 9017 config: Config{ 9018 MaxVersion: VersionTLS13, 9019 Bugs: ProtocolBugs{ 9020 FilterTicket: func(in []byte) ([]byte, error) { 9021 return SetShimTicketVersion(in, VersionTLS12) 9022 }, 9023 }, 9024 }, 9025 flags: []string{ 9026 "-ticket-key", 9027 base64FlagValue(TestShimTicketKey), 9028 }, 9029 expectResumeRejected: true, 9030 }) 9031 9032 // Resumptions are declined if the cipher is invalid or disabled. 9033 testCases = append(testCases, testCase{ 9034 testType: serverTest, 9035 name: "Resume-Server-DeclineBadCipher", 9036 resumeSession: true, 9037 config: Config{ 9038 MaxVersion: VersionTLS12, 9039 Bugs: ProtocolBugs{ 9040 ExpectNewTicket: true, 9041 FilterTicket: func(in []byte) ([]byte, error) { 9042 return SetShimTicketCipherSuite(in, TLS_AES_128_GCM_SHA256) 9043 }, 9044 }, 9045 }, 9046 flags: []string{ 9047 "-ticket-key", 9048 base64FlagValue(TestShimTicketKey), 9049 }, 9050 expectResumeRejected: true, 9051 }) 9052 9053 testCases = append(testCases, testCase{ 9054 testType: serverTest, 9055 name: "Resume-Server-DeclineBadCipher-2", 9056 resumeSession: true, 9057 config: Config{ 9058 MaxVersion: VersionTLS12, 9059 Bugs: ProtocolBugs{ 9060 ExpectNewTicket: true, 9061 FilterTicket: func(in []byte) ([]byte, error) { 9062 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) 9063 }, 9064 }, 9065 }, 9066 flags: []string{ 9067 "-cipher", "AES128", 9068 "-ticket-key", 9069 base64FlagValue(TestShimTicketKey), 9070 }, 9071 expectResumeRejected: true, 9072 }) 9073 9074 // Sessions are not resumed if they do not use the preferred cipher. 9075 testCases = append(testCases, testCase{ 9076 testType: serverTest, 9077 name: "Resume-Server-CipherNotPreferred", 9078 resumeSession: true, 9079 config: Config{ 9080 MaxVersion: VersionTLS12, 9081 Bugs: ProtocolBugs{ 9082 ExpectNewTicket: true, 9083 FilterTicket: func(in []byte) ([]byte, error) { 9084 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) 9085 }, 9086 }, 9087 }, 9088 flags: []string{ 9089 "-ticket-key", 9090 base64FlagValue(TestShimTicketKey), 9091 }, 9092 shouldFail: false, 9093 expectResumeRejected: true, 9094 }) 9095 9096 // TLS 1.3 allows sessions to be resumed at a different cipher if their 9097 // PRF hashes match, but BoringSSL will always decline such resumptions. 9098 testCases = append(testCases, testCase{ 9099 testType: serverTest, 9100 name: "Resume-Server-CipherNotPreferred-TLS13", 9101 resumeSession: true, 9102 config: Config{ 9103 MaxVersion: VersionTLS13, 9104 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_GCM_SHA256}, 9105 Bugs: ProtocolBugs{ 9106 FilterTicket: func(in []byte) ([]byte, error) { 9107 // If the client (runner) offers ChaCha20-Poly1305 first, the 9108 // server (shim) always prefers it. Switch it to AES-GCM. 9109 return SetShimTicketCipherSuite(in, TLS_AES_128_GCM_SHA256) 9110 }, 9111 }, 9112 }, 9113 flags: []string{ 9114 "-ticket-key", 9115 base64FlagValue(TestShimTicketKey), 9116 }, 9117 shouldFail: false, 9118 expectResumeRejected: true, 9119 }) 9120 9121 // Sessions may not be resumed if they contain another version's cipher. 9122 testCases = append(testCases, testCase{ 9123 testType: serverTest, 9124 name: "Resume-Server-DeclineBadCipher-TLS13", 9125 resumeSession: true, 9126 config: Config{ 9127 MaxVersion: VersionTLS13, 9128 Bugs: ProtocolBugs{ 9129 FilterTicket: func(in []byte) ([]byte, error) { 9130 return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) 9131 }, 9132 }, 9133 }, 9134 flags: []string{ 9135 "-ticket-key", 9136 base64FlagValue(TestShimTicketKey), 9137 }, 9138 expectResumeRejected: true, 9139 }) 9140 9141 // If the client does not offer the cipher from the session, decline to 9142 // resume. Clients are forbidden from doing this, but BoringSSL selects 9143 // the cipher first, so we only decline. 9144 testCases = append(testCases, testCase{ 9145 testType: serverTest, 9146 name: "Resume-Server-UnofferedCipher", 9147 resumeSession: true, 9148 config: Config{ 9149 MaxVersion: VersionTLS12, 9150 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 9151 }, 9152 resumeConfig: &Config{ 9153 MaxVersion: VersionTLS12, 9154 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 9155 Bugs: ProtocolBugs{ 9156 SendCipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9157 }, 9158 }, 9159 expectResumeRejected: true, 9160 }) 9161 9162 // In TLS 1.3, clients may advertise a cipher list which does not 9163 // include the selected cipher. Test that we tolerate this. Servers may 9164 // resume at another cipher if the PRF matches and are not doing 0-RTT, but 9165 // BoringSSL will always decline. 9166 testCases = append(testCases, testCase{ 9167 testType: serverTest, 9168 name: "Resume-Server-UnofferedCipher-TLS13", 9169 resumeSession: true, 9170 config: Config{ 9171 MaxVersion: VersionTLS13, 9172 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 9173 }, 9174 resumeConfig: &Config{ 9175 MaxVersion: VersionTLS13, 9176 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 9177 Bugs: ProtocolBugs{ 9178 SendCipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9179 }, 9180 }, 9181 expectResumeRejected: true, 9182 }) 9183 9184 // Sessions may not be resumed at a different cipher. 9185 testCases = append(testCases, testCase{ 9186 name: "Resume-Client-CipherMismatch", 9187 resumeSession: true, 9188 config: Config{ 9189 MaxVersion: VersionTLS12, 9190 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 9191 }, 9192 resumeConfig: &Config{ 9193 MaxVersion: VersionTLS12, 9194 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 9195 Bugs: ProtocolBugs{ 9196 SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA, 9197 }, 9198 }, 9199 shouldFail: true, 9200 expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:", 9201 }) 9202 9203 // Session resumption in TLS 1.3 may change the cipher suite if the PRF 9204 // matches. 9205 testCases = append(testCases, testCase{ 9206 name: "Resume-Client-CipherMismatch-TLS13", 9207 resumeSession: true, 9208 config: Config{ 9209 MaxVersion: VersionTLS13, 9210 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9211 }, 9212 resumeConfig: &Config{ 9213 MaxVersion: VersionTLS13, 9214 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 9215 }, 9216 }) 9217 9218 // Session resumption in TLS 1.3 is forbidden if the PRF does not match. 9219 testCases = append(testCases, testCase{ 9220 name: "Resume-Client-PRFMismatch-TLS13", 9221 resumeSession: true, 9222 config: Config{ 9223 MaxVersion: VersionTLS13, 9224 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9225 }, 9226 resumeConfig: &Config{ 9227 MaxVersion: VersionTLS13, 9228 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 9229 Bugs: ProtocolBugs{ 9230 SendCipherSuite: TLS_AES_256_GCM_SHA384, 9231 }, 9232 }, 9233 shouldFail: true, 9234 expectedError: ":OLD_SESSION_PRF_HASH_MISMATCH:", 9235 }) 9236 9237 for _, secondBinder := range []bool{false, true} { 9238 var suffix string 9239 var defaultCurves []CurveID 9240 if secondBinder { 9241 suffix = "-SecondBinder" 9242 // Force a HelloRetryRequest by predicting an empty curve list. 9243 defaultCurves = []CurveID{} 9244 } 9245 9246 testCases = append(testCases, testCase{ 9247 testType: serverTest, 9248 name: "Resume-Server-BinderWrongLength" + suffix, 9249 resumeSession: true, 9250 config: Config{ 9251 MaxVersion: VersionTLS13, 9252 DefaultCurves: defaultCurves, 9253 Bugs: ProtocolBugs{ 9254 SendShortPSKBinder: true, 9255 OnlyCorruptSecondPSKBinder: secondBinder, 9256 }, 9257 }, 9258 shouldFail: true, 9259 expectedLocalError: "remote error: error decrypting message", 9260 expectedError: ":DIGEST_CHECK_FAILED:", 9261 }) 9262 9263 testCases = append(testCases, testCase{ 9264 testType: serverTest, 9265 name: "Resume-Server-NoPSKBinder" + suffix, 9266 resumeSession: true, 9267 config: Config{ 9268 MaxVersion: VersionTLS13, 9269 DefaultCurves: defaultCurves, 9270 Bugs: ProtocolBugs{ 9271 SendNoPSKBinder: true, 9272 OnlyCorruptSecondPSKBinder: secondBinder, 9273 }, 9274 }, 9275 shouldFail: true, 9276 expectedLocalError: "remote error: error decoding message", 9277 expectedError: ":DECODE_ERROR:", 9278 }) 9279 9280 testCases = append(testCases, testCase{ 9281 testType: serverTest, 9282 name: "Resume-Server-ExtraPSKBinder" + suffix, 9283 resumeSession: true, 9284 config: Config{ 9285 MaxVersion: VersionTLS13, 9286 DefaultCurves: defaultCurves, 9287 Bugs: ProtocolBugs{ 9288 SendExtraPSKBinder: true, 9289 OnlyCorruptSecondPSKBinder: secondBinder, 9290 }, 9291 }, 9292 shouldFail: true, 9293 expectedLocalError: "remote error: illegal parameter", 9294 expectedError: ":PSK_IDENTITY_BINDER_COUNT_MISMATCH:", 9295 }) 9296 9297 testCases = append(testCases, testCase{ 9298 testType: serverTest, 9299 name: "Resume-Server-ExtraIdentityNoBinder" + suffix, 9300 resumeSession: true, 9301 config: Config{ 9302 MaxVersion: VersionTLS13, 9303 DefaultCurves: defaultCurves, 9304 Bugs: ProtocolBugs{ 9305 ExtraPSKIdentity: true, 9306 OnlyCorruptSecondPSKBinder: secondBinder, 9307 }, 9308 }, 9309 shouldFail: true, 9310 expectedLocalError: "remote error: illegal parameter", 9311 expectedError: ":PSK_IDENTITY_BINDER_COUNT_MISMATCH:", 9312 }) 9313 9314 testCases = append(testCases, testCase{ 9315 testType: serverTest, 9316 name: "Resume-Server-InvalidPSKBinder" + suffix, 9317 resumeSession: true, 9318 config: Config{ 9319 MaxVersion: VersionTLS13, 9320 DefaultCurves: defaultCurves, 9321 Bugs: ProtocolBugs{ 9322 SendInvalidPSKBinder: true, 9323 OnlyCorruptSecondPSKBinder: secondBinder, 9324 }, 9325 }, 9326 shouldFail: true, 9327 expectedLocalError: "remote error: error decrypting message", 9328 expectedError: ":DIGEST_CHECK_FAILED:", 9329 }) 9330 9331 testCases = append(testCases, testCase{ 9332 testType: serverTest, 9333 name: "Resume-Server-PSKBinderFirstExtension" + suffix, 9334 resumeSession: true, 9335 config: Config{ 9336 MaxVersion: VersionTLS13, 9337 DefaultCurves: defaultCurves, 9338 Bugs: ProtocolBugs{ 9339 PSKBinderFirst: true, 9340 OnlyCorruptSecondPSKBinder: secondBinder, 9341 }, 9342 }, 9343 shouldFail: true, 9344 expectedLocalError: "remote error: illegal parameter", 9345 expectedError: ":PRE_SHARED_KEY_MUST_BE_LAST:", 9346 }) 9347 } 9348 9349 testCases = append(testCases, testCase{ 9350 testType: serverTest, 9351 name: "Resume-Server-OmitPSKsOnSecondClientHello", 9352 resumeSession: true, 9353 config: Config{ 9354 MaxVersion: VersionTLS13, 9355 DefaultCurves: []CurveID{}, 9356 Bugs: ProtocolBugs{ 9357 OmitPSKsOnSecondClientHello: true, 9358 }, 9359 }, 9360 shouldFail: true, 9361 expectedLocalError: "remote error: illegal parameter", 9362 expectedError: ":INCONSISTENT_CLIENT_HELLO:", 9363 }) 9364} 9365 9366func addRenegotiationTests() { 9367 // Servers cannot renegotiate. 9368 testCases = append(testCases, testCase{ 9369 testType: serverTest, 9370 name: "Renegotiate-Server-Forbidden", 9371 config: Config{ 9372 MaxVersion: VersionTLS12, 9373 }, 9374 renegotiate: 1, 9375 shouldFail: true, 9376 expectedError: ":NO_RENEGOTIATION:", 9377 expectedLocalError: "remote error: no renegotiation", 9378 }) 9379 // The server shouldn't echo the renegotiation extension unless 9380 // requested by the client. 9381 testCases = append(testCases, testCase{ 9382 testType: serverTest, 9383 name: "Renegotiate-Server-NoExt", 9384 config: Config{ 9385 MaxVersion: VersionTLS12, 9386 Bugs: ProtocolBugs{ 9387 NoRenegotiationInfo: true, 9388 RequireRenegotiationInfo: true, 9389 }, 9390 }, 9391 shouldFail: true, 9392 expectedLocalError: "renegotiation extension missing", 9393 }) 9394 // The renegotiation SCSV should be sufficient for the server to echo 9395 // the extension. 9396 testCases = append(testCases, testCase{ 9397 testType: serverTest, 9398 name: "Renegotiate-Server-NoExt-SCSV", 9399 config: Config{ 9400 MaxVersion: VersionTLS12, 9401 Bugs: ProtocolBugs{ 9402 NoRenegotiationInfo: true, 9403 SendRenegotiationSCSV: true, 9404 RequireRenegotiationInfo: true, 9405 }, 9406 }, 9407 }) 9408 testCases = append(testCases, testCase{ 9409 name: "Renegotiate-Client", 9410 config: Config{ 9411 MaxVersion: VersionTLS12, 9412 Bugs: ProtocolBugs{ 9413 FailIfResumeOnRenego: true, 9414 }, 9415 }, 9416 renegotiate: 1, 9417 // Test renegotiation after both an initial and resumption 9418 // handshake. 9419 resumeSession: true, 9420 flags: []string{ 9421 "-renegotiate-freely", 9422 "-expect-total-renegotiations", "1", 9423 "-expect-secure-renegotiation", 9424 }, 9425 }) 9426 testCases = append(testCases, testCase{ 9427 name: "Renegotiate-Client-TLS12", 9428 config: Config{ 9429 MaxVersion: VersionTLS12, 9430 Bugs: ProtocolBugs{ 9431 FailIfResumeOnRenego: true, 9432 }, 9433 }, 9434 renegotiate: 1, 9435 // Test renegotiation after both an initial and resumption 9436 // handshake. 9437 resumeSession: true, 9438 flags: []string{ 9439 "-renegotiate-freely", 9440 "-expect-total-renegotiations", "1", 9441 "-expect-secure-renegotiation", 9442 }, 9443 }) 9444 testCases = append(testCases, testCase{ 9445 name: "Renegotiate-Client-EmptyExt", 9446 renegotiate: 1, 9447 config: Config{ 9448 MaxVersion: VersionTLS12, 9449 Bugs: ProtocolBugs{ 9450 EmptyRenegotiationInfo: true, 9451 }, 9452 }, 9453 flags: []string{"-renegotiate-freely"}, 9454 shouldFail: true, 9455 expectedError: ":RENEGOTIATION_MISMATCH:", 9456 expectedLocalError: "handshake failure", 9457 }) 9458 testCases = append(testCases, testCase{ 9459 name: "Renegotiate-Client-BadExt", 9460 renegotiate: 1, 9461 config: Config{ 9462 MaxVersion: VersionTLS12, 9463 Bugs: ProtocolBugs{ 9464 BadRenegotiationInfo: true, 9465 }, 9466 }, 9467 flags: []string{"-renegotiate-freely"}, 9468 shouldFail: true, 9469 expectedError: ":RENEGOTIATION_MISMATCH:", 9470 expectedLocalError: "handshake failure", 9471 }) 9472 testCases = append(testCases, testCase{ 9473 name: "Renegotiate-Client-BadExt2", 9474 renegotiate: 1, 9475 config: Config{ 9476 MaxVersion: VersionTLS12, 9477 Bugs: ProtocolBugs{ 9478 BadRenegotiationInfoEnd: true, 9479 }, 9480 }, 9481 flags: []string{"-renegotiate-freely"}, 9482 shouldFail: true, 9483 expectedError: ":RENEGOTIATION_MISMATCH:", 9484 expectedLocalError: "handshake failure", 9485 }) 9486 testCases = append(testCases, testCase{ 9487 name: "Renegotiate-Client-Downgrade", 9488 renegotiate: 1, 9489 config: Config{ 9490 MaxVersion: VersionTLS12, 9491 Bugs: ProtocolBugs{ 9492 NoRenegotiationInfoAfterInitial: true, 9493 }, 9494 }, 9495 flags: []string{"-renegotiate-freely"}, 9496 shouldFail: true, 9497 expectedError: ":RENEGOTIATION_MISMATCH:", 9498 expectedLocalError: "handshake failure", 9499 }) 9500 testCases = append(testCases, testCase{ 9501 name: "Renegotiate-Client-Upgrade", 9502 renegotiate: 1, 9503 config: Config{ 9504 MaxVersion: VersionTLS12, 9505 Bugs: ProtocolBugs{ 9506 NoRenegotiationInfoInInitial: true, 9507 }, 9508 }, 9509 flags: []string{"-renegotiate-freely"}, 9510 shouldFail: true, 9511 expectedError: ":RENEGOTIATION_MISMATCH:", 9512 expectedLocalError: "handshake failure", 9513 }) 9514 testCases = append(testCases, testCase{ 9515 name: "Renegotiate-Client-NoExt-Allowed", 9516 renegotiate: 1, 9517 config: Config{ 9518 MaxVersion: VersionTLS12, 9519 Bugs: ProtocolBugs{ 9520 NoRenegotiationInfo: true, 9521 }, 9522 }, 9523 flags: []string{ 9524 "-renegotiate-freely", 9525 "-expect-total-renegotiations", "1", 9526 "-expect-no-secure-renegotiation", 9527 }, 9528 }) 9529 9530 // Test that the server may switch ciphers on renegotiation without 9531 // problems. 9532 testCases = append(testCases, testCase{ 9533 name: "Renegotiate-Client-SwitchCiphers", 9534 renegotiate: 1, 9535 config: Config{ 9536 MaxVersion: VersionTLS12, 9537 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 9538 }, 9539 renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9540 flags: []string{ 9541 "-renegotiate-freely", 9542 "-expect-total-renegotiations", "1", 9543 }, 9544 }) 9545 testCases = append(testCases, testCase{ 9546 name: "Renegotiate-Client-SwitchCiphers2", 9547 renegotiate: 1, 9548 config: Config{ 9549 MaxVersion: VersionTLS12, 9550 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9551 }, 9552 renegotiateCiphers: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 9553 flags: []string{ 9554 "-renegotiate-freely", 9555 "-expect-total-renegotiations", "1", 9556 }, 9557 }) 9558 9559 // Test that the server may not switch versions on renegotiation. 9560 testCases = append(testCases, testCase{ 9561 name: "Renegotiate-Client-SwitchVersion", 9562 config: Config{ 9563 MaxVersion: VersionTLS12, 9564 // Pick a cipher which exists at both versions. 9565 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 9566 Bugs: ProtocolBugs{ 9567 NegotiateVersionOnRenego: VersionTLS11, 9568 // Avoid failing early at the record layer. 9569 SendRecordVersion: VersionTLS12, 9570 }, 9571 }, 9572 renegotiate: 1, 9573 flags: []string{ 9574 "-renegotiate-freely", 9575 "-expect-total-renegotiations", "1", 9576 }, 9577 shouldFail: true, 9578 expectedError: ":WRONG_SSL_VERSION:", 9579 }) 9580 9581 testCases = append(testCases, testCase{ 9582 name: "Renegotiate-SameClientVersion", 9583 renegotiate: 1, 9584 config: Config{ 9585 MaxVersion: VersionTLS10, 9586 Bugs: ProtocolBugs{ 9587 RequireSameRenegoClientVersion: true, 9588 }, 9589 }, 9590 flags: []string{ 9591 "-renegotiate-freely", 9592 "-expect-total-renegotiations", "1", 9593 }, 9594 }) 9595 testCases = append(testCases, testCase{ 9596 name: "Renegotiate-FalseStart", 9597 renegotiate: 1, 9598 config: Config{ 9599 MaxVersion: VersionTLS12, 9600 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 9601 NextProtos: []string{"foo"}, 9602 }, 9603 flags: []string{ 9604 "-false-start", 9605 "-select-next-proto", "foo", 9606 "-renegotiate-freely", 9607 "-expect-total-renegotiations", "1", 9608 }, 9609 shimWritesFirst: true, 9610 }) 9611 9612 // Client-side renegotiation controls. 9613 testCases = append(testCases, testCase{ 9614 name: "Renegotiate-Client-Forbidden-1", 9615 config: Config{ 9616 MaxVersion: VersionTLS12, 9617 }, 9618 renegotiate: 1, 9619 shouldFail: true, 9620 expectedError: ":NO_RENEGOTIATION:", 9621 expectedLocalError: "remote error: no renegotiation", 9622 }) 9623 testCases = append(testCases, testCase{ 9624 name: "Renegotiate-Client-Once-1", 9625 config: Config{ 9626 MaxVersion: VersionTLS12, 9627 }, 9628 renegotiate: 1, 9629 flags: []string{ 9630 "-renegotiate-once", 9631 "-expect-total-renegotiations", "1", 9632 }, 9633 }) 9634 testCases = append(testCases, testCase{ 9635 name: "Renegotiate-Client-Freely-1", 9636 config: Config{ 9637 MaxVersion: VersionTLS12, 9638 }, 9639 renegotiate: 1, 9640 flags: []string{ 9641 "-renegotiate-freely", 9642 "-expect-total-renegotiations", "1", 9643 }, 9644 }) 9645 testCases = append(testCases, testCase{ 9646 name: "Renegotiate-Client-Once-2", 9647 config: Config{ 9648 MaxVersion: VersionTLS12, 9649 }, 9650 renegotiate: 2, 9651 flags: []string{"-renegotiate-once"}, 9652 shouldFail: true, 9653 expectedError: ":NO_RENEGOTIATION:", 9654 expectedLocalError: "remote error: no renegotiation", 9655 }) 9656 testCases = append(testCases, testCase{ 9657 name: "Renegotiate-Client-Freely-2", 9658 config: Config{ 9659 MaxVersion: VersionTLS12, 9660 }, 9661 renegotiate: 2, 9662 flags: []string{ 9663 "-renegotiate-freely", 9664 "-expect-total-renegotiations", "2", 9665 }, 9666 }) 9667 testCases = append(testCases, testCase{ 9668 name: "Renegotiate-Client-NoIgnore", 9669 config: Config{ 9670 MaxVersion: VersionTLS12, 9671 Bugs: ProtocolBugs{ 9672 SendHelloRequestBeforeEveryAppDataRecord: true, 9673 }, 9674 }, 9675 shouldFail: true, 9676 expectedError: ":NO_RENEGOTIATION:", 9677 }) 9678 testCases = append(testCases, testCase{ 9679 name: "Renegotiate-Client-Ignore", 9680 config: Config{ 9681 MaxVersion: VersionTLS12, 9682 Bugs: ProtocolBugs{ 9683 SendHelloRequestBeforeEveryAppDataRecord: true, 9684 }, 9685 }, 9686 flags: []string{ 9687 "-renegotiate-ignore", 9688 "-expect-total-renegotiations", "0", 9689 }, 9690 }) 9691 9692 // Renegotiation may be enabled and then disabled immediately after the 9693 // handshake. 9694 testCases = append(testCases, testCase{ 9695 name: "Renegotiate-ForbidAfterHandshake", 9696 config: Config{ 9697 MaxVersion: VersionTLS12, 9698 }, 9699 renegotiate: 1, 9700 flags: []string{"-forbid-renegotiation-after-handshake"}, 9701 shouldFail: true, 9702 expectedError: ":NO_RENEGOTIATION:", 9703 expectedLocalError: "remote error: no renegotiation", 9704 }) 9705 9706 // Renegotiation is not allowed when there is an unfinished write. 9707 testCases = append(testCases, testCase{ 9708 name: "Renegotiate-Client-UnfinishedWrite", 9709 config: Config{ 9710 MaxVersion: VersionTLS12, 9711 }, 9712 renegotiate: 1, 9713 readWithUnfinishedWrite: true, 9714 flags: []string{ 9715 "-async", 9716 "-renegotiate-freely", 9717 }, 9718 shouldFail: true, 9719 expectedError: ":NO_RENEGOTIATION:", 9720 // We do not successfully send the no_renegotiation alert in 9721 // this case. https://crbug.com/boringssl/130 9722 }) 9723 9724 // We reject stray HelloRequests during the handshake in TLS 1.2. 9725 testCases = append(testCases, testCase{ 9726 name: "StrayHelloRequest", 9727 config: Config{ 9728 MaxVersion: VersionTLS12, 9729 Bugs: ProtocolBugs{ 9730 SendHelloRequestBeforeEveryHandshakeMessage: true, 9731 }, 9732 }, 9733 shouldFail: true, 9734 expectedError: ":UNEXPECTED_MESSAGE:", 9735 }) 9736 testCases = append(testCases, testCase{ 9737 name: "StrayHelloRequest-Packed", 9738 config: Config{ 9739 MaxVersion: VersionTLS12, 9740 Bugs: ProtocolBugs{ 9741 PackHandshakeFlight: true, 9742 SendHelloRequestBeforeEveryHandshakeMessage: true, 9743 }, 9744 }, 9745 shouldFail: true, 9746 expectedError: ":UNEXPECTED_MESSAGE:", 9747 }) 9748 9749 // Test that HelloRequest is rejected if it comes in the same record as the 9750 // server Finished. 9751 testCases = append(testCases, testCase{ 9752 name: "Renegotiate-Client-Packed", 9753 config: Config{ 9754 MaxVersion: VersionTLS12, 9755 Bugs: ProtocolBugs{ 9756 PackHandshakeFlight: true, 9757 PackHelloRequestWithFinished: true, 9758 }, 9759 }, 9760 renegotiate: 1, 9761 flags: []string{"-renegotiate-freely"}, 9762 shouldFail: true, 9763 expectedError: ":EXCESS_HANDSHAKE_DATA:", 9764 expectedLocalError: "remote error: unexpected message", 9765 }) 9766 9767 // Renegotiation is forbidden in TLS 1.3. 9768 testCases = append(testCases, testCase{ 9769 name: "Renegotiate-Client-TLS13", 9770 config: Config{ 9771 MaxVersion: VersionTLS13, 9772 Bugs: ProtocolBugs{ 9773 SendHelloRequestBeforeEveryAppDataRecord: true, 9774 }, 9775 }, 9776 flags: []string{ 9777 "-renegotiate-freely", 9778 }, 9779 shouldFail: true, 9780 expectedError: ":UNEXPECTED_MESSAGE:", 9781 }) 9782 9783 // Stray HelloRequests during the handshake are forbidden in TLS 1.3. 9784 testCases = append(testCases, testCase{ 9785 name: "StrayHelloRequest-TLS13", 9786 config: Config{ 9787 MaxVersion: VersionTLS13, 9788 Bugs: ProtocolBugs{ 9789 SendHelloRequestBeforeEveryHandshakeMessage: true, 9790 }, 9791 }, 9792 shouldFail: true, 9793 expectedError: ":UNEXPECTED_MESSAGE:", 9794 }) 9795 9796 // The renegotiation_info extension is not sent in TLS 1.3, but TLS 1.3 9797 // always reads as supporting it, regardless of whether it was 9798 // negotiated. 9799 testCases = append(testCases, testCase{ 9800 name: "AlwaysReportRenegotiationInfo-TLS13", 9801 config: Config{ 9802 MaxVersion: VersionTLS13, 9803 Bugs: ProtocolBugs{ 9804 NoRenegotiationInfo: true, 9805 }, 9806 }, 9807 flags: []string{ 9808 "-expect-secure-renegotiation", 9809 }, 9810 }) 9811 9812 // Certificates may not change on renegotiation. 9813 testCases = append(testCases, testCase{ 9814 name: "Renegotiation-CertificateChange", 9815 config: Config{ 9816 MaxVersion: VersionTLS12, 9817 Credential: &rsaCertificate, 9818 Bugs: ProtocolBugs{ 9819 RenegotiationCertificate: &rsaChainCertificate, 9820 }, 9821 }, 9822 renegotiate: 1, 9823 flags: []string{"-renegotiate-freely"}, 9824 shouldFail: true, 9825 expectedError: ":SERVER_CERT_CHANGED:", 9826 }) 9827 testCases = append(testCases, testCase{ 9828 name: "Renegotiation-CertificateChange-2", 9829 config: Config{ 9830 MaxVersion: VersionTLS12, 9831 Credential: &rsaCertificate, 9832 Bugs: ProtocolBugs{ 9833 RenegotiationCertificate: &rsa1024Certificate, 9834 }, 9835 }, 9836 renegotiate: 1, 9837 flags: []string{"-renegotiate-freely"}, 9838 shouldFail: true, 9839 expectedError: ":SERVER_CERT_CHANGED:", 9840 }) 9841 9842 // We do not negotiate ALPN after the initial handshake. This is 9843 // error-prone and only risks bugs in consumers. 9844 testCases = append(testCases, testCase{ 9845 testType: clientTest, 9846 name: "Renegotiation-ForbidALPN", 9847 config: Config{ 9848 MaxVersion: VersionTLS12, 9849 Bugs: ProtocolBugs{ 9850 // Forcibly negotiate ALPN on both initial and 9851 // renegotiation handshakes. The test stack will 9852 // internally check the client does not offer 9853 // it. 9854 SendALPN: "foo", 9855 }, 9856 }, 9857 flags: []string{ 9858 "-advertise-alpn", "\x03foo\x03bar\x03baz", 9859 "-expect-alpn", "foo", 9860 "-renegotiate-freely", 9861 }, 9862 renegotiate: 1, 9863 shouldFail: true, 9864 expectedError: ":UNEXPECTED_EXTENSION:", 9865 }) 9866 9867 // The server may send different stapled OCSP responses or SCT lists on 9868 // renegotiation, but BoringSSL ignores this and reports the old values. 9869 // Also test that non-fatal verify results are preserved. 9870 testCases = append(testCases, testCase{ 9871 testType: clientTest, 9872 name: "Renegotiation-ChangeAuthProperties", 9873 config: Config{ 9874 MaxVersion: VersionTLS12, 9875 Credential: rsaCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 9876 Bugs: ProtocolBugs{ 9877 SendOCSPResponseOnRenegotiation: testOCSPResponse2, 9878 SendSCTListOnRenegotiation: testSCTList2, 9879 }, 9880 }, 9881 renegotiate: 1, 9882 flags: []string{ 9883 "-renegotiate-freely", 9884 "-expect-total-renegotiations", "1", 9885 "-enable-ocsp-stapling", 9886 "-expect-ocsp-response", 9887 base64FlagValue(testOCSPResponse), 9888 "-enable-signed-cert-timestamps", 9889 "-expect-signed-cert-timestamps", 9890 base64FlagValue(testSCTList), 9891 "-verify-fail", 9892 "-expect-verify-result", 9893 }, 9894 }) 9895} 9896 9897func addDTLSReplayTests() { 9898 // Test that sequence number replays are detected. 9899 testCases = append(testCases, testCase{ 9900 protocol: dtls, 9901 name: "DTLS-Replay", 9902 messageCount: 200, 9903 replayWrites: true, 9904 }) 9905 9906 // Test the incoming sequence number skipping by values larger 9907 // than the retransmit window. 9908 testCases = append(testCases, testCase{ 9909 protocol: dtls, 9910 name: "DTLS-Replay-LargeGaps", 9911 config: Config{ 9912 Bugs: ProtocolBugs{ 9913 SequenceNumberMapping: func(in uint64) uint64 { 9914 return in * 1023 9915 }, 9916 }, 9917 }, 9918 messageCount: 200, 9919 replayWrites: true, 9920 }) 9921 9922 // Test the incoming sequence number changing non-monotonically. 9923 testCases = append(testCases, testCase{ 9924 protocol: dtls, 9925 name: "DTLS-Replay-NonMonotonic", 9926 config: Config{ 9927 Bugs: ProtocolBugs{ 9928 SequenceNumberMapping: func(in uint64) uint64 { 9929 // This mapping has numbers counting backwards in groups 9930 // of 256, and then jumping forwards 511 numbers. 9931 return in ^ 255 9932 }, 9933 }, 9934 }, 9935 // This messageCount is large enough to make sure that the SequenceNumberMapping 9936 // will reach the point where it jumps forwards after stepping backwards. 9937 messageCount: 500, 9938 replayWrites: true, 9939 }) 9940} 9941 9942var testSignatureAlgorithms = []struct { 9943 name string 9944 id signatureAlgorithm 9945 baseCert *Credential 9946 // If non-zero, the curve that must be supported in TLS 1.2 for cert to be 9947 // accepted. 9948 curve CurveID 9949}{ 9950 {"RSA_PKCS1_SHA1", signatureRSAPKCS1WithSHA1, &rsaCertificate, 0}, 9951 {"RSA_PKCS1_SHA256", signatureRSAPKCS1WithSHA256, &rsaCertificate, 0}, 9952 {"RSA_PKCS1_SHA384", signatureRSAPKCS1WithSHA384, &rsaCertificate, 0}, 9953 {"RSA_PKCS1_SHA512", signatureRSAPKCS1WithSHA512, &rsaCertificate, 0}, 9954 {"ECDSA_SHA1", signatureECDSAWithSHA1, &ecdsaP256Certificate, CurveP256}, 9955 // The “P256” in the following line is not a mistake. In TLS 1.2 the 9956 // hash function doesn't have to match the curve and so the same 9957 // signature algorithm works with P-224. 9958 {"ECDSA_P224_SHA256", signatureECDSAWithP256AndSHA256, &ecdsaP224Certificate, CurveP224}, 9959 {"ECDSA_P256_SHA256", signatureECDSAWithP256AndSHA256, &ecdsaP256Certificate, CurveP256}, 9960 {"ECDSA_P384_SHA384", signatureECDSAWithP384AndSHA384, &ecdsaP384Certificate, CurveP384}, 9961 {"ECDSA_P521_SHA512", signatureECDSAWithP521AndSHA512, &ecdsaP521Certificate, CurveP521}, 9962 {"RSA_PSS_SHA256", signatureRSAPSSWithSHA256, &rsaCertificate, 0}, 9963 {"RSA_PSS_SHA384", signatureRSAPSSWithSHA384, &rsaCertificate, 0}, 9964 {"RSA_PSS_SHA512", signatureRSAPSSWithSHA512, &rsaCertificate, 0}, 9965 {"Ed25519", signatureEd25519, &ed25519Certificate, 0}, 9966 // Tests for key types prior to TLS 1.2. 9967 {"RSA", 0, &rsaCertificate, 0}, 9968 {"ECDSA", 0, &ecdsaP256Certificate, CurveP256}, 9969} 9970 9971const fakeSigAlg1 signatureAlgorithm = 0x2a01 9972const fakeSigAlg2 signatureAlgorithm = 0xff01 9973 9974func addSignatureAlgorithmTests() { 9975 // Not all ciphers involve a signature. Advertise a list which gives all 9976 // versions a signing cipher. 9977 signingCiphers := []uint16{ 9978 TLS_AES_256_GCM_SHA384, 9979 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 9980 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 9981 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 9982 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 9983 } 9984 9985 var allAlgorithms []signatureAlgorithm 9986 for _, alg := range testSignatureAlgorithms { 9987 if alg.id != 0 { 9988 allAlgorithms = append(allAlgorithms, alg.id) 9989 } 9990 } 9991 9992 // Make sure each signature algorithm works. Include some fake values in 9993 // the list and ensure they're ignored. 9994 for _, alg := range testSignatureAlgorithms { 9995 // Make a version of the certificate that will not sign any other algorithm. 9996 cert := alg.baseCert 9997 if alg.id != 0 { 9998 cert = cert.WithSignatureAlgorithms(alg.id) 9999 } 10000 10001 for _, ver := range tlsVersions { 10002 if (ver.version < VersionTLS12) != (alg.id == 0) { 10003 continue 10004 } 10005 10006 var shouldFail, rejectByDefault bool 10007 // ecdsa_sha1 does not exist in TLS 1.3. 10008 if ver.version >= VersionTLS13 && alg.id == signatureECDSAWithSHA1 { 10009 shouldFail = true 10010 } 10011 // RSA-PKCS1 does not exist in TLS 1.3. 10012 if ver.version >= VersionTLS13 && hasComponent(alg.name, "PKCS1") { 10013 shouldFail = true 10014 } 10015 // SHA-224 has been removed from TLS 1.3 and, in 1.3, 10016 // the curve has to match the hash size. 10017 if ver.version >= VersionTLS13 && alg.curve == CurveP224 { 10018 shouldFail = true 10019 } 10020 10021 // By default, BoringSSL does not enable ecdsa_sha1, ecdsa_secp521_sha512, and ed25519. 10022 if alg.id == signatureECDSAWithSHA1 || alg.id == signatureECDSAWithP521AndSHA512 || alg.id == signatureEd25519 { 10023 rejectByDefault = true 10024 } 10025 10026 var curveFlags []string 10027 var runnerCurves []CurveID 10028 if alg.curve != 0 && ver.version <= VersionTLS12 { 10029 // In TLS 1.2, the ECDH curve list also constrains ECDSA keys. Ensure the 10030 // corresponding curve is enabled. Also include X25519 to ensure the shim 10031 // and runner have something in common for ECDH. 10032 curveFlags = flagInts("-curves", []int{int(CurveX25519), int(alg.curve)}) 10033 runnerCurves = []CurveID{CurveX25519, alg.curve} 10034 } 10035 10036 var signError, signLocalError, verifyError, verifyLocalError, defaultError, defaultLocalError string 10037 if shouldFail { 10038 signError = ":NO_COMMON_SIGNATURE_ALGORITHMS:" 10039 signLocalError = "remote error: handshake failure" 10040 verifyError = ":WRONG_SIGNATURE_TYPE:" 10041 verifyLocalError = "remote error" 10042 rejectByDefault = true 10043 } 10044 if rejectByDefault { 10045 defaultError = ":WRONG_SIGNATURE_TYPE:" 10046 defaultLocalError = "remote error" 10047 } 10048 10049 suffix := "-" + alg.name + "-" + ver.name 10050 10051 for _, testType := range []testType{clientTest, serverTest} { 10052 prefix := "Client-" 10053 if testType == serverTest { 10054 prefix = "Server-" 10055 } 10056 10057 // Test the shim using the algorithm for signing. 10058 signTest := testCase{ 10059 testType: testType, 10060 name: prefix + "Sign" + suffix, 10061 config: Config{ 10062 MaxVersion: ver.version, 10063 CurvePreferences: runnerCurves, 10064 VerifySignatureAlgorithms: []signatureAlgorithm{ 10065 fakeSigAlg1, 10066 alg.id, 10067 fakeSigAlg2, 10068 }, 10069 }, 10070 shimCertificate: cert, 10071 flags: curveFlags, 10072 shouldFail: shouldFail, 10073 expectedError: signError, 10074 expectedLocalError: signLocalError, 10075 expectations: connectionExpectations{ 10076 peerSignatureAlgorithm: alg.id, 10077 }, 10078 } 10079 10080 // Test that the shim will select the algorithm when configured to only 10081 // support it. 10082 negotiateTest := testCase{ 10083 testType: testType, 10084 name: prefix + "Sign-Negotiate" + suffix, 10085 config: Config{ 10086 MaxVersion: ver.version, 10087 CurvePreferences: runnerCurves, 10088 VerifySignatureAlgorithms: allAlgorithms, 10089 }, 10090 shimCertificate: cert, 10091 flags: curveFlags, 10092 expectations: connectionExpectations{ 10093 peerSignatureAlgorithm: alg.id, 10094 }, 10095 } 10096 10097 if testType == serverTest { 10098 // TLS 1.2 servers only sign on some cipher suites. 10099 signTest.config.CipherSuites = signingCiphers 10100 negotiateTest.config.CipherSuites = signingCiphers 10101 } else { 10102 // TLS 1.2 clients only sign when the server requests certificates. 10103 signTest.config.ClientAuth = RequireAnyClientCert 10104 negotiateTest.config.ClientAuth = RequireAnyClientCert 10105 } 10106 testCases = append(testCases, signTest) 10107 if ver.version >= VersionTLS12 && !shouldFail { 10108 testCases = append(testCases, negotiateTest) 10109 } 10110 10111 // Test the shim using the algorithm for verifying. 10112 verifyTest := testCase{ 10113 testType: testType, 10114 name: prefix + "Verify" + suffix, 10115 config: Config{ 10116 MaxVersion: ver.version, 10117 Credential: cert, 10118 Bugs: ProtocolBugs{ 10119 SkipECDSACurveCheck: shouldFail, 10120 IgnoreSignatureVersionChecks: shouldFail, 10121 // Some signature algorithms may not be advertised. 10122 IgnorePeerSignatureAlgorithmPreferences: shouldFail, 10123 }, 10124 }, 10125 flags: curveFlags, 10126 // Resume the session to assert the peer signature 10127 // algorithm is reported on both handshakes. 10128 resumeSession: !shouldFail, 10129 shouldFail: shouldFail, 10130 expectedError: verifyError, 10131 expectedLocalError: verifyLocalError, 10132 } 10133 if alg.id != 0 { 10134 verifyTest.flags = append(verifyTest.flags, "-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))) 10135 // The algorithm may be disabled by default, so explicitly enable it. 10136 verifyTest.flags = append(verifyTest.flags, "-verify-prefs", strconv.Itoa(int(alg.id))) 10137 } 10138 10139 // Test whether the shim expects the algorithm enabled by default. 10140 defaultTest := testCase{ 10141 testType: testType, 10142 name: prefix + "VerifyDefault" + suffix, 10143 config: Config{ 10144 MaxVersion: ver.version, 10145 Credential: cert, 10146 Bugs: ProtocolBugs{ 10147 SkipECDSACurveCheck: rejectByDefault, 10148 IgnoreSignatureVersionChecks: rejectByDefault, 10149 // Some signature algorithms may not be advertised. 10150 IgnorePeerSignatureAlgorithmPreferences: rejectByDefault, 10151 }, 10152 }, 10153 flags: append( 10154 []string{"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id))}, 10155 curveFlags..., 10156 ), 10157 // Resume the session to assert the peer signature 10158 // algorithm is reported on both handshakes. 10159 resumeSession: !rejectByDefault, 10160 shouldFail: rejectByDefault, 10161 expectedError: defaultError, 10162 expectedLocalError: defaultLocalError, 10163 } 10164 10165 // Test whether the shim handles invalid signatures for this algorithm. 10166 invalidTest := testCase{ 10167 testType: testType, 10168 name: prefix + "InvalidSignature" + suffix, 10169 config: Config{ 10170 MaxVersion: ver.version, 10171 Credential: cert, 10172 Bugs: ProtocolBugs{ 10173 InvalidSignature: true, 10174 }, 10175 }, 10176 flags: curveFlags, 10177 shouldFail: true, 10178 expectedError: ":BAD_SIGNATURE:", 10179 } 10180 if alg.id != 0 { 10181 // The algorithm may be disabled by default, so explicitly enable it. 10182 invalidTest.flags = append(invalidTest.flags, "-verify-prefs", strconv.Itoa(int(alg.id))) 10183 } 10184 10185 if testType == serverTest { 10186 // TLS 1.2 servers only verify when they request client certificates. 10187 verifyTest.flags = append(verifyTest.flags, "-require-any-client-certificate") 10188 defaultTest.flags = append(defaultTest.flags, "-require-any-client-certificate") 10189 invalidTest.flags = append(invalidTest.flags, "-require-any-client-certificate") 10190 } else { 10191 // TLS 1.2 clients only verify on some cipher suites. 10192 verifyTest.config.CipherSuites = signingCiphers 10193 defaultTest.config.CipherSuites = signingCiphers 10194 invalidTest.config.CipherSuites = signingCiphers 10195 } 10196 testCases = append(testCases, verifyTest, defaultTest) 10197 if !shouldFail { 10198 testCases = append(testCases, invalidTest) 10199 } 10200 } 10201 } 10202 } 10203 10204 // Test the peer's verify preferences are available. 10205 for _, ver := range tlsVersions { 10206 if ver.version < VersionTLS12 { 10207 continue 10208 } 10209 testCases = append(testCases, testCase{ 10210 name: "ClientAuth-PeerVerifyPrefs-" + ver.name, 10211 config: Config{ 10212 MaxVersion: ver.version, 10213 ClientAuth: RequireAnyClientCert, 10214 VerifySignatureAlgorithms: []signatureAlgorithm{ 10215 signatureRSAPSSWithSHA256, 10216 signatureEd25519, 10217 signatureECDSAWithP256AndSHA256, 10218 }, 10219 }, 10220 shimCertificate: &rsaCertificate, 10221 flags: []string{ 10222 "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 10223 "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), 10224 "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 10225 }, 10226 }) 10227 10228 testCases = append(testCases, testCase{ 10229 testType: serverTest, 10230 name: "ServerAuth-PeerVerifyPrefs-" + ver.name, 10231 config: Config{ 10232 MaxVersion: ver.version, 10233 VerifySignatureAlgorithms: []signatureAlgorithm{ 10234 signatureRSAPSSWithSHA256, 10235 signatureEd25519, 10236 signatureECDSAWithP256AndSHA256, 10237 }, 10238 }, 10239 shimCertificate: &rsaCertificate, 10240 flags: []string{ 10241 "-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)), 10242 "-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)), 10243 "-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)), 10244 }, 10245 }) 10246 10247 } 10248 10249 // Test that algorithm selection takes the key type into account. 10250 testCases = append(testCases, testCase{ 10251 name: "ClientAuth-SignatureType", 10252 config: Config{ 10253 ClientAuth: RequireAnyClientCert, 10254 MaxVersion: VersionTLS12, 10255 VerifySignatureAlgorithms: []signatureAlgorithm{ 10256 signatureECDSAWithP521AndSHA512, 10257 signatureRSAPKCS1WithSHA384, 10258 signatureECDSAWithSHA1, 10259 }, 10260 }, 10261 shimCertificate: &rsaCertificate, 10262 expectations: connectionExpectations{ 10263 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, 10264 }, 10265 }) 10266 10267 testCases = append(testCases, testCase{ 10268 name: "ClientAuth-SignatureType-TLS13", 10269 config: Config{ 10270 ClientAuth: RequireAnyClientCert, 10271 MaxVersion: VersionTLS13, 10272 VerifySignatureAlgorithms: []signatureAlgorithm{ 10273 signatureECDSAWithP521AndSHA512, 10274 signatureRSAPKCS1WithSHA384, 10275 signatureRSAPSSWithSHA384, 10276 signatureECDSAWithSHA1, 10277 }, 10278 }, 10279 shimCertificate: &rsaCertificate, 10280 expectations: connectionExpectations{ 10281 peerSignatureAlgorithm: signatureRSAPSSWithSHA384, 10282 }, 10283 }) 10284 10285 testCases = append(testCases, testCase{ 10286 testType: serverTest, 10287 name: "ServerAuth-SignatureType", 10288 config: Config{ 10289 MaxVersion: VersionTLS12, 10290 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10291 VerifySignatureAlgorithms: []signatureAlgorithm{ 10292 signatureECDSAWithP521AndSHA512, 10293 signatureRSAPKCS1WithSHA384, 10294 signatureECDSAWithSHA1, 10295 }, 10296 }, 10297 expectations: connectionExpectations{ 10298 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384, 10299 }, 10300 }) 10301 10302 testCases = append(testCases, testCase{ 10303 testType: serverTest, 10304 name: "ServerAuth-SignatureType-TLS13", 10305 config: Config{ 10306 MaxVersion: VersionTLS13, 10307 VerifySignatureAlgorithms: []signatureAlgorithm{ 10308 signatureECDSAWithP521AndSHA512, 10309 signatureRSAPKCS1WithSHA384, 10310 signatureRSAPSSWithSHA384, 10311 signatureECDSAWithSHA1, 10312 }, 10313 }, 10314 expectations: connectionExpectations{ 10315 peerSignatureAlgorithm: signatureRSAPSSWithSHA384, 10316 }, 10317 }) 10318 10319 // Test that signature verification takes the key type into account. 10320 testCases = append(testCases, testCase{ 10321 testType: serverTest, 10322 name: "Verify-ClientAuth-SignatureType", 10323 config: Config{ 10324 MaxVersion: VersionTLS12, 10325 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithSHA256), 10326 Bugs: ProtocolBugs{ 10327 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10328 }, 10329 }, 10330 flags: []string{ 10331 "-require-any-client-certificate", 10332 }, 10333 shouldFail: true, 10334 expectedError: ":WRONG_SIGNATURE_TYPE:", 10335 }) 10336 10337 testCases = append(testCases, testCase{ 10338 testType: serverTest, 10339 name: "Verify-ClientAuth-SignatureType-TLS13", 10340 config: Config{ 10341 MaxVersion: VersionTLS13, 10342 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 10343 Bugs: ProtocolBugs{ 10344 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10345 }, 10346 }, 10347 flags: []string{ 10348 "-require-any-client-certificate", 10349 }, 10350 shouldFail: true, 10351 expectedError: ":WRONG_SIGNATURE_TYPE:", 10352 }) 10353 10354 testCases = append(testCases, testCase{ 10355 name: "Verify-ServerAuth-SignatureType", 10356 config: Config{ 10357 MaxVersion: VersionTLS12, 10358 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10359 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithSHA256), 10360 Bugs: ProtocolBugs{ 10361 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10362 }, 10363 }, 10364 shouldFail: true, 10365 expectedError: ":WRONG_SIGNATURE_TYPE:", 10366 }) 10367 10368 testCases = append(testCases, testCase{ 10369 name: "Verify-ServerAuth-SignatureType-TLS13", 10370 config: Config{ 10371 MaxVersion: VersionTLS13, 10372 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 10373 Bugs: ProtocolBugs{ 10374 SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10375 }, 10376 }, 10377 shouldFail: true, 10378 expectedError: ":WRONG_SIGNATURE_TYPE:", 10379 }) 10380 10381 // Test that, if the ClientHello list is missing, the server falls back 10382 // to SHA-1 in TLS 1.2, but not TLS 1.3. 10383 testCases = append(testCases, testCase{ 10384 testType: serverTest, 10385 name: "ServerAuth-SHA1-Fallback-RSA", 10386 config: Config{ 10387 MaxVersion: VersionTLS12, 10388 VerifySignatureAlgorithms: []signatureAlgorithm{ 10389 signatureRSAPKCS1WithSHA1, 10390 }, 10391 Bugs: ProtocolBugs{ 10392 NoSignatureAlgorithms: true, 10393 }, 10394 }, 10395 shimCertificate: &rsaCertificate, 10396 }) 10397 10398 testCases = append(testCases, testCase{ 10399 testType: serverTest, 10400 name: "ServerAuth-SHA1-Fallback-ECDSA", 10401 config: Config{ 10402 MaxVersion: VersionTLS12, 10403 VerifySignatureAlgorithms: []signatureAlgorithm{ 10404 signatureECDSAWithSHA1, 10405 }, 10406 Bugs: ProtocolBugs{ 10407 NoSignatureAlgorithms: true, 10408 }, 10409 }, 10410 shimCertificate: &ecdsaP256Certificate, 10411 }) 10412 10413 testCases = append(testCases, testCase{ 10414 testType: serverTest, 10415 name: "ServerAuth-NoFallback-TLS13", 10416 config: Config{ 10417 MaxVersion: VersionTLS13, 10418 VerifySignatureAlgorithms: []signatureAlgorithm{ 10419 signatureRSAPKCS1WithSHA1, 10420 }, 10421 Bugs: ProtocolBugs{ 10422 NoSignatureAlgorithms: true, 10423 }, 10424 }, 10425 shouldFail: true, 10426 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10427 }) 10428 10429 // The CertificateRequest list, however, may never be omitted. It is a 10430 // syntax error for it to be empty. 10431 testCases = append(testCases, testCase{ 10432 name: "ClientAuth-NoFallback-RSA", 10433 config: Config{ 10434 MaxVersion: VersionTLS12, 10435 ClientAuth: RequireAnyClientCert, 10436 VerifySignatureAlgorithms: []signatureAlgorithm{ 10437 signatureRSAPKCS1WithSHA1, 10438 }, 10439 Bugs: ProtocolBugs{ 10440 NoSignatureAlgorithms: true, 10441 }, 10442 }, 10443 shimCertificate: &rsaCertificate, 10444 shouldFail: true, 10445 expectedError: ":DECODE_ERROR:", 10446 expectedLocalError: "remote error: error decoding message", 10447 }) 10448 10449 testCases = append(testCases, testCase{ 10450 name: "ClientAuth-NoFallback-ECDSA", 10451 config: Config{ 10452 MaxVersion: VersionTLS12, 10453 ClientAuth: RequireAnyClientCert, 10454 VerifySignatureAlgorithms: []signatureAlgorithm{ 10455 signatureECDSAWithSHA1, 10456 }, 10457 Bugs: ProtocolBugs{ 10458 NoSignatureAlgorithms: true, 10459 }, 10460 }, 10461 shimCertificate: &ecdsaP256Certificate, 10462 shouldFail: true, 10463 expectedError: ":DECODE_ERROR:", 10464 expectedLocalError: "remote error: error decoding message", 10465 }) 10466 10467 testCases = append(testCases, testCase{ 10468 name: "ClientAuth-NoFallback-TLS13", 10469 config: Config{ 10470 MaxVersion: VersionTLS13, 10471 ClientAuth: RequireAnyClientCert, 10472 VerifySignatureAlgorithms: []signatureAlgorithm{ 10473 signatureRSAPKCS1WithSHA1, 10474 }, 10475 Bugs: ProtocolBugs{ 10476 NoSignatureAlgorithms: true, 10477 }, 10478 }, 10479 shimCertificate: &rsaCertificate, 10480 shouldFail: true, 10481 expectedError: ":DECODE_ERROR:", 10482 expectedLocalError: "remote error: error decoding message", 10483 }) 10484 10485 // Test that signature preferences are enforced. BoringSSL does not 10486 // implement MD5 signatures. 10487 testCases = append(testCases, testCase{ 10488 testType: serverTest, 10489 name: "ClientAuth-Enforced", 10490 config: Config{ 10491 MaxVersion: VersionTLS12, 10492 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 10493 Bugs: ProtocolBugs{ 10494 IgnorePeerSignatureAlgorithmPreferences: true, 10495 }, 10496 }, 10497 flags: []string{"-require-any-client-certificate"}, 10498 shouldFail: true, 10499 expectedError: ":WRONG_SIGNATURE_TYPE:", 10500 }) 10501 10502 testCases = append(testCases, testCase{ 10503 name: "ServerAuth-Enforced", 10504 config: Config{ 10505 MaxVersion: VersionTLS12, 10506 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 10507 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 10508 Bugs: ProtocolBugs{ 10509 IgnorePeerSignatureAlgorithmPreferences: true, 10510 }, 10511 }, 10512 shouldFail: true, 10513 expectedError: ":WRONG_SIGNATURE_TYPE:", 10514 }) 10515 testCases = append(testCases, testCase{ 10516 testType: serverTest, 10517 name: "ClientAuth-Enforced-TLS13", 10518 config: Config{ 10519 MaxVersion: VersionTLS13, 10520 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 10521 Bugs: ProtocolBugs{ 10522 IgnorePeerSignatureAlgorithmPreferences: true, 10523 IgnoreSignatureVersionChecks: true, 10524 }, 10525 }, 10526 flags: []string{"-require-any-client-certificate"}, 10527 shouldFail: true, 10528 expectedError: ":WRONG_SIGNATURE_TYPE:", 10529 }) 10530 10531 testCases = append(testCases, testCase{ 10532 name: "ServerAuth-Enforced-TLS13", 10533 config: Config{ 10534 MaxVersion: VersionTLS13, 10535 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithMD5), 10536 Bugs: ProtocolBugs{ 10537 IgnorePeerSignatureAlgorithmPreferences: true, 10538 IgnoreSignatureVersionChecks: true, 10539 }, 10540 }, 10541 shouldFail: true, 10542 expectedError: ":WRONG_SIGNATURE_TYPE:", 10543 }) 10544 10545 // Test that the negotiated signature algorithm respects the client and 10546 // server preferences. 10547 testCases = append(testCases, testCase{ 10548 name: "NoCommonAlgorithms", 10549 config: Config{ 10550 MaxVersion: VersionTLS12, 10551 ClientAuth: RequireAnyClientCert, 10552 VerifySignatureAlgorithms: []signatureAlgorithm{ 10553 signatureRSAPKCS1WithSHA512, 10554 signatureRSAPKCS1WithSHA1, 10555 }, 10556 }, 10557 shimCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPKCS1WithSHA256), 10558 shouldFail: true, 10559 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10560 }) 10561 testCases = append(testCases, testCase{ 10562 name: "NoCommonAlgorithms-TLS13", 10563 config: Config{ 10564 MaxVersion: VersionTLS13, 10565 ClientAuth: RequireAnyClientCert, 10566 VerifySignatureAlgorithms: []signatureAlgorithm{ 10567 signatureRSAPSSWithSHA512, 10568 signatureRSAPSSWithSHA384, 10569 }, 10570 }, 10571 shimCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 10572 shouldFail: true, 10573 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10574 }) 10575 testCases = append(testCases, testCase{ 10576 name: "Agree-Digest-SHA256", 10577 config: Config{ 10578 MaxVersion: VersionTLS12, 10579 ClientAuth: RequireAnyClientCert, 10580 VerifySignatureAlgorithms: []signatureAlgorithm{ 10581 signatureRSAPKCS1WithSHA1, 10582 signatureRSAPKCS1WithSHA256, 10583 }, 10584 }, 10585 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 10586 signatureRSAPKCS1WithSHA256, 10587 signatureRSAPKCS1WithSHA1, 10588 ), 10589 expectations: connectionExpectations{ 10590 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10591 }, 10592 }) 10593 testCases = append(testCases, testCase{ 10594 name: "Agree-Digest-SHA1", 10595 config: Config{ 10596 MaxVersion: VersionTLS12, 10597 ClientAuth: RequireAnyClientCert, 10598 VerifySignatureAlgorithms: []signatureAlgorithm{ 10599 signatureRSAPKCS1WithSHA1, 10600 }, 10601 }, 10602 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 10603 signatureRSAPKCS1WithSHA512, 10604 signatureRSAPKCS1WithSHA256, 10605 signatureRSAPKCS1WithSHA1, 10606 ), 10607 expectations: connectionExpectations{ 10608 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA1, 10609 }, 10610 }) 10611 testCases = append(testCases, testCase{ 10612 name: "Agree-Digest-Default", 10613 config: Config{ 10614 MaxVersion: VersionTLS12, 10615 ClientAuth: RequireAnyClientCert, 10616 VerifySignatureAlgorithms: []signatureAlgorithm{ 10617 signatureRSAPKCS1WithSHA256, 10618 signatureECDSAWithP256AndSHA256, 10619 signatureRSAPKCS1WithSHA1, 10620 signatureECDSAWithSHA1, 10621 }, 10622 }, 10623 shimCertificate: &rsaCertificate, 10624 expectations: connectionExpectations{ 10625 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10626 }, 10627 }) 10628 10629 // Test that the signing preference list may include extra algorithms 10630 // without negotiation problems. 10631 testCases = append(testCases, testCase{ 10632 testType: serverTest, 10633 name: "FilterExtraAlgorithms", 10634 config: Config{ 10635 MaxVersion: VersionTLS12, 10636 VerifySignatureAlgorithms: []signatureAlgorithm{ 10637 signatureRSAPKCS1WithSHA256, 10638 }, 10639 }, 10640 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 10641 signatureECDSAWithP256AndSHA256, 10642 signatureRSAPKCS1WithSHA256, 10643 ), 10644 expectations: connectionExpectations{ 10645 peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256, 10646 }, 10647 }) 10648 10649 // In TLS 1.2 and below, ECDSA uses the curve list rather than the 10650 // signature algorithms. 10651 testCases = append(testCases, testCase{ 10652 name: "CheckLeafCurve", 10653 config: Config{ 10654 MaxVersion: VersionTLS12, 10655 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 10656 Credential: &ecdsaP256Certificate, 10657 }, 10658 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 10659 shouldFail: true, 10660 expectedError: ":BAD_ECC_CERT:", 10661 }) 10662 10663 // In TLS 1.3, ECDSA does not use the ECDHE curve list. 10664 testCases = append(testCases, testCase{ 10665 name: "CheckLeafCurve-TLS13", 10666 config: Config{ 10667 MaxVersion: VersionTLS13, 10668 Credential: &ecdsaP256Certificate, 10669 }, 10670 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 10671 }) 10672 10673 // In TLS 1.2, the ECDSA curve is not in the signature algorithm, so the 10674 // shim should accept P-256 with SHA-384. 10675 testCases = append(testCases, testCase{ 10676 name: "ECDSACurveMismatch-Verify-TLS12", 10677 config: Config{ 10678 MaxVersion: VersionTLS12, 10679 CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, 10680 Credential: ecdsaP256Certificate.WithSignatureAlgorithms(signatureECDSAWithP384AndSHA384), 10681 }, 10682 }) 10683 10684 // In TLS 1.3, the ECDSA curve comes from the signature algorithm, so the 10685 // shim should reject P-256 with SHA-384. 10686 testCases = append(testCases, testCase{ 10687 name: "ECDSACurveMismatch-Verify-TLS13", 10688 config: Config{ 10689 MaxVersion: VersionTLS13, 10690 Credential: ecdsaP256Certificate.WithSignatureAlgorithms(signatureECDSAWithP384AndSHA384), 10691 Bugs: ProtocolBugs{ 10692 SkipECDSACurveCheck: true, 10693 }, 10694 }, 10695 shouldFail: true, 10696 expectedError: ":WRONG_SIGNATURE_TYPE:", 10697 }) 10698 10699 // Signature algorithm selection in TLS 1.3 should take the curve into 10700 // account. 10701 testCases = append(testCases, testCase{ 10702 testType: serverTest, 10703 name: "ECDSACurveMismatch-Sign-TLS13", 10704 config: Config{ 10705 MaxVersion: VersionTLS13, 10706 VerifySignatureAlgorithms: []signatureAlgorithm{ 10707 signatureECDSAWithP384AndSHA384, 10708 signatureECDSAWithP256AndSHA256, 10709 }, 10710 }, 10711 shimCertificate: &ecdsaP256Certificate, 10712 expectations: connectionExpectations{ 10713 peerSignatureAlgorithm: signatureECDSAWithP256AndSHA256, 10714 }, 10715 }) 10716 10717 // RSASSA-PSS with SHA-512 is too large for 1024-bit RSA. Test that the 10718 // server does not attempt to sign in that case. 10719 testCases = append(testCases, testCase{ 10720 testType: serverTest, 10721 name: "RSA-PSS-Large", 10722 config: Config{ 10723 MaxVersion: VersionTLS13, 10724 VerifySignatureAlgorithms: []signatureAlgorithm{ 10725 signatureRSAPSSWithSHA512, 10726 }, 10727 }, 10728 shimCertificate: &rsa1024Certificate, 10729 shouldFail: true, 10730 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10731 }) 10732 10733 // Test that RSA-PSS is enabled by default for TLS 1.2. 10734 testCases = append(testCases, testCase{ 10735 testType: clientTest, 10736 name: "RSA-PSS-Default-Verify", 10737 config: Config{ 10738 MaxVersion: VersionTLS12, 10739 Credential: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 10740 }, 10741 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 10742 }) 10743 10744 testCases = append(testCases, testCase{ 10745 testType: serverTest, 10746 name: "RSA-PSS-Default-Sign", 10747 config: Config{ 10748 MaxVersion: VersionTLS12, 10749 VerifySignatureAlgorithms: []signatureAlgorithm{ 10750 signatureRSAPSSWithSHA256, 10751 }, 10752 }, 10753 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 10754 }) 10755 10756 // TLS 1.1 and below has no way to advertise support for or negotiate 10757 // Ed25519's signature algorithm. 10758 testCases = append(testCases, testCase{ 10759 testType: clientTest, 10760 name: "NoEd25519-TLS11-ServerAuth-Verify", 10761 config: Config{ 10762 MaxVersion: VersionTLS11, 10763 Credential: &ed25519Certificate, 10764 Bugs: ProtocolBugs{ 10765 // Sign with Ed25519 even though it is TLS 1.1. 10766 SigningAlgorithmForLegacyVersions: signatureEd25519, 10767 }, 10768 }, 10769 flags: []string{"-verify-prefs", strconv.Itoa(int(signatureEd25519))}, 10770 shouldFail: true, 10771 expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:", 10772 }) 10773 testCases = append(testCases, testCase{ 10774 testType: serverTest, 10775 name: "NoEd25519-TLS11-ServerAuth-Sign", 10776 config: Config{ 10777 MaxVersion: VersionTLS11, 10778 }, 10779 shimCertificate: &ed25519Certificate, 10780 shouldFail: true, 10781 expectedError: ":NO_SHARED_CIPHER:", 10782 }) 10783 testCases = append(testCases, testCase{ 10784 testType: serverTest, 10785 name: "NoEd25519-TLS11-ClientAuth-Verify", 10786 config: Config{ 10787 MaxVersion: VersionTLS11, 10788 Credential: &ed25519Certificate, 10789 Bugs: ProtocolBugs{ 10790 // Sign with Ed25519 even though it is TLS 1.1. 10791 SigningAlgorithmForLegacyVersions: signatureEd25519, 10792 }, 10793 }, 10794 flags: []string{ 10795 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 10796 "-require-any-client-certificate", 10797 }, 10798 shouldFail: true, 10799 expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:", 10800 }) 10801 testCases = append(testCases, testCase{ 10802 testType: clientTest, 10803 name: "NoEd25519-TLS11-ClientAuth-Sign", 10804 config: Config{ 10805 MaxVersion: VersionTLS11, 10806 ClientAuth: RequireAnyClientCert, 10807 }, 10808 shimCertificate: &ed25519Certificate, 10809 shouldFail: true, 10810 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 10811 }) 10812 10813 // Test Ed25519 is not advertised by default. 10814 testCases = append(testCases, testCase{ 10815 testType: clientTest, 10816 name: "Ed25519DefaultDisable-NoAdvertise", 10817 config: Config{ 10818 Credential: &ed25519Certificate, 10819 }, 10820 shouldFail: true, 10821 expectedLocalError: "tls: no common signature algorithms", 10822 }) 10823 10824 // Test Ed25519, when disabled, is not accepted if the peer ignores our 10825 // preferences. 10826 testCases = append(testCases, testCase{ 10827 testType: clientTest, 10828 name: "Ed25519DefaultDisable-NoAccept", 10829 config: Config{ 10830 Credential: &ed25519Certificate, 10831 Bugs: ProtocolBugs{ 10832 IgnorePeerSignatureAlgorithmPreferences: true, 10833 }, 10834 }, 10835 shouldFail: true, 10836 expectedLocalError: "remote error: illegal parameter", 10837 expectedError: ":WRONG_SIGNATURE_TYPE:", 10838 }) 10839 10840 // Test that configuring verify preferences changes what the client 10841 // advertises. 10842 testCases = append(testCases, testCase{ 10843 name: "VerifyPreferences-Advertised", 10844 config: Config{ 10845 Credential: rsaCertificate.WithSignatureAlgorithms( 10846 signatureRSAPSSWithSHA256, 10847 signatureRSAPSSWithSHA384, 10848 signatureRSAPSSWithSHA512, 10849 ), 10850 }, 10851 flags: []string{ 10852 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10853 "-expect-peer-signature-algorithm", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10854 }, 10855 }) 10856 10857 // Test that the client advertises a set which the runner can find 10858 // nothing in common with. 10859 testCases = append(testCases, testCase{ 10860 name: "VerifyPreferences-NoCommonAlgorithms", 10861 config: Config{ 10862 Credential: rsaCertificate.WithSignatureAlgorithms( 10863 signatureRSAPSSWithSHA256, 10864 signatureRSAPSSWithSHA512, 10865 ), 10866 }, 10867 flags: []string{ 10868 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10869 }, 10870 shouldFail: true, 10871 expectedLocalError: "tls: no common signature algorithms", 10872 }) 10873 10874 // Test that the client enforces its preferences when configured. 10875 testCases = append(testCases, testCase{ 10876 name: "VerifyPreferences-Enforced", 10877 config: Config{ 10878 Credential: rsaCertificate.WithSignatureAlgorithms( 10879 signatureRSAPSSWithSHA256, 10880 signatureRSAPSSWithSHA512, 10881 ), 10882 Bugs: ProtocolBugs{ 10883 IgnorePeerSignatureAlgorithmPreferences: true, 10884 }, 10885 }, 10886 flags: []string{ 10887 "-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)), 10888 }, 10889 shouldFail: true, 10890 expectedLocalError: "remote error: illegal parameter", 10891 expectedError: ":WRONG_SIGNATURE_TYPE:", 10892 }) 10893 10894 // Test that explicitly configuring Ed25519 is as good as changing the 10895 // boolean toggle. 10896 testCases = append(testCases, testCase{ 10897 name: "VerifyPreferences-Ed25519", 10898 config: Config{ 10899 Credential: &ed25519Certificate, 10900 }, 10901 flags: []string{ 10902 "-verify-prefs", strconv.Itoa(int(signatureEd25519)), 10903 }, 10904 }) 10905 10906 for _, testType := range []testType{clientTest, serverTest} { 10907 for _, ver := range tlsVersions { 10908 if ver.version < VersionTLS12 { 10909 continue 10910 } 10911 10912 prefix := "Client-" + ver.name + "-" 10913 noCommonAlgorithmsError := ":NO_COMMON_SIGNATURE_ALGORITHMS:" 10914 if testType == serverTest { 10915 prefix = "Server-" + ver.name + "-" 10916 // In TLS 1.2 servers, cipher selection and algorithm 10917 // selection are linked. 10918 if ver.version <= VersionTLS12 { 10919 noCommonAlgorithmsError = ":NO_SHARED_CIPHER:" 10920 } 10921 } 10922 10923 // Test that the shim will not sign MD5/SHA1 with RSA at TLS 1.2, 10924 // even if specified in signing preferences. 10925 testCases = append(testCases, testCase{ 10926 testType: testType, 10927 name: prefix + "NoSign-RSA_PKCS1_MD5_SHA1", 10928 config: Config{ 10929 MaxVersion: ver.version, 10930 CipherSuites: signingCiphers, 10931 ClientAuth: RequireAnyClientCert, 10932 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPKCS1WithMD5AndSHA1}, 10933 }, 10934 shimCertificate: rsaCertificate.WithSignatureAlgorithms( 10935 signatureRSAPKCS1WithMD5AndSHA1, 10936 // Include a valid algorithm as well, to avoid an empty list 10937 // if filtered out. 10938 signatureRSAPKCS1WithSHA256, 10939 ), 10940 shouldFail: true, 10941 expectedError: noCommonAlgorithmsError, 10942 }) 10943 10944 // Test that the shim will not accept MD5/SHA1 with RSA at TLS 1.2, 10945 // even if specified in verify preferences. 10946 testCases = append(testCases, testCase{ 10947 testType: testType, 10948 name: prefix + "NoVerify-RSA_PKCS1_MD5_SHA1", 10949 config: Config{ 10950 MaxVersion: ver.version, 10951 Credential: &rsaCertificate, 10952 Bugs: ProtocolBugs{ 10953 IgnorePeerSignatureAlgorithmPreferences: true, 10954 AlwaysSignAsLegacyVersion: true, 10955 SendSignatureAlgorithm: signatureRSAPKCS1WithMD5AndSHA1, 10956 }, 10957 }, 10958 shimCertificate: &rsaCertificate, 10959 flags: []string{ 10960 "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithMD5AndSHA1)), 10961 // Include a valid algorithm as well, to avoid an empty list 10962 // if filtered out. 10963 "-verify-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)), 10964 "-require-any-client-certificate", 10965 }, 10966 shouldFail: true, 10967 expectedError: ":WRONG_SIGNATURE_TYPE:", 10968 }) 10969 } 10970 } 10971 10972 // Test that, when there are no signature algorithms in common in TLS 10973 // 1.2, the server will still consider the legacy RSA key exchange. 10974 testCases = append(testCases, testCase{ 10975 testType: serverTest, 10976 name: "NoCommonSignatureAlgorithms-TLS12-Fallback", 10977 config: Config{ 10978 MaxVersion: VersionTLS12, 10979 CipherSuites: []uint16{ 10980 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 10981 TLS_RSA_WITH_AES_128_GCM_SHA256, 10982 }, 10983 VerifySignatureAlgorithms: []signatureAlgorithm{ 10984 signatureECDSAWithP256AndSHA256, 10985 }, 10986 }, 10987 expectations: connectionExpectations{ 10988 cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, 10989 }, 10990 }) 10991} 10992 10993// timeouts is the retransmit schedule for BoringSSL. It doubles and 10994// caps at 60 seconds. On the 13th timeout, it gives up. 10995var timeouts = []time.Duration{ 10996 1 * time.Second, 10997 2 * time.Second, 10998 4 * time.Second, 10999 8 * time.Second, 11000 16 * time.Second, 11001 32 * time.Second, 11002 60 * time.Second, 11003 60 * time.Second, 11004 60 * time.Second, 11005 60 * time.Second, 11006 60 * time.Second, 11007 60 * time.Second, 11008 60 * time.Second, 11009} 11010 11011// shortTimeouts is an alternate set of timeouts which would occur if the 11012// initial timeout duration was set to 250ms. 11013var shortTimeouts = []time.Duration{ 11014 250 * time.Millisecond, 11015 500 * time.Millisecond, 11016 1 * time.Second, 11017 2 * time.Second, 11018 4 * time.Second, 11019 8 * time.Second, 11020 16 * time.Second, 11021 32 * time.Second, 11022 60 * time.Second, 11023 60 * time.Second, 11024 60 * time.Second, 11025 60 * time.Second, 11026 60 * time.Second, 11027} 11028 11029func addDTLSRetransmitTests() { 11030 // These tests work by coordinating some behavior on both the shim and 11031 // the runner. 11032 // 11033 // TimeoutSchedule configures the runner to send a series of timeout 11034 // opcodes to the shim (see packetAdaptor) immediately before reading 11035 // each peer handshake flight N. The timeout opcode both simulates a 11036 // timeout in the shim and acts as a synchronization point to help the 11037 // runner bracket each handshake flight. 11038 // 11039 // We assume the shim does not read from the channel eagerly. It must 11040 // first wait until it has sent flight N and is ready to receive 11041 // handshake flight N+1. At this point, it will process the timeout 11042 // opcode. It must then immediately respond with a timeout ACK and act 11043 // as if the shim was idle for the specified amount of time. 11044 // 11045 // The runner then drops all packets received before the ACK and 11046 // continues waiting for flight N. This ordering results in one attempt 11047 // at sending flight N to be dropped. For the test to complete, the 11048 // shim must send flight N again, testing that the shim implements DTLS 11049 // retransmit on a timeout. 11050 11051 // TODO(davidben): Add DTLS 1.3 versions of these tests. There will 11052 // likely be more epochs to cross and the final message's retransmit may 11053 // be more complex. 11054 11055 // Test that this is indeed the timeout schedule. Stress all 11056 // four patterns of handshake. 11057 for i := 1; i < len(timeouts); i++ { 11058 number := strconv.Itoa(i) 11059 testCases = append(testCases, testCase{ 11060 protocol: dtls, 11061 name: "DTLS-Retransmit-Client-" + number, 11062 config: Config{ 11063 MaxVersion: VersionTLS12, 11064 Bugs: ProtocolBugs{ 11065 TimeoutSchedule: timeouts[:i], 11066 }, 11067 }, 11068 resumeSession: true, 11069 flags: []string{"-async"}, 11070 }) 11071 testCases = append(testCases, testCase{ 11072 protocol: dtls, 11073 testType: serverTest, 11074 name: "DTLS-Retransmit-Server-" + number, 11075 config: Config{ 11076 MaxVersion: VersionTLS12, 11077 Bugs: ProtocolBugs{ 11078 TimeoutSchedule: timeouts[:i], 11079 }, 11080 }, 11081 resumeSession: true, 11082 flags: []string{"-async"}, 11083 }) 11084 } 11085 11086 // Test that exceeding the timeout schedule hits a read 11087 // timeout. 11088 testCases = append(testCases, testCase{ 11089 protocol: dtls, 11090 name: "DTLS-Retransmit-Timeout", 11091 config: Config{ 11092 MaxVersion: VersionTLS12, 11093 Bugs: ProtocolBugs{ 11094 TimeoutSchedule: timeouts, 11095 }, 11096 }, 11097 resumeSession: true, 11098 flags: []string{"-async"}, 11099 shouldFail: true, 11100 expectedError: ":READ_TIMEOUT_EXPIRED:", 11101 }) 11102 11103 // Test that timeout handling has a fudge factor, due to API 11104 // problems. 11105 testCases = append(testCases, testCase{ 11106 protocol: dtls, 11107 name: "DTLS-Retransmit-Fudge", 11108 config: Config{ 11109 MaxVersion: VersionTLS12, 11110 Bugs: ProtocolBugs{ 11111 TimeoutSchedule: []time.Duration{ 11112 timeouts[0] - 10*time.Millisecond, 11113 }, 11114 }, 11115 }, 11116 resumeSession: true, 11117 flags: []string{"-async"}, 11118 }) 11119 11120 // Test that the final Finished retransmitting isn't 11121 // duplicated if the peer badly fragments everything. 11122 testCases = append(testCases, testCase{ 11123 testType: serverTest, 11124 protocol: dtls, 11125 name: "DTLS-Retransmit-Fragmented", 11126 config: Config{ 11127 MaxVersion: VersionTLS12, 11128 Bugs: ProtocolBugs{ 11129 TimeoutSchedule: []time.Duration{timeouts[0]}, 11130 MaxHandshakeRecordLength: 2, 11131 }, 11132 }, 11133 flags: []string{"-async"}, 11134 }) 11135 11136 // Test the timeout schedule when a shorter initial timeout duration is set. 11137 testCases = append(testCases, testCase{ 11138 protocol: dtls, 11139 name: "DTLS-Retransmit-Short-Client", 11140 config: Config{ 11141 MaxVersion: VersionTLS12, 11142 Bugs: ProtocolBugs{ 11143 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1], 11144 }, 11145 }, 11146 resumeSession: true, 11147 flags: []string{ 11148 "-async", 11149 "-initial-timeout-duration-ms", "250", 11150 }, 11151 }) 11152 testCases = append(testCases, testCase{ 11153 protocol: dtls, 11154 testType: serverTest, 11155 name: "DTLS-Retransmit-Short-Server", 11156 config: Config{ 11157 MaxVersion: VersionTLS12, 11158 Bugs: ProtocolBugs{ 11159 TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1], 11160 }, 11161 }, 11162 resumeSession: true, 11163 flags: []string{ 11164 "-async", 11165 "-initial-timeout-duration-ms", "250", 11166 }, 11167 }) 11168 11169 // If the shim sends the last Finished (server full or client resume 11170 // handshakes), it must retransmit that Finished when it sees a 11171 // post-handshake penultimate Finished from the runner. The above tests 11172 // cover this. Conversely, if the shim sends the penultimate Finished 11173 // (client full or server resume), test that it does not retransmit. 11174 testCases = append(testCases, testCase{ 11175 protocol: dtls, 11176 testType: clientTest, 11177 name: "DTLS-StrayRetransmitFinished-ClientFull", 11178 config: Config{ 11179 MaxVersion: VersionTLS12, 11180 Bugs: ProtocolBugs{ 11181 RetransmitFinished: true, 11182 }, 11183 }, 11184 }) 11185 testCases = append(testCases, testCase{ 11186 protocol: dtls, 11187 testType: serverTest, 11188 name: "DTLS-StrayRetransmitFinished-ServerResume", 11189 config: Config{ 11190 MaxVersion: VersionTLS12, 11191 }, 11192 resumeConfig: &Config{ 11193 MaxVersion: VersionTLS12, 11194 Bugs: ProtocolBugs{ 11195 RetransmitFinished: true, 11196 }, 11197 }, 11198 resumeSession: true, 11199 }) 11200} 11201 11202func addExportKeyingMaterialTests() { 11203 for _, vers := range tlsVersions { 11204 testCases = append(testCases, testCase{ 11205 name: "ExportKeyingMaterial-" + vers.name, 11206 config: Config{ 11207 MaxVersion: vers.version, 11208 }, 11209 // Test the exporter in both initial and resumption 11210 // handshakes. 11211 resumeSession: true, 11212 exportKeyingMaterial: 1024, 11213 exportLabel: "label", 11214 exportContext: "context", 11215 useExportContext: true, 11216 }) 11217 testCases = append(testCases, testCase{ 11218 name: "ExportKeyingMaterial-NoContext-" + vers.name, 11219 config: Config{ 11220 MaxVersion: vers.version, 11221 }, 11222 exportKeyingMaterial: 1024, 11223 }) 11224 testCases = append(testCases, testCase{ 11225 name: "ExportKeyingMaterial-EmptyContext-" + vers.name, 11226 config: Config{ 11227 MaxVersion: vers.version, 11228 }, 11229 exportKeyingMaterial: 1024, 11230 useExportContext: true, 11231 }) 11232 testCases = append(testCases, testCase{ 11233 name: "ExportKeyingMaterial-Small-" + vers.name, 11234 config: Config{ 11235 MaxVersion: vers.version, 11236 }, 11237 exportKeyingMaterial: 1, 11238 exportLabel: "label", 11239 exportContext: "context", 11240 useExportContext: true, 11241 }) 11242 11243 if vers.version >= VersionTLS13 { 11244 // Test the exporters do not work while the client is 11245 // sending 0-RTT data. 11246 testCases = append(testCases, testCase{ 11247 name: "NoEarlyKeyingMaterial-Client-InEarlyData-" + vers.name, 11248 config: Config{ 11249 MaxVersion: vers.version, 11250 }, 11251 resumeSession: true, 11252 earlyData: true, 11253 flags: []string{ 11254 "-on-resume-export-keying-material", "1024", 11255 "-on-resume-export-label", "label", 11256 "-on-resume-export-context", "context", 11257 }, 11258 shouldFail: true, 11259 expectedError: ":HANDSHAKE_NOT_COMPLETE:", 11260 }) 11261 11262 // Test the normal exporter on the server in half-RTT. 11263 testCases = append(testCases, testCase{ 11264 testType: serverTest, 11265 name: "ExportKeyingMaterial-Server-HalfRTT-" + vers.name, 11266 config: Config{ 11267 MaxVersion: vers.version, 11268 Bugs: ProtocolBugs{ 11269 // The shim writes exported data immediately after 11270 // the handshake returns, so disable the built-in 11271 // early data test. 11272 SendEarlyData: [][]byte{}, 11273 ExpectHalfRTTData: [][]byte{}, 11274 }, 11275 }, 11276 resumeSession: true, 11277 earlyData: true, 11278 exportKeyingMaterial: 1024, 11279 exportLabel: "label", 11280 exportContext: "context", 11281 useExportContext: true, 11282 }) 11283 } 11284 } 11285 11286 // Exporters work during a False Start. 11287 testCases = append(testCases, testCase{ 11288 name: "ExportKeyingMaterial-FalseStart", 11289 config: Config{ 11290 MaxVersion: VersionTLS12, 11291 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11292 NextProtos: []string{"foo"}, 11293 Bugs: ProtocolBugs{ 11294 ExpectFalseStart: true, 11295 }, 11296 }, 11297 flags: []string{ 11298 "-false-start", 11299 "-advertise-alpn", "\x03foo", 11300 "-expect-alpn", "foo", 11301 }, 11302 shimWritesFirst: true, 11303 exportKeyingMaterial: 1024, 11304 exportLabel: "label", 11305 exportContext: "context", 11306 useExportContext: true, 11307 }) 11308 11309 // Exporters do not work in the middle of a renegotiation. Test this by 11310 // triggering the exporter after every SSL_read call and configuring the 11311 // shim to run asynchronously. 11312 testCases = append(testCases, testCase{ 11313 name: "ExportKeyingMaterial-Renegotiate", 11314 config: Config{ 11315 MaxVersion: VersionTLS12, 11316 }, 11317 renegotiate: 1, 11318 flags: []string{ 11319 "-async", 11320 "-use-exporter-between-reads", 11321 "-renegotiate-freely", 11322 "-expect-total-renegotiations", "1", 11323 }, 11324 shouldFail: true, 11325 expectedError: "failed to export keying material", 11326 }) 11327} 11328 11329func addExportTrafficSecretsTests() { 11330 for _, cipherSuite := range []testCipherSuite{ 11331 // Test a SHA-256 and SHA-384 based cipher suite. 11332 {"AEAD-AES128-GCM-SHA256", TLS_AES_128_GCM_SHA256}, 11333 {"AEAD-AES256-GCM-SHA384", TLS_AES_256_GCM_SHA384}, 11334 } { 11335 11336 testCases = append(testCases, testCase{ 11337 name: "ExportTrafficSecrets-" + cipherSuite.name, 11338 config: Config{ 11339 MinVersion: VersionTLS13, 11340 CipherSuites: []uint16{cipherSuite.id}, 11341 }, 11342 exportTrafficSecrets: true, 11343 }) 11344 } 11345} 11346 11347func addTLSUniqueTests() { 11348 for _, isClient := range []bool{false, true} { 11349 for _, isResumption := range []bool{false, true} { 11350 for _, hasEMS := range []bool{false, true} { 11351 var suffix string 11352 if isResumption { 11353 suffix = "Resume-" 11354 } else { 11355 suffix = "Full-" 11356 } 11357 11358 if hasEMS { 11359 suffix += "EMS-" 11360 } else { 11361 suffix += "NoEMS-" 11362 } 11363 11364 if isClient { 11365 suffix += "Client" 11366 } else { 11367 suffix += "Server" 11368 } 11369 11370 test := testCase{ 11371 name: "TLSUnique-" + suffix, 11372 testTLSUnique: true, 11373 config: Config{ 11374 MaxVersion: VersionTLS12, 11375 Bugs: ProtocolBugs{ 11376 NoExtendedMasterSecret: !hasEMS, 11377 }, 11378 }, 11379 } 11380 11381 if isResumption { 11382 test.resumeSession = true 11383 test.resumeConfig = &Config{ 11384 MaxVersion: VersionTLS12, 11385 Bugs: ProtocolBugs{ 11386 NoExtendedMasterSecret: !hasEMS, 11387 }, 11388 } 11389 } 11390 11391 if isResumption && !hasEMS { 11392 test.shouldFail = true 11393 test.expectedError = "failed to get tls-unique" 11394 } 11395 11396 testCases = append(testCases, test) 11397 } 11398 } 11399 } 11400} 11401 11402func addCustomExtensionTests() { 11403 // Test an unknown extension from the server. 11404 testCases = append(testCases, testCase{ 11405 testType: clientTest, 11406 name: "UnknownExtension-Client", 11407 config: Config{ 11408 MaxVersion: VersionTLS12, 11409 Bugs: ProtocolBugs{ 11410 CustomExtension: "custom extension", 11411 }, 11412 }, 11413 shouldFail: true, 11414 expectedError: ":UNEXPECTED_EXTENSION:", 11415 expectedLocalError: "remote error: unsupported extension", 11416 }) 11417 testCases = append(testCases, testCase{ 11418 testType: clientTest, 11419 name: "UnknownExtension-Client-TLS13", 11420 config: Config{ 11421 MaxVersion: VersionTLS13, 11422 Bugs: ProtocolBugs{ 11423 CustomExtension: "custom extension", 11424 }, 11425 }, 11426 shouldFail: true, 11427 expectedError: ":UNEXPECTED_EXTENSION:", 11428 expectedLocalError: "remote error: unsupported extension", 11429 }) 11430 testCases = append(testCases, testCase{ 11431 testType: clientTest, 11432 name: "UnknownUnencryptedExtension-Client-TLS13", 11433 config: Config{ 11434 MaxVersion: VersionTLS13, 11435 Bugs: ProtocolBugs{ 11436 CustomUnencryptedExtension: "custom extension", 11437 }, 11438 }, 11439 shouldFail: true, 11440 expectedError: ":UNEXPECTED_EXTENSION:", 11441 // The shim must send an alert, but alerts at this point do not 11442 // get successfully decrypted by the runner. 11443 expectedLocalError: "local error: bad record MAC", 11444 }) 11445 testCases = append(testCases, testCase{ 11446 testType: clientTest, 11447 name: "UnexpectedUnencryptedExtension-Client-TLS13", 11448 config: Config{ 11449 MaxVersion: VersionTLS13, 11450 Bugs: ProtocolBugs{ 11451 SendUnencryptedALPN: "foo", 11452 }, 11453 }, 11454 flags: []string{ 11455 "-advertise-alpn", "\x03foo\x03bar", 11456 }, 11457 shouldFail: true, 11458 expectedError: ":UNEXPECTED_EXTENSION:", 11459 // The shim must send an alert, but alerts at this point do not 11460 // get successfully decrypted by the runner. 11461 expectedLocalError: "local error: bad record MAC", 11462 }) 11463 11464 // Test a known but unoffered extension from the server. 11465 testCases = append(testCases, testCase{ 11466 testType: clientTest, 11467 name: "UnofferedExtension-Client", 11468 config: Config{ 11469 MaxVersion: VersionTLS12, 11470 Bugs: ProtocolBugs{ 11471 SendALPN: "alpn", 11472 }, 11473 }, 11474 shouldFail: true, 11475 expectedError: ":UNEXPECTED_EXTENSION:", 11476 expectedLocalError: "remote error: unsupported extension", 11477 }) 11478 testCases = append(testCases, testCase{ 11479 testType: clientTest, 11480 name: "UnofferedExtension-Client-TLS13", 11481 config: Config{ 11482 MaxVersion: VersionTLS13, 11483 Bugs: ProtocolBugs{ 11484 SendALPN: "alpn", 11485 }, 11486 }, 11487 shouldFail: true, 11488 expectedError: ":UNEXPECTED_EXTENSION:", 11489 expectedLocalError: "remote error: unsupported extension", 11490 }) 11491} 11492 11493func addRSAClientKeyExchangeTests() { 11494 for bad := RSABadValue(1); bad < NumRSABadValues; bad++ { 11495 testCases = append(testCases, testCase{ 11496 testType: serverTest, 11497 name: fmt.Sprintf("BadRSAClientKeyExchange-%d", bad), 11498 config: Config{ 11499 // Ensure the ClientHello version and final 11500 // version are different, to detect if the 11501 // server uses the wrong one. 11502 MaxVersion: VersionTLS11, 11503 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA}, 11504 Bugs: ProtocolBugs{ 11505 BadRSAClientKeyExchange: bad, 11506 }, 11507 }, 11508 shouldFail: true, 11509 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 11510 }) 11511 } 11512 11513 // The server must compare whatever was in ClientHello.version for the 11514 // RSA premaster. 11515 testCases = append(testCases, testCase{ 11516 testType: serverTest, 11517 name: "SendClientVersion-RSA", 11518 config: Config{ 11519 CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}, 11520 Bugs: ProtocolBugs{ 11521 SendClientVersion: 0x1234, 11522 }, 11523 }, 11524 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 11525 }) 11526} 11527 11528var testCurves = []struct { 11529 name string 11530 id CurveID 11531}{ 11532 {"P-224", CurveP224}, 11533 {"P-256", CurveP256}, 11534 {"P-384", CurveP384}, 11535 {"P-521", CurveP521}, 11536 {"X25519", CurveX25519}, 11537 {"Kyber", CurveX25519Kyber768}, 11538} 11539 11540const bogusCurve = 0x1234 11541 11542func isPqGroup(r CurveID) bool { 11543 return r == CurveX25519Kyber768 11544} 11545 11546func addCurveTests() { 11547 for _, curve := range testCurves { 11548 for _, ver := range tlsVersions { 11549 if isPqGroup(curve.id) && ver.version < VersionTLS13 { 11550 continue 11551 } 11552 11553 suffix := curve.name + "-" + ver.name 11554 11555 testCases = append(testCases, testCase{ 11556 name: "CurveTest-Client-" + suffix, 11557 config: Config{ 11558 MaxVersion: ver.version, 11559 CipherSuites: []uint16{ 11560 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11561 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11562 TLS_AES_256_GCM_SHA384, 11563 }, 11564 CurvePreferences: []CurveID{curve.id}, 11565 }, 11566 flags: append( 11567 []string{"-expect-curve-id", strconv.Itoa(int(curve.id))}, 11568 flagInts("-curves", shimConfig.AllCurves)..., 11569 ), 11570 expectations: connectionExpectations{ 11571 curveID: curve.id, 11572 }, 11573 }) 11574 testCases = append(testCases, testCase{ 11575 testType: serverTest, 11576 name: "CurveTest-Server-" + suffix, 11577 config: Config{ 11578 MaxVersion: ver.version, 11579 CipherSuites: []uint16{ 11580 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11581 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11582 TLS_AES_256_GCM_SHA384, 11583 }, 11584 CurvePreferences: []CurveID{curve.id}, 11585 }, 11586 flags: append( 11587 []string{"-expect-curve-id", strconv.Itoa(int(curve.id))}, 11588 flagInts("-curves", shimConfig.AllCurves)..., 11589 ), 11590 expectations: connectionExpectations{ 11591 curveID: curve.id, 11592 }, 11593 }) 11594 11595 if curve.id != CurveX25519 && !isPqGroup(curve.id) { 11596 testCases = append(testCases, testCase{ 11597 name: "CurveTest-Client-Compressed-" + suffix, 11598 config: Config{ 11599 MaxVersion: ver.version, 11600 CipherSuites: []uint16{ 11601 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11602 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11603 TLS_AES_256_GCM_SHA384, 11604 }, 11605 CurvePreferences: []CurveID{curve.id}, 11606 Bugs: ProtocolBugs{ 11607 SendCompressedCoordinates: true, 11608 }, 11609 }, 11610 flags: flagInts("-curves", shimConfig.AllCurves), 11611 shouldFail: true, 11612 expectedError: ":BAD_ECPOINT:", 11613 }) 11614 testCases = append(testCases, testCase{ 11615 testType: serverTest, 11616 name: "CurveTest-Server-Compressed-" + suffix, 11617 config: Config{ 11618 MaxVersion: ver.version, 11619 CipherSuites: []uint16{ 11620 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11621 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11622 TLS_AES_256_GCM_SHA384, 11623 }, 11624 CurvePreferences: []CurveID{curve.id}, 11625 Bugs: ProtocolBugs{ 11626 SendCompressedCoordinates: true, 11627 }, 11628 }, 11629 flags: flagInts("-curves", shimConfig.AllCurves), 11630 shouldFail: true, 11631 expectedError: ":BAD_ECPOINT:", 11632 }) 11633 } 11634 } 11635 } 11636 11637 // The server must be tolerant to bogus curves. 11638 testCases = append(testCases, testCase{ 11639 testType: serverTest, 11640 name: "UnknownCurve", 11641 config: Config{ 11642 MaxVersion: VersionTLS12, 11643 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11644 CurvePreferences: []CurveID{bogusCurve, CurveP256}, 11645 }, 11646 }) 11647 11648 // The server must be tolerant to bogus curves. 11649 testCases = append(testCases, testCase{ 11650 testType: serverTest, 11651 name: "UnknownCurve-TLS13", 11652 config: Config{ 11653 MaxVersion: VersionTLS13, 11654 CurvePreferences: []CurveID{bogusCurve, CurveP256}, 11655 }, 11656 }) 11657 11658 // The server must not consider ECDHE ciphers when there are no 11659 // supported curves. 11660 testCases = append(testCases, testCase{ 11661 testType: serverTest, 11662 name: "NoSupportedCurves", 11663 config: Config{ 11664 MaxVersion: VersionTLS12, 11665 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11666 Bugs: ProtocolBugs{ 11667 NoSupportedCurves: true, 11668 }, 11669 }, 11670 shouldFail: true, 11671 expectedError: ":NO_SHARED_CIPHER:", 11672 }) 11673 testCases = append(testCases, testCase{ 11674 testType: serverTest, 11675 name: "NoSupportedCurves-TLS13", 11676 config: Config{ 11677 MaxVersion: VersionTLS13, 11678 Bugs: ProtocolBugs{ 11679 NoSupportedCurves: true, 11680 }, 11681 }, 11682 shouldFail: true, 11683 expectedError: ":NO_SHARED_GROUP:", 11684 }) 11685 11686 // The server must fall back to another cipher when there are no 11687 // supported curves. 11688 testCases = append(testCases, testCase{ 11689 testType: serverTest, 11690 name: "NoCommonCurves", 11691 config: Config{ 11692 MaxVersion: VersionTLS12, 11693 CipherSuites: []uint16{ 11694 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11695 TLS_RSA_WITH_AES_128_GCM_SHA256, 11696 }, 11697 CurvePreferences: []CurveID{CurveP224}, 11698 }, 11699 expectations: connectionExpectations{ 11700 cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, 11701 }, 11702 }) 11703 11704 // The client must reject bogus curves and disabled curves. 11705 testCases = append(testCases, testCase{ 11706 name: "BadECDHECurve", 11707 config: Config{ 11708 MaxVersion: VersionTLS12, 11709 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11710 Bugs: ProtocolBugs{ 11711 SendCurve: bogusCurve, 11712 }, 11713 }, 11714 shouldFail: true, 11715 expectedError: ":WRONG_CURVE:", 11716 }) 11717 testCases = append(testCases, testCase{ 11718 name: "BadECDHECurve-TLS13", 11719 config: Config{ 11720 MaxVersion: VersionTLS13, 11721 Bugs: ProtocolBugs{ 11722 SendCurve: bogusCurve, 11723 }, 11724 }, 11725 shouldFail: true, 11726 expectedError: ":WRONG_CURVE:", 11727 }) 11728 11729 testCases = append(testCases, testCase{ 11730 name: "UnsupportedCurve", 11731 config: Config{ 11732 MaxVersion: VersionTLS12, 11733 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11734 CurvePreferences: []CurveID{CurveP256}, 11735 Bugs: ProtocolBugs{ 11736 IgnorePeerCurvePreferences: true, 11737 }, 11738 }, 11739 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 11740 shouldFail: true, 11741 expectedError: ":WRONG_CURVE:", 11742 }) 11743 11744 testCases = append(testCases, testCase{ 11745 // TODO(davidben): Add a TLS 1.3 version where 11746 // HelloRetryRequest requests an unsupported curve. 11747 name: "UnsupportedCurve-ServerHello-TLS13", 11748 config: Config{ 11749 MaxVersion: VersionTLS13, 11750 CurvePreferences: []CurveID{CurveP384}, 11751 Bugs: ProtocolBugs{ 11752 SendCurve: CurveP256, 11753 }, 11754 }, 11755 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 11756 shouldFail: true, 11757 expectedError: ":WRONG_CURVE:", 11758 }) 11759 11760 // Test invalid curve points. 11761 testCases = append(testCases, testCase{ 11762 name: "InvalidECDHPoint-Client", 11763 config: Config{ 11764 MaxVersion: VersionTLS12, 11765 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11766 CurvePreferences: []CurveID{CurveP256}, 11767 Bugs: ProtocolBugs{ 11768 InvalidECDHPoint: true, 11769 }, 11770 }, 11771 shouldFail: true, 11772 expectedError: ":BAD_ECPOINT:", 11773 }) 11774 testCases = append(testCases, testCase{ 11775 name: "InvalidECDHPoint-Client-TLS13", 11776 config: Config{ 11777 MaxVersion: VersionTLS13, 11778 CurvePreferences: []CurveID{CurveP256}, 11779 Bugs: ProtocolBugs{ 11780 InvalidECDHPoint: true, 11781 }, 11782 }, 11783 shouldFail: true, 11784 expectedError: ":BAD_ECPOINT:", 11785 }) 11786 testCases = append(testCases, testCase{ 11787 testType: serverTest, 11788 name: "InvalidECDHPoint-Server", 11789 config: Config{ 11790 MaxVersion: VersionTLS12, 11791 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11792 CurvePreferences: []CurveID{CurveP256}, 11793 Bugs: ProtocolBugs{ 11794 InvalidECDHPoint: true, 11795 }, 11796 }, 11797 shouldFail: true, 11798 expectedError: ":BAD_ECPOINT:", 11799 }) 11800 testCases = append(testCases, testCase{ 11801 testType: serverTest, 11802 name: "InvalidECDHPoint-Server-TLS13", 11803 config: Config{ 11804 MaxVersion: VersionTLS13, 11805 CurvePreferences: []CurveID{CurveP256}, 11806 Bugs: ProtocolBugs{ 11807 InvalidECDHPoint: true, 11808 }, 11809 }, 11810 shouldFail: true, 11811 expectedError: ":BAD_ECPOINT:", 11812 }) 11813 11814 // The previous curve ID should be reported on TLS 1.2 resumption. 11815 testCases = append(testCases, testCase{ 11816 name: "CurveID-Resume-Client", 11817 config: Config{ 11818 MaxVersion: VersionTLS12, 11819 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11820 CurvePreferences: []CurveID{CurveX25519}, 11821 }, 11822 flags: []string{"-expect-curve-id", strconv.Itoa(int(CurveX25519))}, 11823 resumeSession: true, 11824 }) 11825 testCases = append(testCases, testCase{ 11826 testType: serverTest, 11827 name: "CurveID-Resume-Server", 11828 config: Config{ 11829 MaxVersion: VersionTLS12, 11830 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 11831 CurvePreferences: []CurveID{CurveX25519}, 11832 }, 11833 flags: []string{"-expect-curve-id", strconv.Itoa(int(CurveX25519))}, 11834 resumeSession: true, 11835 }) 11836 11837 // TLS 1.3 allows resuming at a differet curve. If this happens, the new 11838 // one should be reported. 11839 testCases = append(testCases, testCase{ 11840 name: "CurveID-Resume-Client-TLS13", 11841 config: Config{ 11842 MaxVersion: VersionTLS13, 11843 CurvePreferences: []CurveID{CurveX25519}, 11844 }, 11845 resumeConfig: &Config{ 11846 MaxVersion: VersionTLS13, 11847 CurvePreferences: []CurveID{CurveP256}, 11848 }, 11849 flags: []string{ 11850 "-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)), 11851 "-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)), 11852 }, 11853 resumeSession: true, 11854 }) 11855 testCases = append(testCases, testCase{ 11856 testType: serverTest, 11857 name: "CurveID-Resume-Server-TLS13", 11858 config: Config{ 11859 MaxVersion: VersionTLS13, 11860 CurvePreferences: []CurveID{CurveX25519}, 11861 }, 11862 resumeConfig: &Config{ 11863 MaxVersion: VersionTLS13, 11864 CurvePreferences: []CurveID{CurveP256}, 11865 }, 11866 flags: []string{ 11867 "-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)), 11868 "-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)), 11869 }, 11870 resumeSession: true, 11871 }) 11872 11873 // Server-sent point formats are legal in TLS 1.2, but not in TLS 1.3. 11874 testCases = append(testCases, testCase{ 11875 name: "PointFormat-ServerHello-TLS12", 11876 config: Config{ 11877 MaxVersion: VersionTLS12, 11878 Bugs: ProtocolBugs{ 11879 SendSupportedPointFormats: []byte{pointFormatUncompressed}, 11880 }, 11881 }, 11882 }) 11883 testCases = append(testCases, testCase{ 11884 name: "PointFormat-EncryptedExtensions-TLS13", 11885 config: Config{ 11886 MaxVersion: VersionTLS13, 11887 Bugs: ProtocolBugs{ 11888 SendSupportedPointFormats: []byte{pointFormatUncompressed}, 11889 }, 11890 }, 11891 shouldFail: true, 11892 expectedError: ":ERROR_PARSING_EXTENSION:", 11893 }) 11894 11895 // Server-sent supported groups/curves are legal in TLS 1.3. They are 11896 // illegal in TLS 1.2, but some servers send them anyway, so we must 11897 // tolerate them. 11898 testCases = append(testCases, testCase{ 11899 name: "SupportedCurves-ServerHello-TLS12", 11900 config: Config{ 11901 MaxVersion: VersionTLS12, 11902 Bugs: ProtocolBugs{ 11903 SendServerSupportedCurves: true, 11904 }, 11905 }, 11906 }) 11907 testCases = append(testCases, testCase{ 11908 name: "SupportedCurves-EncryptedExtensions-TLS13", 11909 config: Config{ 11910 MaxVersion: VersionTLS13, 11911 Bugs: ProtocolBugs{ 11912 SendServerSupportedCurves: true, 11913 }, 11914 }, 11915 }) 11916 11917 // Test that we tolerate unknown point formats, as long as 11918 // pointFormatUncompressed is present. Limit ciphers to ECDHE ciphers to 11919 // check they are still functional. 11920 testCases = append(testCases, testCase{ 11921 name: "PointFormat-Client-Tolerance", 11922 config: Config{ 11923 MaxVersion: VersionTLS12, 11924 Bugs: ProtocolBugs{ 11925 SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime}, 11926 }, 11927 }, 11928 }) 11929 testCases = append(testCases, testCase{ 11930 testType: serverTest, 11931 name: "PointFormat-Server-Tolerance", 11932 config: Config{ 11933 MaxVersion: VersionTLS12, 11934 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 11935 Bugs: ProtocolBugs{ 11936 SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime}, 11937 }, 11938 }, 11939 }) 11940 11941 // Test TLS 1.2 does not require the point format extension to be 11942 // present. 11943 testCases = append(testCases, testCase{ 11944 name: "PointFormat-Client-Missing", 11945 config: Config{ 11946 MaxVersion: VersionTLS12, 11947 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 11948 Bugs: ProtocolBugs{ 11949 SendSupportedPointFormats: []byte{}, 11950 }, 11951 }, 11952 }) 11953 testCases = append(testCases, testCase{ 11954 testType: serverTest, 11955 name: "PointFormat-Server-Missing", 11956 config: Config{ 11957 MaxVersion: VersionTLS12, 11958 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256}, 11959 Bugs: ProtocolBugs{ 11960 SendSupportedPointFormats: []byte{}, 11961 }, 11962 }, 11963 }) 11964 11965 // If the point format extension is present, uncompressed points must be 11966 // offered. BoringSSL requires this whether or not ECDHE is used. 11967 testCases = append(testCases, testCase{ 11968 name: "PointFormat-Client-MissingUncompressed", 11969 config: Config{ 11970 MaxVersion: VersionTLS12, 11971 Bugs: ProtocolBugs{ 11972 SendSupportedPointFormats: []byte{pointFormatCompressedPrime}, 11973 }, 11974 }, 11975 shouldFail: true, 11976 expectedError: ":ERROR_PARSING_EXTENSION:", 11977 }) 11978 testCases = append(testCases, testCase{ 11979 testType: serverTest, 11980 name: "PointFormat-Server-MissingUncompressed", 11981 config: Config{ 11982 MaxVersion: VersionTLS12, 11983 Bugs: ProtocolBugs{ 11984 SendSupportedPointFormats: []byte{pointFormatCompressedPrime}, 11985 }, 11986 }, 11987 shouldFail: true, 11988 expectedError: ":ERROR_PARSING_EXTENSION:", 11989 }) 11990 11991 // Implementations should mask off the high order bit in X25519. 11992 testCases = append(testCases, testCase{ 11993 name: "SetX25519HighBit", 11994 config: Config{ 11995 CipherSuites: []uint16{ 11996 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 11997 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 11998 TLS_AES_128_GCM_SHA256, 11999 }, 12000 CurvePreferences: []CurveID{CurveX25519}, 12001 Bugs: ProtocolBugs{ 12002 SetX25519HighBit: true, 12003 }, 12004 }, 12005 }) 12006 12007 // Kyber should not be offered by a TLS < 1.3 client. 12008 testCases = append(testCases, testCase{ 12009 name: "KyberNotInTLS12", 12010 config: Config{ 12011 Bugs: ProtocolBugs{ 12012 FailIfKyberOffered: true, 12013 }, 12014 }, 12015 flags: []string{ 12016 "-max-version", strconv.Itoa(VersionTLS12), 12017 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12018 "-curves", strconv.Itoa(int(CurveX25519)), 12019 }, 12020 }) 12021 12022 // Kyber should not crash a TLS < 1.3 client if the server mistakenly 12023 // selects it. 12024 testCases = append(testCases, testCase{ 12025 name: "KyberNotAcceptedByTLS12Client", 12026 config: Config{ 12027 Bugs: ProtocolBugs{ 12028 SendCurve: CurveX25519Kyber768, 12029 }, 12030 }, 12031 flags: []string{ 12032 "-max-version", strconv.Itoa(VersionTLS12), 12033 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12034 "-curves", strconv.Itoa(int(CurveX25519)), 12035 }, 12036 shouldFail: true, 12037 expectedError: ":WRONG_CURVE:", 12038 }) 12039 12040 // Kyber should not be offered by default as a client. 12041 testCases = append(testCases, testCase{ 12042 name: "KyberNotEnabledByDefaultInClients", 12043 config: Config{ 12044 MinVersion: VersionTLS13, 12045 Bugs: ProtocolBugs{ 12046 FailIfKyberOffered: true, 12047 }, 12048 }, 12049 }) 12050 12051 // If Kyber is offered, both X25519 and Kyber should have a key-share. 12052 testCases = append(testCases, testCase{ 12053 name: "NotJustKyberKeyShare", 12054 config: Config{ 12055 MinVersion: VersionTLS13, 12056 Bugs: ProtocolBugs{ 12057 ExpectedKeyShares: []CurveID{CurveX25519Kyber768, CurveX25519}, 12058 }, 12059 }, 12060 flags: []string{ 12061 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12062 "-curves", strconv.Itoa(int(CurveX25519)), 12063 // Cannot expect Kyber until we have a Go implementation of it. 12064 // "-expect-curve-id", strconv.Itoa(int(CurveX25519Kyber768)), 12065 }, 12066 }) 12067 12068 // ... and the other way around 12069 testCases = append(testCases, testCase{ 12070 name: "KyberKeyShareIncludedSecond", 12071 config: Config{ 12072 MinVersion: VersionTLS13, 12073 Bugs: ProtocolBugs{ 12074 ExpectedKeyShares: []CurveID{CurveX25519, CurveX25519Kyber768}, 12075 }, 12076 }, 12077 flags: []string{ 12078 "-curves", strconv.Itoa(int(CurveX25519)), 12079 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12080 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 12081 }, 12082 }) 12083 12084 // ... and even if there's another curve in the middle because it's the 12085 // first classical and first post-quantum "curves" that get key shares 12086 // included. 12087 testCases = append(testCases, testCase{ 12088 name: "KyberKeyShareIncludedThird", 12089 config: Config{ 12090 MinVersion: VersionTLS13, 12091 Bugs: ProtocolBugs{ 12092 ExpectedKeyShares: []CurveID{CurveX25519, CurveX25519Kyber768}, 12093 }, 12094 }, 12095 flags: []string{ 12096 "-curves", strconv.Itoa(int(CurveX25519)), 12097 "-curves", strconv.Itoa(int(CurveP256)), 12098 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12099 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 12100 }, 12101 }) 12102 12103 // If Kyber is the only configured curve, the key share is sent. 12104 testCases = append(testCases, testCase{ 12105 name: "JustConfiguringKyberWorks", 12106 config: Config{ 12107 MinVersion: VersionTLS13, 12108 Bugs: ProtocolBugs{ 12109 ExpectedKeyShares: []CurveID{CurveX25519Kyber768}, 12110 }, 12111 }, 12112 flags: []string{ 12113 "-curves", strconv.Itoa(int(CurveX25519Kyber768)), 12114 "-expect-curve-id", strconv.Itoa(int(CurveX25519Kyber768)), 12115 }, 12116 }) 12117 12118 // As a server, Kyber is not yet supported by default. 12119 testCases = append(testCases, testCase{ 12120 testType: serverTest, 12121 name: "KyberNotEnabledByDefaultForAServer", 12122 config: Config{ 12123 MinVersion: VersionTLS13, 12124 CurvePreferences: []CurveID{CurveX25519Kyber768, CurveX25519}, 12125 DefaultCurves: []CurveID{CurveX25519Kyber768}, 12126 }, 12127 flags: []string{ 12128 "-server-preference", 12129 "-expect-curve-id", strconv.Itoa(int(CurveX25519)), 12130 }, 12131 }) 12132 12133 // In TLS 1.2, the curve list is also used to signal ECDSA curves. 12134 testCases = append(testCases, testCase{ 12135 testType: serverTest, 12136 name: "CheckECDSACurve-TLS12", 12137 config: Config{ 12138 MinVersion: VersionTLS12, 12139 MaxVersion: VersionTLS12, 12140 CurvePreferences: []CurveID{CurveP384}, 12141 }, 12142 shimCertificate: &ecdsaP256Certificate, 12143 shouldFail: true, 12144 expectedError: ":WRONG_CURVE:", 12145 }) 12146 12147 // This behavior may, temporarily, be disabled with a flag. 12148 testCases = append(testCases, testCase{ 12149 testType: serverTest, 12150 name: "NoCheckECDSACurve-TLS12", 12151 config: Config{ 12152 MinVersion: VersionTLS12, 12153 MaxVersion: VersionTLS12, 12154 CurvePreferences: []CurveID{CurveP384}, 12155 }, 12156 shimCertificate: &ecdsaP256Certificate, 12157 flags: []string{"-no-check-ecdsa-curve"}, 12158 }) 12159 12160 // If the ECDSA certificate is ineligible due to a curve mismatch, the 12161 // server may still consider a PSK cipher suite. 12162 testCases = append(testCases, testCase{ 12163 testType: serverTest, 12164 name: "CheckECDSACurve-PSK-TLS12", 12165 config: Config{ 12166 MinVersion: VersionTLS12, 12167 MaxVersion: VersionTLS12, 12168 CipherSuites: []uint16{ 12169 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 12170 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 12171 }, 12172 CurvePreferences: []CurveID{CurveP384}, 12173 PreSharedKey: []byte("12345"), 12174 PreSharedKeyIdentity: "luggage combo", 12175 }, 12176 shimCertificate: &ecdsaP256Certificate, 12177 expectations: connectionExpectations{ 12178 cipher: TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 12179 }, 12180 flags: []string{ 12181 "-psk", "12345", 12182 "-psk-identity", "luggage combo", 12183 }, 12184 }) 12185 12186 // In TLS 1.3, the curve list only controls ECDH. 12187 testCases = append(testCases, testCase{ 12188 testType: serverTest, 12189 name: "CheckECDSACurve-NotApplicable-TLS13", 12190 config: Config{ 12191 MinVersion: VersionTLS13, 12192 MaxVersion: VersionTLS13, 12193 CurvePreferences: []CurveID{CurveP384}, 12194 }, 12195 shimCertificate: &ecdsaP256Certificate, 12196 }) 12197} 12198 12199func addTLS13RecordTests() { 12200 testCases = append(testCases, testCase{ 12201 name: "TLS13-RecordPadding", 12202 config: Config{ 12203 MaxVersion: VersionTLS13, 12204 MinVersion: VersionTLS13, 12205 Bugs: ProtocolBugs{ 12206 RecordPadding: 10, 12207 }, 12208 }, 12209 }) 12210 12211 testCases = append(testCases, testCase{ 12212 name: "TLS13-EmptyRecords", 12213 config: Config{ 12214 MaxVersion: VersionTLS13, 12215 MinVersion: VersionTLS13, 12216 Bugs: ProtocolBugs{ 12217 OmitRecordContents: true, 12218 }, 12219 }, 12220 shouldFail: true, 12221 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 12222 }) 12223 12224 testCases = append(testCases, testCase{ 12225 name: "TLS13-OnlyPadding", 12226 config: Config{ 12227 MaxVersion: VersionTLS13, 12228 MinVersion: VersionTLS13, 12229 Bugs: ProtocolBugs{ 12230 OmitRecordContents: true, 12231 RecordPadding: 10, 12232 }, 12233 }, 12234 shouldFail: true, 12235 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 12236 }) 12237 12238 testCases = append(testCases, testCase{ 12239 name: "TLS13-WrongOuterRecord", 12240 config: Config{ 12241 MaxVersion: VersionTLS13, 12242 MinVersion: VersionTLS13, 12243 Bugs: ProtocolBugs{ 12244 OuterRecordType: recordTypeHandshake, 12245 }, 12246 }, 12247 shouldFail: true, 12248 expectedError: ":INVALID_OUTER_RECORD_TYPE:", 12249 }) 12250} 12251 12252func addSessionTicketTests() { 12253 testCases = append(testCases, testCase{ 12254 // In TLS 1.2 and below, empty NewSessionTicket messages 12255 // mean the server changed its mind on sending a ticket. 12256 name: "SendEmptySessionTicket", 12257 config: Config{ 12258 MaxVersion: VersionTLS12, 12259 Bugs: ProtocolBugs{ 12260 SendEmptySessionTicket: true, 12261 }, 12262 }, 12263 flags: []string{"-expect-no-session"}, 12264 }) 12265 12266 // Test that the server ignores unknown PSK modes. 12267 testCases = append(testCases, testCase{ 12268 testType: serverTest, 12269 name: "TLS13-SendUnknownModeSessionTicket-Server", 12270 config: Config{ 12271 MaxVersion: VersionTLS13, 12272 Bugs: ProtocolBugs{ 12273 SendPSKKeyExchangeModes: []byte{0x1a, pskDHEKEMode, 0x2a}, 12274 }, 12275 }, 12276 resumeSession: true, 12277 expectations: connectionExpectations{ 12278 version: VersionTLS13, 12279 }, 12280 }) 12281 12282 // Test that the server does not send session tickets with no matching key exchange mode. 12283 testCases = append(testCases, testCase{ 12284 testType: serverTest, 12285 name: "TLS13-ExpectNoSessionTicketOnBadKEMode-Server", 12286 config: Config{ 12287 MaxVersion: VersionTLS13, 12288 Bugs: ProtocolBugs{ 12289 SendPSKKeyExchangeModes: []byte{0x1a}, 12290 ExpectNoNewSessionTicket: true, 12291 }, 12292 }, 12293 }) 12294 12295 // Test that the server does not accept a session with no matching key exchange mode. 12296 testCases = append(testCases, testCase{ 12297 testType: serverTest, 12298 name: "TLS13-SendBadKEModeSessionTicket-Server", 12299 config: Config{ 12300 MaxVersion: VersionTLS13, 12301 }, 12302 resumeConfig: &Config{ 12303 MaxVersion: VersionTLS13, 12304 Bugs: ProtocolBugs{ 12305 SendPSKKeyExchangeModes: []byte{0x1a}, 12306 }, 12307 }, 12308 resumeSession: true, 12309 expectResumeRejected: true, 12310 }) 12311 12312 // Test that the server rejects ClientHellos with pre_shared_key but without 12313 // psk_key_exchange_modes. 12314 testCases = append(testCases, testCase{ 12315 testType: serverTest, 12316 name: "TLS13-SendNoKEMModesWithPSK-Server", 12317 config: Config{ 12318 MaxVersion: VersionTLS13, 12319 }, 12320 resumeConfig: &Config{ 12321 MaxVersion: VersionTLS13, 12322 Bugs: ProtocolBugs{ 12323 SendPSKKeyExchangeModes: []byte{}, 12324 }, 12325 }, 12326 resumeSession: true, 12327 shouldFail: true, 12328 expectedLocalError: "remote error: missing extension", 12329 expectedError: ":MISSING_EXTENSION:", 12330 }) 12331 12332 // Test that the client ticket age is sent correctly. 12333 testCases = append(testCases, testCase{ 12334 testType: clientTest, 12335 name: "TLS13-TestValidTicketAge-Client", 12336 config: Config{ 12337 MaxVersion: VersionTLS13, 12338 Bugs: ProtocolBugs{ 12339 ExpectTicketAge: 10 * time.Second, 12340 }, 12341 }, 12342 resumeSession: true, 12343 flags: []string{ 12344 "-resumption-delay", "10", 12345 }, 12346 }) 12347 12348 // Test that the client ticket age is enforced. 12349 testCases = append(testCases, testCase{ 12350 testType: clientTest, 12351 name: "TLS13-TestBadTicketAge-Client", 12352 config: Config{ 12353 MaxVersion: VersionTLS13, 12354 Bugs: ProtocolBugs{ 12355 ExpectTicketAge: 1000 * time.Second, 12356 }, 12357 }, 12358 resumeSession: true, 12359 shouldFail: true, 12360 expectedLocalError: "tls: invalid ticket age", 12361 }) 12362 12363 // Test that the server's ticket age skew reporting works. 12364 testCases = append(testCases, testCase{ 12365 testType: serverTest, 12366 name: "TLS13-TicketAgeSkew-Forward", 12367 config: Config{ 12368 MaxVersion: VersionTLS13, 12369 Bugs: ProtocolBugs{ 12370 SendTicketAge: 15 * time.Second, 12371 }, 12372 }, 12373 resumeSession: true, 12374 resumeRenewedSession: true, 12375 flags: []string{ 12376 "-resumption-delay", "10", 12377 "-expect-ticket-age-skew", "5", 12378 }, 12379 }) 12380 testCases = append(testCases, testCase{ 12381 testType: serverTest, 12382 name: "TLS13-TicketAgeSkew-Backward", 12383 config: Config{ 12384 MaxVersion: VersionTLS13, 12385 Bugs: ProtocolBugs{ 12386 SendTicketAge: 5 * time.Second, 12387 }, 12388 }, 12389 resumeSession: true, 12390 resumeRenewedSession: true, 12391 flags: []string{ 12392 "-resumption-delay", "10", 12393 "-expect-ticket-age-skew", "-5", 12394 }, 12395 }) 12396 12397 // Test that ticket age skew up to 60 seconds in either direction is accepted. 12398 testCases = append(testCases, testCase{ 12399 testType: serverTest, 12400 name: "TLS13-TicketAgeSkew-Forward-60-Accept", 12401 config: Config{ 12402 MaxVersion: VersionTLS13, 12403 Bugs: ProtocolBugs{ 12404 SendTicketAge: 70 * time.Second, 12405 }, 12406 }, 12407 resumeSession: true, 12408 earlyData: true, 12409 flags: []string{ 12410 "-resumption-delay", "10", 12411 "-expect-ticket-age-skew", "60", 12412 }, 12413 }) 12414 testCases = append(testCases, testCase{ 12415 testType: serverTest, 12416 name: "TLS13-TicketAgeSkew-Backward-60-Accept", 12417 config: Config{ 12418 MaxVersion: VersionTLS13, 12419 Bugs: ProtocolBugs{ 12420 SendTicketAge: 10 * time.Second, 12421 }, 12422 }, 12423 resumeSession: true, 12424 earlyData: true, 12425 flags: []string{ 12426 "-resumption-delay", "70", 12427 "-expect-ticket-age-skew", "-60", 12428 }, 12429 }) 12430 12431 // Test that ticket age skew beyond 60 seconds in either direction is rejected. 12432 testCases = append(testCases, testCase{ 12433 testType: serverTest, 12434 name: "TLS13-TicketAgeSkew-Forward-61-Reject", 12435 config: Config{ 12436 MaxVersion: VersionTLS13, 12437 Bugs: ProtocolBugs{ 12438 SendTicketAge: 71 * time.Second, 12439 }, 12440 }, 12441 resumeSession: true, 12442 earlyData: true, 12443 expectEarlyDataRejected: true, 12444 flags: []string{ 12445 "-resumption-delay", "10", 12446 "-expect-ticket-age-skew", "61", 12447 "-on-resume-expect-early-data-reason", "ticket_age_skew", 12448 }, 12449 }) 12450 testCases = append(testCases, testCase{ 12451 testType: serverTest, 12452 name: "TLS13-TicketAgeSkew-Backward-61-Reject", 12453 config: Config{ 12454 MaxVersion: VersionTLS13, 12455 Bugs: ProtocolBugs{ 12456 SendTicketAge: 10 * time.Second, 12457 }, 12458 }, 12459 resumeSession: true, 12460 earlyData: true, 12461 expectEarlyDataRejected: true, 12462 flags: []string{ 12463 "-resumption-delay", "71", 12464 "-expect-ticket-age-skew", "-61", 12465 "-on-resume-expect-early-data-reason", "ticket_age_skew", 12466 }, 12467 }) 12468 12469 testCases = append(testCases, testCase{ 12470 testType: clientTest, 12471 name: "TLS13-SendTicketEarlyDataSupport", 12472 config: Config{ 12473 MaxVersion: VersionTLS13, 12474 MaxEarlyDataSize: 16384, 12475 }, 12476 flags: []string{ 12477 "-enable-early-data", 12478 "-expect-ticket-supports-early-data", 12479 }, 12480 }) 12481 12482 // Test that 0-RTT tickets are still recorded as such when early data is disabled overall. 12483 testCases = append(testCases, testCase{ 12484 testType: clientTest, 12485 name: "TLS13-SendTicketEarlyDataSupport-Disabled", 12486 config: Config{ 12487 MaxVersion: VersionTLS13, 12488 MaxEarlyDataSize: 16384, 12489 }, 12490 flags: []string{ 12491 "-expect-ticket-supports-early-data", 12492 }, 12493 }) 12494 12495 testCases = append(testCases, testCase{ 12496 testType: clientTest, 12497 name: "TLS13-DuplicateTicketEarlyDataSupport", 12498 config: Config{ 12499 MaxVersion: VersionTLS13, 12500 MaxEarlyDataSize: 16384, 12501 Bugs: ProtocolBugs{ 12502 DuplicateTicketEarlyData: true, 12503 }, 12504 }, 12505 shouldFail: true, 12506 expectedError: ":DUPLICATE_EXTENSION:", 12507 expectedLocalError: "remote error: illegal parameter", 12508 }) 12509 12510 testCases = append(testCases, testCase{ 12511 testType: serverTest, 12512 name: "TLS13-ExpectTicketEarlyDataSupport", 12513 config: Config{ 12514 MaxVersion: VersionTLS13, 12515 Bugs: ProtocolBugs{ 12516 ExpectTicketEarlyData: true, 12517 }, 12518 }, 12519 flags: []string{ 12520 "-enable-early-data", 12521 }, 12522 }) 12523 12524 // Test that, in TLS 1.3, the server-offered NewSessionTicket lifetime 12525 // is honored. 12526 testCases = append(testCases, testCase{ 12527 testType: clientTest, 12528 name: "TLS13-HonorServerSessionTicketLifetime", 12529 config: Config{ 12530 MaxVersion: VersionTLS13, 12531 Bugs: ProtocolBugs{ 12532 SendTicketLifetime: 20 * time.Second, 12533 }, 12534 }, 12535 flags: []string{ 12536 "-resumption-delay", "19", 12537 }, 12538 resumeSession: true, 12539 }) 12540 testCases = append(testCases, testCase{ 12541 testType: clientTest, 12542 name: "TLS13-HonorServerSessionTicketLifetime-2", 12543 config: Config{ 12544 MaxVersion: VersionTLS13, 12545 Bugs: ProtocolBugs{ 12546 SendTicketLifetime: 20 * time.Second, 12547 // The client should not offer the expired session. 12548 ExpectNoTLS13PSK: true, 12549 }, 12550 }, 12551 flags: []string{ 12552 "-resumption-delay", "21", 12553 }, 12554 resumeSession: true, 12555 expectResumeRejected: true, 12556 }) 12557 12558 for _, ver := range tlsVersions { 12559 // Prior to TLS 1.3, disabling session tickets enables session IDs. 12560 useStatefulResumption := ver.version < VersionTLS13 12561 12562 // SSL_OP_NO_TICKET implies the server must not mint any tickets. 12563 testCases = append(testCases, testCase{ 12564 testType: serverTest, 12565 name: ver.name + "-NoTicket-NoMint", 12566 config: Config{ 12567 MinVersion: ver.version, 12568 MaxVersion: ver.version, 12569 Bugs: ProtocolBugs{ 12570 ExpectNoNewSessionTicket: true, 12571 RequireSessionIDs: useStatefulResumption, 12572 }, 12573 }, 12574 resumeSession: useStatefulResumption, 12575 flags: []string{"-no-ticket"}, 12576 }) 12577 12578 // SSL_OP_NO_TICKET implies the server must not accept any tickets. 12579 testCases = append(testCases, testCase{ 12580 testType: serverTest, 12581 name: ver.name + "-NoTicket-NoAccept", 12582 config: Config{ 12583 MinVersion: ver.version, 12584 MaxVersion: ver.version, 12585 }, 12586 resumeSession: true, 12587 expectResumeRejected: true, 12588 // Set SSL_OP_NO_TICKET on the second connection, after the first 12589 // has established tickets. 12590 flags: []string{"-on-resume-no-ticket"}, 12591 }) 12592 } 12593} 12594 12595func addChangeCipherSpecTests() { 12596 // Test missing ChangeCipherSpecs. 12597 testCases = append(testCases, testCase{ 12598 name: "SkipChangeCipherSpec-Client", 12599 config: Config{ 12600 MaxVersion: VersionTLS12, 12601 Bugs: ProtocolBugs{ 12602 SkipChangeCipherSpec: true, 12603 }, 12604 }, 12605 shouldFail: true, 12606 expectedError: ":UNEXPECTED_RECORD:", 12607 }) 12608 testCases = append(testCases, testCase{ 12609 testType: serverTest, 12610 name: "SkipChangeCipherSpec-Server", 12611 config: Config{ 12612 MaxVersion: VersionTLS12, 12613 Bugs: ProtocolBugs{ 12614 SkipChangeCipherSpec: true, 12615 }, 12616 }, 12617 shouldFail: true, 12618 expectedError: ":UNEXPECTED_RECORD:", 12619 }) 12620 testCases = append(testCases, testCase{ 12621 testType: serverTest, 12622 name: "SkipChangeCipherSpec-Server-NPN", 12623 config: Config{ 12624 MaxVersion: VersionTLS12, 12625 NextProtos: []string{"bar"}, 12626 Bugs: ProtocolBugs{ 12627 SkipChangeCipherSpec: true, 12628 }, 12629 }, 12630 flags: []string{ 12631 "-advertise-npn", "\x03foo\x03bar\x03baz", 12632 }, 12633 shouldFail: true, 12634 expectedError: ":UNEXPECTED_RECORD:", 12635 }) 12636 12637 // Test synchronization between the handshake and ChangeCipherSpec. 12638 // Partial post-CCS handshake messages before ChangeCipherSpec should be 12639 // rejected. Test both with and without handshake packing to handle both 12640 // when the partial post-CCS message is in its own record and when it is 12641 // attached to the pre-CCS message. 12642 for _, packed := range []bool{false, true} { 12643 var suffix string 12644 if packed { 12645 suffix = "-Packed" 12646 } 12647 12648 testCases = append(testCases, testCase{ 12649 name: "FragmentAcrossChangeCipherSpec-Client" + suffix, 12650 config: Config{ 12651 MaxVersion: VersionTLS12, 12652 Bugs: ProtocolBugs{ 12653 FragmentAcrossChangeCipherSpec: true, 12654 PackHandshakeFlight: packed, 12655 }, 12656 }, 12657 shouldFail: true, 12658 expectedError: ":UNEXPECTED_RECORD:", 12659 }) 12660 testCases = append(testCases, testCase{ 12661 name: "FragmentAcrossChangeCipherSpec-Client-Resume" + suffix, 12662 config: Config{ 12663 MaxVersion: VersionTLS12, 12664 }, 12665 resumeSession: true, 12666 resumeConfig: &Config{ 12667 MaxVersion: VersionTLS12, 12668 Bugs: ProtocolBugs{ 12669 FragmentAcrossChangeCipherSpec: true, 12670 PackHandshakeFlight: packed, 12671 }, 12672 }, 12673 shouldFail: true, 12674 expectedError: ":UNEXPECTED_RECORD:", 12675 }) 12676 testCases = append(testCases, testCase{ 12677 testType: serverTest, 12678 name: "FragmentAcrossChangeCipherSpec-Server" + suffix, 12679 config: Config{ 12680 MaxVersion: VersionTLS12, 12681 Bugs: ProtocolBugs{ 12682 FragmentAcrossChangeCipherSpec: true, 12683 PackHandshakeFlight: packed, 12684 }, 12685 }, 12686 shouldFail: true, 12687 expectedError: ":UNEXPECTED_RECORD:", 12688 }) 12689 testCases = append(testCases, testCase{ 12690 testType: serverTest, 12691 name: "FragmentAcrossChangeCipherSpec-Server-Resume" + suffix, 12692 config: Config{ 12693 MaxVersion: VersionTLS12, 12694 }, 12695 resumeSession: true, 12696 resumeConfig: &Config{ 12697 MaxVersion: VersionTLS12, 12698 Bugs: ProtocolBugs{ 12699 FragmentAcrossChangeCipherSpec: true, 12700 PackHandshakeFlight: packed, 12701 }, 12702 }, 12703 shouldFail: true, 12704 expectedError: ":UNEXPECTED_RECORD:", 12705 }) 12706 testCases = append(testCases, testCase{ 12707 testType: serverTest, 12708 name: "FragmentAcrossChangeCipherSpec-Server-NPN" + suffix, 12709 config: Config{ 12710 MaxVersion: VersionTLS12, 12711 NextProtos: []string{"bar"}, 12712 Bugs: ProtocolBugs{ 12713 FragmentAcrossChangeCipherSpec: true, 12714 PackHandshakeFlight: packed, 12715 }, 12716 }, 12717 flags: []string{ 12718 "-advertise-npn", "\x03foo\x03bar\x03baz", 12719 }, 12720 shouldFail: true, 12721 expectedError: ":UNEXPECTED_RECORD:", 12722 }) 12723 } 12724 12725 // In TLS 1.2 resumptions, the client sends ClientHello in the first flight 12726 // and ChangeCipherSpec + Finished in the second flight. Test the server's 12727 // behavior when the Finished message is fragmented across not only 12728 // ChangeCipherSpec but also the flight boundary. 12729 testCases = append(testCases, testCase{ 12730 testType: serverTest, 12731 name: "PartialClientFinishedWithClientHello-TLS12-Resume", 12732 config: Config{ 12733 MaxVersion: VersionTLS12, 12734 }, 12735 resumeConfig: &Config{ 12736 MaxVersion: VersionTLS12, 12737 Bugs: ProtocolBugs{ 12738 PartialClientFinishedWithClientHello: true, 12739 }, 12740 }, 12741 resumeSession: true, 12742 shouldFail: true, 12743 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12744 expectedLocalError: "remote error: unexpected message", 12745 }) 12746 12747 // In TLS 1.2 full handshakes without tickets, the server's first flight ends 12748 // with ServerHelloDone and the second flight is ChangeCipherSpec + Finished. 12749 // Test the client's behavior when the Finished message is fragmented across 12750 // not only ChangeCipherSpec but also the flight boundary. 12751 testCases = append(testCases, testCase{ 12752 testType: clientTest, 12753 name: "PartialFinishedWithServerHelloDone", 12754 config: Config{ 12755 MaxVersion: VersionTLS12, 12756 SessionTicketsDisabled: true, 12757 Bugs: ProtocolBugs{ 12758 PartialFinishedWithServerHelloDone: true, 12759 }, 12760 }, 12761 shouldFail: true, 12762 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12763 expectedLocalError: "remote error: unexpected message", 12764 }) 12765 12766 // Test that, in DTLS, ChangeCipherSpec is not allowed when there are 12767 // messages in the handshake queue. Do this by testing the server 12768 // reading the client Finished, reversing the flight so Finished comes 12769 // first. 12770 testCases = append(testCases, testCase{ 12771 protocol: dtls, 12772 testType: serverTest, 12773 name: "SendUnencryptedFinished-DTLS", 12774 config: Config{ 12775 MaxVersion: VersionTLS12, 12776 Bugs: ProtocolBugs{ 12777 SendUnencryptedFinished: true, 12778 ReverseHandshakeFragments: true, 12779 }, 12780 }, 12781 shouldFail: true, 12782 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12783 }) 12784 12785 // Test synchronization between encryption changes and the handshake in 12786 // TLS 1.3, where ChangeCipherSpec is implicit. 12787 testCases = append(testCases, testCase{ 12788 name: "PartialEncryptedExtensionsWithServerHello", 12789 config: Config{ 12790 MaxVersion: VersionTLS13, 12791 Bugs: ProtocolBugs{ 12792 PartialEncryptedExtensionsWithServerHello: true, 12793 }, 12794 }, 12795 shouldFail: true, 12796 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12797 }) 12798 testCases = append(testCases, testCase{ 12799 testType: serverTest, 12800 name: "PartialClientFinishedWithClientHello", 12801 config: Config{ 12802 MaxVersion: VersionTLS13, 12803 Bugs: ProtocolBugs{ 12804 PartialClientFinishedWithClientHello: true, 12805 }, 12806 }, 12807 shouldFail: true, 12808 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12809 }) 12810 testCases = append(testCases, testCase{ 12811 testType: serverTest, 12812 name: "PartialClientFinishedWithSecondClientHello", 12813 config: Config{ 12814 MaxVersion: VersionTLS13, 12815 // Trigger a curve-based HelloRetryRequest. 12816 DefaultCurves: []CurveID{}, 12817 Bugs: ProtocolBugs{ 12818 PartialClientFinishedWithSecondClientHello: true, 12819 }, 12820 }, 12821 shouldFail: true, 12822 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12823 }) 12824 testCases = append(testCases, testCase{ 12825 testType: serverTest, 12826 name: "PartialEndOfEarlyDataWithClientHello", 12827 config: Config{ 12828 MaxVersion: VersionTLS13, 12829 }, 12830 resumeConfig: &Config{ 12831 MaxVersion: VersionTLS13, 12832 Bugs: ProtocolBugs{ 12833 PartialEndOfEarlyDataWithClientHello: true, 12834 }, 12835 }, 12836 resumeSession: true, 12837 earlyData: true, 12838 shouldFail: true, 12839 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12840 }) 12841 12842 // Test that early ChangeCipherSpecs are handled correctly. 12843 testCases = append(testCases, testCase{ 12844 testType: serverTest, 12845 name: "EarlyChangeCipherSpec-server-1", 12846 config: Config{ 12847 MaxVersion: VersionTLS12, 12848 Bugs: ProtocolBugs{ 12849 EarlyChangeCipherSpec: 1, 12850 }, 12851 }, 12852 shouldFail: true, 12853 expectedError: ":UNEXPECTED_RECORD:", 12854 }) 12855 testCases = append(testCases, testCase{ 12856 testType: serverTest, 12857 name: "EarlyChangeCipherSpec-server-2", 12858 config: Config{ 12859 MaxVersion: VersionTLS12, 12860 Bugs: ProtocolBugs{ 12861 EarlyChangeCipherSpec: 2, 12862 }, 12863 }, 12864 shouldFail: true, 12865 expectedError: ":UNEXPECTED_RECORD:", 12866 }) 12867 testCases = append(testCases, testCase{ 12868 protocol: dtls, 12869 name: "StrayChangeCipherSpec", 12870 config: Config{ 12871 // TODO(davidben): Once DTLS 1.3 exists, test 12872 // that stray ChangeCipherSpec messages are 12873 // rejected. 12874 MaxVersion: VersionTLS12, 12875 Bugs: ProtocolBugs{ 12876 StrayChangeCipherSpec: true, 12877 }, 12878 }, 12879 }) 12880 12881 // Test that reordered ChangeCipherSpecs are tolerated. 12882 testCases = append(testCases, testCase{ 12883 protocol: dtls, 12884 name: "ReorderChangeCipherSpec-DTLS-Client", 12885 config: Config{ 12886 MaxVersion: VersionTLS12, 12887 Bugs: ProtocolBugs{ 12888 ReorderChangeCipherSpec: true, 12889 }, 12890 }, 12891 resumeSession: true, 12892 }) 12893 testCases = append(testCases, testCase{ 12894 testType: serverTest, 12895 protocol: dtls, 12896 name: "ReorderChangeCipherSpec-DTLS-Server", 12897 config: Config{ 12898 MaxVersion: VersionTLS12, 12899 Bugs: ProtocolBugs{ 12900 ReorderChangeCipherSpec: true, 12901 }, 12902 }, 12903 resumeSession: true, 12904 }) 12905 12906 // Test that the contents of ChangeCipherSpec are checked. 12907 testCases = append(testCases, testCase{ 12908 name: "BadChangeCipherSpec-1", 12909 config: Config{ 12910 MaxVersion: VersionTLS12, 12911 Bugs: ProtocolBugs{ 12912 BadChangeCipherSpec: []byte{2}, 12913 }, 12914 }, 12915 shouldFail: true, 12916 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12917 }) 12918 testCases = append(testCases, testCase{ 12919 name: "BadChangeCipherSpec-2", 12920 config: Config{ 12921 MaxVersion: VersionTLS12, 12922 Bugs: ProtocolBugs{ 12923 BadChangeCipherSpec: []byte{1, 1}, 12924 }, 12925 }, 12926 shouldFail: true, 12927 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12928 }) 12929 testCases = append(testCases, testCase{ 12930 protocol: dtls, 12931 name: "BadChangeCipherSpec-DTLS-1", 12932 config: Config{ 12933 MaxVersion: VersionTLS12, 12934 Bugs: ProtocolBugs{ 12935 BadChangeCipherSpec: []byte{2}, 12936 }, 12937 }, 12938 shouldFail: true, 12939 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12940 }) 12941 testCases = append(testCases, testCase{ 12942 protocol: dtls, 12943 name: "BadChangeCipherSpec-DTLS-2", 12944 config: Config{ 12945 MaxVersion: VersionTLS12, 12946 Bugs: ProtocolBugs{ 12947 BadChangeCipherSpec: []byte{1, 1}, 12948 }, 12949 }, 12950 shouldFail: true, 12951 expectedError: ":BAD_CHANGE_CIPHER_SPEC:", 12952 }) 12953} 12954 12955// addEndOfFlightTests adds tests where the runner adds extra data in the final 12956// record of each handshake flight. Depending on the implementation strategy, 12957// this data may be carried over to the next flight (assuming no key change) or 12958// may be rejected. To avoid differences with split handshakes and generally 12959// reject misbehavior, BoringSSL treats this as an error. When possible, these 12960// tests pull the extra data from the subsequent flight to distinguish the data 12961// being carried over from a general syntax error. 12962// 12963// These tests are similar to tests in |addChangeCipherSpecTests| that send 12964// extra data at key changes. Not all key changes are at the end of a flight and 12965// not all flights end at a key change. 12966func addEndOfFlightTests() { 12967 // TLS 1.3 client handshakes. 12968 // 12969 // Data following the second TLS 1.3 ClientHello is covered by 12970 // PartialClientFinishedWithClientHello, 12971 // PartialClientFinishedWithSecondClientHello, and 12972 // PartialEndOfEarlyDataWithClientHello in |addChangeCipherSpecTests|. 12973 testCases = append(testCases, testCase{ 12974 testType: serverTest, 12975 name: "PartialSecondClientHelloAfterFirst", 12976 config: Config{ 12977 MaxVersion: VersionTLS13, 12978 // Trigger a curve-based HelloRetryRequest. 12979 DefaultCurves: []CurveID{}, 12980 Bugs: ProtocolBugs{ 12981 PartialSecondClientHelloAfterFirst: true, 12982 }, 12983 }, 12984 shouldFail: true, 12985 expectedError: ":EXCESS_HANDSHAKE_DATA:", 12986 expectedLocalError: "remote error: unexpected message", 12987 }) 12988 12989 // TLS 1.3 server handshakes. 12990 testCases = append(testCases, testCase{ 12991 testType: clientTest, 12992 name: "PartialServerHelloWithHelloRetryRequest", 12993 config: Config{ 12994 MaxVersion: VersionTLS13, 12995 // P-384 requires HelloRetryRequest in BoringSSL. 12996 CurvePreferences: []CurveID{CurveP384}, 12997 Bugs: ProtocolBugs{ 12998 PartialServerHelloWithHelloRetryRequest: true, 12999 }, 13000 }, 13001 shouldFail: true, 13002 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13003 expectedLocalError: "remote error: unexpected message", 13004 }) 13005 13006 // TLS 1.2 client handshakes. 13007 testCases = append(testCases, testCase{ 13008 testType: serverTest, 13009 name: "PartialClientKeyExchangeWithClientHello", 13010 config: Config{ 13011 MaxVersion: VersionTLS12, 13012 Bugs: ProtocolBugs{ 13013 PartialClientKeyExchangeWithClientHello: true, 13014 }, 13015 }, 13016 shouldFail: true, 13017 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13018 expectedLocalError: "remote error: unexpected message", 13019 }) 13020 13021 // TLS 1.2 server handshakes. 13022 testCases = append(testCases, testCase{ 13023 testType: clientTest, 13024 name: "PartialNewSessionTicketWithServerHelloDone", 13025 config: Config{ 13026 MaxVersion: VersionTLS12, 13027 Bugs: ProtocolBugs{ 13028 PartialNewSessionTicketWithServerHelloDone: true, 13029 }, 13030 }, 13031 shouldFail: true, 13032 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13033 expectedLocalError: "remote error: unexpected message", 13034 }) 13035 13036 for _, vers := range tlsVersions { 13037 for _, testType := range []testType{clientTest, serverTest} { 13038 suffix := "-Client" 13039 if testType == serverTest { 13040 suffix = "-Server" 13041 } 13042 suffix += "-" + vers.name 13043 13044 testCases = append(testCases, testCase{ 13045 testType: testType, 13046 name: "TrailingDataWithFinished" + suffix, 13047 config: Config{ 13048 MaxVersion: vers.version, 13049 Bugs: ProtocolBugs{ 13050 TrailingDataWithFinished: true, 13051 }, 13052 }, 13053 shouldFail: true, 13054 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13055 expectedLocalError: "remote error: unexpected message", 13056 }) 13057 testCases = append(testCases, testCase{ 13058 testType: testType, 13059 name: "TrailingDataWithFinished-Resume" + suffix, 13060 config: Config{ 13061 MaxVersion: vers.version, 13062 }, 13063 resumeConfig: &Config{ 13064 MaxVersion: vers.version, 13065 Bugs: ProtocolBugs{ 13066 TrailingDataWithFinished: true, 13067 }, 13068 }, 13069 resumeSession: true, 13070 shouldFail: true, 13071 expectedError: ":EXCESS_HANDSHAKE_DATA:", 13072 expectedLocalError: "remote error: unexpected message", 13073 }) 13074 } 13075 } 13076} 13077 13078type perMessageTest struct { 13079 messageType uint8 13080 test testCase 13081} 13082 13083// makePerMessageTests returns a series of test templates which cover each 13084// message in the TLS handshake. These may be used with bugs like 13085// WrongMessageType to fully test a per-message bug. 13086func makePerMessageTests() []perMessageTest { 13087 var ret []perMessageTest 13088 // The following tests are limited to TLS 1.2, so QUIC is not tested. 13089 for _, protocol := range []protocol{tls, dtls} { 13090 suffix := "-" + protocol.String() 13091 13092 ret = append(ret, perMessageTest{ 13093 messageType: typeClientHello, 13094 test: testCase{ 13095 protocol: protocol, 13096 testType: serverTest, 13097 name: "ClientHello" + suffix, 13098 config: Config{ 13099 MaxVersion: VersionTLS12, 13100 }, 13101 }, 13102 }) 13103 13104 if protocol == dtls { 13105 ret = append(ret, perMessageTest{ 13106 messageType: typeHelloVerifyRequest, 13107 test: testCase{ 13108 protocol: protocol, 13109 name: "HelloVerifyRequest" + suffix, 13110 config: Config{ 13111 MaxVersion: VersionTLS12, 13112 }, 13113 }, 13114 }) 13115 } 13116 13117 ret = append(ret, perMessageTest{ 13118 messageType: typeServerHello, 13119 test: testCase{ 13120 protocol: protocol, 13121 name: "ServerHello" + suffix, 13122 config: Config{ 13123 MaxVersion: VersionTLS12, 13124 }, 13125 }, 13126 }) 13127 13128 ret = append(ret, perMessageTest{ 13129 messageType: typeCertificate, 13130 test: testCase{ 13131 protocol: protocol, 13132 name: "ServerCertificate" + suffix, 13133 config: Config{ 13134 MaxVersion: VersionTLS12, 13135 }, 13136 }, 13137 }) 13138 13139 ret = append(ret, perMessageTest{ 13140 messageType: typeCertificateStatus, 13141 test: testCase{ 13142 protocol: protocol, 13143 name: "CertificateStatus" + suffix, 13144 config: Config{ 13145 MaxVersion: VersionTLS12, 13146 Credential: rsaCertificate.WithOCSP(testOCSPResponse), 13147 }, 13148 flags: []string{"-enable-ocsp-stapling"}, 13149 }, 13150 }) 13151 13152 ret = append(ret, perMessageTest{ 13153 messageType: typeServerKeyExchange, 13154 test: testCase{ 13155 protocol: protocol, 13156 name: "ServerKeyExchange" + suffix, 13157 config: Config{ 13158 MaxVersion: VersionTLS12, 13159 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 13160 }, 13161 }, 13162 }) 13163 13164 ret = append(ret, perMessageTest{ 13165 messageType: typeCertificateRequest, 13166 test: testCase{ 13167 protocol: protocol, 13168 name: "CertificateRequest" + suffix, 13169 config: Config{ 13170 MaxVersion: VersionTLS12, 13171 ClientAuth: RequireAnyClientCert, 13172 }, 13173 }, 13174 }) 13175 13176 ret = append(ret, perMessageTest{ 13177 messageType: typeServerHelloDone, 13178 test: testCase{ 13179 protocol: protocol, 13180 name: "ServerHelloDone" + suffix, 13181 config: Config{ 13182 MaxVersion: VersionTLS12, 13183 }, 13184 }, 13185 }) 13186 13187 ret = append(ret, perMessageTest{ 13188 messageType: typeCertificate, 13189 test: testCase{ 13190 testType: serverTest, 13191 protocol: protocol, 13192 name: "ClientCertificate" + suffix, 13193 config: Config{ 13194 Credential: &rsaCertificate, 13195 MaxVersion: VersionTLS12, 13196 }, 13197 flags: []string{"-require-any-client-certificate"}, 13198 }, 13199 }) 13200 13201 ret = append(ret, perMessageTest{ 13202 messageType: typeCertificateVerify, 13203 test: testCase{ 13204 testType: serverTest, 13205 protocol: protocol, 13206 name: "CertificateVerify" + suffix, 13207 config: Config{ 13208 Credential: &rsaCertificate, 13209 MaxVersion: VersionTLS12, 13210 }, 13211 flags: []string{"-require-any-client-certificate"}, 13212 }, 13213 }) 13214 13215 ret = append(ret, perMessageTest{ 13216 messageType: typeClientKeyExchange, 13217 test: testCase{ 13218 testType: serverTest, 13219 protocol: protocol, 13220 name: "ClientKeyExchange" + suffix, 13221 config: Config{ 13222 MaxVersion: VersionTLS12, 13223 }, 13224 }, 13225 }) 13226 13227 if protocol != dtls { 13228 ret = append(ret, perMessageTest{ 13229 messageType: typeNextProtocol, 13230 test: testCase{ 13231 testType: serverTest, 13232 protocol: protocol, 13233 name: "NextProtocol" + suffix, 13234 config: Config{ 13235 MaxVersion: VersionTLS12, 13236 NextProtos: []string{"bar"}, 13237 }, 13238 flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"}, 13239 }, 13240 }) 13241 13242 ret = append(ret, perMessageTest{ 13243 messageType: typeChannelID, 13244 test: testCase{ 13245 testType: serverTest, 13246 protocol: protocol, 13247 name: "ChannelID" + suffix, 13248 config: Config{ 13249 MaxVersion: VersionTLS12, 13250 ChannelID: &channelIDKey, 13251 }, 13252 flags: []string{ 13253 "-expect-channel-id", 13254 base64FlagValue(channelIDBytes), 13255 }, 13256 }, 13257 }) 13258 } 13259 13260 ret = append(ret, perMessageTest{ 13261 messageType: typeFinished, 13262 test: testCase{ 13263 testType: serverTest, 13264 protocol: protocol, 13265 name: "ClientFinished" + suffix, 13266 config: Config{ 13267 MaxVersion: VersionTLS12, 13268 }, 13269 }, 13270 }) 13271 13272 ret = append(ret, perMessageTest{ 13273 messageType: typeNewSessionTicket, 13274 test: testCase{ 13275 protocol: protocol, 13276 name: "NewSessionTicket" + suffix, 13277 config: Config{ 13278 MaxVersion: VersionTLS12, 13279 }, 13280 }, 13281 }) 13282 13283 ret = append(ret, perMessageTest{ 13284 messageType: typeFinished, 13285 test: testCase{ 13286 protocol: protocol, 13287 name: "ServerFinished" + suffix, 13288 config: Config{ 13289 MaxVersion: VersionTLS12, 13290 }, 13291 }, 13292 }) 13293 13294 } 13295 13296 for _, protocol := range []protocol{tls, quic} { 13297 suffix := "-" + protocol.String() 13298 ret = append(ret, perMessageTest{ 13299 messageType: typeClientHello, 13300 test: testCase{ 13301 testType: serverTest, 13302 protocol: protocol, 13303 name: "TLS13-ClientHello" + suffix, 13304 config: Config{ 13305 MaxVersion: VersionTLS13, 13306 }, 13307 }, 13308 }) 13309 13310 ret = append(ret, perMessageTest{ 13311 messageType: typeServerHello, 13312 test: testCase{ 13313 name: "TLS13-ServerHello" + suffix, 13314 protocol: protocol, 13315 config: Config{ 13316 MaxVersion: VersionTLS13, 13317 }, 13318 }, 13319 }) 13320 13321 ret = append(ret, perMessageTest{ 13322 messageType: typeEncryptedExtensions, 13323 test: testCase{ 13324 name: "TLS13-EncryptedExtensions" + suffix, 13325 protocol: protocol, 13326 config: Config{ 13327 MaxVersion: VersionTLS13, 13328 }, 13329 }, 13330 }) 13331 13332 ret = append(ret, perMessageTest{ 13333 messageType: typeCertificateRequest, 13334 test: testCase{ 13335 name: "TLS13-CertificateRequest" + suffix, 13336 protocol: protocol, 13337 config: Config{ 13338 MaxVersion: VersionTLS13, 13339 ClientAuth: RequireAnyClientCert, 13340 }, 13341 }, 13342 }) 13343 13344 ret = append(ret, perMessageTest{ 13345 messageType: typeCertificate, 13346 test: testCase{ 13347 name: "TLS13-ServerCertificate" + suffix, 13348 protocol: protocol, 13349 config: Config{ 13350 MaxVersion: VersionTLS13, 13351 }, 13352 }, 13353 }) 13354 13355 ret = append(ret, perMessageTest{ 13356 messageType: typeCertificateVerify, 13357 test: testCase{ 13358 name: "TLS13-ServerCertificateVerify" + suffix, 13359 protocol: protocol, 13360 config: Config{ 13361 MaxVersion: VersionTLS13, 13362 }, 13363 }, 13364 }) 13365 13366 ret = append(ret, perMessageTest{ 13367 messageType: typeFinished, 13368 test: testCase{ 13369 name: "TLS13-ServerFinished" + suffix, 13370 protocol: protocol, 13371 config: Config{ 13372 MaxVersion: VersionTLS13, 13373 }, 13374 }, 13375 }) 13376 13377 ret = append(ret, perMessageTest{ 13378 messageType: typeCertificate, 13379 test: testCase{ 13380 testType: serverTest, 13381 protocol: protocol, 13382 name: "TLS13-ClientCertificate" + suffix, 13383 config: Config{ 13384 Credential: &rsaCertificate, 13385 MaxVersion: VersionTLS13, 13386 }, 13387 flags: []string{"-require-any-client-certificate"}, 13388 }, 13389 }) 13390 13391 ret = append(ret, perMessageTest{ 13392 messageType: typeCertificateVerify, 13393 test: testCase{ 13394 testType: serverTest, 13395 protocol: protocol, 13396 name: "TLS13-ClientCertificateVerify" + suffix, 13397 config: Config{ 13398 Credential: &rsaCertificate, 13399 MaxVersion: VersionTLS13, 13400 }, 13401 flags: []string{"-require-any-client-certificate"}, 13402 }, 13403 }) 13404 13405 ret = append(ret, perMessageTest{ 13406 messageType: typeFinished, 13407 test: testCase{ 13408 testType: serverTest, 13409 protocol: protocol, 13410 name: "TLS13-ClientFinished" + suffix, 13411 config: Config{ 13412 MaxVersion: VersionTLS13, 13413 }, 13414 }, 13415 }) 13416 13417 // Only TLS uses EndOfEarlyData. 13418 if protocol == tls { 13419 ret = append(ret, perMessageTest{ 13420 messageType: typeEndOfEarlyData, 13421 test: testCase{ 13422 testType: serverTest, 13423 protocol: protocol, 13424 name: "TLS13-EndOfEarlyData" + suffix, 13425 config: Config{ 13426 MaxVersion: VersionTLS13, 13427 }, 13428 resumeSession: true, 13429 earlyData: true, 13430 }, 13431 }) 13432 } 13433 } 13434 13435 return ret 13436} 13437 13438func addWrongMessageTypeTests() { 13439 for _, t := range makePerMessageTests() { 13440 t.test.name = "WrongMessageType-" + t.test.name 13441 if t.test.resumeConfig != nil { 13442 t.test.resumeConfig.Bugs.SendWrongMessageType = t.messageType 13443 } else { 13444 t.test.config.Bugs.SendWrongMessageType = t.messageType 13445 } 13446 t.test.shouldFail = true 13447 t.test.expectedError = ":UNEXPECTED_MESSAGE:" 13448 t.test.expectedLocalError = "remote error: unexpected message" 13449 13450 if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello { 13451 // In TLS 1.3, if the server believes it has sent ServerHello, 13452 // but the client cannot process it, the client will send an 13453 // unencrypted alert while the server expects encryption. In TLS, 13454 // this is a decryption failure. In QUIC, the encryption levels 13455 // do not match. 13456 if t.test.protocol == quic { 13457 t.test.expectedLocalError = "received record at initial encryption level, but expected handshake" 13458 } else { 13459 t.test.expectedLocalError = "local error: bad record MAC" 13460 } 13461 } 13462 13463 testCases = append(testCases, t.test) 13464 } 13465} 13466 13467func addTrailingMessageDataTests() { 13468 for _, t := range makePerMessageTests() { 13469 t.test.name = "TrailingMessageData-" + t.test.name 13470 if t.test.resumeConfig != nil { 13471 t.test.resumeConfig.Bugs.SendTrailingMessageData = t.messageType 13472 } else { 13473 t.test.config.Bugs.SendTrailingMessageData = t.messageType 13474 } 13475 t.test.shouldFail = true 13476 t.test.expectedError = ":DECODE_ERROR:" 13477 t.test.expectedLocalError = "remote error: error decoding message" 13478 13479 if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello { 13480 // In TLS 1.3, if the server believes it has sent ServerHello, 13481 // but the client cannot process it, the client will send an 13482 // unencrypted alert while the server expects encryption. In TLS, 13483 // this is a decryption failure. In QUIC, the encryption levels 13484 // do not match. 13485 if t.test.protocol == quic { 13486 t.test.expectedLocalError = "received record at initial encryption level, but expected handshake" 13487 } else { 13488 t.test.expectedLocalError = "local error: bad record MAC" 13489 } 13490 } 13491 13492 if t.messageType == typeFinished { 13493 // Bad Finished messages read as the verify data having 13494 // the wrong length. 13495 t.test.expectedError = ":DIGEST_CHECK_FAILED:" 13496 t.test.expectedLocalError = "remote error: error decrypting message" 13497 } 13498 13499 testCases = append(testCases, t.test) 13500 } 13501} 13502 13503func addTLS13HandshakeTests() { 13504 testCases = append(testCases, testCase{ 13505 testType: clientTest, 13506 name: "NegotiatePSKResumption-TLS13", 13507 config: Config{ 13508 MaxVersion: VersionTLS13, 13509 Bugs: ProtocolBugs{ 13510 NegotiatePSKResumption: true, 13511 }, 13512 }, 13513 resumeSession: true, 13514 shouldFail: true, 13515 expectedError: ":MISSING_KEY_SHARE:", 13516 }) 13517 13518 testCases = append(testCases, testCase{ 13519 testType: clientTest, 13520 name: "MissingKeyShare-Client-TLS13", 13521 config: Config{ 13522 MaxVersion: VersionTLS13, 13523 Bugs: ProtocolBugs{ 13524 MissingKeyShare: true, 13525 }, 13526 }, 13527 shouldFail: true, 13528 expectedError: ":MISSING_KEY_SHARE:", 13529 }) 13530 13531 testCases = append(testCases, testCase{ 13532 testType: serverTest, 13533 name: "MissingKeyShare-Server-TLS13", 13534 config: Config{ 13535 MaxVersion: VersionTLS13, 13536 Bugs: ProtocolBugs{ 13537 MissingKeyShare: true, 13538 }, 13539 }, 13540 shouldFail: true, 13541 expectedError: ":MISSING_KEY_SHARE:", 13542 }) 13543 13544 testCases = append(testCases, testCase{ 13545 testType: serverTest, 13546 name: "DuplicateKeyShares-TLS13", 13547 config: Config{ 13548 MaxVersion: VersionTLS13, 13549 Bugs: ProtocolBugs{ 13550 DuplicateKeyShares: true, 13551 }, 13552 }, 13553 shouldFail: true, 13554 expectedError: ":DUPLICATE_KEY_SHARE:", 13555 }) 13556 13557 testCases = append(testCases, testCase{ 13558 testType: serverTest, 13559 name: "SkipEarlyData-TLS13", 13560 config: Config{ 13561 MaxVersion: VersionTLS13, 13562 Bugs: ProtocolBugs{ 13563 SendFakeEarlyDataLength: 4, 13564 }, 13565 }, 13566 }) 13567 13568 // Test that enabling TLS 1.3 does not interfere with TLS 1.2 session ID 13569 // resumption. 13570 testCases = append(testCases, testCase{ 13571 testType: clientTest, 13572 name: "ResumeTLS12SessionID-TLS13", 13573 config: Config{ 13574 MaxVersion: VersionTLS12, 13575 SessionTicketsDisabled: true, 13576 }, 13577 flags: []string{"-max-version", strconv.Itoa(VersionTLS13)}, 13578 resumeSession: true, 13579 }) 13580 13581 // Test that the client correctly handles a TLS 1.3 ServerHello which echoes 13582 // a TLS 1.2 session ID. 13583 testCases = append(testCases, testCase{ 13584 testType: clientTest, 13585 name: "TLS12SessionID-TLS13", 13586 config: Config{ 13587 MaxVersion: VersionTLS12, 13588 SessionTicketsDisabled: true, 13589 }, 13590 resumeConfig: &Config{ 13591 MaxVersion: VersionTLS13, 13592 }, 13593 resumeSession: true, 13594 expectResumeRejected: true, 13595 }) 13596 13597 // Test that the server correctly echoes back session IDs of 13598 // various lengths. The first test additionally asserts that 13599 // BoringSSL always sends the ChangeCipherSpec messages for 13600 // compatibility mode, rather than negotiating it based on the 13601 // ClientHello. 13602 testCases = append(testCases, testCase{ 13603 testType: serverTest, 13604 name: "EmptySessionID-TLS13", 13605 config: Config{ 13606 MaxVersion: VersionTLS13, 13607 Bugs: ProtocolBugs{ 13608 SendClientHelloSessionID: []byte{}, 13609 }, 13610 }, 13611 }) 13612 13613 testCases = append(testCases, testCase{ 13614 testType: serverTest, 13615 name: "Server-ShortSessionID-TLS13", 13616 config: Config{ 13617 MaxVersion: VersionTLS13, 13618 Bugs: ProtocolBugs{ 13619 SendClientHelloSessionID: make([]byte, 16), 13620 }, 13621 }, 13622 }) 13623 13624 testCases = append(testCases, testCase{ 13625 testType: serverTest, 13626 name: "Server-FullSessionID-TLS13", 13627 config: Config{ 13628 MaxVersion: VersionTLS13, 13629 Bugs: ProtocolBugs{ 13630 SendClientHelloSessionID: make([]byte, 32), 13631 }, 13632 }, 13633 }) 13634 13635 // The server should reject ClientHellos whose session IDs are too long. 13636 testCases = append(testCases, testCase{ 13637 testType: serverTest, 13638 name: "Server-TooLongSessionID-TLS13", 13639 config: Config{ 13640 MaxVersion: VersionTLS13, 13641 Bugs: ProtocolBugs{ 13642 SendClientHelloSessionID: make([]byte, 33), 13643 }, 13644 }, 13645 shouldFail: true, 13646 expectedError: ":DECODE_ERROR:", 13647 expectedLocalError: "remote error: error decoding message", 13648 }) 13649 testCases = append(testCases, testCase{ 13650 testType: serverTest, 13651 name: "Server-TooLongSessionID-TLS12", 13652 config: Config{ 13653 MaxVersion: VersionTLS12, 13654 Bugs: ProtocolBugs{ 13655 SendClientHelloSessionID: make([]byte, 33), 13656 }, 13657 }, 13658 shouldFail: true, 13659 expectedError: ":DECODE_ERROR:", 13660 expectedLocalError: "remote error: error decoding message", 13661 }) 13662 13663 // Test that the client correctly accepts or rejects short session IDs from 13664 // the server. Our tests use 32 bytes by default, so the boundary condition 13665 // is already covered. 13666 testCases = append(testCases, testCase{ 13667 name: "Client-ShortSessionID", 13668 config: Config{ 13669 MaxVersion: VersionTLS12, 13670 SessionTicketsDisabled: true, 13671 Bugs: ProtocolBugs{ 13672 NewSessionIDLength: 1, 13673 }, 13674 }, 13675 resumeSession: true, 13676 }) 13677 testCases = append(testCases, testCase{ 13678 name: "Client-TooLongSessionID", 13679 config: Config{ 13680 MaxVersion: VersionTLS12, 13681 SessionTicketsDisabled: true, 13682 Bugs: ProtocolBugs{ 13683 NewSessionIDLength: 33, 13684 }, 13685 }, 13686 shouldFail: true, 13687 expectedError: ":DECODE_ERROR:", 13688 expectedLocalError: "remote error: error decoding message", 13689 }) 13690 13691 // Test that the client sends a fake session ID in TLS 1.3. We cover both 13692 // normal and resumption handshakes to capture interactions with the 13693 // session resumption path. 13694 testCases = append(testCases, testCase{ 13695 testType: clientTest, 13696 name: "TLS13SessionID-TLS13", 13697 config: Config{ 13698 MaxVersion: VersionTLS13, 13699 Bugs: ProtocolBugs{ 13700 ExpectClientHelloSessionID: true, 13701 }, 13702 }, 13703 resumeSession: true, 13704 }) 13705 13706 // Test that the client omits the fake session ID when the max version is TLS 1.2 and below. 13707 testCases = append(testCases, testCase{ 13708 testType: clientTest, 13709 name: "TLS12NoSessionID-TLS13", 13710 config: Config{ 13711 MaxVersion: VersionTLS13, 13712 Bugs: ProtocolBugs{ 13713 ExpectNoSessionID: true, 13714 }, 13715 }, 13716 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 13717 }) 13718 13719 testCases = append(testCases, testCase{ 13720 testType: clientTest, 13721 name: "EarlyData-Client-TLS13", 13722 config: Config{ 13723 MaxVersion: VersionTLS13, 13724 MinVersion: VersionTLS13, 13725 }, 13726 resumeSession: true, 13727 earlyData: true, 13728 flags: []string{ 13729 "-on-initial-expect-early-data-reason", "no_session_offered", 13730 "-on-resume-expect-early-data-reason", "accept", 13731 }, 13732 }) 13733 13734 testCases = append(testCases, testCase{ 13735 testType: clientTest, 13736 name: "EarlyData-Reject-Client-TLS13", 13737 config: Config{ 13738 MaxVersion: VersionTLS13, 13739 }, 13740 resumeConfig: &Config{ 13741 MaxVersion: VersionTLS13, 13742 Bugs: ProtocolBugs{ 13743 AlwaysRejectEarlyData: true, 13744 }, 13745 }, 13746 resumeSession: true, 13747 earlyData: true, 13748 expectEarlyDataRejected: true, 13749 flags: []string{ 13750 "-on-retry-expect-early-data-reason", "peer_declined", 13751 }, 13752 }) 13753 13754 testCases = append(testCases, testCase{ 13755 testType: serverTest, 13756 name: "EarlyData-Server-TLS13", 13757 config: Config{ 13758 MaxVersion: VersionTLS13, 13759 MinVersion: VersionTLS13, 13760 }, 13761 messageCount: 2, 13762 resumeSession: true, 13763 earlyData: true, 13764 flags: []string{ 13765 "-on-initial-expect-early-data-reason", "no_session_offered", 13766 "-on-resume-expect-early-data-reason", "accept", 13767 }, 13768 }) 13769 13770 // The above tests the most recent ticket. Additionally test that 0-RTT 13771 // works on the first ticket issued by the server. 13772 testCases = append(testCases, testCase{ 13773 testType: serverTest, 13774 name: "EarlyData-FirstTicket-Server-TLS13", 13775 config: Config{ 13776 MaxVersion: VersionTLS13, 13777 MinVersion: VersionTLS13, 13778 Bugs: ProtocolBugs{ 13779 UseFirstSessionTicket: true, 13780 }, 13781 }, 13782 messageCount: 2, 13783 resumeSession: true, 13784 earlyData: true, 13785 flags: []string{ 13786 "-on-resume-expect-early-data-reason", "accept", 13787 }, 13788 }) 13789 13790 testCases = append(testCases, testCase{ 13791 testType: serverTest, 13792 name: "SkipEarlyData-OmitEarlyDataExtension-TLS13", 13793 config: Config{ 13794 MaxVersion: VersionTLS13, 13795 Bugs: ProtocolBugs{ 13796 SendFakeEarlyDataLength: 4, 13797 OmitEarlyDataExtension: true, 13798 }, 13799 }, 13800 shouldFail: true, 13801 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 13802 }) 13803 13804 testCases = append(testCases, testCase{ 13805 testType: serverTest, 13806 name: "SkipEarlyData-OmitEarlyDataExtension-HelloRetryRequest-TLS13", 13807 config: Config{ 13808 MaxVersion: VersionTLS13, 13809 // Require a HelloRetryRequest for every curve. 13810 DefaultCurves: []CurveID{}, 13811 Bugs: ProtocolBugs{ 13812 SendFakeEarlyDataLength: 4, 13813 OmitEarlyDataExtension: true, 13814 }, 13815 }, 13816 shouldFail: true, 13817 expectedError: ":UNEXPECTED_RECORD:", 13818 expectedLocalError: "remote error: unexpected message", 13819 }) 13820 13821 testCases = append(testCases, testCase{ 13822 testType: serverTest, 13823 name: "SkipEarlyData-TooMuchData-TLS13", 13824 config: Config{ 13825 MaxVersion: VersionTLS13, 13826 Bugs: ProtocolBugs{ 13827 SendFakeEarlyDataLength: 16384 + 1, 13828 }, 13829 }, 13830 shouldFail: true, 13831 expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:", 13832 }) 13833 13834 testCases = append(testCases, testCase{ 13835 testType: serverTest, 13836 name: "SkipEarlyData-Interleaved-TLS13", 13837 config: Config{ 13838 MaxVersion: VersionTLS13, 13839 Bugs: ProtocolBugs{ 13840 SendFakeEarlyDataLength: 4, 13841 InterleaveEarlyData: true, 13842 }, 13843 }, 13844 shouldFail: true, 13845 expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:", 13846 }) 13847 13848 testCases = append(testCases, testCase{ 13849 testType: serverTest, 13850 name: "SkipEarlyData-EarlyDataInTLS12-TLS13", 13851 config: Config{ 13852 MaxVersion: VersionTLS13, 13853 Bugs: ProtocolBugs{ 13854 SendFakeEarlyDataLength: 4, 13855 }, 13856 }, 13857 shouldFail: true, 13858 expectedError: ":UNEXPECTED_RECORD:", 13859 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 13860 }) 13861 13862 testCases = append(testCases, testCase{ 13863 testType: serverTest, 13864 name: "SkipEarlyData-HRR-TLS13", 13865 config: Config{ 13866 MaxVersion: VersionTLS13, 13867 Bugs: ProtocolBugs{ 13868 SendFakeEarlyDataLength: 4, 13869 }, 13870 DefaultCurves: []CurveID{}, 13871 }, 13872 // Though the session is not resumed and we send HelloRetryRequest, 13873 // early data being disabled takes priority as the reject reason. 13874 flags: []string{"-expect-early-data-reason", "disabled"}, 13875 }) 13876 13877 testCases = append(testCases, testCase{ 13878 testType: serverTest, 13879 name: "SkipEarlyData-HRR-Interleaved-TLS13", 13880 config: Config{ 13881 MaxVersion: VersionTLS13, 13882 Bugs: ProtocolBugs{ 13883 SendFakeEarlyDataLength: 4, 13884 InterleaveEarlyData: true, 13885 }, 13886 DefaultCurves: []CurveID{}, 13887 }, 13888 shouldFail: true, 13889 expectedError: ":UNEXPECTED_RECORD:", 13890 }) 13891 13892 testCases = append(testCases, testCase{ 13893 testType: serverTest, 13894 name: "SkipEarlyData-HRR-TooMuchData-TLS13", 13895 config: Config{ 13896 MaxVersion: VersionTLS13, 13897 Bugs: ProtocolBugs{ 13898 SendFakeEarlyDataLength: 16384 + 1, 13899 }, 13900 DefaultCurves: []CurveID{}, 13901 }, 13902 shouldFail: true, 13903 expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:", 13904 }) 13905 13906 // Test that skipping early data looking for cleartext correctly 13907 // processes an alert record. 13908 testCases = append(testCases, testCase{ 13909 testType: serverTest, 13910 name: "SkipEarlyData-HRR-FatalAlert-TLS13", 13911 config: Config{ 13912 MaxVersion: VersionTLS13, 13913 Bugs: ProtocolBugs{ 13914 SendEarlyAlert: true, 13915 SendFakeEarlyDataLength: 4, 13916 }, 13917 DefaultCurves: []CurveID{}, 13918 }, 13919 shouldFail: true, 13920 expectedError: ":SSLV3_ALERT_HANDSHAKE_FAILURE:", 13921 }) 13922 13923 testCases = append(testCases, testCase{ 13924 testType: serverTest, 13925 name: "SkipEarlyData-SecondClientHelloEarlyData-TLS13", 13926 config: Config{ 13927 MaxVersion: VersionTLS13, 13928 Bugs: ProtocolBugs{ 13929 SendEarlyDataOnSecondClientHello: true, 13930 }, 13931 DefaultCurves: []CurveID{}, 13932 }, 13933 shouldFail: true, 13934 expectedLocalError: "remote error: bad record MAC", 13935 }) 13936 13937 testCases = append(testCases, testCase{ 13938 testType: clientTest, 13939 name: "EmptyEncryptedExtensions-TLS13", 13940 config: Config{ 13941 MaxVersion: VersionTLS13, 13942 Bugs: ProtocolBugs{ 13943 EmptyEncryptedExtensions: true, 13944 }, 13945 }, 13946 shouldFail: true, 13947 expectedLocalError: "remote error: error decoding message", 13948 }) 13949 13950 testCases = append(testCases, testCase{ 13951 testType: clientTest, 13952 name: "EncryptedExtensionsWithKeyShare-TLS13", 13953 config: Config{ 13954 MaxVersion: VersionTLS13, 13955 Bugs: ProtocolBugs{ 13956 EncryptedExtensionsWithKeyShare: true, 13957 }, 13958 }, 13959 shouldFail: true, 13960 expectedLocalError: "remote error: unsupported extension", 13961 }) 13962 13963 testCases = append(testCases, testCase{ 13964 testType: serverTest, 13965 name: "SendHelloRetryRequest-TLS13", 13966 config: Config{ 13967 MaxVersion: VersionTLS13, 13968 // Require a HelloRetryRequest for every curve. 13969 DefaultCurves: []CurveID{}, 13970 CurvePreferences: []CurveID{CurveX25519}, 13971 }, 13972 expectations: connectionExpectations{ 13973 curveID: CurveX25519, 13974 }, 13975 flags: []string{"-expect-hrr"}, 13976 }) 13977 13978 testCases = append(testCases, testCase{ 13979 testType: serverTest, 13980 name: "SendHelloRetryRequest-2-TLS13", 13981 config: Config{ 13982 MaxVersion: VersionTLS13, 13983 DefaultCurves: []CurveID{CurveP384}, 13984 CurvePreferences: []CurveID{CurveX25519, CurveP384}, 13985 }, 13986 // Although the ClientHello did not predict our preferred curve, 13987 // we always select it whether it is predicted or not. 13988 expectations: connectionExpectations{ 13989 curveID: CurveX25519, 13990 }, 13991 flags: []string{"-expect-hrr"}, 13992 }) 13993 13994 testCases = append(testCases, testCase{ 13995 name: "UnknownCurve-HelloRetryRequest-TLS13", 13996 config: Config{ 13997 MaxVersion: VersionTLS13, 13998 // P-384 requires HelloRetryRequest in BoringSSL. 13999 CurvePreferences: []CurveID{CurveP384}, 14000 Bugs: ProtocolBugs{ 14001 SendHelloRetryRequestCurve: bogusCurve, 14002 }, 14003 }, 14004 shouldFail: true, 14005 expectedError: ":WRONG_CURVE:", 14006 }) 14007 14008 testCases = append(testCases, testCase{ 14009 name: "HelloRetryRequest-CipherChange-TLS13", 14010 config: Config{ 14011 MaxVersion: VersionTLS13, 14012 // P-384 requires HelloRetryRequest in BoringSSL. 14013 CurvePreferences: []CurveID{CurveP384}, 14014 Bugs: ProtocolBugs{ 14015 SendCipherSuite: TLS_AES_128_GCM_SHA256, 14016 SendHelloRetryRequestCipherSuite: TLS_CHACHA20_POLY1305_SHA256, 14017 }, 14018 }, 14019 shouldFail: true, 14020 expectedError: ":WRONG_CIPHER_RETURNED:", 14021 }) 14022 14023 // Test that the client does not offer a PSK in the second ClientHello if the 14024 // HelloRetryRequest is incompatible with it. 14025 testCases = append(testCases, testCase{ 14026 testType: clientTest, 14027 name: "HelloRetryRequest-NonResumableCipher-TLS13", 14028 config: Config{ 14029 MaxVersion: VersionTLS13, 14030 CipherSuites: []uint16{ 14031 TLS_AES_128_GCM_SHA256, 14032 }, 14033 }, 14034 resumeConfig: &Config{ 14035 MaxVersion: VersionTLS13, 14036 // P-384 requires HelloRetryRequest in BoringSSL. 14037 CurvePreferences: []CurveID{CurveP384}, 14038 Bugs: ProtocolBugs{ 14039 ExpectNoTLS13PSKAfterHRR: true, 14040 }, 14041 CipherSuites: []uint16{ 14042 TLS_AES_256_GCM_SHA384, 14043 }, 14044 }, 14045 resumeSession: true, 14046 expectResumeRejected: true, 14047 }) 14048 14049 testCases = append(testCases, testCase{ 14050 name: "DisabledCurve-HelloRetryRequest-TLS13", 14051 config: Config{ 14052 MaxVersion: VersionTLS13, 14053 CurvePreferences: []CurveID{CurveP256}, 14054 Bugs: ProtocolBugs{ 14055 IgnorePeerCurvePreferences: true, 14056 }, 14057 }, 14058 flags: []string{"-curves", strconv.Itoa(int(CurveP384))}, 14059 shouldFail: true, 14060 expectedError: ":WRONG_CURVE:", 14061 }) 14062 14063 testCases = append(testCases, testCase{ 14064 name: "UnnecessaryHelloRetryRequest-TLS13", 14065 config: Config{ 14066 MaxVersion: VersionTLS13, 14067 CurvePreferences: []CurveID{CurveX25519}, 14068 Bugs: ProtocolBugs{ 14069 SendHelloRetryRequestCurve: CurveX25519, 14070 }, 14071 }, 14072 shouldFail: true, 14073 expectedError: ":WRONG_CURVE:", 14074 }) 14075 14076 testCases = append(testCases, testCase{ 14077 name: "SecondHelloRetryRequest-TLS13", 14078 config: Config{ 14079 MaxVersion: VersionTLS13, 14080 // P-384 requires HelloRetryRequest in BoringSSL. 14081 CurvePreferences: []CurveID{CurveP384}, 14082 Bugs: ProtocolBugs{ 14083 SecondHelloRetryRequest: true, 14084 }, 14085 }, 14086 shouldFail: true, 14087 expectedError: ":UNEXPECTED_MESSAGE:", 14088 }) 14089 14090 testCases = append(testCases, testCase{ 14091 name: "HelloRetryRequest-Empty-TLS13", 14092 config: Config{ 14093 MaxVersion: VersionTLS13, 14094 Bugs: ProtocolBugs{ 14095 AlwaysSendHelloRetryRequest: true, 14096 }, 14097 }, 14098 shouldFail: true, 14099 expectedError: ":EMPTY_HELLO_RETRY_REQUEST:", 14100 expectedLocalError: "remote error: illegal parameter", 14101 }) 14102 14103 testCases = append(testCases, testCase{ 14104 name: "HelloRetryRequest-DuplicateCurve-TLS13", 14105 config: Config{ 14106 MaxVersion: VersionTLS13, 14107 // P-384 requires a HelloRetryRequest against BoringSSL's default 14108 // configuration. Assert this ExpectMissingKeyShare. 14109 CurvePreferences: []CurveID{CurveP384}, 14110 Bugs: ProtocolBugs{ 14111 ExpectMissingKeyShare: true, 14112 DuplicateHelloRetryRequestExtensions: true, 14113 }, 14114 }, 14115 shouldFail: true, 14116 expectedError: ":DUPLICATE_EXTENSION:", 14117 expectedLocalError: "remote error: illegal parameter", 14118 }) 14119 14120 testCases = append(testCases, testCase{ 14121 name: "HelloRetryRequest-Cookie-TLS13", 14122 config: Config{ 14123 MaxVersion: VersionTLS13, 14124 Bugs: ProtocolBugs{ 14125 SendHelloRetryRequestCookie: []byte("cookie"), 14126 }, 14127 }, 14128 }) 14129 14130 testCases = append(testCases, testCase{ 14131 name: "HelloRetryRequest-DuplicateCookie-TLS13", 14132 config: Config{ 14133 MaxVersion: VersionTLS13, 14134 Bugs: ProtocolBugs{ 14135 SendHelloRetryRequestCookie: []byte("cookie"), 14136 DuplicateHelloRetryRequestExtensions: true, 14137 }, 14138 }, 14139 shouldFail: true, 14140 expectedError: ":DUPLICATE_EXTENSION:", 14141 expectedLocalError: "remote error: illegal parameter", 14142 }) 14143 14144 testCases = append(testCases, testCase{ 14145 name: "HelloRetryRequest-EmptyCookie-TLS13", 14146 config: Config{ 14147 MaxVersion: VersionTLS13, 14148 Bugs: ProtocolBugs{ 14149 SendHelloRetryRequestCookie: []byte{}, 14150 }, 14151 }, 14152 shouldFail: true, 14153 expectedError: ":DECODE_ERROR:", 14154 }) 14155 14156 testCases = append(testCases, testCase{ 14157 name: "HelloRetryRequest-Cookie-Curve-TLS13", 14158 config: Config{ 14159 MaxVersion: VersionTLS13, 14160 // P-384 requires HelloRetryRequest in BoringSSL. 14161 CurvePreferences: []CurveID{CurveP384}, 14162 Bugs: ProtocolBugs{ 14163 SendHelloRetryRequestCookie: []byte("cookie"), 14164 ExpectMissingKeyShare: true, 14165 }, 14166 }, 14167 }) 14168 14169 testCases = append(testCases, testCase{ 14170 name: "HelloRetryRequest-Unknown-TLS13", 14171 config: Config{ 14172 MaxVersion: VersionTLS13, 14173 Bugs: ProtocolBugs{ 14174 CustomHelloRetryRequestExtension: "extension", 14175 }, 14176 }, 14177 shouldFail: true, 14178 expectedError: ":UNEXPECTED_EXTENSION:", 14179 expectedLocalError: "remote error: unsupported extension", 14180 }) 14181 14182 testCases = append(testCases, testCase{ 14183 testType: serverTest, 14184 name: "SecondClientHelloMissingKeyShare-TLS13", 14185 config: Config{ 14186 MaxVersion: VersionTLS13, 14187 DefaultCurves: []CurveID{}, 14188 Bugs: ProtocolBugs{ 14189 SecondClientHelloMissingKeyShare: true, 14190 }, 14191 }, 14192 shouldFail: true, 14193 expectedError: ":MISSING_KEY_SHARE:", 14194 }) 14195 14196 testCases = append(testCases, testCase{ 14197 testType: serverTest, 14198 name: "SecondClientHelloWrongCurve-TLS13", 14199 config: Config{ 14200 MaxVersion: VersionTLS13, 14201 DefaultCurves: []CurveID{}, 14202 Bugs: ProtocolBugs{ 14203 MisinterpretHelloRetryRequestCurve: CurveP521, 14204 }, 14205 }, 14206 shouldFail: true, 14207 expectedError: ":WRONG_CURVE:", 14208 }) 14209 14210 testCases = append(testCases, testCase{ 14211 name: "HelloRetryRequestVersionMismatch-TLS13", 14212 config: Config{ 14213 MaxVersion: VersionTLS13, 14214 // P-384 requires HelloRetryRequest in BoringSSL. 14215 CurvePreferences: []CurveID{CurveP384}, 14216 Bugs: ProtocolBugs{ 14217 SendServerHelloVersion: 0x0305, 14218 }, 14219 }, 14220 shouldFail: true, 14221 expectedError: ":DECODE_ERROR:", 14222 }) 14223 14224 testCases = append(testCases, testCase{ 14225 name: "HelloRetryRequestCurveMismatch-TLS13", 14226 config: Config{ 14227 MaxVersion: VersionTLS13, 14228 // P-384 requires HelloRetryRequest in BoringSSL. 14229 CurvePreferences: []CurveID{CurveP384}, 14230 Bugs: ProtocolBugs{ 14231 // Send P-384 (correct) in the HelloRetryRequest. 14232 SendHelloRetryRequestCurve: CurveP384, 14233 // But send P-256 in the ServerHello. 14234 SendCurve: CurveP256, 14235 }, 14236 }, 14237 shouldFail: true, 14238 expectedError: ":WRONG_CURVE:", 14239 }) 14240 14241 // Test the server selecting a curve that requires a HelloRetryRequest 14242 // without sending it. 14243 testCases = append(testCases, testCase{ 14244 name: "SkipHelloRetryRequest-TLS13", 14245 config: Config{ 14246 MaxVersion: VersionTLS13, 14247 // P-384 requires HelloRetryRequest in BoringSSL. 14248 CurvePreferences: []CurveID{CurveP384}, 14249 Bugs: ProtocolBugs{ 14250 SkipHelloRetryRequest: true, 14251 }, 14252 }, 14253 shouldFail: true, 14254 expectedError: ":WRONG_CURVE:", 14255 }) 14256 14257 testCases = append(testCases, testCase{ 14258 name: "SecondServerHelloNoVersion-TLS13", 14259 config: Config{ 14260 MaxVersion: VersionTLS13, 14261 // P-384 requires HelloRetryRequest in BoringSSL. 14262 CurvePreferences: []CurveID{CurveP384}, 14263 Bugs: ProtocolBugs{ 14264 OmitServerSupportedVersionExtension: true, 14265 }, 14266 }, 14267 shouldFail: true, 14268 expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:", 14269 }) 14270 testCases = append(testCases, testCase{ 14271 name: "SecondServerHelloWrongVersion-TLS13", 14272 config: Config{ 14273 MaxVersion: VersionTLS13, 14274 // P-384 requires HelloRetryRequest in BoringSSL. 14275 CurvePreferences: []CurveID{CurveP384}, 14276 Bugs: ProtocolBugs{ 14277 SendServerSupportedVersionExtension: 0x1234, 14278 }, 14279 }, 14280 shouldFail: true, 14281 expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:", 14282 }) 14283 14284 testCases = append(testCases, testCase{ 14285 name: "RequestContextInHandshake-TLS13", 14286 config: Config{ 14287 MaxVersion: VersionTLS13, 14288 MinVersion: VersionTLS13, 14289 ClientAuth: RequireAnyClientCert, 14290 Bugs: ProtocolBugs{ 14291 SendRequestContext: []byte("request context"), 14292 }, 14293 }, 14294 shimCertificate: &rsaCertificate, 14295 shouldFail: true, 14296 expectedError: ":DECODE_ERROR:", 14297 }) 14298 14299 testCases = append(testCases, testCase{ 14300 name: "UnknownExtensionInCertificateRequest-TLS13", 14301 config: Config{ 14302 MaxVersion: VersionTLS13, 14303 MinVersion: VersionTLS13, 14304 ClientAuth: RequireAnyClientCert, 14305 Bugs: ProtocolBugs{ 14306 SendCustomCertificateRequest: 0x1212, 14307 }, 14308 }, 14309 shimCertificate: &rsaCertificate, 14310 }) 14311 14312 testCases = append(testCases, testCase{ 14313 name: "MissingSignatureAlgorithmsInCertificateRequest-TLS13", 14314 config: Config{ 14315 MaxVersion: VersionTLS13, 14316 MinVersion: VersionTLS13, 14317 ClientAuth: RequireAnyClientCert, 14318 Bugs: ProtocolBugs{ 14319 OmitCertificateRequestAlgorithms: true, 14320 }, 14321 }, 14322 shimCertificate: &rsaCertificate, 14323 shouldFail: true, 14324 expectedError: ":DECODE_ERROR:", 14325 }) 14326 14327 testCases = append(testCases, testCase{ 14328 testType: serverTest, 14329 name: "TrailingKeyShareData-TLS13", 14330 config: Config{ 14331 MaxVersion: VersionTLS13, 14332 Bugs: ProtocolBugs{ 14333 TrailingKeyShareData: true, 14334 }, 14335 }, 14336 shouldFail: true, 14337 expectedError: ":DECODE_ERROR:", 14338 }) 14339 14340 testCases = append(testCases, testCase{ 14341 name: "AlwaysSelectPSKIdentity-TLS13", 14342 config: Config{ 14343 MaxVersion: VersionTLS13, 14344 Bugs: ProtocolBugs{ 14345 AlwaysSelectPSKIdentity: true, 14346 }, 14347 }, 14348 shouldFail: true, 14349 expectedError: ":UNEXPECTED_EXTENSION:", 14350 }) 14351 14352 testCases = append(testCases, testCase{ 14353 name: "InvalidPSKIdentity-TLS13", 14354 config: Config{ 14355 MaxVersion: VersionTLS13, 14356 Bugs: ProtocolBugs{ 14357 SelectPSKIdentityOnResume: 1, 14358 }, 14359 }, 14360 resumeSession: true, 14361 shouldFail: true, 14362 expectedError: ":PSK_IDENTITY_NOT_FOUND:", 14363 }) 14364 14365 testCases = append(testCases, testCase{ 14366 testType: serverTest, 14367 name: "ExtraPSKIdentity-TLS13", 14368 config: Config{ 14369 MaxVersion: VersionTLS13, 14370 Bugs: ProtocolBugs{ 14371 ExtraPSKIdentity: true, 14372 SendExtraPSKBinder: true, 14373 }, 14374 }, 14375 resumeSession: true, 14376 }) 14377 14378 // Test that unknown NewSessionTicket extensions are tolerated. 14379 testCases = append(testCases, testCase{ 14380 name: "CustomTicketExtension-TLS13", 14381 config: Config{ 14382 MaxVersion: VersionTLS13, 14383 Bugs: ProtocolBugs{ 14384 CustomTicketExtension: "1234", 14385 }, 14386 }, 14387 }) 14388 14389 // Test the client handles 0-RTT being rejected by a full handshake 14390 // and correctly reports a certificate change. 14391 testCases = append(testCases, testCase{ 14392 testType: clientTest, 14393 name: "EarlyData-RejectTicket-Client-TLS13", 14394 config: Config{ 14395 MaxVersion: VersionTLS13, 14396 Credential: &rsaCertificate, 14397 }, 14398 resumeConfig: &Config{ 14399 MaxVersion: VersionTLS13, 14400 Credential: &ecdsaP256Certificate, 14401 SessionTicketsDisabled: true, 14402 }, 14403 resumeSession: true, 14404 expectResumeRejected: true, 14405 earlyData: true, 14406 expectEarlyDataRejected: true, 14407 flags: []string{ 14408 "-on-retry-expect-early-data-reason", "session_not_resumed", 14409 // Test the peer certificate is reported correctly in each of the 14410 // three logical connections. 14411 "-on-initial-expect-peer-cert-file", rsaCertificate.ChainPath, 14412 "-on-resume-expect-peer-cert-file", rsaCertificate.ChainPath, 14413 "-on-retry-expect-peer-cert-file", ecdsaP256Certificate.ChainPath, 14414 // Session tickets are disabled, so the runner will not send a ticket. 14415 "-on-retry-expect-no-session", 14416 }, 14417 }) 14418 14419 // Test the server rejects 0-RTT if it does not recognize the ticket. 14420 testCases = append(testCases, testCase{ 14421 testType: serverTest, 14422 name: "EarlyData-RejectTicket-Server-TLS13", 14423 config: Config{ 14424 MaxVersion: VersionTLS13, 14425 MinVersion: VersionTLS13, 14426 Bugs: ProtocolBugs{ 14427 // Corrupt the ticket. 14428 FilterTicket: func(in []byte) ([]byte, error) { 14429 in[len(in)-1] ^= 1 14430 return in, nil 14431 }, 14432 }, 14433 }, 14434 messageCount: 2, 14435 resumeSession: true, 14436 expectResumeRejected: true, 14437 earlyData: true, 14438 expectEarlyDataRejected: true, 14439 flags: []string{ 14440 "-on-resume-expect-early-data-reason", "session_not_resumed", 14441 }, 14442 }) 14443 14444 // Test the client handles 0-RTT being rejected via a HelloRetryRequest. 14445 testCases = append(testCases, testCase{ 14446 testType: clientTest, 14447 name: "EarlyData-HRR-Client-TLS13", 14448 config: Config{ 14449 MaxVersion: VersionTLS13, 14450 }, 14451 resumeConfig: &Config{ 14452 MaxVersion: VersionTLS13, 14453 Bugs: ProtocolBugs{ 14454 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14455 }, 14456 }, 14457 resumeSession: true, 14458 earlyData: true, 14459 expectEarlyDataRejected: true, 14460 flags: []string{ 14461 "-on-retry-expect-early-data-reason", "hello_retry_request", 14462 }, 14463 }) 14464 14465 // Test the server rejects 0-RTT if it needs to send a HelloRetryRequest. 14466 testCases = append(testCases, testCase{ 14467 testType: serverTest, 14468 name: "EarlyData-HRR-Server-TLS13", 14469 config: Config{ 14470 MaxVersion: VersionTLS13, 14471 MinVersion: VersionTLS13, 14472 // Require a HelloRetryRequest for every curve. 14473 DefaultCurves: []CurveID{}, 14474 }, 14475 messageCount: 2, 14476 resumeSession: true, 14477 earlyData: true, 14478 expectEarlyDataRejected: true, 14479 flags: []string{ 14480 "-on-resume-expect-early-data-reason", "hello_retry_request", 14481 }, 14482 }) 14483 14484 // Test the client handles a 0-RTT reject from both ticket rejection and 14485 // HelloRetryRequest. 14486 testCases = append(testCases, testCase{ 14487 testType: clientTest, 14488 name: "EarlyData-HRR-RejectTicket-Client-TLS13", 14489 config: Config{ 14490 MaxVersion: VersionTLS13, 14491 Credential: &rsaCertificate, 14492 }, 14493 resumeConfig: &Config{ 14494 MaxVersion: VersionTLS13, 14495 Credential: &ecdsaP256Certificate, 14496 SessionTicketsDisabled: true, 14497 Bugs: ProtocolBugs{ 14498 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14499 }, 14500 }, 14501 resumeSession: true, 14502 expectResumeRejected: true, 14503 earlyData: true, 14504 expectEarlyDataRejected: true, 14505 flags: []string{ 14506 // The client sees HelloRetryRequest before the resumption result, 14507 // though neither value is inherently preferable. 14508 "-on-retry-expect-early-data-reason", "hello_retry_request", 14509 // Test the peer certificate is reported correctly in each of the 14510 // three logical connections. 14511 "-on-initial-expect-peer-cert-file", rsaCertificate.ChainPath, 14512 "-on-resume-expect-peer-cert-file", rsaCertificate.ChainPath, 14513 "-on-retry-expect-peer-cert-file", ecdsaP256Certificate.ChainPath, 14514 // Session tickets are disabled, so the runner will not send a ticket. 14515 "-on-retry-expect-no-session", 14516 }, 14517 }) 14518 14519 // Test the server rejects 0-RTT if it needs to send a HelloRetryRequest. 14520 testCases = append(testCases, testCase{ 14521 testType: serverTest, 14522 name: "EarlyData-HRR-RejectTicket-Server-TLS13", 14523 config: Config{ 14524 MaxVersion: VersionTLS13, 14525 MinVersion: VersionTLS13, 14526 // Require a HelloRetryRequest for every curve. 14527 DefaultCurves: []CurveID{}, 14528 Bugs: ProtocolBugs{ 14529 // Corrupt the ticket. 14530 FilterTicket: func(in []byte) ([]byte, error) { 14531 in[len(in)-1] ^= 1 14532 return in, nil 14533 }, 14534 }, 14535 }, 14536 messageCount: 2, 14537 resumeSession: true, 14538 expectResumeRejected: true, 14539 earlyData: true, 14540 expectEarlyDataRejected: true, 14541 flags: []string{ 14542 // The server sees the missed resumption before HelloRetryRequest, 14543 // though neither value is inherently preferable. 14544 "-on-resume-expect-early-data-reason", "session_not_resumed", 14545 }, 14546 }) 14547 14548 // The client must check the server does not send the early_data 14549 // extension while rejecting the session. 14550 testCases = append(testCases, testCase{ 14551 testType: clientTest, 14552 name: "EarlyDataWithoutResume-Client-TLS13", 14553 config: Config{ 14554 MaxVersion: VersionTLS13, 14555 MaxEarlyDataSize: 16384, 14556 }, 14557 resumeConfig: &Config{ 14558 MaxVersion: VersionTLS13, 14559 SessionTicketsDisabled: true, 14560 Bugs: ProtocolBugs{ 14561 SendEarlyDataExtension: true, 14562 }, 14563 }, 14564 resumeSession: true, 14565 earlyData: true, 14566 shouldFail: true, 14567 expectedError: ":UNEXPECTED_EXTENSION:", 14568 }) 14569 14570 // The client must fail with a dedicated error code if the server 14571 // responds with TLS 1.2 when offering 0-RTT. 14572 testCases = append(testCases, testCase{ 14573 testType: clientTest, 14574 name: "EarlyDataVersionDowngrade-Client-TLS13", 14575 config: Config{ 14576 MaxVersion: VersionTLS13, 14577 }, 14578 resumeConfig: &Config{ 14579 MaxVersion: VersionTLS12, 14580 }, 14581 resumeSession: true, 14582 earlyData: true, 14583 shouldFail: true, 14584 expectedError: ":WRONG_VERSION_ON_EARLY_DATA:", 14585 }) 14586 14587 // Test that the client rejects an (unsolicited) early_data extension if 14588 // the server sent an HRR. 14589 testCases = append(testCases, testCase{ 14590 testType: clientTest, 14591 name: "ServerAcceptsEarlyDataOnHRR-Client-TLS13", 14592 config: Config{ 14593 MaxVersion: VersionTLS13, 14594 }, 14595 resumeConfig: &Config{ 14596 MaxVersion: VersionTLS13, 14597 Bugs: ProtocolBugs{ 14598 SendHelloRetryRequestCookie: []byte{1, 2, 3, 4}, 14599 SendEarlyDataExtension: true, 14600 }, 14601 }, 14602 resumeSession: true, 14603 earlyData: true, 14604 // The client will first process an early data reject from the HRR. 14605 expectEarlyDataRejected: true, 14606 shouldFail: true, 14607 expectedError: ":UNEXPECTED_EXTENSION:", 14608 }) 14609 14610 testCases = append(testCases, testCase{ 14611 testType: clientTest, 14612 name: "SkipChangeCipherSpec-Client-TLS13", 14613 config: Config{ 14614 MaxVersion: VersionTLS13, 14615 Bugs: ProtocolBugs{ 14616 SkipChangeCipherSpec: true, 14617 }, 14618 }, 14619 }) 14620 14621 testCases = append(testCases, testCase{ 14622 testType: serverTest, 14623 name: "SkipChangeCipherSpec-Server-TLS13", 14624 config: Config{ 14625 MaxVersion: VersionTLS13, 14626 Bugs: ProtocolBugs{ 14627 SkipChangeCipherSpec: true, 14628 }, 14629 }, 14630 }) 14631 14632 testCases = append(testCases, testCase{ 14633 testType: clientTest, 14634 name: "TooManyChangeCipherSpec-Client-TLS13", 14635 config: Config{ 14636 MaxVersion: VersionTLS13, 14637 Bugs: ProtocolBugs{ 14638 SendExtraChangeCipherSpec: 33, 14639 }, 14640 }, 14641 shouldFail: true, 14642 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 14643 }) 14644 14645 testCases = append(testCases, testCase{ 14646 testType: serverTest, 14647 name: "TooManyChangeCipherSpec-Server-TLS13", 14648 config: Config{ 14649 MaxVersion: VersionTLS13, 14650 Bugs: ProtocolBugs{ 14651 SendExtraChangeCipherSpec: 33, 14652 }, 14653 }, 14654 shouldFail: true, 14655 expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:", 14656 }) 14657 14658 testCases = append(testCases, testCase{ 14659 name: "SendPostHandshakeChangeCipherSpec-TLS13", 14660 config: Config{ 14661 MaxVersion: VersionTLS13, 14662 Bugs: ProtocolBugs{ 14663 SendPostHandshakeChangeCipherSpec: true, 14664 }, 14665 }, 14666 shouldFail: true, 14667 expectedError: ":UNEXPECTED_RECORD:", 14668 expectedLocalError: "remote error: unexpected message", 14669 }) 14670 14671 fooString := "foo" 14672 barString := "bar" 14673 14674 // Test that the client reports the correct ALPN after a 0-RTT reject 14675 // that changed it. 14676 testCases = append(testCases, testCase{ 14677 testType: clientTest, 14678 name: "EarlyData-ALPNMismatch-Client-TLS13", 14679 config: Config{ 14680 MaxVersion: VersionTLS13, 14681 Bugs: ProtocolBugs{ 14682 ALPNProtocol: &fooString, 14683 }, 14684 }, 14685 resumeConfig: &Config{ 14686 MaxVersion: VersionTLS13, 14687 Bugs: ProtocolBugs{ 14688 ALPNProtocol: &barString, 14689 }, 14690 }, 14691 resumeSession: true, 14692 earlyData: true, 14693 expectEarlyDataRejected: true, 14694 flags: []string{ 14695 "-advertise-alpn", "\x03foo\x03bar", 14696 // The client does not learn ALPN was the cause. 14697 "-on-retry-expect-early-data-reason", "peer_declined", 14698 // In the 0-RTT state, we surface the predicted ALPN. After 14699 // processing the reject, we surface the real one. 14700 "-on-initial-expect-alpn", "foo", 14701 "-on-resume-expect-alpn", "foo", 14702 "-on-retry-expect-alpn", "bar", 14703 }, 14704 }) 14705 14706 // Test that the client reports the correct ALPN after a 0-RTT reject if 14707 // ALPN was omitted from the first connection. 14708 testCases = append(testCases, testCase{ 14709 testType: clientTest, 14710 name: "EarlyData-ALPNOmitted1-Client-TLS13", 14711 config: Config{ 14712 MaxVersion: VersionTLS13, 14713 }, 14714 resumeConfig: &Config{ 14715 MaxVersion: VersionTLS13, 14716 NextProtos: []string{"foo"}, 14717 }, 14718 resumeSession: true, 14719 earlyData: true, 14720 expectEarlyDataRejected: true, 14721 flags: []string{ 14722 "-advertise-alpn", "\x03foo\x03bar", 14723 // The client does not learn ALPN was the cause. 14724 "-on-retry-expect-early-data-reason", "peer_declined", 14725 // In the 0-RTT state, we surface the predicted ALPN. After 14726 // processing the reject, we surface the real one. 14727 "-on-initial-expect-alpn", "", 14728 "-on-resume-expect-alpn", "", 14729 "-on-retry-expect-alpn", "foo", 14730 }, 14731 }) 14732 14733 // Test that the client reports the correct ALPN after a 0-RTT reject if 14734 // ALPN was omitted from the second connection. 14735 testCases = append(testCases, testCase{ 14736 testType: clientTest, 14737 name: "EarlyData-ALPNOmitted2-Client-TLS13", 14738 config: Config{ 14739 MaxVersion: VersionTLS13, 14740 NextProtos: []string{"foo"}, 14741 }, 14742 resumeConfig: &Config{ 14743 MaxVersion: VersionTLS13, 14744 }, 14745 resumeSession: true, 14746 earlyData: true, 14747 expectEarlyDataRejected: true, 14748 flags: []string{ 14749 "-advertise-alpn", "\x03foo\x03bar", 14750 // The client does not learn ALPN was the cause. 14751 "-on-retry-expect-early-data-reason", "peer_declined", 14752 // In the 0-RTT state, we surface the predicted ALPN. After 14753 // processing the reject, we surface the real one. 14754 "-on-initial-expect-alpn", "foo", 14755 "-on-resume-expect-alpn", "foo", 14756 "-on-retry-expect-alpn", "", 14757 }, 14758 }) 14759 14760 // Test that the client enforces ALPN match on 0-RTT accept. 14761 testCases = append(testCases, testCase{ 14762 testType: clientTest, 14763 name: "EarlyData-BadALPNMismatch-Client-TLS13", 14764 config: Config{ 14765 MaxVersion: VersionTLS13, 14766 Bugs: ProtocolBugs{ 14767 ALPNProtocol: &fooString, 14768 }, 14769 }, 14770 resumeConfig: &Config{ 14771 MaxVersion: VersionTLS13, 14772 Bugs: ProtocolBugs{ 14773 AlwaysAcceptEarlyData: true, 14774 ALPNProtocol: &barString, 14775 }, 14776 }, 14777 resumeSession: true, 14778 earlyData: true, 14779 flags: []string{ 14780 "-advertise-alpn", "\x03foo\x03bar", 14781 "-on-initial-expect-alpn", "foo", 14782 "-on-resume-expect-alpn", "foo", 14783 "-on-retry-expect-alpn", "bar", 14784 }, 14785 shouldFail: true, 14786 expectedError: ":ALPN_MISMATCH_ON_EARLY_DATA:", 14787 expectedLocalError: "remote error: illegal parameter", 14788 }) 14789 14790 // Test that the client does not offer early data if it is incompatible 14791 // with ALPN preferences. 14792 testCases = append(testCases, testCase{ 14793 testType: clientTest, 14794 name: "EarlyData-ALPNPreferenceChanged-TLS13", 14795 config: Config{ 14796 MaxVersion: VersionTLS13, 14797 MaxEarlyDataSize: 16384, 14798 NextProtos: []string{"foo", "bar"}, 14799 }, 14800 resumeSession: true, 14801 flags: []string{ 14802 "-enable-early-data", 14803 "-expect-ticket-supports-early-data", 14804 "-expect-no-offer-early-data", 14805 // Offer different ALPN values in the initial and resumption. 14806 "-on-initial-advertise-alpn", "\x03foo", 14807 "-on-initial-expect-alpn", "foo", 14808 "-on-resume-advertise-alpn", "\x03bar", 14809 "-on-resume-expect-alpn", "bar", 14810 // The ALPN mismatch comes from the client, so it reports it as the 14811 // reason. 14812 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14813 }, 14814 }) 14815 14816 // Test that the client does not offer 0-RTT to servers which never 14817 // advertise it. 14818 testCases = append(testCases, testCase{ 14819 testType: clientTest, 14820 name: "EarlyData-NonZeroRTTSession-Client-TLS13", 14821 config: Config{ 14822 MaxVersion: VersionTLS13, 14823 }, 14824 resumeSession: true, 14825 flags: []string{ 14826 "-enable-early-data", 14827 "-on-resume-expect-no-offer-early-data", 14828 // The client declines to offer 0-RTT because of the session. 14829 "-on-resume-expect-early-data-reason", "unsupported_for_session", 14830 }, 14831 }) 14832 14833 // Test that the server correctly rejects 0-RTT when the previous 14834 // session did not allow early data on resumption. 14835 testCases = append(testCases, testCase{ 14836 testType: serverTest, 14837 name: "EarlyData-NonZeroRTTSession-Server-TLS13", 14838 config: Config{ 14839 MaxVersion: VersionTLS13, 14840 }, 14841 resumeConfig: &Config{ 14842 MaxVersion: VersionTLS13, 14843 Bugs: ProtocolBugs{ 14844 SendEarlyData: [][]byte{{1, 2, 3, 4}}, 14845 ExpectEarlyDataAccepted: false, 14846 }, 14847 }, 14848 resumeSession: true, 14849 // This test configures early data manually instead of the earlyData 14850 // option, to customize the -enable-early-data flag. 14851 flags: []string{ 14852 "-on-resume-enable-early-data", 14853 "-expect-reject-early-data", 14854 // The server rejects 0-RTT because of the session. 14855 "-on-resume-expect-early-data-reason", "unsupported_for_session", 14856 }, 14857 }) 14858 14859 // Test that we reject early data where ALPN is omitted from the first 14860 // connection, but negotiated in the second. 14861 testCases = append(testCases, testCase{ 14862 testType: serverTest, 14863 name: "EarlyData-ALPNOmitted1-Server-TLS13", 14864 config: Config{ 14865 MaxVersion: VersionTLS13, 14866 NextProtos: []string{}, 14867 }, 14868 resumeConfig: &Config{ 14869 MaxVersion: VersionTLS13, 14870 NextProtos: []string{"foo"}, 14871 }, 14872 resumeSession: true, 14873 earlyData: true, 14874 expectEarlyDataRejected: true, 14875 flags: []string{ 14876 "-on-initial-select-alpn", "", 14877 "-on-resume-select-alpn", "foo", 14878 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14879 }, 14880 }) 14881 14882 // Test that we reject early data where ALPN is omitted from the second 14883 // connection, but negotiated in the first. 14884 testCases = append(testCases, testCase{ 14885 testType: serverTest, 14886 name: "EarlyData-ALPNOmitted2-Server-TLS13", 14887 config: Config{ 14888 MaxVersion: VersionTLS13, 14889 NextProtos: []string{"foo"}, 14890 }, 14891 resumeConfig: &Config{ 14892 MaxVersion: VersionTLS13, 14893 NextProtos: []string{}, 14894 }, 14895 resumeSession: true, 14896 earlyData: true, 14897 expectEarlyDataRejected: true, 14898 flags: []string{ 14899 "-on-initial-select-alpn", "foo", 14900 "-on-resume-select-alpn", "", 14901 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14902 }, 14903 }) 14904 14905 // Test that we reject early data with mismatched ALPN. 14906 testCases = append(testCases, testCase{ 14907 testType: serverTest, 14908 name: "EarlyData-ALPNMismatch-Server-TLS13", 14909 config: Config{ 14910 MaxVersion: VersionTLS13, 14911 NextProtos: []string{"foo"}, 14912 }, 14913 resumeConfig: &Config{ 14914 MaxVersion: VersionTLS13, 14915 NextProtos: []string{"bar"}, 14916 }, 14917 resumeSession: true, 14918 earlyData: true, 14919 expectEarlyDataRejected: true, 14920 flags: []string{ 14921 "-on-initial-select-alpn", "foo", 14922 "-on-resume-select-alpn", "bar", 14923 "-on-resume-expect-early-data-reason", "alpn_mismatch", 14924 }, 14925 }) 14926 14927 // Test that the client offering 0-RTT and Channel ID forbids the server 14928 // from accepting both. 14929 testCases = append(testCases, testCase{ 14930 testType: clientTest, 14931 name: "EarlyDataChannelID-AcceptBoth-Client-TLS13", 14932 config: Config{ 14933 MaxVersion: VersionTLS13, 14934 RequestChannelID: true, 14935 }, 14936 resumeSession: true, 14937 earlyData: true, 14938 expectations: connectionExpectations{ 14939 channelID: true, 14940 }, 14941 shouldFail: true, 14942 expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:", 14943 expectedLocalError: "remote error: illegal parameter", 14944 flags: []string{ 14945 "-send-channel-id", channelIDKeyPath, 14946 }, 14947 }) 14948 14949 // Test that the client offering Channel ID and 0-RTT allows the server 14950 // to decline 0-RTT. 14951 testCases = append(testCases, testCase{ 14952 testType: clientTest, 14953 name: "EarlyDataChannelID-AcceptChannelID-Client-TLS13", 14954 config: Config{ 14955 MaxVersion: VersionTLS13, 14956 RequestChannelID: true, 14957 Bugs: ProtocolBugs{ 14958 AlwaysRejectEarlyData: true, 14959 }, 14960 }, 14961 resumeSession: true, 14962 earlyData: true, 14963 expectEarlyDataRejected: true, 14964 expectations: connectionExpectations{ 14965 channelID: true, 14966 }, 14967 flags: []string{ 14968 "-send-channel-id", channelIDKeyPath, 14969 // The client never learns the reason was Channel ID. 14970 "-on-retry-expect-early-data-reason", "peer_declined", 14971 }, 14972 }) 14973 14974 // Test that the client offering Channel ID and 0-RTT allows the server 14975 // to decline Channel ID. 14976 testCases = append(testCases, testCase{ 14977 testType: clientTest, 14978 name: "EarlyDataChannelID-AcceptEarlyData-Client-TLS13", 14979 config: Config{ 14980 MaxVersion: VersionTLS13, 14981 }, 14982 resumeSession: true, 14983 earlyData: true, 14984 flags: []string{ 14985 "-send-channel-id", channelIDKeyPath, 14986 }, 14987 }) 14988 14989 // Test that the server supporting Channel ID and 0-RTT declines 0-RTT 14990 // if it would negotiate Channel ID. 14991 testCases = append(testCases, testCase{ 14992 testType: serverTest, 14993 name: "EarlyDataChannelID-OfferBoth-Server-TLS13", 14994 config: Config{ 14995 MaxVersion: VersionTLS13, 14996 ChannelID: &channelIDKey, 14997 }, 14998 resumeSession: true, 14999 earlyData: true, 15000 expectEarlyDataRejected: true, 15001 expectations: connectionExpectations{ 15002 channelID: true, 15003 }, 15004 flags: []string{ 15005 "-expect-channel-id", 15006 base64FlagValue(channelIDBytes), 15007 "-on-resume-expect-early-data-reason", "channel_id", 15008 }, 15009 }) 15010 15011 // Test that the server supporting Channel ID and 0-RTT accepts 0-RTT 15012 // if not offered Channel ID. 15013 testCases = append(testCases, testCase{ 15014 testType: serverTest, 15015 name: "EarlyDataChannelID-OfferEarlyData-Server-TLS13", 15016 config: Config{ 15017 MaxVersion: VersionTLS13, 15018 }, 15019 resumeSession: true, 15020 earlyData: true, 15021 expectations: connectionExpectations{ 15022 channelID: false, 15023 }, 15024 flags: []string{ 15025 "-enable-channel-id", 15026 "-on-resume-expect-early-data-reason", "accept", 15027 }, 15028 }) 15029 15030 // Test that the server errors on 0-RTT streams without end_of_early_data. 15031 // The subsequent records should fail to decrypt. 15032 testCases = append(testCases, testCase{ 15033 testType: serverTest, 15034 name: "EarlyData-SkipEndOfEarlyData-TLS13", 15035 config: Config{ 15036 MaxVersion: VersionTLS13, 15037 Bugs: ProtocolBugs{ 15038 SkipEndOfEarlyData: true, 15039 }, 15040 }, 15041 resumeSession: true, 15042 earlyData: true, 15043 shouldFail: true, 15044 expectedLocalError: "remote error: bad record MAC", 15045 expectedError: ":BAD_DECRYPT:", 15046 }) 15047 15048 // Test that the server errors on 0-RTT streams with a stray handshake 15049 // message in them. 15050 testCases = append(testCases, testCase{ 15051 testType: serverTest, 15052 name: "EarlyData-UnexpectedHandshake-Server-TLS13", 15053 config: Config{ 15054 MaxVersion: VersionTLS13, 15055 }, 15056 resumeConfig: &Config{ 15057 MaxVersion: VersionTLS13, 15058 Bugs: ProtocolBugs{ 15059 SendStrayEarlyHandshake: true, 15060 }, 15061 }, 15062 resumeSession: true, 15063 earlyData: true, 15064 shouldFail: true, 15065 expectedError: ":UNEXPECTED_MESSAGE:", 15066 expectedLocalError: "remote error: unexpected message", 15067 }) 15068 15069 // Test that the client reports TLS 1.3 as the version while sending 15070 // early data. 15071 testCases = append(testCases, testCase{ 15072 testType: clientTest, 15073 name: "EarlyData-Client-VersionAPI-TLS13", 15074 config: Config{ 15075 MaxVersion: VersionTLS13, 15076 }, 15077 resumeSession: true, 15078 earlyData: true, 15079 flags: []string{ 15080 "-expect-version", strconv.Itoa(VersionTLS13), 15081 }, 15082 }) 15083 15084 // Test that client and server both notice handshake errors after data 15085 // has started flowing. 15086 testCases = append(testCases, testCase{ 15087 testType: clientTest, 15088 name: "EarlyData-Client-BadFinished-TLS13", 15089 config: Config{ 15090 MaxVersion: VersionTLS13, 15091 }, 15092 resumeConfig: &Config{ 15093 MaxVersion: VersionTLS13, 15094 Bugs: ProtocolBugs{ 15095 BadFinished: true, 15096 }, 15097 }, 15098 resumeSession: true, 15099 earlyData: true, 15100 shouldFail: true, 15101 expectedError: ":DIGEST_CHECK_FAILED:", 15102 expectedLocalError: "remote error: error decrypting message", 15103 }) 15104 testCases = append(testCases, testCase{ 15105 testType: serverTest, 15106 name: "EarlyData-Server-BadFinished-TLS13", 15107 config: Config{ 15108 MaxVersion: VersionTLS13, 15109 }, 15110 resumeConfig: &Config{ 15111 MaxVersion: VersionTLS13, 15112 Bugs: ProtocolBugs{ 15113 BadFinished: true, 15114 }, 15115 }, 15116 resumeSession: true, 15117 earlyData: true, 15118 shouldFail: true, 15119 expectedError: ":DIGEST_CHECK_FAILED:", 15120 expectedLocalError: "remote error: error decrypting message", 15121 }) 15122 15123 testCases = append(testCases, testCase{ 15124 testType: serverTest, 15125 name: "Server-NonEmptyEndOfEarlyData-TLS13", 15126 config: Config{ 15127 MaxVersion: VersionTLS13, 15128 }, 15129 resumeConfig: &Config{ 15130 MaxVersion: VersionTLS13, 15131 Bugs: ProtocolBugs{ 15132 NonEmptyEndOfEarlyData: true, 15133 }, 15134 }, 15135 resumeSession: true, 15136 earlyData: true, 15137 shouldFail: true, 15138 expectedError: ":DECODE_ERROR:", 15139 }) 15140 15141 testCases = append(testCases, testCase{ 15142 testType: serverTest, 15143 name: "ServerSkipCertificateVerify-TLS13", 15144 config: Config{ 15145 MinVersion: VersionTLS13, 15146 MaxVersion: VersionTLS13, 15147 Credential: &rsaChainCertificate, 15148 Bugs: ProtocolBugs{ 15149 SkipCertificateVerify: true, 15150 }, 15151 }, 15152 expectations: connectionExpectations{ 15153 peerCertificate: &rsaCertificate, 15154 }, 15155 shimCertificate: &rsaCertificate, 15156 flags: []string{ 15157 "-require-any-client-certificate", 15158 }, 15159 shouldFail: true, 15160 expectedError: ":UNEXPECTED_MESSAGE:", 15161 expectedLocalError: "remote error: unexpected message", 15162 }) 15163 testCases = append(testCases, testCase{ 15164 testType: clientTest, 15165 name: "ClientSkipCertificateVerify-TLS13", 15166 config: Config{ 15167 MinVersion: VersionTLS13, 15168 MaxVersion: VersionTLS13, 15169 Credential: &rsaChainCertificate, 15170 Bugs: ProtocolBugs{ 15171 SkipCertificateVerify: true, 15172 }, 15173 }, 15174 expectations: connectionExpectations{ 15175 peerCertificate: &rsaCertificate, 15176 }, 15177 shimCertificate: &rsaCertificate, 15178 shouldFail: true, 15179 expectedError: ":UNEXPECTED_MESSAGE:", 15180 expectedLocalError: "remote error: unexpected message", 15181 }) 15182 15183 // If the client or server has 0-RTT enabled but disabled TLS 1.3, it should 15184 // report a reason of protocol_version. 15185 testCases = append(testCases, testCase{ 15186 testType: clientTest, 15187 name: "EarlyDataEnabled-Client-MaxTLS12", 15188 expectations: connectionExpectations{ 15189 version: VersionTLS12, 15190 }, 15191 flags: []string{ 15192 "-enable-early-data", 15193 "-max-version", strconv.Itoa(VersionTLS12), 15194 "-expect-early-data-reason", "protocol_version", 15195 }, 15196 }) 15197 testCases = append(testCases, testCase{ 15198 testType: serverTest, 15199 name: "EarlyDataEnabled-Server-MaxTLS12", 15200 expectations: connectionExpectations{ 15201 version: VersionTLS12, 15202 }, 15203 flags: []string{ 15204 "-enable-early-data", 15205 "-max-version", strconv.Itoa(VersionTLS12), 15206 "-expect-early-data-reason", "protocol_version", 15207 }, 15208 }) 15209 15210 // The server additionally reports protocol_version if it enabled TLS 1.3, 15211 // but the peer negotiated TLS 1.2. (The corresponding situation does not 15212 // exist on the client because negotiating TLS 1.2 with a 0-RTT ClientHello 15213 // is a fatal error.) 15214 testCases = append(testCases, testCase{ 15215 testType: serverTest, 15216 name: "EarlyDataEnabled-Server-NegotiateTLS12", 15217 config: Config{ 15218 MaxVersion: VersionTLS12, 15219 }, 15220 expectations: connectionExpectations{ 15221 version: VersionTLS12, 15222 }, 15223 flags: []string{ 15224 "-enable-early-data", 15225 "-expect-early-data-reason", "protocol_version", 15226 }, 15227 }) 15228 15229 // On 0-RTT reject, the server may end up negotiating a cipher suite with a 15230 // different PRF hash. Test that the client handles this correctly. 15231 testCases = append(testCases, testCase{ 15232 testType: clientTest, 15233 name: "EarlyData-Reject0RTT-DifferentPRF-Client", 15234 config: Config{ 15235 MaxVersion: VersionTLS13, 15236 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 15237 }, 15238 resumeConfig: &Config{ 15239 MaxVersion: VersionTLS13, 15240 CipherSuites: []uint16{TLS_AES_256_GCM_SHA384}, 15241 }, 15242 resumeSession: true, 15243 expectResumeRejected: true, 15244 earlyData: true, 15245 expectEarlyDataRejected: true, 15246 flags: []string{ 15247 "-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15248 // The client initially reports the old cipher suite while sending 15249 // early data. After processing the 0-RTT reject, it reports the 15250 // true cipher suite. 15251 "-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15252 "-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)), 15253 }, 15254 }) 15255 testCases = append(testCases, testCase{ 15256 testType: clientTest, 15257 name: "EarlyData-Reject0RTT-DifferentPRF-HRR-Client", 15258 config: Config{ 15259 MaxVersion: VersionTLS13, 15260 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 15261 }, 15262 resumeConfig: &Config{ 15263 MaxVersion: VersionTLS13, 15264 CipherSuites: []uint16{TLS_AES_256_GCM_SHA384}, 15265 // P-384 requires a HelloRetryRequest against BoringSSL's default 15266 // configuration. Assert this with ExpectMissingKeyShare. 15267 CurvePreferences: []CurveID{CurveP384}, 15268 Bugs: ProtocolBugs{ 15269 ExpectMissingKeyShare: true, 15270 }, 15271 }, 15272 resumeSession: true, 15273 expectResumeRejected: true, 15274 earlyData: true, 15275 expectEarlyDataRejected: true, 15276 flags: []string{ 15277 "-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15278 // The client initially reports the old cipher suite while sending 15279 // early data. After processing the 0-RTT reject, it reports the 15280 // true cipher suite. 15281 "-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15282 "-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)), 15283 }, 15284 }) 15285 15286 // Test that the client enforces cipher suite match on 0-RTT accept. 15287 testCases = append(testCases, testCase{ 15288 testType: clientTest, 15289 name: "EarlyData-CipherMismatch-Client-TLS13", 15290 config: Config{ 15291 MaxVersion: VersionTLS13, 15292 CipherSuites: []uint16{TLS_AES_128_GCM_SHA256}, 15293 }, 15294 resumeConfig: &Config{ 15295 MaxVersion: VersionTLS13, 15296 CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256}, 15297 Bugs: ProtocolBugs{ 15298 AlwaysAcceptEarlyData: true, 15299 }, 15300 }, 15301 resumeSession: true, 15302 earlyData: true, 15303 shouldFail: true, 15304 expectedError: ":CIPHER_MISMATCH_ON_EARLY_DATA:", 15305 expectedLocalError: "remote error: illegal parameter", 15306 }) 15307 15308 // Test that the client can write early data when it has received a partial 15309 // ServerHello..Finished flight. See https://crbug.com/1208784. Note the 15310 // EncryptedExtensions test assumes EncryptedExtensions and Finished are in 15311 // separate records, i.e. that PackHandshakeFlight is disabled. 15312 testCases = append(testCases, testCase{ 15313 testType: clientTest, 15314 name: "EarlyData-WriteAfterServerHello", 15315 config: Config{ 15316 MinVersion: VersionTLS13, 15317 MaxVersion: VersionTLS13, 15318 Bugs: ProtocolBugs{ 15319 // Write the server response before expecting early data. 15320 ExpectEarlyData: [][]byte{}, 15321 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 15322 }, 15323 }, 15324 resumeSession: true, 15325 earlyData: true, 15326 flags: []string{ 15327 "-async", 15328 "-on-resume-early-write-after-message", 15329 strconv.Itoa(int(typeServerHello)), 15330 }, 15331 }) 15332 testCases = append(testCases, testCase{ 15333 testType: clientTest, 15334 name: "EarlyData-WriteAfterEncryptedExtensions", 15335 config: Config{ 15336 MinVersion: VersionTLS13, 15337 MaxVersion: VersionTLS13, 15338 Bugs: ProtocolBugs{ 15339 // Write the server response before expecting early data. 15340 ExpectEarlyData: [][]byte{}, 15341 ExpectLateEarlyData: [][]byte{[]byte(shimInitialWrite)}, 15342 }, 15343 }, 15344 resumeSession: true, 15345 earlyData: true, 15346 flags: []string{ 15347 "-async", 15348 "-on-resume-early-write-after-message", 15349 strconv.Itoa(int(typeEncryptedExtensions)), 15350 }, 15351 }) 15352} 15353 15354func addTLS13CipherPreferenceTests() { 15355 // Test that client preference is honored if the shim has AES hardware 15356 // and ChaCha20-Poly1305 is preferred otherwise. 15357 testCases = append(testCases, testCase{ 15358 testType: serverTest, 15359 name: "TLS13-CipherPreference-Server-ChaCha20-AES", 15360 config: Config{ 15361 MaxVersion: VersionTLS13, 15362 CipherSuites: []uint16{ 15363 TLS_CHACHA20_POLY1305_SHA256, 15364 TLS_AES_128_GCM_SHA256, 15365 }, 15366 CurvePreferences: []CurveID{CurveX25519}, 15367 }, 15368 flags: []string{ 15369 "-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15370 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15371 }, 15372 }) 15373 15374 testCases = append(testCases, testCase{ 15375 testType: serverTest, 15376 name: "TLS13-CipherPreference-Server-AES-ChaCha20", 15377 config: Config{ 15378 MaxVersion: VersionTLS13, 15379 CipherSuites: []uint16{ 15380 TLS_AES_128_GCM_SHA256, 15381 TLS_CHACHA20_POLY1305_SHA256, 15382 }, 15383 CurvePreferences: []CurveID{CurveX25519}, 15384 }, 15385 flags: []string{ 15386 "-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15387 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15388 }, 15389 }) 15390 15391 // Test that the client orders ChaCha20-Poly1305 and AES-GCM based on 15392 // whether it has AES hardware. 15393 testCases = append(testCases, testCase{ 15394 name: "TLS13-CipherPreference-Client", 15395 config: Config{ 15396 MaxVersion: VersionTLS13, 15397 // Use the client cipher order. (This is the default but 15398 // is listed to be explicit.) 15399 PreferServerCipherSuites: false, 15400 }, 15401 flags: []string{ 15402 "-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)), 15403 "-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)), 15404 }, 15405 }) 15406} 15407 15408func addPeekTests() { 15409 // Test SSL_peek works, including on empty records. 15410 testCases = append(testCases, testCase{ 15411 name: "Peek-Basic", 15412 sendEmptyRecords: 1, 15413 flags: []string{"-peek-then-read"}, 15414 }) 15415 15416 // Test SSL_peek can drive the initial handshake. 15417 testCases = append(testCases, testCase{ 15418 name: "Peek-ImplicitHandshake", 15419 flags: []string{ 15420 "-peek-then-read", 15421 "-implicit-handshake", 15422 }, 15423 }) 15424 15425 // Test SSL_peek can discover and drive a renegotiation. 15426 testCases = append(testCases, testCase{ 15427 name: "Peek-Renegotiate", 15428 config: Config{ 15429 MaxVersion: VersionTLS12, 15430 }, 15431 renegotiate: 1, 15432 flags: []string{ 15433 "-peek-then-read", 15434 "-renegotiate-freely", 15435 "-expect-total-renegotiations", "1", 15436 }, 15437 }) 15438 15439 // Test SSL_peek can discover a close_notify. 15440 testCases = append(testCases, testCase{ 15441 name: "Peek-Shutdown", 15442 config: Config{ 15443 Bugs: ProtocolBugs{ 15444 ExpectCloseNotify: true, 15445 }, 15446 }, 15447 flags: []string{ 15448 "-peek-then-read", 15449 "-check-close-notify", 15450 }, 15451 }) 15452 15453 // Test SSL_peek can discover an alert. 15454 testCases = append(testCases, testCase{ 15455 name: "Peek-Alert", 15456 config: Config{ 15457 Bugs: ProtocolBugs{ 15458 SendSpuriousAlert: alertRecordOverflow, 15459 }, 15460 }, 15461 flags: []string{"-peek-then-read"}, 15462 shouldFail: true, 15463 expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", 15464 }) 15465 15466 // Test SSL_peek can handle KeyUpdate. 15467 testCases = append(testCases, testCase{ 15468 name: "Peek-KeyUpdate", 15469 config: Config{ 15470 MaxVersion: VersionTLS13, 15471 }, 15472 sendKeyUpdates: 1, 15473 keyUpdateRequest: keyUpdateNotRequested, 15474 flags: []string{"-peek-then-read"}, 15475 }) 15476} 15477 15478func addRecordVersionTests() { 15479 for _, ver := range tlsVersions { 15480 // Test that the record version is enforced. 15481 testCases = append(testCases, testCase{ 15482 name: "CheckRecordVersion-" + ver.name, 15483 config: Config{ 15484 MinVersion: ver.version, 15485 MaxVersion: ver.version, 15486 Bugs: ProtocolBugs{ 15487 SendRecordVersion: 0x03ff, 15488 }, 15489 }, 15490 shouldFail: true, 15491 expectedError: ":WRONG_VERSION_NUMBER:", 15492 }) 15493 15494 // Test that the ClientHello may use any record version, for 15495 // compatibility reasons. 15496 testCases = append(testCases, testCase{ 15497 testType: serverTest, 15498 name: "LooseInitialRecordVersion-" + ver.name, 15499 config: Config{ 15500 MinVersion: ver.version, 15501 MaxVersion: ver.version, 15502 Bugs: ProtocolBugs{ 15503 SendInitialRecordVersion: 0x03ff, 15504 }, 15505 }, 15506 }) 15507 15508 // Test that garbage ClientHello record versions are rejected. 15509 testCases = append(testCases, testCase{ 15510 testType: serverTest, 15511 name: "GarbageInitialRecordVersion-" + ver.name, 15512 config: Config{ 15513 MinVersion: ver.version, 15514 MaxVersion: ver.version, 15515 Bugs: ProtocolBugs{ 15516 SendInitialRecordVersion: 0xffff, 15517 }, 15518 }, 15519 shouldFail: true, 15520 expectedError: ":WRONG_VERSION_NUMBER:", 15521 }) 15522 } 15523} 15524 15525func addCertificateTests() { 15526 for _, ver := range tlsVersions { 15527 // Test that a certificate chain with intermediate may be sent 15528 // and received as both client and server. 15529 testCases = append(testCases, testCase{ 15530 testType: clientTest, 15531 name: "SendReceiveIntermediate-Client-" + ver.name, 15532 config: Config{ 15533 MinVersion: ver.version, 15534 MaxVersion: ver.version, 15535 Credential: &rsaChainCertificate, 15536 ClientAuth: RequireAnyClientCert, 15537 }, 15538 expectations: connectionExpectations{ 15539 peerCertificate: &rsaChainCertificate, 15540 }, 15541 shimCertificate: &rsaChainCertificate, 15542 flags: []string{ 15543 "-expect-peer-cert-file", rsaChainCertificate.ChainPath, 15544 }, 15545 }) 15546 15547 testCases = append(testCases, testCase{ 15548 testType: serverTest, 15549 name: "SendReceiveIntermediate-Server-" + ver.name, 15550 config: Config{ 15551 MinVersion: ver.version, 15552 MaxVersion: ver.version, 15553 Credential: &rsaChainCertificate, 15554 }, 15555 expectations: connectionExpectations{ 15556 peerCertificate: &rsaChainCertificate, 15557 }, 15558 shimCertificate: &rsaChainCertificate, 15559 flags: []string{ 15560 "-require-any-client-certificate", 15561 "-expect-peer-cert-file", rsaChainCertificate.ChainPath, 15562 }, 15563 }) 15564 15565 // Test that garbage leaf certificates are properly rejected. 15566 testCases = append(testCases, testCase{ 15567 testType: clientTest, 15568 name: "GarbageCertificate-Client-" + ver.name, 15569 config: Config{ 15570 MinVersion: ver.version, 15571 MaxVersion: ver.version, 15572 Credential: &garbageCertificate, 15573 }, 15574 shouldFail: true, 15575 expectedError: ":CANNOT_PARSE_LEAF_CERT:", 15576 expectedLocalError: "remote error: error decoding message", 15577 }) 15578 15579 testCases = append(testCases, testCase{ 15580 testType: serverTest, 15581 name: "GarbageCertificate-Server-" + ver.name, 15582 config: Config{ 15583 MinVersion: ver.version, 15584 MaxVersion: ver.version, 15585 Credential: &garbageCertificate, 15586 }, 15587 flags: []string{"-require-any-client-certificate"}, 15588 shouldFail: true, 15589 expectedError: ":CANNOT_PARSE_LEAF_CERT:", 15590 expectedLocalError: "remote error: error decoding message", 15591 }) 15592 } 15593} 15594 15595func addRetainOnlySHA256ClientCertTests() { 15596 for _, ver := range tlsVersions { 15597 // Test that enabling 15598 // SSL_CTX_set_retain_only_sha256_of_client_certs without 15599 // actually requesting a client certificate is a no-op. 15600 testCases = append(testCases, testCase{ 15601 testType: serverTest, 15602 name: "RetainOnlySHA256-NoCert-" + ver.name, 15603 config: Config{ 15604 MinVersion: ver.version, 15605 MaxVersion: ver.version, 15606 }, 15607 flags: []string{ 15608 "-on-initial-retain-only-sha256-client-cert", 15609 "-on-resume-retain-only-sha256-client-cert", 15610 }, 15611 resumeSession: true, 15612 }) 15613 15614 // Test that when retaining only a SHA-256 certificate is 15615 // enabled, the hash appears as expected. 15616 testCases = append(testCases, testCase{ 15617 testType: serverTest, 15618 name: "RetainOnlySHA256-Cert-" + ver.name, 15619 config: Config{ 15620 MinVersion: ver.version, 15621 MaxVersion: ver.version, 15622 Credential: &rsaCertificate, 15623 }, 15624 flags: []string{ 15625 "-verify-peer", 15626 "-on-initial-retain-only-sha256-client-cert", 15627 "-on-resume-retain-only-sha256-client-cert", 15628 "-on-initial-expect-sha256-client-cert", 15629 "-on-resume-expect-sha256-client-cert", 15630 }, 15631 resumeSession: true, 15632 }) 15633 15634 // Test that when the config changes from on to off, a 15635 // resumption is rejected because the server now wants the full 15636 // certificate chain. 15637 testCases = append(testCases, testCase{ 15638 testType: serverTest, 15639 name: "RetainOnlySHA256-OnOff-" + ver.name, 15640 config: Config{ 15641 MinVersion: ver.version, 15642 MaxVersion: ver.version, 15643 Credential: &rsaCertificate, 15644 }, 15645 flags: []string{ 15646 "-verify-peer", 15647 "-on-initial-retain-only-sha256-client-cert", 15648 "-on-initial-expect-sha256-client-cert", 15649 }, 15650 resumeSession: true, 15651 expectResumeRejected: true, 15652 }) 15653 15654 // Test that when the config changes from off to on, a 15655 // resumption is rejected because the server now wants just the 15656 // hash. 15657 testCases = append(testCases, testCase{ 15658 testType: serverTest, 15659 name: "RetainOnlySHA256-OffOn-" + ver.name, 15660 config: Config{ 15661 MinVersion: ver.version, 15662 MaxVersion: ver.version, 15663 Credential: &rsaCertificate, 15664 }, 15665 flags: []string{ 15666 "-verify-peer", 15667 "-on-resume-retain-only-sha256-client-cert", 15668 "-on-resume-expect-sha256-client-cert", 15669 }, 15670 resumeSession: true, 15671 expectResumeRejected: true, 15672 }) 15673 } 15674} 15675 15676func addECDSAKeyUsageTests() { 15677 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 15678 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 15679 if err != nil { 15680 panic(err) 15681 } 15682 15683 template := &x509.Certificate{ 15684 SerialNumber: serialNumber, 15685 Subject: pkix.Name{ 15686 Organization: []string{"Acme Co"}, 15687 }, 15688 NotBefore: time.Now(), 15689 NotAfter: time.Now(), 15690 15691 // An ECC certificate with only the keyAgreement key usgae may 15692 // be used with ECDH, but not ECDSA. 15693 KeyUsage: x509.KeyUsageKeyAgreement, 15694 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 15695 BasicConstraintsValid: true, 15696 } 15697 15698 cert := generateSingleCertChain(template, &ecdsaP256Key) 15699 15700 for _, ver := range tlsVersions { 15701 if ver.version < VersionTLS12 { 15702 continue 15703 } 15704 15705 testCases = append(testCases, testCase{ 15706 testType: clientTest, 15707 name: "ECDSAKeyUsage-Client-" + ver.name, 15708 config: Config{ 15709 MinVersion: ver.version, 15710 MaxVersion: ver.version, 15711 Credential: &cert, 15712 }, 15713 shouldFail: true, 15714 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15715 }) 15716 15717 testCases = append(testCases, testCase{ 15718 testType: serverTest, 15719 name: "ECDSAKeyUsage-Server-" + ver.name, 15720 config: Config{ 15721 MinVersion: ver.version, 15722 MaxVersion: ver.version, 15723 Credential: &cert, 15724 }, 15725 flags: []string{"-require-any-client-certificate"}, 15726 shouldFail: true, 15727 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15728 }) 15729 } 15730} 15731 15732func addRSAKeyUsageTests() { 15733 priv := rsaCertificate.PrivateKey.(*rsa.PrivateKey) 15734 15735 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 15736 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 15737 if err != nil { 15738 panic(err) 15739 } 15740 15741 dsTemplate := x509.Certificate{ 15742 SerialNumber: serialNumber, 15743 Subject: pkix.Name{ 15744 Organization: []string{"Acme Co"}, 15745 }, 15746 NotBefore: time.Now(), 15747 NotAfter: time.Now(), 15748 15749 KeyUsage: x509.KeyUsageDigitalSignature, 15750 BasicConstraintsValid: true, 15751 } 15752 15753 encTemplate := x509.Certificate{ 15754 SerialNumber: serialNumber, 15755 Subject: pkix.Name{ 15756 Organization: []string{"Acme Co"}, 15757 }, 15758 NotBefore: time.Now(), 15759 NotAfter: time.Now(), 15760 15761 KeyUsage: x509.KeyUsageKeyEncipherment, 15762 BasicConstraintsValid: true, 15763 } 15764 15765 dsCert := generateSingleCertChain(&dsTemplate, priv) 15766 15767 encCert := generateSingleCertChain(&encTemplate, priv) 15768 15769 dsSuites := []uint16{ 15770 TLS_AES_128_GCM_SHA256, 15771 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 15772 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 15773 } 15774 encSuites := []uint16{ 15775 TLS_RSA_WITH_AES_128_GCM_SHA256, 15776 TLS_RSA_WITH_AES_128_CBC_SHA, 15777 } 15778 15779 for _, ver := range tlsVersions { 15780 testCases = append(testCases, testCase{ 15781 testType: clientTest, 15782 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-" + ver.name, 15783 config: Config{ 15784 MinVersion: ver.version, 15785 MaxVersion: ver.version, 15786 Credential: &encCert, 15787 CipherSuites: dsSuites, 15788 }, 15789 shouldFail: true, 15790 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15791 }) 15792 15793 testCases = append(testCases, testCase{ 15794 testType: clientTest, 15795 name: "RSAKeyUsage-Client-WantSignature-GotSignature-" + ver.name, 15796 config: Config{ 15797 MinVersion: ver.version, 15798 MaxVersion: ver.version, 15799 Credential: &dsCert, 15800 CipherSuites: dsSuites, 15801 }, 15802 }) 15803 15804 // TLS 1.3 removes the encipherment suites. 15805 if ver.version < VersionTLS13 { 15806 testCases = append(testCases, testCase{ 15807 testType: clientTest, 15808 name: "RSAKeyUsage-Client-WantEncipherment-GotEncipherment" + ver.name, 15809 config: Config{ 15810 MinVersion: ver.version, 15811 MaxVersion: ver.version, 15812 Credential: &encCert, 15813 CipherSuites: encSuites, 15814 }, 15815 }) 15816 15817 testCases = append(testCases, testCase{ 15818 testType: clientTest, 15819 name: "RSAKeyUsage-Client-WantEncipherment-GotSignature-" + ver.name, 15820 config: Config{ 15821 MinVersion: ver.version, 15822 MaxVersion: ver.version, 15823 Credential: &dsCert, 15824 CipherSuites: encSuites, 15825 }, 15826 shouldFail: true, 15827 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15828 }) 15829 15830 // In 1.2 and below, we should not enforce without the enforce-rsa-key-usage flag. 15831 testCases = append(testCases, testCase{ 15832 testType: clientTest, 15833 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-Unenforced-" + ver.name, 15834 config: Config{ 15835 MinVersion: ver.version, 15836 MaxVersion: ver.version, 15837 Credential: &dsCert, 15838 CipherSuites: encSuites, 15839 }, 15840 flags: []string{"-expect-key-usage-invalid", "-ignore-rsa-key-usage"}, 15841 }) 15842 15843 testCases = append(testCases, testCase{ 15844 testType: clientTest, 15845 name: "RSAKeyUsage-Client-WantEncipherment-GotSignature-Unenforced-" + ver.name, 15846 config: Config{ 15847 MinVersion: ver.version, 15848 MaxVersion: ver.version, 15849 Credential: &encCert, 15850 CipherSuites: dsSuites, 15851 }, 15852 flags: []string{"-expect-key-usage-invalid", "-ignore-rsa-key-usage"}, 15853 }) 15854 } 15855 15856 if ver.version >= VersionTLS13 { 15857 // In 1.3 and above, we enforce keyUsage even when disabled. 15858 testCases = append(testCases, testCase{ 15859 testType: clientTest, 15860 name: "RSAKeyUsage-Client-WantSignature-GotEncipherment-AlwaysEnforced-" + ver.name, 15861 config: Config{ 15862 MinVersion: ver.version, 15863 MaxVersion: ver.version, 15864 Credential: &encCert, 15865 CipherSuites: dsSuites, 15866 }, 15867 flags: []string{"-ignore-rsa-key-usage"}, 15868 shouldFail: true, 15869 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15870 }) 15871 } 15872 15873 // The server only uses signatures and always enforces it. 15874 testCases = append(testCases, testCase{ 15875 testType: serverTest, 15876 name: "RSAKeyUsage-Server-WantSignature-GotEncipherment-" + ver.name, 15877 config: Config{ 15878 MinVersion: ver.version, 15879 MaxVersion: ver.version, 15880 Credential: &encCert, 15881 }, 15882 shouldFail: true, 15883 expectedError: ":KEY_USAGE_BIT_INCORRECT:", 15884 flags: []string{"-require-any-client-certificate"}, 15885 }) 15886 15887 testCases = append(testCases, testCase{ 15888 testType: serverTest, 15889 name: "RSAKeyUsage-Server-WantSignature-GotSignature-" + ver.name, 15890 config: Config{ 15891 MinVersion: ver.version, 15892 MaxVersion: ver.version, 15893 Credential: &dsCert, 15894 }, 15895 flags: []string{"-require-any-client-certificate"}, 15896 }) 15897 15898 } 15899} 15900 15901func addExtraHandshakeTests() { 15902 // An extra SSL_do_handshake is normally a no-op. These tests use -async 15903 // to ensure there is no transport I/O. 15904 testCases = append(testCases, testCase{ 15905 testType: clientTest, 15906 name: "ExtraHandshake-Client-TLS12", 15907 config: Config{ 15908 MinVersion: VersionTLS12, 15909 MaxVersion: VersionTLS12, 15910 }, 15911 flags: []string{ 15912 "-async", 15913 "-no-op-extra-handshake", 15914 }, 15915 }) 15916 testCases = append(testCases, testCase{ 15917 testType: serverTest, 15918 name: "ExtraHandshake-Server-TLS12", 15919 config: Config{ 15920 MinVersion: VersionTLS12, 15921 MaxVersion: VersionTLS12, 15922 }, 15923 flags: []string{ 15924 "-async", 15925 "-no-op-extra-handshake", 15926 }, 15927 }) 15928 testCases = append(testCases, testCase{ 15929 testType: clientTest, 15930 name: "ExtraHandshake-Client-TLS13", 15931 config: Config{ 15932 MinVersion: VersionTLS13, 15933 MaxVersion: VersionTLS13, 15934 }, 15935 flags: []string{ 15936 "-async", 15937 "-no-op-extra-handshake", 15938 }, 15939 }) 15940 testCases = append(testCases, testCase{ 15941 testType: serverTest, 15942 name: "ExtraHandshake-Server-TLS13", 15943 config: Config{ 15944 MinVersion: VersionTLS13, 15945 MaxVersion: VersionTLS13, 15946 }, 15947 flags: []string{ 15948 "-async", 15949 "-no-op-extra-handshake", 15950 }, 15951 }) 15952 15953 // An extra SSL_do_handshake is a no-op in server 0-RTT. 15954 testCases = append(testCases, testCase{ 15955 testType: serverTest, 15956 name: "ExtraHandshake-Server-EarlyData-TLS13", 15957 config: Config{ 15958 MaxVersion: VersionTLS13, 15959 MinVersion: VersionTLS13, 15960 }, 15961 messageCount: 2, 15962 resumeSession: true, 15963 earlyData: true, 15964 flags: []string{ 15965 "-async", 15966 "-no-op-extra-handshake", 15967 }, 15968 }) 15969 15970 // An extra SSL_do_handshake drives the handshake to completion in False 15971 // Start. We test this by handshaking twice and asserting the False 15972 // Start does not appear to happen. See AlertBeforeFalseStartTest for 15973 // how the test works. 15974 testCases = append(testCases, testCase{ 15975 testType: clientTest, 15976 name: "ExtraHandshake-FalseStart", 15977 config: Config{ 15978 MaxVersion: VersionTLS12, 15979 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 15980 NextProtos: []string{"foo"}, 15981 Bugs: ProtocolBugs{ 15982 ExpectFalseStart: true, 15983 AlertBeforeFalseStartTest: alertAccessDenied, 15984 }, 15985 }, 15986 flags: []string{ 15987 "-handshake-twice", 15988 "-false-start", 15989 "-advertise-alpn", "\x03foo", 15990 "-expect-alpn", "foo", 15991 }, 15992 shimWritesFirst: true, 15993 shouldFail: true, 15994 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 15995 expectedLocalError: "tls: peer did not false start: EOF", 15996 }) 15997} 15998 15999// Test that omitted and empty extensions blocks are tolerated. 16000func addOmitExtensionsTests() { 16001 // Check the ExpectOmitExtensions setting works. 16002 testCases = append(testCases, testCase{ 16003 testType: serverTest, 16004 name: "ExpectOmitExtensions", 16005 config: Config{ 16006 MinVersion: VersionTLS12, 16007 MaxVersion: VersionTLS12, 16008 Bugs: ProtocolBugs{ 16009 ExpectOmitExtensions: true, 16010 }, 16011 }, 16012 shouldFail: true, 16013 expectedLocalError: "tls: ServerHello did not omit extensions", 16014 }) 16015 16016 for _, ver := range tlsVersions { 16017 if ver.version > VersionTLS12 { 16018 continue 16019 } 16020 16021 testCases = append(testCases, testCase{ 16022 testType: serverTest, 16023 name: "OmitExtensions-ClientHello-" + ver.name, 16024 config: Config{ 16025 MinVersion: ver.version, 16026 MaxVersion: ver.version, 16027 SessionTicketsDisabled: true, 16028 Bugs: ProtocolBugs{ 16029 OmitExtensions: true, 16030 // With no client extensions, the ServerHello must not have 16031 // extensions. It should then omit the extensions field. 16032 ExpectOmitExtensions: true, 16033 }, 16034 }, 16035 }) 16036 16037 testCases = append(testCases, testCase{ 16038 testType: serverTest, 16039 name: "EmptyExtensions-ClientHello-" + ver.name, 16040 config: Config{ 16041 MinVersion: ver.version, 16042 MaxVersion: ver.version, 16043 SessionTicketsDisabled: true, 16044 Bugs: ProtocolBugs{ 16045 EmptyExtensions: true, 16046 // With no client extensions, the ServerHello must not have 16047 // extensions. It should then omit the extensions field. 16048 ExpectOmitExtensions: true, 16049 }, 16050 }, 16051 }) 16052 16053 testCases = append(testCases, testCase{ 16054 testType: clientTest, 16055 name: "OmitExtensions-ServerHello-" + ver.name, 16056 config: Config{ 16057 MinVersion: ver.version, 16058 MaxVersion: ver.version, 16059 SessionTicketsDisabled: true, 16060 Bugs: ProtocolBugs{ 16061 OmitExtensions: true, 16062 // Disable all ServerHello extensions so 16063 // OmitExtensions works. 16064 NoExtendedMasterSecret: true, 16065 NoRenegotiationInfo: true, 16066 NoOCSPStapling: true, 16067 NoSignedCertificateTimestamps: true, 16068 }, 16069 }, 16070 }) 16071 16072 testCases = append(testCases, testCase{ 16073 testType: clientTest, 16074 name: "EmptyExtensions-ServerHello-" + ver.name, 16075 config: Config{ 16076 MinVersion: ver.version, 16077 MaxVersion: ver.version, 16078 SessionTicketsDisabled: true, 16079 Bugs: ProtocolBugs{ 16080 EmptyExtensions: true, 16081 // Disable all ServerHello extensions so 16082 // EmptyExtensions works. 16083 NoExtendedMasterSecret: true, 16084 NoRenegotiationInfo: true, 16085 NoOCSPStapling: true, 16086 NoSignedCertificateTimestamps: true, 16087 }, 16088 }, 16089 }) 16090 } 16091} 16092 16093const ( 16094 shrinkingCompressionAlgID = 0xff01 16095 expandingCompressionAlgID = 0xff02 16096 randomCompressionAlgID = 0xff03 16097) 16098 16099var ( 16100 // shrinkingPrefix is the first two bytes of a Certificate message. 16101 shrinkingPrefix = []byte{0, 0} 16102 // expandingPrefix is just some arbitrary byte string. This has to match the 16103 // value in the shim. 16104 expandingPrefix = []byte{1, 2, 3, 4} 16105) 16106 16107var shrinkingCompression = CertCompressionAlg{ 16108 Compress: func(uncompressed []byte) []byte { 16109 if !bytes.HasPrefix(uncompressed, shrinkingPrefix) { 16110 panic(fmt.Sprintf("cannot compress certificate message %x", uncompressed)) 16111 } 16112 return uncompressed[len(shrinkingPrefix):] 16113 }, 16114 Decompress: func(out []byte, compressed []byte) bool { 16115 if len(out) != len(shrinkingPrefix)+len(compressed) { 16116 return false 16117 } 16118 16119 copy(out, shrinkingPrefix) 16120 copy(out[len(shrinkingPrefix):], compressed) 16121 return true 16122 }, 16123} 16124 16125var expandingCompression = CertCompressionAlg{ 16126 Compress: func(uncompressed []byte) []byte { 16127 ret := make([]byte, 0, len(expandingPrefix)+len(uncompressed)) 16128 ret = append(ret, expandingPrefix...) 16129 return append(ret, uncompressed...) 16130 }, 16131 Decompress: func(out []byte, compressed []byte) bool { 16132 if !bytes.HasPrefix(compressed, expandingPrefix) { 16133 return false 16134 } 16135 copy(out, compressed[len(expandingPrefix):]) 16136 return true 16137 }, 16138} 16139 16140var randomCompression = CertCompressionAlg{ 16141 Compress: func(uncompressed []byte) []byte { 16142 ret := make([]byte, 1+len(uncompressed)) 16143 if _, err := rand.Read(ret[:1]); err != nil { 16144 panic(err) 16145 } 16146 copy(ret[1:], uncompressed) 16147 return ret 16148 }, 16149 Decompress: func(out []byte, compressed []byte) bool { 16150 if len(compressed) != 1+len(out) { 16151 return false 16152 } 16153 copy(out, compressed[1:]) 16154 return true 16155 }, 16156} 16157 16158func addCertCompressionTests() { 16159 for _, ver := range tlsVersions { 16160 if ver.version < VersionTLS12 { 16161 continue 16162 } 16163 16164 // Duplicate compression algorithms is an error, even if nothing is 16165 // configured. 16166 testCases = append(testCases, testCase{ 16167 testType: serverTest, 16168 name: "DuplicateCertCompressionExt-" + ver.name, 16169 config: Config{ 16170 MinVersion: ver.version, 16171 MaxVersion: ver.version, 16172 Bugs: ProtocolBugs{ 16173 DuplicateCompressedCertAlgs: true, 16174 }, 16175 }, 16176 shouldFail: true, 16177 expectedError: ":ERROR_PARSING_EXTENSION:", 16178 }) 16179 16180 // With compression algorithms configured, an duplicate values should still 16181 // be an error. 16182 testCases = append(testCases, testCase{ 16183 testType: serverTest, 16184 name: "DuplicateCertCompressionExt2-" + ver.name, 16185 flags: []string{"-install-cert-compression-algs"}, 16186 config: Config{ 16187 MinVersion: ver.version, 16188 MaxVersion: ver.version, 16189 Bugs: ProtocolBugs{ 16190 DuplicateCompressedCertAlgs: true, 16191 }, 16192 }, 16193 shouldFail: true, 16194 expectedError: ":ERROR_PARSING_EXTENSION:", 16195 }) 16196 16197 if ver.version < VersionTLS13 { 16198 testCases = append(testCases, testCase{ 16199 testType: serverTest, 16200 name: "CertCompressionIgnoredBefore13-" + ver.name, 16201 flags: []string{"-install-cert-compression-algs"}, 16202 config: Config{ 16203 MinVersion: ver.version, 16204 MaxVersion: ver.version, 16205 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16206 expandingCompressionAlgID: expandingCompression, 16207 }, 16208 }, 16209 }) 16210 16211 continue 16212 } 16213 16214 testCases = append(testCases, testCase{ 16215 testType: serverTest, 16216 name: "CertCompressionExpands-" + ver.name, 16217 flags: []string{"-install-cert-compression-algs"}, 16218 config: Config{ 16219 MinVersion: ver.version, 16220 MaxVersion: ver.version, 16221 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16222 expandingCompressionAlgID: expandingCompression, 16223 }, 16224 Bugs: ProtocolBugs{ 16225 ExpectedCompressedCert: expandingCompressionAlgID, 16226 }, 16227 }, 16228 }) 16229 16230 testCases = append(testCases, testCase{ 16231 testType: serverTest, 16232 name: "CertCompressionShrinks-" + ver.name, 16233 flags: []string{"-install-cert-compression-algs"}, 16234 config: Config{ 16235 MinVersion: ver.version, 16236 MaxVersion: ver.version, 16237 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16238 shrinkingCompressionAlgID: shrinkingCompression, 16239 }, 16240 Bugs: ProtocolBugs{ 16241 ExpectedCompressedCert: shrinkingCompressionAlgID, 16242 }, 16243 }, 16244 }) 16245 16246 // Test that the shim behaves consistently if the compression function 16247 // is non-deterministic. This is intended to model version differences 16248 // between the shim and handshaker with handshake hints, but it is also 16249 // useful in confirming we only call the callbacks once. 16250 testCases = append(testCases, testCase{ 16251 testType: serverTest, 16252 name: "CertCompressionRandom-" + ver.name, 16253 flags: []string{"-install-cert-compression-algs"}, 16254 config: Config{ 16255 MinVersion: ver.version, 16256 MaxVersion: ver.version, 16257 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16258 randomCompressionAlgID: randomCompression, 16259 }, 16260 Bugs: ProtocolBugs{ 16261 ExpectedCompressedCert: randomCompressionAlgID, 16262 }, 16263 }, 16264 }) 16265 16266 // With both algorithms configured, the server should pick its most 16267 // preferable. (Which is expandingCompressionAlgID.) 16268 testCases = append(testCases, testCase{ 16269 testType: serverTest, 16270 name: "CertCompressionPriority-" + ver.name, 16271 flags: []string{"-install-cert-compression-algs"}, 16272 config: Config{ 16273 MinVersion: ver.version, 16274 MaxVersion: ver.version, 16275 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16276 shrinkingCompressionAlgID: shrinkingCompression, 16277 expandingCompressionAlgID: expandingCompression, 16278 }, 16279 Bugs: ProtocolBugs{ 16280 ExpectedCompressedCert: expandingCompressionAlgID, 16281 }, 16282 }, 16283 }) 16284 16285 // With no common algorithms configured, the server should decline 16286 // compression. 16287 testCases = append(testCases, testCase{ 16288 testType: serverTest, 16289 name: "CertCompressionNoCommonAlgs-" + ver.name, 16290 flags: []string{"-install-one-cert-compression-alg", strconv.Itoa(shrinkingCompressionAlgID)}, 16291 config: Config{ 16292 MinVersion: ver.version, 16293 MaxVersion: ver.version, 16294 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16295 expandingCompressionAlgID: expandingCompression, 16296 }, 16297 Bugs: ProtocolBugs{ 16298 ExpectUncompressedCert: true, 16299 }, 16300 }, 16301 }) 16302 16303 testCases = append(testCases, testCase{ 16304 testType: clientTest, 16305 name: "CertCompressionExpandsClient-" + ver.name, 16306 flags: []string{"-install-cert-compression-algs"}, 16307 config: Config{ 16308 MinVersion: ver.version, 16309 MaxVersion: ver.version, 16310 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16311 expandingCompressionAlgID: expandingCompression, 16312 }, 16313 Bugs: ProtocolBugs{ 16314 ExpectedCompressedCert: expandingCompressionAlgID, 16315 }, 16316 }, 16317 }) 16318 16319 testCases = append(testCases, testCase{ 16320 testType: clientTest, 16321 name: "CertCompressionShrinksClient-" + ver.name, 16322 flags: []string{"-install-cert-compression-algs"}, 16323 config: Config{ 16324 MinVersion: ver.version, 16325 MaxVersion: ver.version, 16326 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16327 shrinkingCompressionAlgID: shrinkingCompression, 16328 }, 16329 Bugs: ProtocolBugs{ 16330 ExpectedCompressedCert: shrinkingCompressionAlgID, 16331 }, 16332 }, 16333 }) 16334 16335 testCases = append(testCases, testCase{ 16336 testType: clientTest, 16337 name: "CertCompressionBadAlgIDClient-" + ver.name, 16338 flags: []string{"-install-cert-compression-algs"}, 16339 config: Config{ 16340 MinVersion: ver.version, 16341 MaxVersion: ver.version, 16342 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16343 shrinkingCompressionAlgID: shrinkingCompression, 16344 }, 16345 Bugs: ProtocolBugs{ 16346 ExpectedCompressedCert: shrinkingCompressionAlgID, 16347 SendCertCompressionAlgID: 1234, 16348 }, 16349 }, 16350 shouldFail: true, 16351 expectedError: ":UNKNOWN_CERT_COMPRESSION_ALG:", 16352 }) 16353 16354 testCases = append(testCases, testCase{ 16355 testType: clientTest, 16356 name: "CertCompressionTooSmallClient-" + ver.name, 16357 flags: []string{"-install-cert-compression-algs"}, 16358 config: Config{ 16359 MinVersion: ver.version, 16360 MaxVersion: ver.version, 16361 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16362 shrinkingCompressionAlgID: shrinkingCompression, 16363 }, 16364 Bugs: ProtocolBugs{ 16365 ExpectedCompressedCert: shrinkingCompressionAlgID, 16366 SendCertUncompressedLength: 12, 16367 }, 16368 }, 16369 shouldFail: true, 16370 expectedError: ":CERT_DECOMPRESSION_FAILED:", 16371 }) 16372 16373 testCases = append(testCases, testCase{ 16374 testType: clientTest, 16375 name: "CertCompressionTooLargeClient-" + ver.name, 16376 flags: []string{"-install-cert-compression-algs"}, 16377 config: Config{ 16378 MinVersion: ver.version, 16379 MaxVersion: ver.version, 16380 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 16381 shrinkingCompressionAlgID: shrinkingCompression, 16382 }, 16383 Bugs: ProtocolBugs{ 16384 ExpectedCompressedCert: shrinkingCompressionAlgID, 16385 SendCertUncompressedLength: 1 << 20, 16386 }, 16387 }, 16388 shouldFail: true, 16389 expectedError: ":UNCOMPRESSED_CERT_TOO_LARGE:", 16390 }) 16391 } 16392} 16393 16394func addJDK11WorkaroundTests() { 16395 // Test the client treats the JDK 11 downgrade random like the usual one. 16396 testCases = append(testCases, testCase{ 16397 testType: clientTest, 16398 name: "Client-RejectJDK11DowngradeRandom", 16399 config: Config{ 16400 MaxVersion: VersionTLS12, 16401 Bugs: ProtocolBugs{ 16402 SendJDK11DowngradeRandom: true, 16403 }, 16404 }, 16405 shouldFail: true, 16406 expectedError: ":TLS13_DOWNGRADE:", 16407 expectedLocalError: "remote error: illegal parameter", 16408 }) 16409 testCases = append(testCases, testCase{ 16410 testType: clientTest, 16411 name: "Client-AcceptJDK11DowngradeRandom", 16412 config: Config{ 16413 MaxVersion: VersionTLS12, 16414 Bugs: ProtocolBugs{ 16415 SendJDK11DowngradeRandom: true, 16416 }, 16417 }, 16418 flags: []string{"-max-version", strconv.Itoa(VersionTLS12)}, 16419 }) 16420 16421 var clientHelloTests = []struct { 16422 clientHello []byte 16423 isJDK11 bool 16424 }{ 16425 { 16426 // A default JDK 11 ClientHello. 16427 decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"), 16428 true, 16429 }, 16430 { 16431 // The above with supported_versions and 16432 // psk_key_exchange_modes in the wrong order. 16433 decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002d00020101002b00090803040303030203010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"), 16434 false, 16435 }, 16436 { 16437 // The above with a padding extension added at the end. 16438 decodeHexOrPanic("010001b4030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000111000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b50015000700000000000000"), 16439 false, 16440 }, 16441 { 16442 // A JDK 11 ClientHello offering a TLS 1.3 PSK. 16443 decodeHexOrPanic("0100024c0303a8d71b20f060545a398226e807d21371a7a02b7ca2f96f476c2dea7e5860c5a400005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010001c9000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104aaec585ea9e121b24710a23560571322b2cf8ab8cd14e5762ef0486d8a6d0ecd721d8f2abda2eb8ed5ab7195505660450f49bba94bbf0c3f0070a531d9a1be4f002900cb00a600a0e6f7586d9a2bf64a54c1adf55a2f76657047e8e88e26629e2e7b9d630941e06fd87792770f6834e159a70b252157a9b4b082183f24629c8ff5049088b07ce37c49de8cf752a2ed7a545aff63bdc7a1b18e1bc201f23f159ee75d4987a04e00f840824f764691ab83a20e3032646e793065874cdb46138a52f50ed71406f399f96f9309eba4e5b1966148c22a63dc4aa1364269dd41dd5cc0e848d07af0095622c52cfcfc00212009cc315259e2328d65ad17a3de7c182c7874140a9356fecdd4614657806cd659"), 16444 true, 16445 }, 16446 { 16447 // A JDK 11 ClientHello offering a TLS 1.2 session. 16448 decodeHexOrPanic("010001a903038cdec49f4836d064a75046c93f22d0b9c2cf4900917332e6f0e1f41d692d3146201a3e99047492285ec65ab4e0eeee59f8f9d1eb7687398887bcd7b81353e93923005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d0002010100330047004500170041041c83c42fcd8fc06265b9f6e4f076f7e7ee17ace915c587845c0e1bc8cd177f904befeb611b682cae4702509a5f5d0c7162a282b8152d843169b91136e7c6f3e7"), 16449 true, 16450 }, 16451 { 16452 // A JDK 11 ClientHello with EMS disabled. 16453 decodeHexOrPanic("010001a50303323a857c324a9ef57d6e2544d129073830385cb1dc75ea79f6a2ec8ae09d2e7320f85fdd081678874c67ebab235e6d6a81d947f690bc0af9be4d39854ed67d9ef9005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000102000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200110009000702000400000000002b0009080304030303020301002d0002010100330047004500170041049c904c4850b495d75522f955d79e9cabea065c90279d6037a101a4c4ee712afc93ad0df5d12d287d53e458c7075d9a3ce3969c939bb62222bda779cecf54a603"), 16454 true, 16455 }, 16456 { 16457 // A JDK 11 ClientHello with OCSP stapling disabled. 16458 decodeHexOrPanic("0100019303038a50481dc85ee4f6581670821c50f2b3d34ac3251dc6e9b751bfd2521ab47ab02069a963c5486034c37ae0577ddb4c2db28cab592380ef8e4599d1305148712112005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010000f0000000080006000003736e69000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200170000002b0009080304030303020301002d00020101003300470045001700410438a97824f842c549e3c339322d8b2dbaa85d10bd7bca9c969376cb0c60b1e929eb4d13db38dcb0082ad8c637b24f55466a9acbb0b63634c1f431ec8342cf720d"), 16459 true, 16460 }, 16461 { 16462 // A JDK 11 ClientHello configured with a smaller set of 16463 // ciphers. 16464 decodeHexOrPanic("0100015603036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16465 true, 16466 }, 16467 { 16468 // The above with TLS_CHACHA20_POLY1305_SHA256 added, 16469 // which JDK 11 does not support. 16470 decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f48118000813011303c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16471 false, 16472 }, 16473 { 16474 // The above with X25519 added, which JDK 11 does not 16475 // support. 16476 decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000109000000080006000003736e69000500050100000000000a00220020001d0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"), 16477 false, 16478 }, 16479 { 16480 // A JDK 11 ClientHello with ALPN protocols configured. 16481 decodeHexOrPanic("010001bb0303c0e0ea707b00c5311eb09cabd58626692cebfaefaef7265637e4550811dae16220da86d6eea04e214e873675223f08a6926bcf79f16d866280bdbab85e9e09c3ff005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000118000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020010000e000c02683208687474702f312e310011000900070200040000000000170000002b0009080304030303020301002d00020101003300470045001700410416def07c1d66ddde5fc9dcc328c8e77022d321c590c0d30cb41d515b38dca34540819a216c6c053bd47b9068f4f6b960f03647de4e36e8b7ffeea78f7252e3d9"), 16482 true, 16483 }, 16484 } 16485 for i, t := range clientHelloTests { 16486 expectedVersion := uint16(VersionTLS13) 16487 if t.isJDK11 { 16488 expectedVersion = VersionTLS12 16489 } 16490 16491 // In each of these tests, we set DefaultCurves to P-256 to 16492 // match the test inputs. SendClientHelloWithFixes requires the 16493 // key_shares extension to match in type. 16494 16495 // With the workaround enabled, we should negotiate TLS 1.2 on 16496 // JDK 11 ClientHellos. 16497 testCases = append(testCases, testCase{ 16498 testType: serverTest, 16499 name: fmt.Sprintf("Server-JDK11-%d", i), 16500 config: Config{ 16501 MaxVersion: VersionTLS13, 16502 DefaultCurves: []CurveID{CurveP256}, 16503 Bugs: ProtocolBugs{ 16504 SendClientHelloWithFixes: t.clientHello, 16505 ExpectJDK11DowngradeRandom: t.isJDK11, 16506 }, 16507 }, 16508 expectations: connectionExpectations{ 16509 version: expectedVersion, 16510 }, 16511 flags: []string{"-jdk11-workaround"}, 16512 }) 16513 16514 // With the workaround disabled, we always negotiate TLS 1.3. 16515 testCases = append(testCases, testCase{ 16516 testType: serverTest, 16517 name: fmt.Sprintf("Server-JDK11-NoWorkaround-%d", i), 16518 config: Config{ 16519 MaxVersion: VersionTLS13, 16520 DefaultCurves: []CurveID{CurveP256}, 16521 Bugs: ProtocolBugs{ 16522 SendClientHelloWithFixes: t.clientHello, 16523 ExpectJDK11DowngradeRandom: false, 16524 }, 16525 }, 16526 expectations: connectionExpectations{ 16527 version: VersionTLS13, 16528 }, 16529 }) 16530 16531 // If the server does not support TLS 1.3, the workaround should 16532 // be a no-op. In particular, it should not send the downgrade 16533 // signal. 16534 testCases = append(testCases, testCase{ 16535 testType: serverTest, 16536 name: fmt.Sprintf("Server-JDK11-TLS12-%d", i), 16537 config: Config{ 16538 MaxVersion: VersionTLS13, 16539 DefaultCurves: []CurveID{CurveP256}, 16540 Bugs: ProtocolBugs{ 16541 SendClientHelloWithFixes: t.clientHello, 16542 ExpectJDK11DowngradeRandom: false, 16543 }, 16544 }, 16545 expectations: connectionExpectations{ 16546 version: VersionTLS12, 16547 }, 16548 flags: []string{ 16549 "-jdk11-workaround", 16550 "-max-version", strconv.Itoa(VersionTLS12), 16551 }, 16552 }) 16553 } 16554} 16555 16556func addDelegatedCredentialTests() { 16557 p256DC := createDelegatedCredential(&rsaCertificate, delegatedCredentialConfig{ 16558 dcAlgo: signatureECDSAWithP256AndSHA256, 16559 algo: signatureRSAPSSWithSHA256, 16560 }) 16561 16562 testCases = append(testCases, testCase{ 16563 testType: serverTest, 16564 name: "DelegatedCredentials-NoClientSupport", 16565 config: Config{ 16566 MinVersion: VersionTLS13, 16567 MaxVersion: VersionTLS13, 16568 }, 16569 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16570 flags: []string{"-expect-selected-credential", "1"}, 16571 expectations: connectionExpectations{ 16572 peerCertificate: &rsaCertificate, 16573 }, 16574 }) 16575 16576 testCases = append(testCases, testCase{ 16577 testType: serverTest, 16578 name: "DelegatedCredentials-Basic", 16579 config: Config{ 16580 MinVersion: VersionTLS13, 16581 MaxVersion: VersionTLS13, 16582 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 16583 }, 16584 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16585 flags: []string{"-expect-selected-credential", "0"}, 16586 expectations: connectionExpectations{ 16587 peerCertificate: p256DC, 16588 }, 16589 }) 16590 16591 testCases = append(testCases, testCase{ 16592 testType: serverTest, 16593 name: "DelegatedCredentials-ExactAlgorithmMatch", 16594 config: Config{ 16595 MinVersion: VersionTLS13, 16596 MaxVersion: VersionTLS13, 16597 // Test that the server doesn't mix up the two signature algorithm 16598 // fields. These options are a match because the signature_algorithms 16599 // extension matches against the signature on the delegated 16600 // credential, while the delegated_credential extension matches 16601 // against the signature made by the delegated credential. 16602 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 16603 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 16604 }, 16605 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16606 flags: []string{"-expect-selected-credential", "0"}, 16607 expectations: connectionExpectations{ 16608 peerCertificate: p256DC, 16609 }, 16610 }) 16611 16612 testCases = append(testCases, testCase{ 16613 testType: serverTest, 16614 name: "DelegatedCredentials-SigAlgoMissing", 16615 config: Config{ 16616 MinVersion: VersionTLS13, 16617 MaxVersion: VersionTLS13, 16618 // If the client doesn't support the signature in the delegated credential, 16619 // the server should not use delegated credentials. 16620 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA384}, 16621 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 16622 }, 16623 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16624 flags: []string{"-expect-selected-credential", "1"}, 16625 expectations: connectionExpectations{ 16626 peerCertificate: &rsaCertificate, 16627 }, 16628 }) 16629 16630 testCases = append(testCases, testCase{ 16631 testType: serverTest, 16632 name: "DelegatedCredentials-CertVerifySigAlgoMissing", 16633 config: Config{ 16634 MinVersion: VersionTLS13, 16635 MaxVersion: VersionTLS13, 16636 // If the client doesn't support the delegated credential's 16637 // CertificateVerify algorithm, the server should not use delegated 16638 // credentials. 16639 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 16640 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP384AndSHA384}, 16641 }, 16642 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16643 flags: []string{"-expect-selected-credential", "1"}, 16644 expectations: connectionExpectations{ 16645 peerCertificate: &rsaCertificate, 16646 }, 16647 }) 16648 16649 // Delegated credentials are not supported at TLS 1.2, even if the client 16650 // sends the extension. 16651 testCases = append(testCases, testCase{ 16652 testType: serverTest, 16653 name: "DelegatedCredentials-TLS12-Forbidden", 16654 config: Config{ 16655 MinVersion: VersionTLS12, 16656 MaxVersion: VersionTLS12, 16657 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 16658 }, 16659 shimCredentials: []*Credential{p256DC, &rsaCertificate}, 16660 flags: []string{"-expect-selected-credential", "1"}, 16661 expectations: connectionExpectations{ 16662 peerCertificate: &rsaCertificate, 16663 }, 16664 }) 16665 16666 // Generate another delegated credential, so we can get the keys out of sync. 16667 dcWrongKey := createDelegatedCredential(&rsaCertificate, delegatedCredentialConfig{ 16668 algo: signatureRSAPSSWithSHA256, 16669 }) 16670 dcWrongKey.DelegatedCredential = p256DC.DelegatedCredential 16671 testCases = append(testCases, testCase{ 16672 testType: serverTest, 16673 name: "DelegatedCredentials-KeyMismatch", 16674 // The handshake hints version of the test will, as a side effect, use a 16675 // custom private key. Custom private keys can't be checked for key 16676 // mismatches. 16677 skipHints: true, 16678 shimCredentials: []*Credential{dcWrongKey}, 16679 shouldFail: true, 16680 expectedError: ":KEY_VALUES_MISMATCH:", 16681 }) 16682 16683 // RSA delegated credentials should be rejected at configuration time. 16684 rsaDC := createDelegatedCredential(&rsaCertificate, delegatedCredentialConfig{ 16685 algo: signatureRSAPSSWithSHA256, 16686 dcAlgo: signatureRSAPSSWithSHA256, 16687 }) 16688 testCases = append(testCases, testCase{ 16689 testType: serverTest, 16690 name: "DelegatedCredentials-NoRSA", 16691 shimCredentials: []*Credential{rsaDC}, 16692 shouldFail: true, 16693 expectedError: ":INVALID_SIGNATURE_ALGORITHM:", 16694 }) 16695 16696 // If configured with multiple delegated credentials, the server can cleanly 16697 // select the first one that works. 16698 p384DC := createDelegatedCredential(&rsaCertificate, delegatedCredentialConfig{ 16699 dcAlgo: signatureECDSAWithP384AndSHA384, 16700 algo: signatureRSAPSSWithSHA256, 16701 }) 16702 testCases = append(testCases, testCase{ 16703 testType: serverTest, 16704 name: "DelegatedCredentials-Multiple", 16705 config: Config{ 16706 DelegatedCredentialAlgorithms: []signatureAlgorithm{signatureECDSAWithP384AndSHA384}, 16707 }, 16708 shimCredentials: []*Credential{p256DC, p384DC}, 16709 flags: []string{"-expect-selected-credential", "1"}, 16710 expectations: connectionExpectations{ 16711 peerCertificate: p384DC, 16712 }, 16713 }) 16714} 16715 16716type echCipher struct { 16717 name string 16718 cipher HPKECipherSuite 16719} 16720 16721var echCiphers = []echCipher{ 16722 { 16723 name: "HKDF-SHA256-AES-128-GCM", 16724 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.AES128GCM}, 16725 }, 16726 { 16727 name: "HKDF-SHA256-AES-256-GCM", 16728 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.AES256GCM}, 16729 }, { 16730 name: "HKDF-SHA256-ChaCha20-Poly1305", 16731 cipher: HPKECipherSuite{KDF: hpke.HKDFSHA256, AEAD: hpke.ChaCha20Poly1305}, 16732 }, 16733} 16734 16735// generateServerECHConfig constructs a ServerECHConfig with a fresh X25519 16736// keypair and using |template| as a template for the ECHConfig. If fields are 16737// omitted, defaults are used. 16738func generateServerECHConfig(template *ECHConfig) ServerECHConfig { 16739 publicKey, secretKey, err := hpke.GenerateKeyPairX25519() 16740 if err != nil { 16741 panic(err) 16742 } 16743 templateCopy := *template 16744 if templateCopy.KEM == 0 { 16745 templateCopy.KEM = hpke.X25519WithHKDFSHA256 16746 } 16747 if len(templateCopy.PublicKey) == 0 { 16748 templateCopy.PublicKey = publicKey 16749 } 16750 if len(templateCopy.CipherSuites) == 0 { 16751 templateCopy.CipherSuites = make([]HPKECipherSuite, len(echCiphers)) 16752 for i, cipher := range echCiphers { 16753 templateCopy.CipherSuites[i] = cipher.cipher 16754 } 16755 } 16756 if len(templateCopy.PublicName) == 0 { 16757 templateCopy.PublicName = "public.example" 16758 } 16759 if templateCopy.MaxNameLen == 0 { 16760 templateCopy.MaxNameLen = 64 16761 } 16762 return ServerECHConfig{ECHConfig: CreateECHConfig(&templateCopy), Key: secretKey} 16763} 16764 16765func addEncryptedClientHelloTests() { 16766 // echConfig's ConfigID should match the one used in ssl/test/fuzzer.h. 16767 echConfig := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 16768 echConfig1 := generateServerECHConfig(&ECHConfig{ConfigID: 43}) 16769 echConfig2 := generateServerECHConfig(&ECHConfig{ConfigID: 44}) 16770 echConfig3 := generateServerECHConfig(&ECHConfig{ConfigID: 45}) 16771 echConfigRepeatID := generateServerECHConfig(&ECHConfig{ConfigID: 42}) 16772 16773 echSecretCertificate := generateSingleCertChain(&x509.Certificate{ 16774 SerialNumber: big.NewInt(57005), 16775 Subject: pkix.Name{ 16776 CommonName: "test cert", 16777 }, 16778 NotBefore: time.Now().Add(-time.Hour), 16779 NotAfter: time.Now().Add(time.Hour), 16780 DNSNames: []string{"secret.example"}, 16781 IsCA: true, 16782 BasicConstraintsValid: true, 16783 }, &rsa2048Key) 16784 echPublicCertificate := generateSingleCertChain(&x509.Certificate{ 16785 SerialNumber: big.NewInt(57005), 16786 Subject: pkix.Name{ 16787 CommonName: "test cert", 16788 }, 16789 NotBefore: time.Now().Add(-time.Hour), 16790 NotAfter: time.Now().Add(time.Hour), 16791 DNSNames: []string{"public.example"}, 16792 IsCA: true, 16793 BasicConstraintsValid: true, 16794 }, &rsa2048Key) 16795 echLongNameCertificate := generateSingleCertChain(&x509.Certificate{ 16796 SerialNumber: big.NewInt(57005), 16797 Subject: pkix.Name{ 16798 CommonName: "test cert", 16799 }, 16800 NotBefore: time.Now().Add(-time.Hour), 16801 NotAfter: time.Now().Add(time.Hour), 16802 DNSNames: []string{"test0123456789.example"}, 16803 IsCA: true, 16804 BasicConstraintsValid: true, 16805 }, &ecdsaP256Key) 16806 16807 for _, protocol := range []protocol{tls, quic} { 16808 prefix := protocol.String() + "-" 16809 16810 // There are two ClientHellos, so many of our tests have 16811 // HelloRetryRequest variations. 16812 for _, hrr := range []bool{false, true} { 16813 var suffix string 16814 var defaultCurves []CurveID 16815 if hrr { 16816 suffix = "-HelloRetryRequest" 16817 // Require a HelloRetryRequest for every curve. 16818 defaultCurves = []CurveID{} 16819 } 16820 16821 // Test the server can accept ECH. 16822 testCases = append(testCases, testCase{ 16823 testType: serverTest, 16824 protocol: protocol, 16825 name: prefix + "ECH-Server" + suffix, 16826 config: Config{ 16827 ServerName: "secret.example", 16828 ClientECHConfig: echConfig.ECHConfig, 16829 DefaultCurves: defaultCurves, 16830 }, 16831 resumeSession: true, 16832 flags: []string{ 16833 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16834 "-ech-server-key", base64FlagValue(echConfig.Key), 16835 "-ech-is-retry-config", "1", 16836 "-expect-server-name", "secret.example", 16837 "-expect-ech-accept", 16838 }, 16839 expectations: connectionExpectations{ 16840 echAccepted: true, 16841 }, 16842 }) 16843 16844 // Test the server can accept ECH with a minimal ClientHelloOuter. 16845 // This confirms that the server does not unexpectedly pick up 16846 // fields from the wrong ClientHello. 16847 testCases = append(testCases, testCase{ 16848 testType: serverTest, 16849 protocol: protocol, 16850 name: prefix + "ECH-Server-MinimalClientHelloOuter" + suffix, 16851 config: Config{ 16852 ServerName: "secret.example", 16853 ClientECHConfig: echConfig.ECHConfig, 16854 DefaultCurves: defaultCurves, 16855 Bugs: ProtocolBugs{ 16856 MinimalClientHelloOuter: true, 16857 }, 16858 }, 16859 resumeSession: true, 16860 flags: []string{ 16861 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16862 "-ech-server-key", base64FlagValue(echConfig.Key), 16863 "-ech-is-retry-config", "1", 16864 "-expect-server-name", "secret.example", 16865 "-expect-ech-accept", 16866 }, 16867 expectations: connectionExpectations{ 16868 echAccepted: true, 16869 }, 16870 }) 16871 16872 // Test that the server can decline ECH. In particular, it must send 16873 // retry configs. 16874 testCases = append(testCases, testCase{ 16875 testType: serverTest, 16876 protocol: protocol, 16877 name: prefix + "ECH-Server-Decline" + suffix, 16878 config: Config{ 16879 ServerName: "secret.example", 16880 DefaultCurves: defaultCurves, 16881 // The client uses an ECHConfig that the server does not understand 16882 // so we can observe which retry configs the server sends back. 16883 ClientECHConfig: echConfig.ECHConfig, 16884 Bugs: ProtocolBugs{ 16885 OfferSessionInClientHelloOuter: true, 16886 ExpectECHRetryConfigs: CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw), 16887 }, 16888 }, 16889 resumeSession: true, 16890 flags: []string{ 16891 // Configure three ECHConfigs on the shim, only two of which 16892 // should be sent in retry configs. 16893 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 16894 "-ech-server-key", base64FlagValue(echConfig1.Key), 16895 "-ech-is-retry-config", "0", 16896 "-ech-server-config", base64FlagValue(echConfig2.ECHConfig.Raw), 16897 "-ech-server-key", base64FlagValue(echConfig2.Key), 16898 "-ech-is-retry-config", "1", 16899 "-ech-server-config", base64FlagValue(echConfig3.ECHConfig.Raw), 16900 "-ech-server-key", base64FlagValue(echConfig3.Key), 16901 "-ech-is-retry-config", "1", 16902 "-expect-server-name", "public.example", 16903 }, 16904 }) 16905 16906 // Test that the server considers a ClientHelloInner indicating TLS 16907 // 1.2 to be a fatal error. 16908 testCases = append(testCases, testCase{ 16909 testType: serverTest, 16910 protocol: protocol, 16911 name: prefix + "ECH-Server-TLS12InInner" + suffix, 16912 config: Config{ 16913 ServerName: "secret.example", 16914 DefaultCurves: defaultCurves, 16915 ClientECHConfig: echConfig.ECHConfig, 16916 Bugs: ProtocolBugs{ 16917 AllowTLS12InClientHelloInner: true, 16918 }, 16919 }, 16920 flags: []string{ 16921 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16922 "-ech-server-key", base64FlagValue(echConfig.Key), 16923 "-ech-is-retry-config", "1"}, 16924 shouldFail: true, 16925 expectedLocalError: "remote error: illegal parameter", 16926 expectedError: ":INVALID_CLIENT_HELLO_INNER:", 16927 }) 16928 16929 // When inner ECH extension is absent from the ClientHelloInner, the 16930 // server should fail the connection. 16931 testCases = append(testCases, testCase{ 16932 testType: serverTest, 16933 protocol: protocol, 16934 name: prefix + "ECH-Server-MissingECHInner" + suffix, 16935 config: Config{ 16936 ServerName: "secret.example", 16937 DefaultCurves: defaultCurves, 16938 ClientECHConfig: echConfig.ECHConfig, 16939 Bugs: ProtocolBugs{ 16940 OmitECHInner: !hrr, 16941 OmitSecondECHInner: hrr, 16942 }, 16943 }, 16944 flags: []string{ 16945 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16946 "-ech-server-key", base64FlagValue(echConfig.Key), 16947 "-ech-is-retry-config", "1", 16948 }, 16949 shouldFail: true, 16950 expectedLocalError: "remote error: illegal parameter", 16951 expectedError: ":INVALID_CLIENT_HELLO_INNER:", 16952 }) 16953 16954 // Test that the server can decode ech_outer_extensions. 16955 testCases = append(testCases, testCase{ 16956 testType: serverTest, 16957 protocol: protocol, 16958 name: prefix + "ECH-Server-OuterExtensions" + suffix, 16959 config: Config{ 16960 ServerName: "secret.example", 16961 DefaultCurves: defaultCurves, 16962 ClientECHConfig: echConfig.ECHConfig, 16963 ECHOuterExtensions: []uint16{ 16964 extensionKeyShare, 16965 extensionSupportedCurves, 16966 // Include a custom extension, to test that unrecognized 16967 // extensions are also decoded. 16968 extensionCustom, 16969 }, 16970 Bugs: ProtocolBugs{ 16971 CustomExtension: "test", 16972 OnlyCompressSecondClientHelloInner: hrr, 16973 }, 16974 }, 16975 flags: []string{ 16976 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 16977 "-ech-server-key", base64FlagValue(echConfig.Key), 16978 "-ech-is-retry-config", "1", 16979 "-expect-server-name", "secret.example", 16980 "-expect-ech-accept", 16981 }, 16982 expectations: connectionExpectations{ 16983 echAccepted: true, 16984 }, 16985 }) 16986 16987 // Test that the server allows referenced ClientHelloOuter 16988 // extensions to be interleaved with other extensions. Only the 16989 // relative order must match. 16990 testCases = append(testCases, testCase{ 16991 testType: serverTest, 16992 protocol: protocol, 16993 name: prefix + "ECH-Server-OuterExtensions-Interleaved" + suffix, 16994 config: Config{ 16995 ServerName: "secret.example", 16996 DefaultCurves: defaultCurves, 16997 ClientECHConfig: echConfig.ECHConfig, 16998 ECHOuterExtensions: []uint16{ 16999 extensionKeyShare, 17000 extensionSupportedCurves, 17001 extensionCustom, 17002 }, 17003 Bugs: ProtocolBugs{ 17004 CustomExtension: "test", 17005 OnlyCompressSecondClientHelloInner: hrr, 17006 ECHOuterExtensionOrder: []uint16{ 17007 extensionServerName, 17008 extensionKeyShare, 17009 extensionSupportedVersions, 17010 extensionPSKKeyExchangeModes, 17011 extensionSupportedCurves, 17012 extensionSignatureAlgorithms, 17013 extensionCustom, 17014 }, 17015 }, 17016 }, 17017 flags: []string{ 17018 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17019 "-ech-server-key", base64FlagValue(echConfig.Key), 17020 "-ech-is-retry-config", "1", 17021 "-expect-server-name", "secret.example", 17022 "-expect-ech-accept", 17023 }, 17024 expectations: connectionExpectations{ 17025 echAccepted: true, 17026 }, 17027 }) 17028 17029 // Test that the server rejects references to extensions in the 17030 // wrong order. 17031 testCases = append(testCases, testCase{ 17032 testType: serverTest, 17033 protocol: protocol, 17034 name: prefix + "ECH-Server-OuterExtensions-WrongOrder" + suffix, 17035 config: Config{ 17036 ServerName: "secret.example", 17037 DefaultCurves: defaultCurves, 17038 ClientECHConfig: echConfig.ECHConfig, 17039 ECHOuterExtensions: []uint16{ 17040 extensionKeyShare, 17041 extensionSupportedCurves, 17042 }, 17043 Bugs: ProtocolBugs{ 17044 CustomExtension: "test", 17045 OnlyCompressSecondClientHelloInner: hrr, 17046 ECHOuterExtensionOrder: []uint16{ 17047 extensionSupportedCurves, 17048 extensionKeyShare, 17049 }, 17050 }, 17051 }, 17052 flags: []string{ 17053 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17054 "-ech-server-key", base64FlagValue(echConfig.Key), 17055 "-ech-is-retry-config", "1", 17056 "-expect-server-name", "secret.example", 17057 }, 17058 shouldFail: true, 17059 expectedLocalError: "remote error: illegal parameter", 17060 expectedError: ":INVALID_OUTER_EXTENSION:", 17061 }) 17062 17063 // Test that the server rejects duplicated values in ech_outer_extensions. 17064 // Besides causing the server to reconstruct an invalid ClientHelloInner 17065 // with duplicated extensions, this behavior would be vulnerable to DoS 17066 // attacks. 17067 testCases = append(testCases, testCase{ 17068 testType: serverTest, 17069 protocol: protocol, 17070 name: prefix + "ECH-Server-OuterExtensions-Duplicate" + suffix, 17071 config: Config{ 17072 ServerName: "secret.example", 17073 DefaultCurves: defaultCurves, 17074 ClientECHConfig: echConfig.ECHConfig, 17075 ECHOuterExtensions: []uint16{ 17076 extensionSupportedCurves, 17077 extensionSupportedCurves, 17078 }, 17079 Bugs: ProtocolBugs{ 17080 OnlyCompressSecondClientHelloInner: hrr, 17081 // Don't duplicate the extension in ClientHelloOuter. 17082 ECHOuterExtensionOrder: []uint16{ 17083 extensionSupportedCurves, 17084 }, 17085 }, 17086 }, 17087 flags: []string{ 17088 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17089 "-ech-server-key", base64FlagValue(echConfig.Key), 17090 "-ech-is-retry-config", "1", 17091 }, 17092 shouldFail: true, 17093 expectedLocalError: "remote error: illegal parameter", 17094 expectedError: ":INVALID_OUTER_EXTENSION:", 17095 }) 17096 17097 // Test that the server rejects references to missing extensions in 17098 // ech_outer_extensions. 17099 testCases = append(testCases, testCase{ 17100 testType: serverTest, 17101 protocol: protocol, 17102 name: prefix + "ECH-Server-OuterExtensions-Missing" + suffix, 17103 config: Config{ 17104 ServerName: "secret.example", 17105 DefaultCurves: defaultCurves, 17106 ClientECHConfig: echConfig.ECHConfig, 17107 ECHOuterExtensions: []uint16{ 17108 extensionCustom, 17109 }, 17110 Bugs: ProtocolBugs{ 17111 OnlyCompressSecondClientHelloInner: hrr, 17112 }, 17113 }, 17114 flags: []string{ 17115 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17116 "-ech-server-key", base64FlagValue(echConfig.Key), 17117 "-ech-is-retry-config", "1", 17118 "-expect-server-name", "secret.example", 17119 "-expect-ech-accept", 17120 }, 17121 shouldFail: true, 17122 expectedLocalError: "remote error: illegal parameter", 17123 expectedError: ":INVALID_OUTER_EXTENSION:", 17124 }) 17125 17126 // Test that the server rejects a references to the ECH extension in 17127 // ech_outer_extensions. The ECH extension is not authenticated in the 17128 // AAD and would result in an invalid ClientHelloInner. 17129 testCases = append(testCases, testCase{ 17130 testType: serverTest, 17131 protocol: protocol, 17132 name: prefix + "ECH-Server-OuterExtensions-SelfReference" + suffix, 17133 config: Config{ 17134 ServerName: "secret.example", 17135 DefaultCurves: defaultCurves, 17136 ClientECHConfig: echConfig.ECHConfig, 17137 ECHOuterExtensions: []uint16{ 17138 extensionEncryptedClientHello, 17139 }, 17140 Bugs: ProtocolBugs{ 17141 OnlyCompressSecondClientHelloInner: hrr, 17142 }, 17143 }, 17144 flags: []string{ 17145 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17146 "-ech-server-key", base64FlagValue(echConfig.Key), 17147 "-ech-is-retry-config", "1", 17148 }, 17149 shouldFail: true, 17150 expectedLocalError: "remote error: illegal parameter", 17151 expectedError: ":INVALID_OUTER_EXTENSION:", 17152 }) 17153 17154 // Test the message callback is correctly reported with ECH. 17155 clientAndServerHello := "read hs 1\nread clienthelloinner\nwrite hs 2\n" 17156 expectMsgCallback := clientAndServerHello + "write ccs\n" 17157 if hrr { 17158 expectMsgCallback += clientAndServerHello 17159 } 17160 // EncryptedExtensions onwards. 17161 expectMsgCallback += `write hs 8 17162write hs 11 17163write hs 15 17164write hs 20 17165read hs 20 17166write hs 4 17167write hs 4 17168` 17169 testCases = append(testCases, testCase{ 17170 testType: serverTest, 17171 protocol: protocol, 17172 name: prefix + "ECH-Server-MessageCallback" + suffix, 17173 config: Config{ 17174 ServerName: "secret.example", 17175 ClientECHConfig: echConfig.ECHConfig, 17176 DefaultCurves: defaultCurves, 17177 Bugs: ProtocolBugs{ 17178 NoCloseNotify: true, // Align QUIC and TCP traces. 17179 }, 17180 }, 17181 flags: []string{ 17182 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17183 "-ech-server-key", base64FlagValue(echConfig.Key), 17184 "-ech-is-retry-config", "1", 17185 "-expect-ech-accept", 17186 "-expect-msg-callback", expectMsgCallback, 17187 }, 17188 expectations: connectionExpectations{ 17189 echAccepted: true, 17190 }, 17191 }) 17192 } 17193 17194 // Test that ECH, which runs before an async early callback, interacts 17195 // correctly in the state machine. 17196 testCases = append(testCases, testCase{ 17197 testType: serverTest, 17198 protocol: protocol, 17199 name: prefix + "ECH-Server-AsyncEarlyCallback", 17200 config: Config{ 17201 ServerName: "secret.example", 17202 ClientECHConfig: echConfig.ECHConfig, 17203 }, 17204 flags: []string{ 17205 "-async", 17206 "-use-early-callback", 17207 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17208 "-ech-server-key", base64FlagValue(echConfig.Key), 17209 "-ech-is-retry-config", "1", 17210 "-expect-server-name", "secret.example", 17211 "-expect-ech-accept", 17212 }, 17213 expectations: connectionExpectations{ 17214 echAccepted: true, 17215 }, 17216 }) 17217 17218 // Test ECH-enabled server with two ECHConfigs can decrypt client's ECH when 17219 // it uses the second ECHConfig. 17220 testCases = append(testCases, testCase{ 17221 testType: serverTest, 17222 protocol: protocol, 17223 name: prefix + "ECH-Server-SecondECHConfig", 17224 config: Config{ 17225 ServerName: "secret.example", 17226 ClientECHConfig: echConfig1.ECHConfig, 17227 }, 17228 flags: []string{ 17229 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17230 "-ech-server-key", base64FlagValue(echConfig.Key), 17231 "-ech-is-retry-config", "1", 17232 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 17233 "-ech-server-key", base64FlagValue(echConfig1.Key), 17234 "-ech-is-retry-config", "1", 17235 "-expect-server-name", "secret.example", 17236 "-expect-ech-accept", 17237 }, 17238 expectations: connectionExpectations{ 17239 echAccepted: true, 17240 }, 17241 }) 17242 17243 // Test ECH-enabled server with two ECHConfigs that have the same config 17244 // ID can decrypt client's ECH when it uses the second ECHConfig. 17245 testCases = append(testCases, testCase{ 17246 testType: serverTest, 17247 protocol: protocol, 17248 name: prefix + "ECH-Server-RepeatedConfigID", 17249 config: Config{ 17250 ServerName: "secret.example", 17251 ClientECHConfig: echConfigRepeatID.ECHConfig, 17252 }, 17253 flags: []string{ 17254 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17255 "-ech-server-key", base64FlagValue(echConfig.Key), 17256 "-ech-is-retry-config", "1", 17257 "-ech-server-config", base64FlagValue(echConfigRepeatID.ECHConfig.Raw), 17258 "-ech-server-key", base64FlagValue(echConfigRepeatID.Key), 17259 "-ech-is-retry-config", "1", 17260 "-expect-server-name", "secret.example", 17261 "-expect-ech-accept", 17262 }, 17263 expectations: connectionExpectations{ 17264 echAccepted: true, 17265 }, 17266 }) 17267 17268 // Test all supported ECH cipher suites. 17269 for i, cipher := range echCiphers { 17270 otherCipher := echCiphers[(i+1)%len(echCiphers)] 17271 17272 // Test the ECH server can handle the specified cipher. 17273 testCases = append(testCases, testCase{ 17274 testType: serverTest, 17275 protocol: protocol, 17276 name: prefix + "ECH-Server-Cipher-" + cipher.name, 17277 config: Config{ 17278 ServerName: "secret.example", 17279 ClientECHConfig: echConfig.ECHConfig, 17280 ECHCipherSuites: []HPKECipherSuite{cipher.cipher}, 17281 }, 17282 flags: []string{ 17283 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17284 "-ech-server-key", base64FlagValue(echConfig.Key), 17285 "-ech-is-retry-config", "1", 17286 "-expect-server-name", "secret.example", 17287 "-expect-ech-accept", 17288 }, 17289 expectations: connectionExpectations{ 17290 echAccepted: true, 17291 }, 17292 }) 17293 17294 // Test that client can offer the specified cipher and skip over 17295 // unrecognized ones. 17296 cipherConfig := generateServerECHConfig(&ECHConfig{ 17297 ConfigID: 42, 17298 CipherSuites: []HPKECipherSuite{ 17299 {KDF: 0x1111, AEAD: 0x2222}, 17300 {KDF: cipher.cipher.KDF, AEAD: 0x2222}, 17301 {KDF: 0x1111, AEAD: cipher.cipher.AEAD}, 17302 cipher.cipher, 17303 }, 17304 }) 17305 testCases = append(testCases, testCase{ 17306 testType: clientTest, 17307 protocol: protocol, 17308 name: prefix + "ECH-Client-Cipher-" + cipher.name, 17309 config: Config{ 17310 ServerECHConfigs: []ServerECHConfig{cipherConfig}, 17311 Credential: &echSecretCertificate, 17312 }, 17313 flags: []string{ 17314 "-ech-config-list", base64FlagValue(CreateECHConfigList(cipherConfig.ECHConfig.Raw)), 17315 "-host-name", "secret.example", 17316 "-expect-ech-accept", 17317 }, 17318 expectations: connectionExpectations{ 17319 echAccepted: true, 17320 }, 17321 }) 17322 17323 // Test that the ECH server rejects the specified cipher if not 17324 // listed in its ECHConfig. 17325 otherCipherConfig := generateServerECHConfig(&ECHConfig{ 17326 ConfigID: 42, 17327 CipherSuites: []HPKECipherSuite{otherCipher.cipher}, 17328 }) 17329 testCases = append(testCases, testCase{ 17330 testType: serverTest, 17331 protocol: protocol, 17332 name: prefix + "ECH-Server-DisabledCipher-" + cipher.name, 17333 config: Config{ 17334 ServerName: "secret.example", 17335 ClientECHConfig: echConfig.ECHConfig, 17336 ECHCipherSuites: []HPKECipherSuite{cipher.cipher}, 17337 Bugs: ProtocolBugs{ 17338 ExpectECHRetryConfigs: CreateECHConfigList(otherCipherConfig.ECHConfig.Raw), 17339 }, 17340 }, 17341 flags: []string{ 17342 "-ech-server-config", base64FlagValue(otherCipherConfig.ECHConfig.Raw), 17343 "-ech-server-key", base64FlagValue(otherCipherConfig.Key), 17344 "-ech-is-retry-config", "1", 17345 "-expect-server-name", "public.example", 17346 }, 17347 }) 17348 } 17349 17350 // Test that the ECH server handles a short enc value by falling back to 17351 // ClientHelloOuter. 17352 testCases = append(testCases, testCase{ 17353 testType: serverTest, 17354 protocol: protocol, 17355 name: prefix + "ECH-Server-ShortEnc", 17356 config: Config{ 17357 ServerName: "secret.example", 17358 ClientECHConfig: echConfig.ECHConfig, 17359 Bugs: ProtocolBugs{ 17360 ExpectECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw), 17361 TruncateClientECHEnc: true, 17362 }, 17363 }, 17364 flags: []string{ 17365 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17366 "-ech-server-key", base64FlagValue(echConfig.Key), 17367 "-ech-is-retry-config", "1", 17368 "-expect-server-name", "public.example", 17369 }, 17370 }) 17371 17372 // Test that the server handles decryption failure by falling back to 17373 // ClientHelloOuter. 17374 testCases = append(testCases, testCase{ 17375 testType: serverTest, 17376 protocol: protocol, 17377 name: prefix + "ECH-Server-CorruptEncryptedClientHello", 17378 config: Config{ 17379 ServerName: "secret.example", 17380 ClientECHConfig: echConfig.ECHConfig, 17381 Bugs: ProtocolBugs{ 17382 ExpectECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw), 17383 CorruptEncryptedClientHello: true, 17384 }, 17385 }, 17386 flags: []string{ 17387 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17388 "-ech-server-key", base64FlagValue(echConfig.Key), 17389 "-ech-is-retry-config", "1", 17390 }, 17391 }) 17392 17393 // Test that the server treats decryption failure in the second 17394 // ClientHello as fatal. 17395 testCases = append(testCases, testCase{ 17396 testType: serverTest, 17397 protocol: protocol, 17398 name: prefix + "ECH-Server-CorruptSecondEncryptedClientHello", 17399 config: Config{ 17400 ServerName: "secret.example", 17401 ClientECHConfig: echConfig.ECHConfig, 17402 // Force a HelloRetryRequest. 17403 DefaultCurves: []CurveID{}, 17404 Bugs: ProtocolBugs{ 17405 CorruptSecondEncryptedClientHello: true, 17406 }, 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 }, 17413 shouldFail: true, 17414 expectedError: ":DECRYPTION_FAILED:", 17415 expectedLocalError: "remote error: error decrypting message", 17416 }) 17417 17418 // Test that the server treats a missing second ECH extension as fatal. 17419 testCases = append(testCases, testCase{ 17420 testType: serverTest, 17421 protocol: protocol, 17422 name: prefix + "ECH-Server-OmitSecondEncryptedClientHello", 17423 config: Config{ 17424 ServerName: "secret.example", 17425 ClientECHConfig: echConfig.ECHConfig, 17426 // Force a HelloRetryRequest. 17427 DefaultCurves: []CurveID{}, 17428 Bugs: ProtocolBugs{ 17429 OmitSecondEncryptedClientHello: true, 17430 }, 17431 }, 17432 flags: []string{ 17433 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17434 "-ech-server-key", base64FlagValue(echConfig.Key), 17435 "-ech-is-retry-config", "1", 17436 }, 17437 shouldFail: true, 17438 expectedError: ":MISSING_EXTENSION:", 17439 expectedLocalError: "remote error: missing extension", 17440 }) 17441 17442 // Test that the server treats a mismatched config ID in the second ClientHello as fatal. 17443 testCases = append(testCases, testCase{ 17444 testType: serverTest, 17445 protocol: protocol, 17446 name: prefix + "ECH-Server-DifferentConfigIDSecondClientHello", 17447 config: Config{ 17448 ServerName: "secret.example", 17449 ClientECHConfig: echConfig.ECHConfig, 17450 // Force a HelloRetryRequest. 17451 DefaultCurves: []CurveID{}, 17452 Bugs: ProtocolBugs{ 17453 CorruptSecondEncryptedClientHelloConfigID: true, 17454 }, 17455 }, 17456 flags: []string{ 17457 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17458 "-ech-server-key", base64FlagValue(echConfig.Key), 17459 "-ech-is-retry-config", "1", 17460 }, 17461 shouldFail: true, 17462 expectedError: ":DECODE_ERROR:", 17463 expectedLocalError: "remote error: illegal parameter", 17464 }) 17465 17466 // Test early data works with ECH, in both accept and reject cases. 17467 testCases = append(testCases, testCase{ 17468 testType: serverTest, 17469 protocol: protocol, 17470 name: prefix + "ECH-Server-EarlyData", 17471 config: Config{ 17472 ServerName: "secret.example", 17473 ClientECHConfig: echConfig.ECHConfig, 17474 }, 17475 resumeSession: true, 17476 earlyData: true, 17477 flags: []string{ 17478 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17479 "-ech-server-key", base64FlagValue(echConfig.Key), 17480 "-ech-is-retry-config", "1", 17481 "-expect-ech-accept", 17482 }, 17483 expectations: connectionExpectations{ 17484 echAccepted: true, 17485 }, 17486 }) 17487 testCases = append(testCases, testCase{ 17488 testType: serverTest, 17489 protocol: protocol, 17490 name: prefix + "ECH-Server-EarlyDataRejected", 17491 config: Config{ 17492 ServerName: "secret.example", 17493 ClientECHConfig: echConfig.ECHConfig, 17494 Bugs: ProtocolBugs{ 17495 // Cause the server to reject 0-RTT with a bad ticket age. 17496 SendTicketAge: 1 * time.Hour, 17497 }, 17498 }, 17499 resumeSession: true, 17500 earlyData: true, 17501 expectEarlyDataRejected: true, 17502 flags: []string{ 17503 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17504 "-ech-server-key", base64FlagValue(echConfig.Key), 17505 "-ech-is-retry-config", "1", 17506 "-expect-ech-accept", 17507 }, 17508 expectations: connectionExpectations{ 17509 echAccepted: true, 17510 }, 17511 }) 17512 17513 // Test servers with ECH disabled correctly ignore the extension and 17514 // handshake with the ClientHelloOuter. 17515 testCases = append(testCases, testCase{ 17516 testType: serverTest, 17517 protocol: protocol, 17518 name: prefix + "ECH-Server-Disabled", 17519 config: Config{ 17520 ServerName: "secret.example", 17521 ClientECHConfig: echConfig.ECHConfig, 17522 }, 17523 flags: []string{ 17524 "-expect-server-name", "public.example", 17525 }, 17526 }) 17527 17528 // Test that ECH can be used with client certificates. In particular, 17529 // the name override logic should not interfere with the server. 17530 // Test the server can accept ECH. 17531 testCases = append(testCases, testCase{ 17532 testType: serverTest, 17533 protocol: protocol, 17534 name: prefix + "ECH-Server-ClientAuth", 17535 config: Config{ 17536 Credential: &rsaCertificate, 17537 ClientECHConfig: echConfig.ECHConfig, 17538 }, 17539 flags: []string{ 17540 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17541 "-ech-server-key", base64FlagValue(echConfig.Key), 17542 "-ech-is-retry-config", "1", 17543 "-expect-ech-accept", 17544 "-require-any-client-certificate", 17545 }, 17546 expectations: connectionExpectations{ 17547 echAccepted: true, 17548 }, 17549 }) 17550 testCases = append(testCases, testCase{ 17551 testType: serverTest, 17552 protocol: protocol, 17553 name: prefix + "ECH-Server-Decline-ClientAuth", 17554 config: Config{ 17555 Credential: &rsaCertificate, 17556 ClientECHConfig: echConfig.ECHConfig, 17557 Bugs: ProtocolBugs{ 17558 ExpectECHRetryConfigs: CreateECHConfigList(echConfig1.ECHConfig.Raw), 17559 }, 17560 }, 17561 flags: []string{ 17562 "-ech-server-config", base64FlagValue(echConfig1.ECHConfig.Raw), 17563 "-ech-server-key", base64FlagValue(echConfig1.Key), 17564 "-ech-is-retry-config", "1", 17565 "-require-any-client-certificate", 17566 }, 17567 }) 17568 17569 // Test that the server accepts padding. 17570 testCases = append(testCases, testCase{ 17571 testType: serverTest, 17572 protocol: protocol, 17573 name: prefix + "ECH-Server-Padding", 17574 config: Config{ 17575 ClientECHConfig: echConfig.ECHConfig, 17576 Bugs: ProtocolBugs{ 17577 ClientECHPadding: 10, 17578 }, 17579 }, 17580 flags: []string{ 17581 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17582 "-ech-server-key", base64FlagValue(echConfig.Key), 17583 "-ech-is-retry-config", "1", 17584 "-expect-ech-accept", 17585 }, 17586 expectations: connectionExpectations{ 17587 echAccepted: true, 17588 }, 17589 }) 17590 17591 // Test that the server rejects bad padding. 17592 testCases = append(testCases, testCase{ 17593 testType: serverTest, 17594 protocol: protocol, 17595 name: prefix + "ECH-Server-BadPadding", 17596 config: Config{ 17597 ClientECHConfig: echConfig.ECHConfig, 17598 Bugs: ProtocolBugs{ 17599 ClientECHPadding: 10, 17600 BadClientECHPadding: true, 17601 }, 17602 }, 17603 flags: []string{ 17604 "-ech-server-config", base64FlagValue(echConfig.ECHConfig.Raw), 17605 "-ech-server-key", base64FlagValue(echConfig.Key), 17606 "-ech-is-retry-config", "1", 17607 "-expect-ech-accept", 17608 }, 17609 expectations: connectionExpectations{ 17610 echAccepted: true, 17611 }, 17612 shouldFail: true, 17613 expectedError: ":DECODE_ERROR", 17614 expectedLocalError: "remote error: illegal parameter", 17615 }) 17616 17617 // Test the client's behavior when the server ignores ECH GREASE. 17618 testCases = append(testCases, testCase{ 17619 testType: clientTest, 17620 protocol: protocol, 17621 name: prefix + "ECH-GREASE-Client-TLS13", 17622 config: Config{ 17623 MinVersion: VersionTLS13, 17624 MaxVersion: VersionTLS13, 17625 Bugs: ProtocolBugs{ 17626 ExpectClientECH: true, 17627 }, 17628 }, 17629 flags: []string{"-enable-ech-grease"}, 17630 }) 17631 17632 // Test the client's ECH GREASE behavior when responding to server's 17633 // HelloRetryRequest. This test implicitly checks that the first and second 17634 // ClientHello messages have identical ECH extensions. 17635 testCases = append(testCases, testCase{ 17636 testType: clientTest, 17637 protocol: protocol, 17638 name: prefix + "ECH-GREASE-Client-TLS13-HelloRetryRequest", 17639 config: Config{ 17640 MaxVersion: VersionTLS13, 17641 MinVersion: VersionTLS13, 17642 // P-384 requires a HelloRetryRequest against BoringSSL's default 17643 // configuration. Assert this with ExpectMissingKeyShare. 17644 CurvePreferences: []CurveID{CurveP384}, 17645 Bugs: ProtocolBugs{ 17646 ExpectMissingKeyShare: true, 17647 ExpectClientECH: true, 17648 }, 17649 }, 17650 flags: []string{"-enable-ech-grease", "-expect-hrr"}, 17651 }) 17652 17653 unsupportedVersion := []byte{ 17654 // version 17655 0xba, 0xdd, 17656 // length 17657 0x00, 0x05, 17658 // contents 17659 0x05, 0x04, 0x03, 0x02, 0x01, 17660 } 17661 17662 // Test that the client accepts a well-formed encrypted_client_hello 17663 // extension in response to ECH GREASE. The response includes one ECHConfig 17664 // with a supported version and one with an unsupported version. 17665 testCases = append(testCases, testCase{ 17666 testType: clientTest, 17667 protocol: protocol, 17668 name: prefix + "ECH-GREASE-Client-TLS13-Retry-Configs", 17669 config: Config{ 17670 MinVersion: VersionTLS13, 17671 MaxVersion: VersionTLS13, 17672 Bugs: ProtocolBugs{ 17673 ExpectClientECH: true, 17674 // Include an additional well-formed ECHConfig with an 17675 // unsupported version. This ensures the client can skip 17676 // unsupported configs. 17677 SendECHRetryConfigs: CreateECHConfigList(echConfig.ECHConfig.Raw, unsupportedVersion), 17678 }, 17679 }, 17680 flags: []string{"-enable-ech-grease"}, 17681 }) 17682 17683 // TLS 1.2 ServerHellos cannot contain retry configs. 17684 if protocol != quic { 17685 testCases = append(testCases, testCase{ 17686 testType: clientTest, 17687 protocol: protocol, 17688 name: prefix + "ECH-GREASE-Client-TLS12-RejectRetryConfigs", 17689 config: Config{ 17690 MinVersion: VersionTLS12, 17691 MaxVersion: VersionTLS12, 17692 ServerECHConfigs: []ServerECHConfig{echConfig}, 17693 Bugs: ProtocolBugs{ 17694 ExpectClientECH: true, 17695 AlwaysSendECHRetryConfigs: true, 17696 }, 17697 }, 17698 flags: []string{"-enable-ech-grease"}, 17699 shouldFail: true, 17700 expectedLocalError: "remote error: unsupported extension", 17701 expectedError: ":UNEXPECTED_EXTENSION:", 17702 }) 17703 testCases = append(testCases, testCase{ 17704 testType: clientTest, 17705 protocol: protocol, 17706 name: prefix + "ECH-Client-TLS12-RejectRetryConfigs", 17707 config: Config{ 17708 MinVersion: VersionTLS12, 17709 MaxVersion: VersionTLS12, 17710 ServerECHConfigs: []ServerECHConfig{echConfig}, 17711 Bugs: ProtocolBugs{ 17712 ExpectClientECH: true, 17713 AlwaysSendECHRetryConfigs: true, 17714 }, 17715 }, 17716 flags: []string{ 17717 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig1.ECHConfig.Raw)), 17718 }, 17719 shouldFail: true, 17720 expectedLocalError: "remote error: unsupported extension", 17721 expectedError: ":UNEXPECTED_EXTENSION:", 17722 }) 17723 } 17724 17725 // Retry configs must be rejected when ECH is accepted. 17726 testCases = append(testCases, testCase{ 17727 testType: clientTest, 17728 protocol: protocol, 17729 name: prefix + "ECH-Client-Accept-RejectRetryConfigs", 17730 config: Config{ 17731 ServerECHConfigs: []ServerECHConfig{echConfig}, 17732 Bugs: ProtocolBugs{ 17733 ExpectClientECH: true, 17734 AlwaysSendECHRetryConfigs: true, 17735 }, 17736 }, 17737 flags: []string{ 17738 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17739 }, 17740 shouldFail: true, 17741 expectedLocalError: "remote error: unsupported extension", 17742 expectedError: ":UNEXPECTED_EXTENSION:", 17743 }) 17744 17745 // Unsolicited ECH HelloRetryRequest extensions should be rejected. 17746 testCases = append(testCases, testCase{ 17747 testType: clientTest, 17748 protocol: protocol, 17749 name: prefix + "ECH-Client-UnsolictedHRRExtension", 17750 config: Config{ 17751 ServerECHConfigs: []ServerECHConfig{echConfig}, 17752 CurvePreferences: []CurveID{CurveP384}, 17753 Bugs: ProtocolBugs{ 17754 AlwaysSendECHHelloRetryRequest: true, 17755 ExpectMissingKeyShare: true, // Check we triggered HRR. 17756 }, 17757 }, 17758 shouldFail: true, 17759 expectedLocalError: "remote error: unsupported extension", 17760 expectedError: ":UNEXPECTED_EXTENSION:", 17761 }) 17762 17763 // GREASE should ignore ECH HelloRetryRequest extensions. 17764 testCases = append(testCases, testCase{ 17765 testType: clientTest, 17766 protocol: protocol, 17767 name: prefix + "ECH-Client-GREASE-IgnoreHRRExtension", 17768 config: Config{ 17769 CurvePreferences: []CurveID{CurveP384}, 17770 Bugs: ProtocolBugs{ 17771 AlwaysSendECHHelloRetryRequest: true, 17772 ExpectMissingKeyShare: true, // Check we triggered HRR. 17773 }, 17774 }, 17775 flags: []string{"-enable-ech-grease"}, 17776 }) 17777 17778 // Random ECH HelloRetryRequest extensions also signal ECH reject. 17779 testCases = append(testCases, testCase{ 17780 testType: clientTest, 17781 protocol: protocol, 17782 name: prefix + "ECH-Client-Reject-RandomHRRExtension", 17783 config: Config{ 17784 CurvePreferences: []CurveID{CurveP384}, 17785 Bugs: ProtocolBugs{ 17786 AlwaysSendECHHelloRetryRequest: true, 17787 ExpectMissingKeyShare: true, // Check we triggered HRR. 17788 }, 17789 }, 17790 flags: []string{ 17791 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17792 }, 17793 shouldFail: true, 17794 expectedLocalError: "remote error: ECH required", 17795 expectedError: ":ECH_REJECTED:", 17796 }) 17797 17798 // Test that the client aborts with a decode_error alert when it receives a 17799 // syntactically-invalid encrypted_client_hello extension from the server. 17800 testCases = append(testCases, testCase{ 17801 testType: clientTest, 17802 protocol: protocol, 17803 name: prefix + "ECH-GREASE-Client-TLS13-Invalid-Retry-Configs", 17804 config: Config{ 17805 MinVersion: VersionTLS13, 17806 MaxVersion: VersionTLS13, 17807 Bugs: ProtocolBugs{ 17808 ExpectClientECH: true, 17809 SendECHRetryConfigs: []byte{0xba, 0xdd, 0xec, 0xcc}, 17810 }, 17811 }, 17812 flags: []string{"-enable-ech-grease"}, 17813 shouldFail: true, 17814 expectedLocalError: "remote error: error decoding message", 17815 expectedError: ":ERROR_PARSING_EXTENSION:", 17816 }) 17817 17818 // Test that the server responds to an inner ECH extension with the 17819 // acceptance confirmation. 17820 testCases = append(testCases, testCase{ 17821 testType: serverTest, 17822 protocol: protocol, 17823 name: prefix + "ECH-Server-ECHInner", 17824 config: Config{ 17825 MinVersion: VersionTLS13, 17826 MaxVersion: VersionTLS13, 17827 Bugs: ProtocolBugs{ 17828 AlwaysSendECHInner: true, 17829 }, 17830 }, 17831 resumeSession: true, 17832 }) 17833 testCases = append(testCases, testCase{ 17834 testType: serverTest, 17835 protocol: protocol, 17836 name: prefix + "ECH-Server-ECHInner-HelloRetryRequest", 17837 config: Config{ 17838 MinVersion: VersionTLS13, 17839 MaxVersion: VersionTLS13, 17840 // Force a HelloRetryRequest. 17841 DefaultCurves: []CurveID{}, 17842 Bugs: ProtocolBugs{ 17843 AlwaysSendECHInner: true, 17844 }, 17845 }, 17846 resumeSession: true, 17847 }) 17848 17849 // Test that server fails the handshake when it sees a non-empty 17850 // inner ECH extension. 17851 testCases = append(testCases, testCase{ 17852 testType: serverTest, 17853 protocol: protocol, 17854 name: prefix + "ECH-Server-ECHInner-NotEmpty", 17855 config: Config{ 17856 MinVersion: VersionTLS13, 17857 MaxVersion: VersionTLS13, 17858 Bugs: ProtocolBugs{ 17859 AlwaysSendECHInner: true, 17860 SendInvalidECHInner: []byte{42, 42, 42}, 17861 }, 17862 }, 17863 shouldFail: true, 17864 expectedLocalError: "remote error: error decoding message", 17865 expectedError: ":ERROR_PARSING_EXTENSION:", 17866 }) 17867 17868 // Test that a TLS 1.3 server that receives an inner ECH extension can 17869 // negotiate TLS 1.2 without clobbering the downgrade signal. 17870 if protocol != quic { 17871 testCases = append(testCases, testCase{ 17872 testType: serverTest, 17873 protocol: protocol, 17874 name: prefix + "ECH-Server-ECHInner-Absent-TLS12", 17875 config: Config{ 17876 MinVersion: VersionTLS12, 17877 MaxVersion: VersionTLS13, 17878 Bugs: ProtocolBugs{ 17879 // Omit supported_versions extension so the server negotiates 17880 // TLS 1.2. 17881 OmitSupportedVersions: true, 17882 AlwaysSendECHInner: true, 17883 }, 17884 }, 17885 // Check that the client sees the TLS 1.3 downgrade signal in 17886 // ServerHello.random. 17887 shouldFail: true, 17888 expectedLocalError: "tls: downgrade from TLS 1.3 detected", 17889 }) 17890 } 17891 17892 // Test the client can negotiate ECH, with and without HelloRetryRequest. 17893 testCases = append(testCases, testCase{ 17894 testType: clientTest, 17895 protocol: protocol, 17896 name: prefix + "ECH-Client", 17897 config: Config{ 17898 MinVersion: VersionTLS13, 17899 MaxVersion: VersionTLS13, 17900 ServerECHConfigs: []ServerECHConfig{echConfig}, 17901 Bugs: ProtocolBugs{ 17902 ExpectServerName: "secret.example", 17903 ExpectOuterServerName: "public.example", 17904 }, 17905 Credential: &echSecretCertificate, 17906 }, 17907 flags: []string{ 17908 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17909 "-host-name", "secret.example", 17910 "-expect-ech-accept", 17911 }, 17912 resumeSession: true, 17913 expectations: connectionExpectations{echAccepted: true}, 17914 }) 17915 testCases = append(testCases, testCase{ 17916 testType: clientTest, 17917 protocol: protocol, 17918 name: prefix + "ECH-Client-HelloRetryRequest", 17919 config: Config{ 17920 MinVersion: VersionTLS13, 17921 MaxVersion: VersionTLS13, 17922 CurvePreferences: []CurveID{CurveP384}, 17923 ServerECHConfigs: []ServerECHConfig{echConfig}, 17924 Bugs: ProtocolBugs{ 17925 ExpectServerName: "secret.example", 17926 ExpectOuterServerName: "public.example", 17927 ExpectMissingKeyShare: true, // Check we triggered HRR. 17928 }, 17929 Credential: &echSecretCertificate, 17930 }, 17931 resumeSession: true, 17932 flags: []string{ 17933 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17934 "-host-name", "secret.example", 17935 "-expect-ech-accept", 17936 "-expect-hrr", // Check we triggered HRR. 17937 }, 17938 expectations: connectionExpectations{echAccepted: true}, 17939 }) 17940 17941 // Test the client can negotiate ECH with early data. 17942 testCases = append(testCases, testCase{ 17943 testType: clientTest, 17944 protocol: protocol, 17945 name: prefix + "ECH-Client-EarlyData", 17946 config: Config{ 17947 MinVersion: VersionTLS13, 17948 MaxVersion: VersionTLS13, 17949 ServerECHConfigs: []ServerECHConfig{echConfig}, 17950 Bugs: ProtocolBugs{ 17951 ExpectServerName: "secret.example", 17952 }, 17953 Credential: &echSecretCertificate, 17954 }, 17955 flags: []string{ 17956 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17957 "-host-name", "secret.example", 17958 "-expect-ech-accept", 17959 }, 17960 resumeSession: true, 17961 earlyData: true, 17962 expectations: connectionExpectations{echAccepted: true}, 17963 }) 17964 testCases = append(testCases, testCase{ 17965 testType: clientTest, 17966 protocol: protocol, 17967 name: prefix + "ECH-Client-EarlyDataRejected", 17968 config: Config{ 17969 MinVersion: VersionTLS13, 17970 MaxVersion: VersionTLS13, 17971 ServerECHConfigs: []ServerECHConfig{echConfig}, 17972 Bugs: ProtocolBugs{ 17973 ExpectServerName: "secret.example", 17974 AlwaysRejectEarlyData: true, 17975 }, 17976 Credential: &echSecretCertificate, 17977 }, 17978 flags: []string{ 17979 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 17980 "-host-name", "secret.example", 17981 "-expect-ech-accept", 17982 }, 17983 resumeSession: true, 17984 earlyData: true, 17985 expectEarlyDataRejected: true, 17986 expectations: connectionExpectations{echAccepted: true}, 17987 }) 17988 17989 if protocol != quic { 17990 // Test that an ECH client does not offer a TLS 1.2 session. 17991 testCases = append(testCases, testCase{ 17992 testType: clientTest, 17993 protocol: protocol, 17994 name: prefix + "ECH-Client-TLS12SessionID", 17995 config: Config{ 17996 MaxVersion: VersionTLS12, 17997 SessionTicketsDisabled: true, 17998 }, 17999 resumeConfig: &Config{ 18000 ServerECHConfigs: []ServerECHConfig{echConfig}, 18001 Bugs: ProtocolBugs{ 18002 ExpectNoTLS12Session: true, 18003 }, 18004 }, 18005 flags: []string{ 18006 "-on-resume-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18007 "-on-resume-expect-ech-accept", 18008 }, 18009 resumeSession: true, 18010 expectResumeRejected: true, 18011 resumeExpectations: &connectionExpectations{echAccepted: true}, 18012 }) 18013 testCases = append(testCases, testCase{ 18014 testType: clientTest, 18015 protocol: protocol, 18016 name: prefix + "ECH-Client-TLS12SessionTicket", 18017 config: Config{ 18018 MaxVersion: VersionTLS12, 18019 }, 18020 resumeConfig: &Config{ 18021 ServerECHConfigs: []ServerECHConfig{echConfig}, 18022 Bugs: ProtocolBugs{ 18023 ExpectNoTLS12Session: true, 18024 }, 18025 }, 18026 flags: []string{ 18027 "-on-resume-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18028 "-on-resume-expect-ech-accept", 18029 }, 18030 resumeSession: true, 18031 expectResumeRejected: true, 18032 resumeExpectations: &connectionExpectations{echAccepted: true}, 18033 }) 18034 } 18035 18036 // ClientHelloInner should not include NPN, which is a TLS 1.2-only 18037 // extensions. The Go server will enforce this, so this test only needs 18038 // to configure the feature on the shim. Other application extensions 18039 // are sent implicitly. 18040 testCases = append(testCases, testCase{ 18041 testType: clientTest, 18042 protocol: protocol, 18043 name: prefix + "ECH-Client-NoNPN", 18044 config: Config{ 18045 ServerECHConfigs: []ServerECHConfig{echConfig}, 18046 }, 18047 flags: []string{ 18048 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18049 "-expect-ech-accept", 18050 // Enable NPN. 18051 "-select-next-proto", "foo", 18052 }, 18053 expectations: connectionExpectations{echAccepted: true}, 18054 }) 18055 18056 // Test that the client iterates over configurations in the 18057 // ECHConfigList and selects the first with supported parameters. 18058 unsupportedKEM := generateServerECHConfig(&ECHConfig{ 18059 KEM: 0x6666, 18060 PublicKey: []byte{1, 2, 3, 4}, 18061 }).ECHConfig 18062 unsupportedCipherSuites := generateServerECHConfig(&ECHConfig{ 18063 CipherSuites: []HPKECipherSuite{{0x1111, 0x2222}}, 18064 }).ECHConfig 18065 unsupportedMandatoryExtension := generateServerECHConfig(&ECHConfig{ 18066 UnsupportedMandatoryExtension: true, 18067 }).ECHConfig 18068 testCases = append(testCases, testCase{ 18069 testType: clientTest, 18070 protocol: protocol, 18071 name: prefix + "ECH-Client-SelectECHConfig", 18072 config: Config{ 18073 ServerECHConfigs: []ServerECHConfig{echConfig}, 18074 }, 18075 flags: []string{ 18076 "-ech-config-list", base64FlagValue(CreateECHConfigList( 18077 unsupportedVersion, 18078 unsupportedKEM.Raw, 18079 unsupportedCipherSuites.Raw, 18080 unsupportedMandatoryExtension.Raw, 18081 echConfig.ECHConfig.Raw, 18082 // |echConfig1| is also supported, but the client should 18083 // select the first one. 18084 echConfig1.ECHConfig.Raw, 18085 )), 18086 "-expect-ech-accept", 18087 }, 18088 expectations: connectionExpectations{ 18089 echAccepted: true, 18090 }, 18091 }) 18092 18093 // Test that the client skips sending ECH if all ECHConfigs are 18094 // unsupported. 18095 testCases = append(testCases, testCase{ 18096 testType: clientTest, 18097 protocol: protocol, 18098 name: prefix + "ECH-Client-NoSupportedConfigs", 18099 config: Config{ 18100 Bugs: ProtocolBugs{ 18101 ExpectNoClientECH: true, 18102 }, 18103 }, 18104 flags: []string{ 18105 "-ech-config-list", base64FlagValue(CreateECHConfigList( 18106 unsupportedVersion, 18107 unsupportedKEM.Raw, 18108 unsupportedCipherSuites.Raw, 18109 unsupportedMandatoryExtension.Raw, 18110 )), 18111 }, 18112 }) 18113 18114 // If ECH GREASE is enabled, the client should send ECH GREASE when no 18115 // configured ECHConfig is suitable. 18116 testCases = append(testCases, testCase{ 18117 testType: clientTest, 18118 protocol: protocol, 18119 name: prefix + "ECH-Client-NoSupportedConfigs-GREASE", 18120 config: Config{ 18121 Bugs: ProtocolBugs{ 18122 ExpectClientECH: true, 18123 }, 18124 }, 18125 flags: []string{ 18126 "-ech-config-list", base64FlagValue(CreateECHConfigList( 18127 unsupportedVersion, 18128 unsupportedKEM.Raw, 18129 unsupportedCipherSuites.Raw, 18130 unsupportedMandatoryExtension.Raw, 18131 )), 18132 "-enable-ech-grease", 18133 }, 18134 }) 18135 18136 // If both ECH GREASE and suitable ECHConfigs are available, the 18137 // client should send normal ECH. 18138 testCases = append(testCases, testCase{ 18139 testType: clientTest, 18140 protocol: protocol, 18141 name: prefix + "ECH-Client-GREASE", 18142 config: Config{ 18143 ServerECHConfigs: []ServerECHConfig{echConfig}, 18144 }, 18145 flags: []string{ 18146 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18147 "-expect-ech-accept", 18148 }, 18149 resumeSession: true, 18150 expectations: connectionExpectations{echAccepted: true}, 18151 }) 18152 18153 // Test that GREASE extensions correctly interact with ECH. Both the 18154 // inner and outer ClientHellos should include GREASE extensions. 18155 testCases = append(testCases, testCase{ 18156 testType: clientTest, 18157 protocol: protocol, 18158 name: prefix + "ECH-Client-GREASEExtensions", 18159 config: Config{ 18160 ServerECHConfigs: []ServerECHConfig{echConfig}, 18161 Bugs: ProtocolBugs{ 18162 ExpectGREASE: true, 18163 }, 18164 }, 18165 flags: []string{ 18166 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18167 "-expect-ech-accept", 18168 "-enable-grease", 18169 }, 18170 resumeSession: true, 18171 expectations: connectionExpectations{echAccepted: true}, 18172 }) 18173 18174 // Test that the client tolerates unsupported extensions if the 18175 // mandatory bit is not set. 18176 unsupportedExtension := generateServerECHConfig(&ECHConfig{UnsupportedExtension: true}) 18177 testCases = append(testCases, testCase{ 18178 testType: clientTest, 18179 protocol: protocol, 18180 name: prefix + "ECH-Client-UnsupportedExtension", 18181 config: Config{ 18182 ServerECHConfigs: []ServerECHConfig{unsupportedExtension}, 18183 }, 18184 flags: []string{ 18185 "-ech-config-list", base64FlagValue(CreateECHConfigList(unsupportedExtension.ECHConfig.Raw)), 18186 "-expect-ech-accept", 18187 }, 18188 expectations: connectionExpectations{echAccepted: true}, 18189 }) 18190 18191 // Syntax errors in the ECHConfigList should be rejected. 18192 testCases = append(testCases, testCase{ 18193 testType: clientTest, 18194 protocol: protocol, 18195 name: prefix + "ECH-Client-InvalidECHConfigList", 18196 flags: []string{ 18197 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw[1:])), 18198 }, 18199 shouldFail: true, 18200 expectedError: ":INVALID_ECH_CONFIG_LIST:", 18201 }) 18202 18203 // If the ClientHelloInner has no server_name extension, while the 18204 // ClientHelloOuter has one, the client must check for unsolicited 18205 // extensions based on the selected ClientHello. 18206 testCases = append(testCases, testCase{ 18207 testType: clientTest, 18208 protocol: protocol, 18209 name: prefix + "ECH-Client-UnsolicitedInnerServerNameAck", 18210 config: Config{ 18211 ServerECHConfigs: []ServerECHConfig{echConfig}, 18212 Bugs: ProtocolBugs{ 18213 // ClientHelloOuter should have a server name. 18214 ExpectOuterServerName: "public.example", 18215 // The server will acknowledge the server_name extension. 18216 // This option runs whether or not the client requested the 18217 // extension. 18218 SendServerNameAck: true, 18219 }, 18220 }, 18221 flags: []string{ 18222 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18223 // No -host-name flag. 18224 "-expect-ech-accept", 18225 }, 18226 shouldFail: true, 18227 expectedError: ":UNEXPECTED_EXTENSION:", 18228 expectedLocalError: "remote error: unsupported extension", 18229 expectations: connectionExpectations{echAccepted: true}, 18230 }) 18231 18232 // Most extensions are the same between ClientHelloInner and 18233 // ClientHelloOuter and can be compressed. 18234 testCases = append(testCases, testCase{ 18235 testType: clientTest, 18236 protocol: protocol, 18237 name: prefix + "ECH-Client-ExpectECHOuterExtensions", 18238 config: Config{ 18239 ServerECHConfigs: []ServerECHConfig{echConfig}, 18240 NextProtos: []string{"proto"}, 18241 Bugs: ProtocolBugs{ 18242 ExpectECHOuterExtensions: []uint16{ 18243 extensionALPN, 18244 extensionKeyShare, 18245 extensionPSKKeyExchangeModes, 18246 extensionSignatureAlgorithms, 18247 extensionSupportedCurves, 18248 }, 18249 }, 18250 Credential: &echSecretCertificate, 18251 }, 18252 flags: []string{ 18253 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18254 "-expect-ech-accept", 18255 "-advertise-alpn", "\x05proto", 18256 "-expect-alpn", "proto", 18257 "-host-name", "secret.example", 18258 }, 18259 expectations: connectionExpectations{ 18260 echAccepted: true, 18261 nextProto: "proto", 18262 }, 18263 skipQUICALPNConfig: true, 18264 }) 18265 18266 // If the server name happens to match the public name, it still should 18267 // not be compressed. It is not publicly known that they match. 18268 testCases = append(testCases, testCase{ 18269 testType: clientTest, 18270 protocol: protocol, 18271 name: prefix + "ECH-Client-NeverCompressServerName", 18272 config: Config{ 18273 ServerECHConfigs: []ServerECHConfig{echConfig}, 18274 NextProtos: []string{"proto"}, 18275 Bugs: ProtocolBugs{ 18276 ExpectECHUncompressedExtensions: []uint16{extensionServerName}, 18277 ExpectServerName: "public.example", 18278 ExpectOuterServerName: "public.example", 18279 }, 18280 Credential: &echPublicCertificate, 18281 }, 18282 flags: []string{ 18283 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18284 "-expect-ech-accept", 18285 "-host-name", "public.example", 18286 }, 18287 expectations: connectionExpectations{echAccepted: true}, 18288 }) 18289 18290 // If the ClientHelloOuter disables TLS 1.3, e.g. in QUIC, the client 18291 // should also compress supported_versions. 18292 testCases = append(testCases, testCase{ 18293 testType: clientTest, 18294 protocol: protocol, 18295 name: prefix + "ECH-Client-CompressSupportedVersions", 18296 config: Config{ 18297 ServerECHConfigs: []ServerECHConfig{echConfig}, 18298 Bugs: ProtocolBugs{ 18299 ExpectECHOuterExtensions: []uint16{ 18300 extensionSupportedVersions, 18301 }, 18302 }, 18303 Credential: &echSecretCertificate, 18304 }, 18305 flags: []string{ 18306 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18307 "-host-name", "secret.example", 18308 "-expect-ech-accept", 18309 "-min-version", strconv.Itoa(int(VersionTLS13)), 18310 }, 18311 expectations: connectionExpectations{echAccepted: true}, 18312 }) 18313 18314 // Test that the client can still offer server names that exceed the 18315 // maximum name length. It is only a padding hint. 18316 maxNameLen10 := generateServerECHConfig(&ECHConfig{MaxNameLen: 10}) 18317 testCases = append(testCases, testCase{ 18318 testType: clientTest, 18319 protocol: protocol, 18320 name: prefix + "ECH-Client-NameTooLong", 18321 config: Config{ 18322 ServerECHConfigs: []ServerECHConfig{maxNameLen10}, 18323 Bugs: ProtocolBugs{ 18324 ExpectServerName: "test0123456789.example", 18325 }, 18326 Credential: &echLongNameCertificate, 18327 }, 18328 flags: []string{ 18329 "-ech-config-list", base64FlagValue(CreateECHConfigList(maxNameLen10.ECHConfig.Raw)), 18330 "-host-name", "test0123456789.example", 18331 "-expect-ech-accept", 18332 }, 18333 expectations: connectionExpectations{echAccepted: true}, 18334 }) 18335 18336 // Test the client can recognize when ECH is rejected. 18337 testCases = append(testCases, testCase{ 18338 testType: clientTest, 18339 protocol: protocol, 18340 name: prefix + "ECH-Client-Reject", 18341 config: Config{ 18342 ServerECHConfigs: []ServerECHConfig{echConfig2, echConfig3}, 18343 Bugs: ProtocolBugs{ 18344 ExpectServerName: "public.example", 18345 }, 18346 }, 18347 flags: []string{ 18348 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18349 "-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw)), 18350 }, 18351 shouldFail: true, 18352 expectedLocalError: "remote error: ECH required", 18353 expectedError: ":ECH_REJECTED:", 18354 }) 18355 testCases = append(testCases, testCase{ 18356 testType: clientTest, 18357 protocol: protocol, 18358 name: prefix + "ECH-Client-Reject-HelloRetryRequest", 18359 config: Config{ 18360 ServerECHConfigs: []ServerECHConfig{echConfig2, echConfig3}, 18361 CurvePreferences: []CurveID{CurveP384}, 18362 Bugs: ProtocolBugs{ 18363 ExpectServerName: "public.example", 18364 ExpectMissingKeyShare: true, // Check we triggered HRR. 18365 }, 18366 }, 18367 flags: []string{ 18368 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18369 "-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw, echConfig3.ECHConfig.Raw)), 18370 "-expect-hrr", // Check we triggered HRR. 18371 }, 18372 shouldFail: true, 18373 expectedLocalError: "remote error: ECH required", 18374 expectedError: ":ECH_REJECTED:", 18375 }) 18376 testCases = append(testCases, testCase{ 18377 testType: clientTest, 18378 protocol: protocol, 18379 name: prefix + "ECH-Client-Reject-NoRetryConfigs", 18380 config: Config{ 18381 Bugs: ProtocolBugs{ 18382 ExpectServerName: "public.example", 18383 }, 18384 }, 18385 flags: []string{ 18386 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18387 "-expect-no-ech-retry-configs", 18388 }, 18389 shouldFail: true, 18390 expectedLocalError: "remote error: ECH required", 18391 expectedError: ":ECH_REJECTED:", 18392 }) 18393 if protocol != quic { 18394 testCases = append(testCases, testCase{ 18395 testType: clientTest, 18396 protocol: protocol, 18397 name: prefix + "ECH-Client-Reject-TLS12", 18398 config: Config{ 18399 MaxVersion: VersionTLS12, 18400 Bugs: ProtocolBugs{ 18401 ExpectServerName: "public.example", 18402 }, 18403 }, 18404 flags: []string{ 18405 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18406 // TLS 1.2 cannot provide retry configs. 18407 "-expect-no-ech-retry-configs", 18408 }, 18409 shouldFail: true, 18410 expectedLocalError: "remote error: ECH required", 18411 expectedError: ":ECH_REJECTED:", 18412 }) 18413 18414 // Test that the client disables False Start when ECH is rejected. 18415 testCases = append(testCases, testCase{ 18416 name: prefix + "ECH-Client-Reject-TLS12-NoFalseStart", 18417 config: Config{ 18418 MaxVersion: VersionTLS12, 18419 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 18420 NextProtos: []string{"foo"}, 18421 Bugs: ProtocolBugs{ 18422 // The options below cause the server to, immediately 18423 // after client Finished, send an alert and try to read 18424 // application data without sending server Finished. 18425 ExpectFalseStart: true, 18426 AlertBeforeFalseStartTest: alertAccessDenied, 18427 }, 18428 }, 18429 flags: []string{ 18430 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18431 "-false-start", 18432 "-advertise-alpn", "\x03foo", 18433 "-expect-alpn", "foo", 18434 }, 18435 shimWritesFirst: true, 18436 shouldFail: true, 18437 // Ensure the client does not send application data at the False 18438 // Start point. EOF comes from the client closing the connection 18439 // in response ot the alert. 18440 expectedLocalError: "tls: peer did not false start: EOF", 18441 // Ensures the client picks up the alert before reporting an 18442 // authenticated |SSL_R_ECH_REJECTED|. 18443 expectedError: ":TLSV1_ALERT_ACCESS_DENIED:", 18444 }) 18445 } 18446 18447 // Test that unsupported retry configs in a valid ECHConfigList are 18448 // allowed. They will be skipped when configured in the retry. 18449 retryConfigs := CreateECHConfigList( 18450 unsupportedVersion, 18451 unsupportedKEM.Raw, 18452 unsupportedCipherSuites.Raw, 18453 unsupportedMandatoryExtension.Raw, 18454 echConfig2.ECHConfig.Raw) 18455 testCases = append(testCases, testCase{ 18456 testType: clientTest, 18457 protocol: protocol, 18458 name: prefix + "ECH-Client-Reject-UnsupportedRetryConfigs", 18459 config: Config{ 18460 Bugs: ProtocolBugs{ 18461 SendECHRetryConfigs: retryConfigs, 18462 ExpectServerName: "public.example", 18463 }, 18464 }, 18465 flags: []string{ 18466 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18467 "-expect-ech-retry-configs", base64FlagValue(retryConfigs), 18468 }, 18469 shouldFail: true, 18470 expectedLocalError: "remote error: ECH required", 18471 expectedError: ":ECH_REJECTED:", 18472 }) 18473 18474 // Test that the client rejects ClientHelloOuter handshakes that attempt 18475 // to resume the ClientHelloInner's ticket, at TLS 1.2 and TLS 1.3. 18476 testCases = append(testCases, testCase{ 18477 testType: clientTest, 18478 protocol: protocol, 18479 name: prefix + "ECH-Client-Reject-ResumeInnerSession-TLS13", 18480 config: Config{ 18481 ServerECHConfigs: []ServerECHConfig{echConfig}, 18482 Bugs: ProtocolBugs{ 18483 ExpectServerName: "secret.example", 18484 }, 18485 Credential: &echSecretCertificate, 18486 }, 18487 resumeConfig: &Config{ 18488 MaxVersion: VersionTLS13, 18489 ServerECHConfigs: []ServerECHConfig{echConfig}, 18490 Bugs: ProtocolBugs{ 18491 ExpectServerName: "public.example", 18492 UseInnerSessionWithClientHelloOuter: true, 18493 }, 18494 Credential: &echPublicCertificate, 18495 }, 18496 resumeSession: true, 18497 flags: []string{ 18498 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18499 "-host-name", "secret.example", 18500 "-on-initial-expect-ech-accept", 18501 }, 18502 shouldFail: true, 18503 expectedError: ":UNEXPECTED_EXTENSION:", 18504 expectations: connectionExpectations{echAccepted: true}, 18505 resumeExpectations: &connectionExpectations{echAccepted: false}, 18506 }) 18507 if protocol != quic { 18508 testCases = append(testCases, testCase{ 18509 testType: clientTest, 18510 protocol: protocol, 18511 name: prefix + "ECH-Client-Reject-ResumeInnerSession-TLS12", 18512 config: Config{ 18513 ServerECHConfigs: []ServerECHConfig{echConfig}, 18514 Bugs: ProtocolBugs{ 18515 ExpectServerName: "secret.example", 18516 }, 18517 Credential: &echSecretCertificate, 18518 }, 18519 resumeConfig: &Config{ 18520 MinVersion: VersionTLS12, 18521 MaxVersion: VersionTLS12, 18522 ServerECHConfigs: []ServerECHConfig{echConfig}, 18523 Bugs: ProtocolBugs{ 18524 ExpectServerName: "public.example", 18525 UseInnerSessionWithClientHelloOuter: true, 18526 // The client only ever offers TLS 1.3 sessions in 18527 // ClientHelloInner. AcceptAnySession allows them to be 18528 // resumed at TLS 1.2. 18529 AcceptAnySession: true, 18530 }, 18531 Credential: &echPublicCertificate, 18532 }, 18533 resumeSession: true, 18534 flags: []string{ 18535 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18536 "-host-name", "secret.example", 18537 "-on-initial-expect-ech-accept", 18538 }, 18539 // From the client's perspective, the server echoed a session ID to 18540 // signal resumption, but the selected ClientHello had nothing to 18541 // resume. 18542 shouldFail: true, 18543 expectedError: ":SERVER_ECHOED_INVALID_SESSION_ID:", 18544 expectedLocalError: "remote error: illegal parameter", 18545 expectations: connectionExpectations{echAccepted: true}, 18546 resumeExpectations: &connectionExpectations{echAccepted: false}, 18547 }) 18548 } 18549 18550 // Test that the client can process ECH rejects after an early data reject. 18551 testCases = append(testCases, testCase{ 18552 testType: clientTest, 18553 protocol: protocol, 18554 name: prefix + "ECH-Client-Reject-EarlyDataRejected", 18555 config: Config{ 18556 ServerECHConfigs: []ServerECHConfig{echConfig}, 18557 Bugs: ProtocolBugs{ 18558 ExpectServerName: "secret.example", 18559 }, 18560 Credential: &echSecretCertificate, 18561 }, 18562 resumeConfig: &Config{ 18563 ServerECHConfigs: []ServerECHConfig{echConfig2}, 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 "-host-name", "secret.example", 18572 // Although the resumption connection does not accept ECH, the 18573 // API will report ECH was accepted at the 0-RTT point. 18574 "-expect-ech-accept", 18575 // -on-retry refers to the retried handshake after 0-RTT reject, 18576 // while ech-retry-configs refers to the ECHConfigs to use in 18577 // the next connection attempt. 18578 "-on-retry-expect-ech-retry-configs", base64FlagValue(CreateECHConfigList(echConfig2.ECHConfig.Raw)), 18579 }, 18580 resumeSession: true, 18581 expectResumeRejected: true, 18582 earlyData: true, 18583 expectEarlyDataRejected: true, 18584 expectations: connectionExpectations{echAccepted: true}, 18585 resumeExpectations: &connectionExpectations{echAccepted: false}, 18586 shouldFail: true, 18587 expectedLocalError: "remote error: ECH required", 18588 expectedError: ":ECH_REJECTED:", 18589 }) 18590 if protocol != quic { 18591 testCases = append(testCases, testCase{ 18592 testType: clientTest, 18593 protocol: protocol, 18594 name: prefix + "ECH-Client-Reject-EarlyDataRejected-TLS12", 18595 config: Config{ 18596 ServerECHConfigs: []ServerECHConfig{echConfig}, 18597 Bugs: ProtocolBugs{ 18598 ExpectServerName: "secret.example", 18599 }, 18600 Credential: &echSecretCertificate, 18601 }, 18602 resumeConfig: &Config{ 18603 MaxVersion: VersionTLS12, 18604 Bugs: ProtocolBugs{ 18605 ExpectServerName: "public.example", 18606 }, 18607 Credential: &echPublicCertificate, 18608 }, 18609 flags: []string{ 18610 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18611 "-host-name", "secret.example", 18612 // Although the resumption connection does not accept ECH, the 18613 // API will report ECH was accepted at the 0-RTT point. 18614 "-expect-ech-accept", 18615 }, 18616 resumeSession: true, 18617 expectResumeRejected: true, 18618 earlyData: true, 18619 expectEarlyDataRejected: true, 18620 expectations: connectionExpectations{echAccepted: true}, 18621 resumeExpectations: &connectionExpectations{echAccepted: false}, 18622 // ClientHellos with early data cannot negotiate TLS 1.2, with 18623 // or without ECH. The shim should first report 18624 // |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. The caller will then 18625 // repair the first error by retrying without early data. That 18626 // will look like ECH-Client-Reject-TLS12 and select TLS 1.2 18627 // and ClientHelloOuter. The caller will then trigger a third 18628 // attempt, which will succeed. 18629 shouldFail: true, 18630 expectedError: ":WRONG_VERSION_ON_EARLY_DATA:", 18631 }) 18632 } 18633 18634 // Test that the client ignores ECHConfigs with invalid public names. 18635 invalidPublicName := generateServerECHConfig(&ECHConfig{PublicName: "dns_names_have_no_underscores.example"}) 18636 testCases = append(testCases, testCase{ 18637 testType: clientTest, 18638 protocol: protocol, 18639 name: prefix + "ECH-Client-SkipInvalidPublicName", 18640 config: Config{ 18641 Bugs: ProtocolBugs{ 18642 // No ECHConfigs are supported, so the client should fall 18643 // back to cleartext. 18644 ExpectNoClientECH: true, 18645 ExpectServerName: "secret.example", 18646 }, 18647 Credential: &echSecretCertificate, 18648 }, 18649 flags: []string{ 18650 "-ech-config-list", base64FlagValue(CreateECHConfigList(invalidPublicName.ECHConfig.Raw)), 18651 "-host-name", "secret.example", 18652 }, 18653 }) 18654 testCases = append(testCases, testCase{ 18655 testType: clientTest, 18656 protocol: protocol, 18657 name: prefix + "ECH-Client-SkipInvalidPublicName-2", 18658 config: Config{ 18659 // The client should skip |invalidPublicName| and use |echConfig|. 18660 ServerECHConfigs: []ServerECHConfig{echConfig}, 18661 Bugs: ProtocolBugs{ 18662 ExpectOuterServerName: "public.example", 18663 ExpectServerName: "secret.example", 18664 }, 18665 Credential: &echSecretCertificate, 18666 }, 18667 flags: []string{ 18668 "-ech-config-list", base64FlagValue(CreateECHConfigList(invalidPublicName.ECHConfig.Raw, echConfig.ECHConfig.Raw)), 18669 "-host-name", "secret.example", 18670 "-expect-ech-accept", 18671 }, 18672 expectations: connectionExpectations{echAccepted: true}, 18673 }) 18674 18675 // Test both sync and async mode, to test both with and without the 18676 // client certificate callback. 18677 for _, async := range []bool{false, true} { 18678 var flags []string 18679 var suffix string 18680 if async { 18681 flags = []string{"-async"} 18682 suffix = "-Async" 18683 } 18684 18685 // Test that ECH and client certificates can be used together. 18686 testCases = append(testCases, testCase{ 18687 testType: clientTest, 18688 protocol: protocol, 18689 name: prefix + "ECH-Client-ClientCertificate" + suffix, 18690 config: Config{ 18691 ServerECHConfigs: []ServerECHConfig{echConfig}, 18692 ClientAuth: RequireAnyClientCert, 18693 }, 18694 shimCertificate: &rsaCertificate, 18695 flags: append([]string{ 18696 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18697 "-expect-ech-accept", 18698 }, flags...), 18699 expectations: connectionExpectations{echAccepted: true}, 18700 }) 18701 18702 // Test that, when ECH is rejected, the client does not send a client 18703 // certificate. 18704 testCases = append(testCases, testCase{ 18705 testType: clientTest, 18706 protocol: protocol, 18707 name: prefix + "ECH-Client-Reject-NoClientCertificate-TLS13" + suffix, 18708 config: Config{ 18709 MinVersion: VersionTLS13, 18710 MaxVersion: VersionTLS13, 18711 ClientAuth: RequireAnyClientCert, 18712 }, 18713 shimCertificate: &rsaCertificate, 18714 flags: append([]string{ 18715 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18716 }, flags...), 18717 shouldFail: true, 18718 expectedLocalError: "tls: client didn't provide a certificate", 18719 }) 18720 if protocol != quic { 18721 testCases = append(testCases, testCase{ 18722 testType: clientTest, 18723 protocol: protocol, 18724 name: prefix + "ECH-Client-Reject-NoClientCertificate-TLS12" + suffix, 18725 config: Config{ 18726 MinVersion: VersionTLS12, 18727 MaxVersion: VersionTLS12, 18728 ClientAuth: RequireAnyClientCert, 18729 }, 18730 shimCertificate: &rsaCertificate, 18731 flags: append([]string{ 18732 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18733 }, flags...), 18734 shouldFail: true, 18735 expectedLocalError: "tls: client didn't provide a certificate", 18736 }) 18737 } 18738 } 18739 18740 // Test that ECH and Channel ID can be used together. 18741 testCases = append(testCases, testCase{ 18742 testType: clientTest, 18743 protocol: protocol, 18744 name: prefix + "ECH-Client-ChannelID", 18745 config: Config{ 18746 ServerECHConfigs: []ServerECHConfig{echConfig}, 18747 RequestChannelID: true, 18748 }, 18749 flags: []string{ 18750 "-send-channel-id", channelIDKeyPath, 18751 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18752 "-expect-ech-accept", 18753 }, 18754 resumeSession: true, 18755 expectations: connectionExpectations{ 18756 channelID: true, 18757 echAccepted: true, 18758 }, 18759 }) 18760 18761 // Handshakes where ECH is rejected do not offer or accept Channel ID. 18762 testCases = append(testCases, testCase{ 18763 testType: clientTest, 18764 protocol: protocol, 18765 name: prefix + "ECH-Client-Reject-NoChannelID-TLS13", 18766 config: Config{ 18767 MinVersion: VersionTLS13, 18768 MaxVersion: VersionTLS13, 18769 Bugs: ProtocolBugs{ 18770 AlwaysNegotiateChannelID: true, 18771 }, 18772 }, 18773 flags: []string{ 18774 "-send-channel-id", channelIDKeyPath, 18775 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18776 }, 18777 shouldFail: true, 18778 expectedLocalError: "remote error: unsupported extension", 18779 expectedError: ":UNEXPECTED_EXTENSION:", 18780 }) 18781 if protocol != quic { 18782 testCases = append(testCases, testCase{ 18783 testType: clientTest, 18784 protocol: protocol, 18785 name: prefix + "ECH-Client-Reject-NoChannelID-TLS12", 18786 config: Config{ 18787 MinVersion: VersionTLS12, 18788 MaxVersion: VersionTLS12, 18789 Bugs: ProtocolBugs{ 18790 AlwaysNegotiateChannelID: true, 18791 }, 18792 }, 18793 flags: []string{ 18794 "-send-channel-id", channelIDKeyPath, 18795 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18796 }, 18797 shouldFail: true, 18798 expectedLocalError: "remote error: unsupported extension", 18799 expectedError: ":UNEXPECTED_EXTENSION:", 18800 }) 18801 } 18802 18803 // Test that ECH correctly overrides the host name for certificate 18804 // verification. 18805 testCases = append(testCases, testCase{ 18806 testType: clientTest, 18807 protocol: protocol, 18808 name: prefix + "ECH-Client-NotOffered-NoOverrideName", 18809 flags: []string{ 18810 "-verify-peer", 18811 "-use-custom-verify-callback", 18812 // When not offering ECH, verify the usual name in both full 18813 // and resumption handshakes. 18814 "-reverify-on-resume", 18815 "-expect-no-ech-name-override", 18816 }, 18817 resumeSession: true, 18818 }) 18819 testCases = append(testCases, testCase{ 18820 testType: clientTest, 18821 protocol: protocol, 18822 name: prefix + "ECH-Client-GREASE-NoOverrideName", 18823 flags: []string{ 18824 "-verify-peer", 18825 "-use-custom-verify-callback", 18826 "-enable-ech-grease", 18827 // When offering ECH GREASE, verify the usual name in both full 18828 // and resumption handshakes. 18829 "-reverify-on-resume", 18830 "-expect-no-ech-name-override", 18831 }, 18832 resumeSession: true, 18833 }) 18834 if protocol != quic { 18835 testCases = append(testCases, testCase{ 18836 testType: clientTest, 18837 protocol: protocol, 18838 name: prefix + "ECH-Client-Rejected-OverrideName-TLS12", 18839 config: Config{ 18840 MinVersion: VersionTLS12, 18841 MaxVersion: VersionTLS12, 18842 }, 18843 flags: []string{ 18844 "-verify-peer", 18845 "-use-custom-verify-callback", 18846 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18847 // When ECH is rejected, verify the public name. This can 18848 // only happen in full handshakes. 18849 "-expect-ech-name-override", "public.example", 18850 }, 18851 shouldFail: true, 18852 expectedError: ":ECH_REJECTED:", 18853 expectedLocalError: "remote error: ECH required", 18854 }) 18855 } 18856 testCases = append(testCases, testCase{ 18857 testType: clientTest, 18858 protocol: protocol, 18859 name: prefix + "ECH-Client-Reject-OverrideName-TLS13", 18860 config: Config{ 18861 MinVersion: VersionTLS13, 18862 MaxVersion: VersionTLS13, 18863 }, 18864 flags: []string{ 18865 "-verify-peer", 18866 "-use-custom-verify-callback", 18867 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18868 // When ECH is rejected, verify the public name. This can 18869 // only happen in full handshakes. 18870 "-expect-ech-name-override", "public.example", 18871 }, 18872 shouldFail: true, 18873 expectedError: ":ECH_REJECTED:", 18874 expectedLocalError: "remote error: ECH required", 18875 }) 18876 testCases = append(testCases, testCase{ 18877 testType: clientTest, 18878 protocol: protocol, 18879 name: prefix + "ECH-Client-Accept-NoOverrideName", 18880 config: Config{ 18881 ServerECHConfigs: []ServerECHConfig{echConfig}, 18882 }, 18883 flags: []string{ 18884 "-verify-peer", 18885 "-use-custom-verify-callback", 18886 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18887 "-expect-ech-accept", 18888 // When ECH is accepted, verify the usual name in both full and 18889 // resumption handshakes. 18890 "-reverify-on-resume", 18891 "-expect-no-ech-name-override", 18892 }, 18893 resumeSession: true, 18894 expectations: connectionExpectations{echAccepted: true}, 18895 }) 18896 testCases = append(testCases, testCase{ 18897 testType: clientTest, 18898 protocol: protocol, 18899 name: prefix + "ECH-Client-Reject-EarlyDataRejected-OverrideNameOnRetry", 18900 config: Config{ 18901 ServerECHConfigs: []ServerECHConfig{echConfig}, 18902 }, 18903 resumeConfig: &Config{}, 18904 flags: []string{ 18905 "-verify-peer", 18906 "-use-custom-verify-callback", 18907 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18908 // Although the resumption connection does not accept ECH, the 18909 // API will report ECH was accepted at the 0-RTT point. 18910 "-expect-ech-accept", 18911 // The resumption connection verifies certificates twice. First, 18912 // if reverification is enabled, we verify the 0-RTT certificate 18913 // as if ECH as accepted. There should be no name override. 18914 // Next, on the post-0-RTT-rejection retry, we verify the new 18915 // server certificate. This picks up the ECH reject, so it 18916 // should use public.example. 18917 "-reverify-on-resume", 18918 "-on-resume-expect-no-ech-name-override", 18919 "-on-retry-expect-ech-name-override", "public.example", 18920 }, 18921 resumeSession: true, 18922 expectResumeRejected: true, 18923 earlyData: true, 18924 expectEarlyDataRejected: true, 18925 expectations: connectionExpectations{echAccepted: true}, 18926 resumeExpectations: &connectionExpectations{echAccepted: false}, 18927 shouldFail: true, 18928 expectedError: ":ECH_REJECTED:", 18929 expectedLocalError: "remote error: ECH required", 18930 }) 18931 18932 // Test that the client checks both HelloRetryRequest and ServerHello 18933 // for a confirmation signal. 18934 testCases = append(testCases, testCase{ 18935 testType: clientTest, 18936 protocol: protocol, 18937 name: prefix + "ECH-Client-HelloRetryRequest-MissingServerHelloConfirmation", 18938 config: Config{ 18939 MinVersion: VersionTLS13, 18940 MaxVersion: VersionTLS13, 18941 CurvePreferences: []CurveID{CurveP384}, 18942 ServerECHConfigs: []ServerECHConfig{echConfig}, 18943 Bugs: ProtocolBugs{ 18944 ExpectMissingKeyShare: true, // Check we triggered HRR. 18945 OmitServerHelloECHConfirmation: true, 18946 }, 18947 }, 18948 resumeSession: true, 18949 flags: []string{ 18950 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18951 "-expect-hrr", // Check we triggered HRR. 18952 }, 18953 shouldFail: true, 18954 expectedError: ":INCONSISTENT_ECH_NEGOTIATION:", 18955 }) 18956 18957 // Test the message callback is correctly reported, with and without 18958 // HelloRetryRequest. 18959 clientAndServerHello := "write clienthelloinner\nwrite hs 1\nread hs 2\n" 18960 // EncryptedExtensions onwards. 18961 finishHandshake := `read hs 8 18962read hs 11 18963read hs 15 18964read hs 20 18965write hs 20 18966read hs 4 18967read hs 4 18968` 18969 testCases = append(testCases, testCase{ 18970 testType: clientTest, 18971 protocol: protocol, 18972 name: prefix + "ECH-Client-MessageCallback", 18973 config: Config{ 18974 MinVersion: VersionTLS13, 18975 MaxVersion: VersionTLS13, 18976 ServerECHConfigs: []ServerECHConfig{echConfig}, 18977 Bugs: ProtocolBugs{ 18978 NoCloseNotify: true, // Align QUIC and TCP traces. 18979 }, 18980 }, 18981 flags: []string{ 18982 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 18983 "-expect-ech-accept", 18984 "-expect-msg-callback", clientAndServerHello + "write ccs\n" + finishHandshake, 18985 }, 18986 expectations: connectionExpectations{echAccepted: true}, 18987 }) 18988 testCases = append(testCases, testCase{ 18989 testType: clientTest, 18990 protocol: protocol, 18991 name: prefix + "ECH-Client-MessageCallback-HelloRetryRequest", 18992 config: Config{ 18993 MinVersion: VersionTLS13, 18994 MaxVersion: VersionTLS13, 18995 CurvePreferences: []CurveID{CurveP384}, 18996 ServerECHConfigs: []ServerECHConfig{echConfig}, 18997 Bugs: ProtocolBugs{ 18998 ExpectMissingKeyShare: true, // Check we triggered HRR. 18999 NoCloseNotify: true, // Align QUIC and TCP traces. 19000 }, 19001 }, 19002 flags: []string{ 19003 "-ech-config-list", base64FlagValue(CreateECHConfigList(echConfig.ECHConfig.Raw)), 19004 "-expect-ech-accept", 19005 "-expect-hrr", // Check we triggered HRR. 19006 "-expect-msg-callback", clientAndServerHello + "write ccs\n" + clientAndServerHello + finishHandshake, 19007 }, 19008 expectations: connectionExpectations{echAccepted: true}, 19009 }) 19010 } 19011} 19012 19013func addHintMismatchTests() { 19014 // Each of these tests skips split handshakes because split handshakes does 19015 // not handle a mismatch between shim and handshaker. Handshake hints, 19016 // however, are designed to tolerate the mismatch. 19017 // 19018 // Note also these tests do not specify -handshake-hints directly. Instead, 19019 // we define normal tests, that run even without a handshaker, and rely on 19020 // convertToSplitHandshakeTests to generate a handshaker hints variant. This 19021 // avoids repeating the -is-handshaker-supported and -handshaker-path logic. 19022 // (While not useful, the tests will still pass without a handshaker.) 19023 for _, protocol := range []protocol{tls, quic} { 19024 // If the signing payload is different, the handshake still completes 19025 // successfully. Different ALPN preferences will trigger a mismatch. 19026 testCases = append(testCases, testCase{ 19027 name: protocol.String() + "-HintMismatch-SignatureInput", 19028 testType: serverTest, 19029 protocol: protocol, 19030 skipSplitHandshake: true, 19031 config: Config{ 19032 MinVersion: VersionTLS13, 19033 MaxVersion: VersionTLS13, 19034 NextProtos: []string{"foo", "bar"}, 19035 }, 19036 flags: []string{ 19037 "-allow-hint-mismatch", 19038 "-on-shim-select-alpn", "foo", 19039 "-on-handshaker-select-alpn", "bar", 19040 }, 19041 expectations: connectionExpectations{ 19042 nextProto: "foo", 19043 nextProtoType: alpn, 19044 }, 19045 }) 19046 19047 // The shim and handshaker may have different curve preferences. 19048 testCases = append(testCases, testCase{ 19049 name: protocol.String() + "-HintMismatch-KeyShare", 19050 testType: serverTest, 19051 protocol: protocol, 19052 skipSplitHandshake: true, 19053 config: Config{ 19054 MinVersion: VersionTLS13, 19055 MaxVersion: VersionTLS13, 19056 // Send both curves in the key share list, to avoid getting 19057 // mixed up with HelloRetryRequest. 19058 DefaultCurves: []CurveID{CurveX25519, CurveP256}, 19059 }, 19060 flags: []string{ 19061 "-allow-hint-mismatch", 19062 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 19063 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 19064 }, 19065 expectations: connectionExpectations{ 19066 curveID: CurveX25519, 19067 }, 19068 }) 19069 if protocol != quic { 19070 testCases = append(testCases, testCase{ 19071 name: protocol.String() + "-HintMismatch-ECDHE-Group", 19072 testType: serverTest, 19073 protocol: protocol, 19074 skipSplitHandshake: true, 19075 config: Config{ 19076 MinVersion: VersionTLS12, 19077 MaxVersion: VersionTLS12, 19078 DefaultCurves: []CurveID{CurveX25519, CurveP256}, 19079 }, 19080 flags: []string{ 19081 "-allow-hint-mismatch", 19082 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 19083 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 19084 }, 19085 expectations: connectionExpectations{ 19086 curveID: CurveX25519, 19087 }, 19088 }) 19089 } 19090 19091 // If the handshaker does HelloRetryRequest, it will omit most hints. 19092 // The shim should still work. 19093 testCases = append(testCases, testCase{ 19094 name: protocol.String() + "-HintMismatch-HandshakerHelloRetryRequest", 19095 testType: serverTest, 19096 protocol: protocol, 19097 skipSplitHandshake: true, 19098 config: Config{ 19099 MinVersion: VersionTLS13, 19100 MaxVersion: VersionTLS13, 19101 DefaultCurves: []CurveID{CurveX25519}, 19102 }, 19103 flags: []string{ 19104 "-allow-hint-mismatch", 19105 "-on-shim-curves", strconv.Itoa(int(CurveX25519)), 19106 "-on-handshaker-curves", strconv.Itoa(int(CurveP256)), 19107 }, 19108 expectations: connectionExpectations{ 19109 curveID: CurveX25519, 19110 }, 19111 }) 19112 19113 // If the shim does HelloRetryRequest, the hints from the handshaker 19114 // will be ignored. This is not reported as a mismatch because hints 19115 // would not have helped the shim anyway. 19116 testCases = append(testCases, testCase{ 19117 name: protocol.String() + "-HintMismatch-ShimHelloRetryRequest", 19118 testType: serverTest, 19119 protocol: protocol, 19120 skipSplitHandshake: true, 19121 config: Config{ 19122 MinVersion: VersionTLS13, 19123 MaxVersion: VersionTLS13, 19124 DefaultCurves: []CurveID{CurveX25519}, 19125 }, 19126 flags: []string{ 19127 "-on-shim-curves", strconv.Itoa(int(CurveP256)), 19128 "-on-handshaker-curves", strconv.Itoa(int(CurveX25519)), 19129 }, 19130 expectations: connectionExpectations{ 19131 curveID: CurveP256, 19132 }, 19133 }) 19134 19135 // The shim and handshaker may have different signature algorithm 19136 // preferences. 19137 testCases = append(testCases, testCase{ 19138 name: protocol.String() + "-HintMismatch-SignatureAlgorithm-TLS13", 19139 testType: serverTest, 19140 protocol: protocol, 19141 skipSplitHandshake: true, 19142 config: Config{ 19143 MinVersion: VersionTLS13, 19144 MaxVersion: VersionTLS13, 19145 VerifySignatureAlgorithms: []signatureAlgorithm{ 19146 signatureRSAPSSWithSHA256, 19147 signatureRSAPSSWithSHA384, 19148 }, 19149 }, 19150 shimCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 19151 handshakerCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA384), 19152 flags: []string{"-allow-hint-mismatch"}, 19153 expectations: connectionExpectations{ 19154 peerSignatureAlgorithm: signatureRSAPSSWithSHA256, 19155 }, 19156 }) 19157 if protocol != quic { 19158 testCases = append(testCases, testCase{ 19159 name: protocol.String() + "-HintMismatch-SignatureAlgorithm-TLS12", 19160 testType: serverTest, 19161 protocol: protocol, 19162 skipSplitHandshake: true, 19163 config: Config{ 19164 MinVersion: VersionTLS12, 19165 MaxVersion: VersionTLS12, 19166 VerifySignatureAlgorithms: []signatureAlgorithm{ 19167 signatureRSAPSSWithSHA256, 19168 signatureRSAPSSWithSHA384, 19169 }, 19170 }, 19171 shimCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 19172 handshakerCertificate: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA384), 19173 flags: []string{"-allow-hint-mismatch"}, 19174 expectations: connectionExpectations{ 19175 peerSignatureAlgorithm: signatureRSAPSSWithSHA256, 19176 }, 19177 }) 19178 } 19179 19180 // The shim and handshaker may use different certificates. In TLS 1.3, 19181 // the signature input includes the certificate, so we do not need to 19182 // explicitly check for a public key match. In TLS 1.2, it does not. 19183 ecdsaP256Certificate2 := generateSingleCertChain(nil, &channelIDKey) 19184 testCases = append(testCases, testCase{ 19185 name: protocol.String() + "-HintMismatch-Certificate-TLS13", 19186 testType: serverTest, 19187 protocol: protocol, 19188 skipSplitHandshake: true, 19189 config: Config{ 19190 MinVersion: VersionTLS13, 19191 MaxVersion: VersionTLS13, 19192 }, 19193 shimCertificate: &ecdsaP256Certificate, 19194 handshakerCertificate: &ecdsaP256Certificate2, 19195 flags: []string{"-allow-hint-mismatch"}, 19196 expectations: connectionExpectations{ 19197 peerCertificate: &ecdsaP256Certificate, 19198 }, 19199 }) 19200 if protocol != quic { 19201 testCases = append(testCases, testCase{ 19202 name: protocol.String() + "-HintMismatch-Certificate-TLS12", 19203 testType: serverTest, 19204 protocol: protocol, 19205 skipSplitHandshake: true, 19206 config: Config{ 19207 MinVersion: VersionTLS12, 19208 MaxVersion: VersionTLS12, 19209 }, 19210 shimCertificate: &ecdsaP256Certificate, 19211 handshakerCertificate: &ecdsaP256Certificate2, 19212 flags: []string{"-allow-hint-mismatch"}, 19213 expectations: connectionExpectations{ 19214 peerCertificate: &ecdsaP256Certificate, 19215 }, 19216 }) 19217 } 19218 19219 // The shim and handshaker may disagree on whether resumption is allowed. 19220 // We run the first connection with tickets enabled, so the client is 19221 // issued a ticket, then disable tickets on the second connection. 19222 testCases = append(testCases, testCase{ 19223 name: protocol.String() + "-HintMismatch-NoTickets1-TLS13", 19224 testType: serverTest, 19225 protocol: protocol, 19226 skipSplitHandshake: true, 19227 config: Config{ 19228 MinVersion: VersionTLS13, 19229 MaxVersion: VersionTLS13, 19230 }, 19231 flags: []string{ 19232 "-on-resume-allow-hint-mismatch", 19233 "-on-shim-on-resume-no-ticket", 19234 }, 19235 resumeSession: true, 19236 expectResumeRejected: true, 19237 }) 19238 testCases = append(testCases, testCase{ 19239 name: protocol.String() + "-HintMismatch-NoTickets2-TLS13", 19240 testType: serverTest, 19241 protocol: protocol, 19242 skipSplitHandshake: true, 19243 config: Config{ 19244 MinVersion: VersionTLS13, 19245 MaxVersion: VersionTLS13, 19246 }, 19247 flags: []string{ 19248 "-on-resume-allow-hint-mismatch", 19249 "-on-handshaker-on-resume-no-ticket", 19250 }, 19251 resumeSession: true, 19252 }) 19253 if protocol != quic { 19254 testCases = append(testCases, testCase{ 19255 name: protocol.String() + "-HintMismatch-NoTickets1-TLS12", 19256 testType: serverTest, 19257 protocol: protocol, 19258 skipSplitHandshake: true, 19259 config: Config{ 19260 MinVersion: VersionTLS12, 19261 MaxVersion: VersionTLS12, 19262 }, 19263 flags: []string{ 19264 "-on-resume-allow-hint-mismatch", 19265 "-on-shim-on-resume-no-ticket", 19266 }, 19267 resumeSession: true, 19268 expectResumeRejected: true, 19269 }) 19270 testCases = append(testCases, testCase{ 19271 name: protocol.String() + "-HintMismatch-NoTickets2-TLS12", 19272 testType: serverTest, 19273 protocol: protocol, 19274 skipSplitHandshake: true, 19275 config: Config{ 19276 MinVersion: VersionTLS12, 19277 MaxVersion: VersionTLS12, 19278 }, 19279 flags: []string{ 19280 "-on-resume-allow-hint-mismatch", 19281 "-on-handshaker-on-resume-no-ticket", 19282 }, 19283 resumeSession: true, 19284 }) 19285 } 19286 19287 // The shim and handshaker may disagree on whether to request a client 19288 // certificate. 19289 testCases = append(testCases, testCase{ 19290 name: protocol.String() + "-HintMismatch-CertificateRequest", 19291 testType: serverTest, 19292 protocol: protocol, 19293 skipSplitHandshake: true, 19294 config: Config{ 19295 MinVersion: VersionTLS13, 19296 MaxVersion: VersionTLS13, 19297 Credential: &rsaCertificate, 19298 }, 19299 flags: []string{ 19300 "-allow-hint-mismatch", 19301 "-on-shim-require-any-client-certificate", 19302 }, 19303 }) 19304 19305 // The shim and handshaker may negotiate different versions altogether. 19306 if protocol != quic { 19307 testCases = append(testCases, testCase{ 19308 name: protocol.String() + "-HintMismatch-Version1", 19309 testType: serverTest, 19310 protocol: protocol, 19311 skipSplitHandshake: true, 19312 config: Config{ 19313 MinVersion: VersionTLS12, 19314 MaxVersion: VersionTLS13, 19315 }, 19316 flags: []string{ 19317 "-allow-hint-mismatch", 19318 "-on-shim-max-version", strconv.Itoa(VersionTLS12), 19319 "-on-handshaker-max-version", strconv.Itoa(VersionTLS13), 19320 }, 19321 expectations: connectionExpectations{ 19322 version: VersionTLS12, 19323 }, 19324 }) 19325 testCases = append(testCases, testCase{ 19326 name: protocol.String() + "-HintMismatch-Version2", 19327 testType: serverTest, 19328 protocol: protocol, 19329 skipSplitHandshake: true, 19330 config: Config{ 19331 MinVersion: VersionTLS12, 19332 MaxVersion: VersionTLS13, 19333 }, 19334 flags: []string{ 19335 "-allow-hint-mismatch", 19336 "-on-shim-max-version", strconv.Itoa(VersionTLS13), 19337 "-on-handshaker-max-version", strconv.Itoa(VersionTLS12), 19338 }, 19339 expectations: connectionExpectations{ 19340 version: VersionTLS13, 19341 }, 19342 }) 19343 } 19344 19345 // The shim and handshaker may disagree on the certificate compression 19346 // algorithm, whether to enable certificate compression, or certificate 19347 // compression inputs. 19348 testCases = append(testCases, testCase{ 19349 name: protocol.String() + "-HintMismatch-CertificateCompression-ShimOnly", 19350 testType: serverTest, 19351 protocol: protocol, 19352 skipSplitHandshake: true, 19353 config: Config{ 19354 MinVersion: VersionTLS13, 19355 MaxVersion: VersionTLS13, 19356 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19357 shrinkingCompressionAlgID: shrinkingCompression, 19358 }, 19359 Bugs: ProtocolBugs{ 19360 ExpectedCompressedCert: shrinkingCompressionAlgID, 19361 }, 19362 }, 19363 flags: []string{ 19364 "-allow-hint-mismatch", 19365 "-on-shim-install-cert-compression-algs", 19366 }, 19367 }) 19368 testCases = append(testCases, testCase{ 19369 name: protocol.String() + "-HintMismatch-CertificateCompression-HandshakerOnly", 19370 testType: serverTest, 19371 protocol: protocol, 19372 skipSplitHandshake: true, 19373 config: Config{ 19374 MinVersion: VersionTLS13, 19375 MaxVersion: VersionTLS13, 19376 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19377 shrinkingCompressionAlgID: shrinkingCompression, 19378 }, 19379 Bugs: ProtocolBugs{ 19380 ExpectUncompressedCert: true, 19381 }, 19382 }, 19383 flags: []string{ 19384 "-allow-hint-mismatch", 19385 "-on-handshaker-install-cert-compression-algs", 19386 }, 19387 }) 19388 testCases = append(testCases, testCase{ 19389 testType: serverTest, 19390 name: protocol.String() + "-HintMismatch-CertificateCompression-AlgorithmMismatch", 19391 protocol: protocol, 19392 skipSplitHandshake: true, 19393 config: Config{ 19394 MinVersion: VersionTLS13, 19395 MaxVersion: VersionTLS13, 19396 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19397 shrinkingCompressionAlgID: shrinkingCompression, 19398 expandingCompressionAlgID: expandingCompression, 19399 }, 19400 Bugs: ProtocolBugs{ 19401 // The shim's preferences should take effect. 19402 ExpectedCompressedCert: shrinkingCompressionAlgID, 19403 }, 19404 }, 19405 flags: []string{ 19406 "-allow-hint-mismatch", 19407 "-on-shim-install-one-cert-compression-alg", strconv.Itoa(shrinkingCompressionAlgID), 19408 "-on-handshaker-install-one-cert-compression-alg", strconv.Itoa(expandingCompressionAlgID), 19409 }, 19410 }) 19411 testCases = append(testCases, testCase{ 19412 testType: serverTest, 19413 name: protocol.String() + "-HintMismatch-CertificateCompression-InputMismatch", 19414 protocol: protocol, 19415 skipSplitHandshake: true, 19416 config: Config{ 19417 MinVersion: VersionTLS13, 19418 MaxVersion: VersionTLS13, 19419 CertCompressionAlgs: map[uint16]CertCompressionAlg{ 19420 shrinkingCompressionAlgID: shrinkingCompression, 19421 }, 19422 Bugs: ProtocolBugs{ 19423 ExpectedCompressedCert: shrinkingCompressionAlgID, 19424 }, 19425 }, 19426 // Configure the shim and handshaker with different OCSP responses, 19427 // so the compression inputs do not match. 19428 shimCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 19429 handshakerCertificate: rsaCertificate.WithOCSP(testOCSPResponse2), 19430 flags: []string{ 19431 "-allow-hint-mismatch", 19432 "-install-cert-compression-algs", 19433 }, 19434 expectations: connectionExpectations{ 19435 // The shim's configuration should take precendence. 19436 peerCertificate: rsaCertificate.WithOCSP(testOCSPResponse), 19437 }, 19438 }) 19439 19440 // The shim and handshaker may disagree on cipher suite, to the point 19441 // that one selects RSA key exchange (no applicable hint) and the other 19442 // selects ECDHE_RSA (hints are useful). 19443 if protocol != quic { 19444 testCases = append(testCases, testCase{ 19445 testType: serverTest, 19446 name: protocol.String() + "-HintMismatch-CipherMismatch1", 19447 protocol: protocol, 19448 skipSplitHandshake: true, 19449 config: Config{ 19450 MinVersion: VersionTLS12, 19451 MaxVersion: VersionTLS12, 19452 }, 19453 flags: []string{ 19454 "-allow-hint-mismatch", 19455 "-on-shim-cipher", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 19456 "-on-handshaker-cipher", "TLS_RSA_WITH_AES_128_GCM_SHA256", 19457 }, 19458 expectations: connectionExpectations{ 19459 cipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 19460 }, 19461 }) 19462 testCases = append(testCases, testCase{ 19463 testType: serverTest, 19464 name: protocol.String() + "-HintMismatch-CipherMismatch2", 19465 protocol: protocol, 19466 skipSplitHandshake: true, 19467 config: Config{ 19468 MinVersion: VersionTLS12, 19469 MaxVersion: VersionTLS12, 19470 }, 19471 flags: []string{ 19472 // There is no need to pass -allow-hint-mismatch. The 19473 // handshaker will unnecessarily generate a signature hints. 19474 // This is not reported as a mismatch because hints would 19475 // not have helped the shim anyway. 19476 "-on-shim-cipher", "TLS_RSA_WITH_AES_128_GCM_SHA256", 19477 "-on-handshaker-cipher", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 19478 }, 19479 expectations: connectionExpectations{ 19480 cipher: TLS_RSA_WITH_AES_128_GCM_SHA256, 19481 }, 19482 }) 19483 } 19484 } 19485} 19486 19487func addCompliancePolicyTests() { 19488 for _, protocol := range []protocol{tls, quic} { 19489 for _, suite := range testCipherSuites { 19490 var isFIPSCipherSuite bool 19491 switch suite.id { 19492 case TLS_AES_128_GCM_SHA256, 19493 TLS_AES_256_GCM_SHA384, 19494 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 19495 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 19496 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 19497 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: 19498 isFIPSCipherSuite = true 19499 } 19500 19501 var isWPACipherSuite bool 19502 switch suite.id { 19503 case TLS_AES_256_GCM_SHA384, 19504 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 19505 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: 19506 isWPACipherSuite = true 19507 } 19508 19509 var cert Credential 19510 if hasComponent(suite.name, "ECDSA") { 19511 cert = ecdsaP384Certificate 19512 } else { 19513 cert = rsaCertificate 19514 } 19515 19516 maxVersion := uint16(VersionTLS13) 19517 if !isTLS13Suite(suite.name) { 19518 if protocol == quic { 19519 continue 19520 } 19521 maxVersion = VersionTLS12 19522 } 19523 19524 policies := []struct { 19525 flag string 19526 cipherSuiteOk bool 19527 }{ 19528 {"-fips-202205", isFIPSCipherSuite}, 19529 {"-wpa-202304", isWPACipherSuite}, 19530 } 19531 19532 for _, policy := range policies { 19533 testCases = append(testCases, testCase{ 19534 testType: serverTest, 19535 protocol: protocol, 19536 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + suite.name, 19537 config: Config{ 19538 MinVersion: VersionTLS12, 19539 MaxVersion: maxVersion, 19540 CipherSuites: []uint16{suite.id}, 19541 }, 19542 shimCertificate: &cert, 19543 flags: []string{ 19544 policy.flag, 19545 }, 19546 shouldFail: !policy.cipherSuiteOk, 19547 }) 19548 19549 testCases = append(testCases, testCase{ 19550 testType: clientTest, 19551 protocol: protocol, 19552 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + suite.name, 19553 config: Config{ 19554 MinVersion: VersionTLS12, 19555 MaxVersion: maxVersion, 19556 CipherSuites: []uint16{suite.id}, 19557 Credential: &cert, 19558 }, 19559 flags: []string{ 19560 policy.flag, 19561 }, 19562 shouldFail: !policy.cipherSuiteOk, 19563 }) 19564 } 19565 } 19566 19567 // Check that a TLS 1.3 client won't accept ChaCha20 even if the server 19568 // picks it without it being in the client's cipher list. 19569 testCases = append(testCases, testCase{ 19570 testType: clientTest, 19571 protocol: protocol, 19572 name: "Compliance-fips202205-" + protocol.String() + "-Client-ReallyWontAcceptChaCha", 19573 config: Config{ 19574 MinVersion: VersionTLS12, 19575 MaxVersion: maxVersion, 19576 Bugs: ProtocolBugs{ 19577 SendCipherSuite: TLS_CHACHA20_POLY1305_SHA256, 19578 }, 19579 }, 19580 flags: []string{ 19581 "-fips-202205", 19582 }, 19583 shouldFail: true, 19584 expectedError: ":WRONG_CIPHER_RETURNED:", 19585 }) 19586 19587 for _, curve := range testCurves { 19588 var isFIPSCurve bool 19589 switch curve.id { 19590 case CurveP256, CurveP384: 19591 isFIPSCurve = true 19592 } 19593 19594 var isWPACurve bool 19595 switch curve.id { 19596 case CurveP384: 19597 isWPACurve = true 19598 } 19599 19600 policies := []struct { 19601 flag string 19602 curveOk bool 19603 }{ 19604 {"-fips-202205", isFIPSCurve}, 19605 {"-wpa-202304", isWPACurve}, 19606 } 19607 19608 for _, policy := range policies { 19609 testCases = append(testCases, testCase{ 19610 testType: serverTest, 19611 protocol: protocol, 19612 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + curve.name, 19613 config: Config{ 19614 MinVersion: VersionTLS12, 19615 MaxVersion: VersionTLS13, 19616 CurvePreferences: []CurveID{curve.id}, 19617 }, 19618 flags: []string{ 19619 policy.flag, 19620 }, 19621 shouldFail: !policy.curveOk, 19622 }) 19623 19624 testCases = append(testCases, testCase{ 19625 testType: clientTest, 19626 protocol: protocol, 19627 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + curve.name, 19628 config: Config{ 19629 MinVersion: VersionTLS12, 19630 MaxVersion: VersionTLS13, 19631 CurvePreferences: []CurveID{curve.id}, 19632 }, 19633 flags: []string{ 19634 policy.flag, 19635 }, 19636 shouldFail: !policy.curveOk, 19637 }) 19638 } 19639 } 19640 19641 for _, sigalg := range testSignatureAlgorithms { 19642 // The TLS 1.0 and TLS 1.1 default signature algorithm does not 19643 // apply to these tests. 19644 if sigalg.id == 0 { 19645 continue 19646 } 19647 19648 var isFIPSSigAlg bool 19649 switch sigalg.id { 19650 case signatureRSAPKCS1WithSHA256, 19651 signatureRSAPKCS1WithSHA384, 19652 signatureRSAPKCS1WithSHA512, 19653 signatureECDSAWithP256AndSHA256, 19654 signatureECDSAWithP384AndSHA384, 19655 signatureRSAPSSWithSHA256, 19656 signatureRSAPSSWithSHA384, 19657 signatureRSAPSSWithSHA512: 19658 isFIPSSigAlg = true 19659 } 19660 19661 var isWPASigAlg bool 19662 switch sigalg.id { 19663 case signatureRSAPKCS1WithSHA384, 19664 signatureRSAPKCS1WithSHA512, 19665 signatureECDSAWithP384AndSHA384, 19666 signatureRSAPSSWithSHA384, 19667 signatureRSAPSSWithSHA512: 19668 isWPASigAlg = true 19669 } 19670 19671 if sigalg.curve == CurveP224 { 19672 // This can work in TLS 1.2, but not with TLS 1.3. 19673 // For consistency it's not permitted in FIPS mode. 19674 isFIPSSigAlg = false 19675 } 19676 19677 maxVersion := uint16(VersionTLS13) 19678 if hasComponent(sigalg.name, "PKCS1") { 19679 if protocol == quic { 19680 continue 19681 } 19682 maxVersion = VersionTLS12 19683 } 19684 19685 policies := []struct { 19686 flag string 19687 sigAlgOk bool 19688 }{ 19689 {"-fips-202205", isFIPSSigAlg}, 19690 {"-wpa-202304", isWPASigAlg}, 19691 } 19692 19693 cert := sigalg.baseCert.WithSignatureAlgorithms(sigalg.id) 19694 for _, policy := range policies { 19695 testCases = append(testCases, testCase{ 19696 testType: serverTest, 19697 protocol: protocol, 19698 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Server-" + sigalg.name, 19699 config: Config{ 19700 MinVersion: VersionTLS12, 19701 MaxVersion: maxVersion, 19702 VerifySignatureAlgorithms: []signatureAlgorithm{sigalg.id}, 19703 }, 19704 // Use the base certificate. We wish to pick up the signature algorithm 19705 // preferences from the FIPS policy. 19706 shimCertificate: sigalg.baseCert, 19707 flags: []string{policy.flag}, 19708 shouldFail: !policy.sigAlgOk, 19709 }) 19710 19711 testCases = append(testCases, testCase{ 19712 testType: clientTest, 19713 protocol: protocol, 19714 name: "Compliance" + policy.flag + "-" + protocol.String() + "-Client-" + sigalg.name, 19715 config: Config{ 19716 MinVersion: VersionTLS12, 19717 MaxVersion: maxVersion, 19718 Credential: cert, 19719 }, 19720 flags: []string{ 19721 policy.flag, 19722 }, 19723 shouldFail: !policy.sigAlgOk, 19724 }) 19725 } 19726 } 19727 } 19728} 19729 19730func addCertificateSelectionTests() { 19731 // Combinatorially test each selection criteria at different versions, 19732 // protocols, and with the matching certificate before and after the 19733 // mismatching one. 19734 type certSelectTest struct { 19735 name string 19736 testType testType 19737 minVersion uint16 19738 maxVersion uint16 19739 config Config 19740 match *Credential 19741 mismatch *Credential 19742 flags []string 19743 expectedError string 19744 } 19745 certSelectTests := []certSelectTest{ 19746 // TLS 1.0 through TLS 1.2 servers should incorporate TLS cipher suites 19747 // into certificate selection. 19748 { 19749 name: "Server-CipherSuite-ECDHE_ECDSA", 19750 testType: serverTest, 19751 maxVersion: VersionTLS12, 19752 config: Config{ 19753 CipherSuites: []uint16{ 19754 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 19755 }, 19756 }, 19757 match: &ecdsaP256Certificate, 19758 mismatch: &rsaCertificate, 19759 expectedError: ":NO_SHARED_CIPHER:", 19760 }, 19761 { 19762 name: "Server-CipherSuite-ECDHE_RSA", 19763 testType: serverTest, 19764 maxVersion: VersionTLS12, 19765 config: Config{ 19766 CipherSuites: []uint16{ 19767 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 19768 }, 19769 }, 19770 match: &rsaCertificate, 19771 mismatch: &ecdsaP256Certificate, 19772 expectedError: ":NO_SHARED_CIPHER:", 19773 }, 19774 { 19775 name: "Server-CipherSuite-RSA", 19776 testType: serverTest, 19777 maxVersion: VersionTLS12, 19778 config: Config{ 19779 CipherSuites: []uint16{ 19780 TLS_RSA_WITH_AES_128_CBC_SHA, 19781 }, 19782 }, 19783 match: &rsaCertificate, 19784 mismatch: &ecdsaP256Certificate, 19785 expectedError: ":NO_SHARED_CIPHER:", 19786 }, 19787 19788 // Ed25519 counts as ECDSA for purposes of cipher suite matching. 19789 { 19790 name: "Server-CipherSuite-ECDHE_ECDSA-Ed25519", 19791 testType: serverTest, 19792 minVersion: VersionTLS12, 19793 maxVersion: VersionTLS12, 19794 config: Config{ 19795 CipherSuites: []uint16{ 19796 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 19797 }, 19798 }, 19799 match: &ed25519Certificate, 19800 mismatch: &rsaCertificate, 19801 expectedError: ":NO_SHARED_CIPHER:", 19802 }, 19803 { 19804 name: "Server-CipherSuite-ECDHE_RSA-Ed25519", 19805 testType: serverTest, 19806 minVersion: VersionTLS12, 19807 maxVersion: VersionTLS12, 19808 config: Config{ 19809 CipherSuites: []uint16{ 19810 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 19811 }, 19812 }, 19813 match: &rsaCertificate, 19814 mismatch: &ed25519Certificate, 19815 expectedError: ":NO_SHARED_CIPHER:", 19816 }, 19817 19818 // If there is no ECDHE curve match, ECDHE cipher suites are 19819 // disqualified in TLS 1.2 and below. This, in turn, impacts the 19820 // available cipher suites for each credential. 19821 { 19822 name: "Server-CipherSuite-NoECDHE", 19823 testType: serverTest, 19824 maxVersion: VersionTLS12, 19825 config: Config{ 19826 CurvePreferences: []CurveID{CurveP256}, 19827 }, 19828 flags: []string{"-curves", strconv.Itoa(int(CurveX25519))}, 19829 match: &rsaCertificate, 19830 mismatch: &ecdsaP256Certificate, 19831 expectedError: ":NO_SHARED_CIPHER:", 19832 }, 19833 19834 // If the client offered a cipher that would allow a certificate, but it 19835 // wasn't one of the ones we configured, the certificate should be 19836 // skipped in favor of another one. 19837 { 19838 name: "Server-CipherSuite-Prefs", 19839 testType: serverTest, 19840 maxVersion: VersionTLS12, 19841 config: Config{ 19842 CipherSuites: []uint16{ 19843 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 19844 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 19845 }, 19846 }, 19847 flags: []string{"-cipher", "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"}, 19848 match: &rsaCertificate, 19849 mismatch: &ecdsaP256Certificate, 19850 expectedError: ":NO_SHARED_CIPHER:", 19851 }, 19852 19853 // TLS 1.0 through 1.2 servers should incorporate the curve list into 19854 // ECDSA certificate selection. 19855 { 19856 name: "Server-Curve", 19857 testType: serverTest, 19858 maxVersion: VersionTLS12, 19859 config: Config{ 19860 CurvePreferences: []CurveID{CurveP256}, 19861 }, 19862 match: &ecdsaP256Certificate, 19863 mismatch: &ecdsaP384Certificate, 19864 expectedError: ":WRONG_CURVE:", 19865 }, 19866 19867 // TLS 1.3 servers ignore the curve list. ECDSA certificate selection is 19868 // solely determined by the signature algorithm list. 19869 { 19870 name: "Server-IgnoreCurve", 19871 testType: serverTest, 19872 minVersion: VersionTLS13, 19873 config: Config{ 19874 CurvePreferences: []CurveID{CurveP256}, 19875 }, 19876 match: &ecdsaP384Certificate, 19877 }, 19878 19879 // TLS 1.2 servers also ignore the curve list for Ed25519. The signature 19880 // algorithm list is sufficient for Ed25519. 19881 { 19882 name: "Server-IgnoreCurveEd25519", 19883 testType: serverTest, 19884 minVersion: VersionTLS12, 19885 config: Config{ 19886 CurvePreferences: []CurveID{CurveP256}, 19887 }, 19888 match: &ed25519Certificate, 19889 }, 19890 19891 // Without signature algorithm negotiation, Ed25519 is not usable in TLS 19892 // 1.1 and below. 19893 { 19894 name: "Server-NoEd25519", 19895 testType: serverTest, 19896 maxVersion: VersionTLS11, 19897 match: &rsaCertificate, 19898 mismatch: &ed25519Certificate, 19899 }, 19900 19901 // TLS 1.2 and up should incorporate the signature algorithm list into 19902 // certificate selection. 19903 { 19904 name: "Server-SignatureAlgorithm", 19905 testType: serverTest, 19906 minVersion: VersionTLS12, 19907 maxVersion: VersionTLS12, 19908 config: Config{ 19909 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 19910 CipherSuites: []uint16{ 19911 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 19912 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 19913 }, 19914 }, 19915 match: &ecdsaP256Certificate, 19916 mismatch: &rsaCertificate, 19917 expectedError: ":NO_SHARED_CIPHER:", 19918 }, 19919 { 19920 name: "Server-SignatureAlgorithm", 19921 testType: serverTest, 19922 minVersion: VersionTLS13, 19923 config: Config{ 19924 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 19925 }, 19926 match: &ecdsaP256Certificate, 19927 mismatch: &rsaCertificate, 19928 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 19929 }, 19930 19931 // TLS 1.2's use of the signature algorithm list only disables the 19932 // signing-based algorithms. If an RSA key exchange cipher suite is 19933 // eligible, that is fine. (This is not a realistic configuration, 19934 // however. No one would configure RSA before ECDSA.) 19935 { 19936 name: "Server-SignatureAlgorithmImpactsECDHEOnly", 19937 testType: serverTest, 19938 minVersion: VersionTLS12, 19939 maxVersion: VersionTLS12, 19940 config: Config{ 19941 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 19942 CipherSuites: []uint16{ 19943 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 19944 TLS_RSA_WITH_AES_128_CBC_SHA, 19945 }, 19946 }, 19947 match: &rsaCertificate, 19948 }, 19949 19950 // TLS 1.3's use of the signature algorithm looks at the ECDSA curve 19951 // embedded in the signature algorithm. 19952 { 19953 name: "Server-SignatureAlgorithmECDSACurve", 19954 testType: serverTest, 19955 minVersion: VersionTLS13, 19956 config: Config{ 19957 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 19958 }, 19959 match: &ecdsaP256Certificate, 19960 mismatch: &ecdsaP384Certificate, 19961 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 19962 }, 19963 19964 // TLS 1.2's use does not. 19965 { 19966 name: "Server-SignatureAlgorithmECDSACurve", 19967 testType: serverTest, 19968 minVersion: VersionTLS12, 19969 maxVersion: VersionTLS12, 19970 config: Config{ 19971 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 19972 }, 19973 match: &ecdsaP384Certificate, 19974 }, 19975 19976 // TLS 1.0 and 1.1 do not look at the signature algorithm. 19977 { 19978 name: "Server-IgnoreSignatureAlgorithm", 19979 testType: serverTest, 19980 maxVersion: VersionTLS11, 19981 config: Config{ 19982 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 19983 }, 19984 match: &rsaCertificate, 19985 }, 19986 19987 // Signature algorithm matches take preferences on the keys into 19988 // consideration. 19989 { 19990 name: "Server-SignatureAlgorithmKeyPrefs", 19991 testType: serverTest, 19992 minVersion: VersionTLS12, 19993 maxVersion: VersionTLS12, 19994 config: Config{ 19995 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 19996 CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, 19997 }, 19998 match: rsaChainCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 19999 mismatch: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA384), 20000 expectedError: ":NO_SHARED_CIPHER:", 20001 }, 20002 { 20003 name: "Server-SignatureAlgorithmKeyPrefs", 20004 testType: serverTest, 20005 minVersion: VersionTLS13, 20006 config: Config{ 20007 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 20008 }, 20009 match: rsaChainCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 20010 mismatch: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA384), 20011 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 20012 }, 20013 20014 // TLS 1.2 clients and below check the certificate against the old 20015 // client certificate types field. 20016 { 20017 name: "Client-ClientCertificateTypes-RSA", 20018 testType: clientTest, 20019 maxVersion: VersionTLS12, 20020 config: Config{ 20021 ClientAuth: RequestClientCert, 20022 ClientCertificateTypes: []uint8{CertTypeRSASign}, 20023 }, 20024 match: &rsaCertificate, 20025 mismatch: &ecdsaP256Certificate, 20026 expectedError: ":UNKNOWN_CERTIFICATE_TYPE:", 20027 }, 20028 { 20029 name: "Client-ClientCertificateTypes-ECDSA", 20030 testType: clientTest, 20031 maxVersion: VersionTLS12, 20032 config: Config{ 20033 ClientAuth: RequestClientCert, 20034 ClientCertificateTypes: []uint8{CertTypeECDSASign}, 20035 }, 20036 match: &ecdsaP256Certificate, 20037 mismatch: &rsaCertificate, 20038 expectedError: ":UNKNOWN_CERTIFICATE_TYPE:", 20039 }, 20040 20041 // Ed25519 is considered ECDSA for purposes of client certificate types. 20042 { 20043 name: "Client-ClientCertificateTypes-RSA-Ed25519", 20044 testType: clientTest, 20045 minVersion: VersionTLS12, 20046 maxVersion: VersionTLS12, 20047 config: Config{ 20048 ClientAuth: RequestClientCert, 20049 ClientCertificateTypes: []uint8{CertTypeRSASign}, 20050 }, 20051 match: &rsaCertificate, 20052 mismatch: &ed25519Certificate, 20053 expectedError: ":UNKNOWN_CERTIFICATE_TYPE:", 20054 }, 20055 { 20056 name: "Client-ClientCertificateTypes-ECDSA-Ed25519", 20057 testType: clientTest, 20058 minVersion: VersionTLS12, 20059 maxVersion: VersionTLS12, 20060 config: Config{ 20061 ClientAuth: RequestClientCert, 20062 ClientCertificateTypes: []uint8{CertTypeECDSASign}, 20063 }, 20064 match: &ed25519Certificate, 20065 mismatch: &rsaCertificate, 20066 expectedError: ":UNKNOWN_CERTIFICATE_TYPE:", 20067 }, 20068 20069 // TLS 1.2 and up should incorporate the signature algorithm list into 20070 // certificate selection. (There is no signature algorithm list to look 20071 // at in TLS 1.0 and 1.1.) 20072 { 20073 name: "Client-SignatureAlgorithm", 20074 testType: clientTest, 20075 minVersion: VersionTLS12, 20076 config: Config{ 20077 ClientAuth: RequestClientCert, 20078 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20079 }, 20080 match: &ecdsaP256Certificate, 20081 mismatch: &rsaCertificate, 20082 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 20083 }, 20084 20085 // TLS 1.3's use of the signature algorithm looks at the ECDSA curve 20086 // embedded in the signature algorithm. 20087 { 20088 name: "Client-SignatureAlgorithmECDSACurve", 20089 testType: clientTest, 20090 minVersion: VersionTLS13, 20091 config: Config{ 20092 ClientAuth: RequestClientCert, 20093 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20094 }, 20095 match: &ecdsaP256Certificate, 20096 mismatch: &ecdsaP384Certificate, 20097 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 20098 }, 20099 20100 // TLS 1.2's use does not. It is not possible to determine what ECDSA 20101 // curves are allowed by the server. 20102 { 20103 name: "Client-SignatureAlgorithmECDSACurve", 20104 testType: clientTest, 20105 minVersion: VersionTLS12, 20106 maxVersion: VersionTLS12, 20107 config: Config{ 20108 ClientAuth: RequestClientCert, 20109 VerifySignatureAlgorithms: []signatureAlgorithm{signatureECDSAWithP256AndSHA256}, 20110 }, 20111 match: &ecdsaP384Certificate, 20112 }, 20113 20114 // Signature algorithm matches take preferences on the keys into 20115 // consideration. 20116 { 20117 name: "Client-SignatureAlgorithmKeyPrefs", 20118 testType: clientTest, 20119 minVersion: VersionTLS12, 20120 config: Config{ 20121 ClientAuth: RequestClientCert, 20122 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 20123 }, 20124 match: rsaChainCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA256), 20125 mismatch: rsaCertificate.WithSignatureAlgorithms(signatureRSAPSSWithSHA384), 20126 expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:", 20127 }, 20128 } 20129 20130 for _, protocol := range []protocol{tls, dtls} { 20131 for _, vers := range allVersions(protocol) { 20132 suffix := fmt.Sprintf("%s-%s", protocol, vers) 20133 20134 // Test that the credential list is interpreted in preference order, 20135 // with the default credential, if any, at the end. 20136 testCases = append(testCases, testCase{ 20137 name: fmt.Sprintf("CertificateSelection-Client-PreferenceOrder-%s", suffix), 20138 testType: clientTest, 20139 protocol: protocol, 20140 config: Config{ 20141 MinVersion: vers.version, 20142 MaxVersion: vers.version, 20143 ClientAuth: RequestClientCert, 20144 }, 20145 shimCredentials: []*Credential{&ecdsaP256Certificate, &ecdsaP384Certificate}, 20146 shimCertificate: &rsaCertificate, 20147 flags: []string{"-expect-selected-credential", "0"}, 20148 expectations: connectionExpectations{peerCertificate: &ecdsaP256Certificate}, 20149 }) 20150 testCases = append(testCases, testCase{ 20151 name: fmt.Sprintf("CertificateSelection-Server-PreferenceOrder-%s", suffix), 20152 testType: serverTest, 20153 protocol: protocol, 20154 config: Config{ 20155 MinVersion: vers.version, 20156 MaxVersion: vers.version, 20157 }, 20158 shimCredentials: []*Credential{&ecdsaP256Certificate, &ecdsaP384Certificate}, 20159 shimCertificate: &rsaCertificate, 20160 flags: []string{"-expect-selected-credential", "0"}, 20161 expectations: connectionExpectations{peerCertificate: &ecdsaP256Certificate}, 20162 }) 20163 20164 // Test that the selected credential contributes the certificate chain, OCSP response, 20165 // and SCT list. 20166 testCases = append(testCases, testCase{ 20167 name: fmt.Sprintf("CertificateSelection-Server-OCSP-SCT-%s", suffix), 20168 testType: serverTest, 20169 protocol: protocol, 20170 config: Config{ 20171 MinVersion: vers.version, 20172 MaxVersion: vers.version, 20173 // Configure enough options so that, at all TLS versions, only an RSA 20174 // certificate will be accepted. 20175 CipherSuites: []uint16{ 20176 TLS_AES_128_GCM_SHA256, 20177 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 20178 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 20179 }, 20180 VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256}, 20181 }, 20182 shimCredentials: []*Credential{ 20183 ecdsaP256Certificate.WithOCSP(testOCSPResponse2).WithSCTList(testSCTList2), 20184 rsaChainCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 20185 }, 20186 shimCertificate: ecdsaP384Certificate.WithOCSP(testOCSPResponse2).WithSCTList(testSCTList2), 20187 flags: []string{"-expect-selected-credential", "1"}, 20188 expectations: connectionExpectations{ 20189 peerCertificate: rsaChainCertificate.WithOCSP(testOCSPResponse).WithSCTList(testSCTList), 20190 }, 20191 }) 20192 20193 // Test that the credentials API works asynchronously. This tests both deferring the 20194 // configuration to the certificate callback, and using a custom, async private key. 20195 testCases = append(testCases, testCase{ 20196 name: fmt.Sprintf("CertificateSelection-Client-Async-%s", suffix), 20197 testType: clientTest, 20198 protocol: protocol, 20199 config: Config{ 20200 MinVersion: vers.version, 20201 MaxVersion: vers.version, 20202 ClientAuth: RequestClientCert, 20203 }, 20204 shimCredentials: []*Credential{&ecdsaP256Certificate}, 20205 shimCertificate: &rsaCertificate, 20206 flags: []string{"-async", "-expect-selected-credential", "0"}, 20207 expectations: connectionExpectations{peerCertificate: &ecdsaP256Certificate}, 20208 }) 20209 testCases = append(testCases, testCase{ 20210 name: fmt.Sprintf("CertificateSelection-Server-Async-%s", suffix), 20211 testType: serverTest, 20212 protocol: protocol, 20213 config: Config{ 20214 MinVersion: vers.version, 20215 MaxVersion: vers.version, 20216 }, 20217 shimCredentials: []*Credential{&ecdsaP256Certificate}, 20218 shimCertificate: &rsaCertificate, 20219 flags: []string{"-async", "-expect-selected-credential", "0"}, 20220 expectations: connectionExpectations{peerCertificate: &ecdsaP256Certificate}, 20221 }) 20222 20223 for _, test := range certSelectTests { 20224 if test.minVersion != 0 && vers.version < test.minVersion { 20225 continue 20226 } 20227 if test.maxVersion != 0 && vers.version > test.maxVersion { 20228 continue 20229 } 20230 20231 config := test.config 20232 config.MinVersion = vers.version 20233 config.MaxVersion = vers.version 20234 20235 // If the mismatch field is omitted, this is a positive test, 20236 // just to confirm that the selection logic does not block a 20237 // particular certificate. 20238 if test.mismatch == nil { 20239 testCases = append(testCases, testCase{ 20240 name: fmt.Sprintf("CertificateSelection-%s-%s", test.name, suffix), 20241 protocol: protocol, 20242 testType: test.testType, 20243 config: config, 20244 shimCredentials: []*Credential{test.match}, 20245 flags: append([]string{"-expect-selected-credential", "0"}, test.flags...), 20246 expectations: connectionExpectations{peerCertificate: test.match}, 20247 }) 20248 continue 20249 } 20250 20251 testCases = append(testCases, testCase{ 20252 name: fmt.Sprintf("CertificateSelection-%s-MatchFirst-%s", test.name, suffix), 20253 protocol: protocol, 20254 testType: test.testType, 20255 config: config, 20256 shimCredentials: []*Credential{test.match, test.mismatch}, 20257 flags: append([]string{"-expect-selected-credential", "0"}, test.flags...), 20258 expectations: connectionExpectations{peerCertificate: test.match}, 20259 }) 20260 testCases = append(testCases, testCase{ 20261 name: fmt.Sprintf("CertificateSelection-%s-MatchSecond-%s", test.name, suffix), 20262 protocol: protocol, 20263 testType: test.testType, 20264 config: config, 20265 shimCredentials: []*Credential{test.mismatch, test.match}, 20266 flags: append([]string{"-expect-selected-credential", "1"}, test.flags...), 20267 expectations: connectionExpectations{peerCertificate: test.match}, 20268 }) 20269 testCases = append(testCases, testCase{ 20270 name: fmt.Sprintf("CertificateSelection-%s-MatchDefault-%s", test.name, suffix), 20271 protocol: protocol, 20272 testType: test.testType, 20273 config: config, 20274 shimCredentials: []*Credential{test.mismatch}, 20275 shimCertificate: test.match, 20276 flags: append([]string{"-expect-selected-credential", "-1"}, test.flags...), 20277 expectations: connectionExpectations{peerCertificate: test.match}, 20278 }) 20279 testCases = append(testCases, testCase{ 20280 name: fmt.Sprintf("CertificateSelection-%s-MatchNone-%s", test.name, suffix), 20281 protocol: protocol, 20282 testType: test.testType, 20283 config: config, 20284 shimCredentials: []*Credential{test.mismatch, test.mismatch, test.mismatch}, 20285 flags: test.flags, 20286 shouldFail: true, 20287 expectedLocalError: "remote error: handshake failure", 20288 expectedError: test.expectedError, 20289 }) 20290 } 20291 } 20292 } 20293} 20294 20295func worker(dispatcher *shimDispatcher, statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { 20296 defer wg.Done() 20297 20298 for test := range c { 20299 var err error 20300 20301 if *mallocTest >= 0 { 20302 for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ { 20303 statusChan <- statusMsg{test: test, statusType: statusStarted} 20304 if err = runTest(dispatcher, statusChan, test, shimPath, mallocNumToFail); err != errMoreMallocs { 20305 if err != nil { 20306 fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err) 20307 } 20308 break 20309 } 20310 } 20311 } else if *repeatUntilFailure { 20312 for err == nil { 20313 statusChan <- statusMsg{test: test, statusType: statusStarted} 20314 err = runTest(dispatcher, statusChan, test, shimPath, -1) 20315 } 20316 } else { 20317 statusChan <- statusMsg{test: test, statusType: statusStarted} 20318 err = runTest(dispatcher, statusChan, test, shimPath, -1) 20319 } 20320 statusChan <- statusMsg{test: test, statusType: statusDone, err: err} 20321 } 20322} 20323 20324type statusType int 20325 20326const ( 20327 statusStarted statusType = iota 20328 statusShimStarted 20329 statusDone 20330) 20331 20332type statusMsg struct { 20333 test *testCase 20334 statusType statusType 20335 pid int 20336 err error 20337} 20338 20339func statusPrinter(doneChan chan *testresult.Results, statusChan chan statusMsg, total int) { 20340 var started, done, failed, unimplemented, lineLen int 20341 20342 testOutput := testresult.NewResults() 20343 for msg := range statusChan { 20344 if !*pipe { 20345 // Erase the previous status line. 20346 var erase string 20347 for i := 0; i < lineLen; i++ { 20348 erase += "\b \b" 20349 } 20350 fmt.Print(erase) 20351 } 20352 20353 if msg.statusType == statusStarted { 20354 started++ 20355 } else if msg.statusType == statusDone { 20356 done++ 20357 20358 if msg.err != nil { 20359 if msg.err == errUnimplemented { 20360 if *pipe { 20361 // Print each test instead of a status line. 20362 fmt.Printf("UNIMPLEMENTED (%s)\n", msg.test.name) 20363 } 20364 unimplemented++ 20365 if *allowUnimplemented { 20366 testOutput.AddSkip(msg.test.name) 20367 } else { 20368 testOutput.AddResult(msg.test.name, "SKIP") 20369 } 20370 } else { 20371 fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err) 20372 failed++ 20373 testOutput.AddResult(msg.test.name, "FAIL") 20374 } 20375 } else { 20376 if *pipe { 20377 // Print each test instead of a status line. 20378 fmt.Printf("PASSED (%s)\n", msg.test.name) 20379 } 20380 testOutput.AddResult(msg.test.name, "PASS") 20381 } 20382 } 20383 20384 if !*pipe { 20385 // Print a new status line. 20386 line := fmt.Sprintf("%d/%d/%d/%d/%d", failed, unimplemented, done, started, total) 20387 if msg.statusType == statusShimStarted && *waitForDebugger { 20388 // Note -wait-for-debugger limits the test to one worker, 20389 // otherwise some output would be skipped. 20390 line += fmt.Sprintf(" (%s: attach to process %d to continue)", msg.test.name, msg.pid) 20391 } 20392 lineLen = len(line) 20393 os.Stdout.WriteString(line) 20394 } 20395 } 20396 20397 doneChan <- testOutput 20398} 20399 20400func match(oneOfPatternIfAny []string, noneOfPattern []string, candidate string) (matched bool, err error) { 20401 matched = len(oneOfPatternIfAny) == 0 20402 20403 var didMatch bool 20404 for _, pattern := range oneOfPatternIfAny { 20405 didMatch, err = filepath.Match(pattern, candidate) 20406 if err != nil { 20407 return false, err 20408 } 20409 20410 matched = didMatch || matched 20411 } 20412 20413 for _, pattern := range noneOfPattern { 20414 didMatch, err = filepath.Match(pattern, candidate) 20415 if err != nil { 20416 return false, err 20417 } 20418 20419 matched = !didMatch && matched 20420 } 20421 20422 return matched, nil 20423} 20424 20425func checkTests() { 20426 for _, test := range testCases { 20427 if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) { 20428 panic("Error expected without shouldFail in " + test.name) 20429 } 20430 20431 if test.expectResumeRejected && !test.resumeSession { 20432 panic("expectResumeRejected without resumeSession in " + test.name) 20433 } 20434 20435 if !test.skipVersionNameCheck { 20436 for _, ver := range tlsVersions { 20437 if !strings.Contains("-"+test.name+"-", "-"+ver.name+"-") { 20438 continue 20439 } 20440 20441 found := test.config.MaxVersion == ver.version || test.config.MinVersion == ver.version || test.expectations.version == ver.version 20442 if test.resumeConfig != nil { 20443 found = found || test.resumeConfig.MaxVersion == ver.version || test.resumeConfig.MinVersion == ver.version 20444 } 20445 if test.resumeExpectations != nil { 20446 found = found || test.resumeExpectations.version == ver.version 20447 } 20448 shimFlag := ver.shimFlag(test.protocol) 20449 for _, flag := range test.flags { 20450 if flag == shimFlag { 20451 found = true 20452 break 20453 } 20454 } 20455 if !found { 20456 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)) 20457 } 20458 } 20459 } 20460 20461 for _, protocol := range []protocol{tls, dtls, quic} { 20462 if strings.Contains("-"+test.name+"-", "-"+protocol.String()+"-") && test.protocol != protocol { 20463 panic(fmt.Sprintf("The name of test %q suggests that it tests %q, but the test does not reference it", test.name, protocol)) 20464 } 20465 } 20466 } 20467} 20468 20469func main() { 20470 flag.Parse() 20471 var err error 20472 if tmpDir, err = os.MkdirTemp("", "testing-certs"); err != nil { 20473 fmt.Fprintf(os.Stderr, "failed to make temporary directory: %s", err) 20474 os.Exit(1) 20475 } 20476 defer os.RemoveAll(tmpDir) 20477 initKeys() 20478 initCertificates() 20479 20480 if len(*shimConfigFile) != 0 { 20481 encoded, err := os.ReadFile(*shimConfigFile) 20482 if err != nil { 20483 fmt.Fprintf(os.Stderr, "Couldn't read config file %q: %s\n", *shimConfigFile, err) 20484 os.Exit(1) 20485 } 20486 20487 if err := json.Unmarshal(encoded, &shimConfig); err != nil { 20488 fmt.Fprintf(os.Stderr, "Couldn't decode config file %q: %s\n", *shimConfigFile, err) 20489 os.Exit(1) 20490 } 20491 } 20492 20493 if shimConfig.AllCurves == nil { 20494 for _, curve := range testCurves { 20495 shimConfig.AllCurves = append(shimConfig.AllCurves, int(curve.id)) 20496 } 20497 } 20498 20499 addBasicTests() 20500 addCipherSuiteTests() 20501 addBadECDSASignatureTests() 20502 addCBCPaddingTests() 20503 addCBCSplittingTests() 20504 addClientAuthTests() 20505 addDDoSCallbackTests() 20506 addVersionNegotiationTests() 20507 addMinimumVersionTests() 20508 addExtensionTests() 20509 addResumptionVersionTests() 20510 addExtendedMasterSecretTests() 20511 addRenegotiationTests() 20512 addDTLSReplayTests() 20513 addSignatureAlgorithmTests() 20514 addDTLSRetransmitTests() 20515 addExportKeyingMaterialTests() 20516 addExportTrafficSecretsTests() 20517 addTLSUniqueTests() 20518 addCustomExtensionTests() 20519 addRSAClientKeyExchangeTests() 20520 addCurveTests() 20521 addSessionTicketTests() 20522 addTLS13RecordTests() 20523 addAllStateMachineCoverageTests() 20524 addChangeCipherSpecTests() 20525 addEndOfFlightTests() 20526 addWrongMessageTypeTests() 20527 addTrailingMessageDataTests() 20528 addTLS13HandshakeTests() 20529 addTLS13CipherPreferenceTests() 20530 addPeekTests() 20531 addRecordVersionTests() 20532 addCertificateTests() 20533 addRetainOnlySHA256ClientCertTests() 20534 addECDSAKeyUsageTests() 20535 addRSAKeyUsageTests() 20536 addExtraHandshakeTests() 20537 addOmitExtensionsTests() 20538 addCertCompressionTests() 20539 addJDK11WorkaroundTests() 20540 addDelegatedCredentialTests() 20541 addEncryptedClientHelloTests() 20542 addHintMismatchTests() 20543 addCompliancePolicyTests() 20544 addCertificateSelectionTests() 20545 20546 toAppend, err := convertToSplitHandshakeTests(testCases) 20547 if err != nil { 20548 fmt.Fprintf(os.Stderr, "Error making split handshake tests: %s", err) 20549 os.Exit(1) 20550 } 20551 testCases = append(testCases, toAppend...) 20552 20553 checkTests() 20554 20555 dispatcher, err := newShimDispatcher() 20556 if err != nil { 20557 fmt.Fprintf(os.Stderr, "Error opening socket: %s", err) 20558 os.Exit(1) 20559 } 20560 defer dispatcher.Close() 20561 20562 numWorkers := *numWorkersFlag 20563 if useDebugger() { 20564 numWorkers = 1 20565 } 20566 20567 statusChan := make(chan statusMsg, numWorkers) 20568 testChan := make(chan *testCase, numWorkers) 20569 doneChan := make(chan *testresult.Results) 20570 20571 go statusPrinter(doneChan, statusChan, len(testCases)) 20572 20573 var wg sync.WaitGroup 20574 for i := 0; i < numWorkers; i++ { 20575 wg.Add(1) 20576 go worker(dispatcher, statusChan, testChan, *shimPath, &wg) 20577 } 20578 20579 var oneOfPatternIfAny, noneOfPattern []string 20580 if len(*testToRun) > 0 { 20581 oneOfPatternIfAny = strings.Split(*testToRun, ";") 20582 } 20583 if len(*skipTest) > 0 { 20584 noneOfPattern = strings.Split(*skipTest, ";") 20585 } 20586 20587 shardIndex, shardTotal, err := getSharding() 20588 if err != nil { 20589 fmt.Fprintln(os.Stderr, err) 20590 os.Exit(1) 20591 } 20592 20593 if shardTotal > 0 { 20594 fmt.Printf("This is shard %d of 0..%d (inclusive)\n", shardIndex, shardTotal-1) 20595 } 20596 20597 var foundTest bool 20598 for i := range testCases { 20599 if shardTotal > 0 && i%shardTotal != shardIndex { 20600 continue 20601 } 20602 20603 matched, err := match(oneOfPatternIfAny, noneOfPattern, testCases[i].name) 20604 if err != nil { 20605 fmt.Fprintf(os.Stderr, "Error matching pattern: %s\n", err) 20606 os.Exit(1) 20607 } 20608 20609 if !*includeDisabled { 20610 for pattern := range shimConfig.DisabledTests { 20611 isDisabled, err := filepath.Match(pattern, testCases[i].name) 20612 if err != nil { 20613 fmt.Fprintf(os.Stderr, "Error matching pattern %q from config file: %s\n", pattern, err) 20614 os.Exit(1) 20615 } 20616 20617 if isDisabled { 20618 matched = false 20619 break 20620 } 20621 } 20622 } 20623 20624 if matched { 20625 if foundTest && *useRR { 20626 fmt.Fprintf(os.Stderr, "Too many matching tests. Only one test can run when RR is enabled.\n") 20627 os.Exit(1) 20628 } 20629 20630 foundTest = true 20631 testChan <- &testCases[i] 20632 20633 // Only run one test if repeating until failure. 20634 if *repeatUntilFailure { 20635 break 20636 } 20637 } 20638 } 20639 20640 if !foundTest && shardTotal == 0 { 20641 fmt.Fprintf(os.Stderr, "No tests run\n") 20642 os.Exit(1) 20643 } 20644 20645 close(testChan) 20646 wg.Wait() 20647 close(statusChan) 20648 testOutput := <-doneChan 20649 20650 fmt.Printf("\n") 20651 20652 if *jsonOutput != "" { 20653 if err := testOutput.WriteToFile(*jsonOutput); err != nil { 20654 fmt.Fprintf(os.Stderr, "Error: %s\n", err) 20655 } 20656 } 20657 20658 if *useRR { 20659 fmt.Println("RR trace recorded. Replay with `rr replay`.") 20660 } 20661 20662 if !testOutput.HasUnexpectedResults() { 20663 os.Exit(1) 20664 } 20665} 20666