• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2016, Google Inc.
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15package runner
16
17import (
18	"bytes"
19	"crypto"
20	"crypto/ecdsa"
21	"crypto/elliptic"
22	"crypto/rand"
23	"crypto/rsa"
24	"crypto/x509"
25	"crypto/x509/pkix"
26	"encoding/base64"
27	"encoding/binary"
28	"encoding/hex"
29	"encoding/json"
30	"encoding/pem"
31	"errors"
32	"flag"
33	"fmt"
34	"io"
35	"io/ioutil"
36	"math/big"
37	"net"
38	"os"
39	"os/exec"
40	"path"
41	"path/filepath"
42	"runtime"
43	"strconv"
44	"strings"
45	"sync"
46	"syscall"
47	"time"
48
49	"boringssl.googlesource.com/boringssl/ssl/test/runner/hpke"
50	"boringssl.googlesource.com/boringssl/util/testresult"
51)
52
53var (
54	useValgrind              = flag.Bool("valgrind", false, "If true, run code under valgrind")
55	useGDB                   = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb")
56	useLLDB                  = flag.Bool("lldb", false, "If true, run BoringSSL code under lldb")
57	waitForDebugger          = flag.Bool("wait-for-debugger", false, "If true, jobs will run one at a time and pause for a debugger to attach")
58	flagDebug                = flag.Bool("debug", false, "Hexdump the contents of the connection")
59	mallocTest               = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.")
60	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.")
61	jsonOutput               = flag.String("json-output", "", "The file to output JSON results to.")
62	pipe                     = flag.Bool("pipe", false, "If true, print status output suitable for piping into another program.")
63	testToRun                = flag.String("test", "", "Semicolon-separated patterns of tests to run, or empty to run all tests")
64	skipTest                 = flag.String("skip", "", "Semicolon-separated patterns of tests to skip")
65	numWorkersFlag           = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.")
66	shimPath                 = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.")
67	handshakerPath           = flag.String("handshaker-path", "../../../build/ssl/test/handshaker", "The location of the handshaker binary.")
68	resourceDir              = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.")
69	fuzzer                   = flag.Bool("fuzzer", false, "If true, tests against a BoringSSL built in fuzzer mode.")
70	transcriptDir            = flag.String("transcript-dir", "", "The directory in which to write transcripts.")
71	idleTimeout              = flag.Duration("idle-timeout", 15*time.Second, "The number of seconds to wait for a read or write to bssl_shim.")
72	deterministic            = flag.Bool("deterministic", false, "If true, uses a deterministic PRNG in the runner.")
73	allowUnimplemented       = flag.Bool("allow-unimplemented", false, "If true, report pass even if some tests are unimplemented.")
74	looseErrors              = flag.Bool("loose-errors", false, "If true, allow shims to report an untranslated error code.")
75	shimConfigFile           = flag.String("shim-config", "", "A config file to use to configure the tests for this shim.")
76	includeDisabled          = flag.Bool("include-disabled", false, "If true, also runs disabled tests.")
77	repeatUntilFailure       = flag.Bool("repeat-until-failure", false, "If true, the first selected test will be run repeatedly until failure.")
78	tls13SplitHandshakeTests = flag.Bool("tls13-split-handshake-tests", true, "If true, TLS 1.3 tests that use the handshaker will be performed")
79)
80
81// ShimConfigurations is used with the “json” package and represents a shim
82// config file.
83type ShimConfiguration struct {
84	// DisabledTests maps from a glob-based pattern to a freeform string.
85	// The glob pattern is used to exclude tests from being run and the
86	// freeform string is unparsed but expected to explain why the test is
87	// disabled.
88	DisabledTests map[string]string
89
90	// ErrorMap maps from expected error strings to the correct error
91	// string for the shim in question. For example, it might map
92	// “:NO_SHARED_CIPHER:” (a BoringSSL error string) to something
93	// like “SSL_ERROR_NO_CYPHER_OVERLAP”.
94	ErrorMap map[string]string
95
96	// HalfRTTTickets is the number of half-RTT tickets the client should
97	// expect before half-RTT data when testing 0-RTT.
98	HalfRTTTickets int
99}
100
101// Setup shimConfig defaults aligning with BoringSSL.
102var shimConfig ShimConfiguration = ShimConfiguration{
103	HalfRTTTickets: 2,
104}
105
106type testCert int
107
108const (
109	testCertRSA testCert = iota
110	testCertRSA1024
111	testCertRSAChain
112	testCertECDSAP224
113	testCertECDSAP256
114	testCertECDSAP384
115	testCertECDSAP521
116	testCertEd25519
117)
118
119const (
120	rsaCertificateFile       = "cert.pem"
121	rsa1024CertificateFile   = "rsa_1024_cert.pem"
122	rsaChainCertificateFile  = "rsa_chain_cert.pem"
123	ecdsaP224CertificateFile = "ecdsa_p224_cert.pem"
124	ecdsaP256CertificateFile = "ecdsa_p256_cert.pem"
125	ecdsaP384CertificateFile = "ecdsa_p384_cert.pem"
126	ecdsaP521CertificateFile = "ecdsa_p521_cert.pem"
127	ed25519CertificateFile   = "ed25519_cert.pem"
128)
129
130const (
131	rsaKeyFile       = "key.pem"
132	rsa1024KeyFile   = "rsa_1024_key.pem"
133	rsaChainKeyFile  = "rsa_chain_key.pem"
134	ecdsaP224KeyFile = "ecdsa_p224_key.pem"
135	ecdsaP256KeyFile = "ecdsa_p256_key.pem"
136	ecdsaP384KeyFile = "ecdsa_p384_key.pem"
137	ecdsaP521KeyFile = "ecdsa_p521_key.pem"
138	ed25519KeyFile   = "ed25519_key.pem"
139	channelIDKeyFile = "channel_id_key.pem"
140)
141
142var (
143	rsaCertificate       Certificate
144	rsa1024Certificate   Certificate
145	rsaChainCertificate  Certificate
146	ecdsaP224Certificate Certificate
147	ecdsaP256Certificate Certificate
148	ecdsaP384Certificate Certificate
149	ecdsaP521Certificate Certificate
150	ed25519Certificate   Certificate
151	garbageCertificate   Certificate
152)
153
154var testCerts = []struct {
155	id                testCert
156	certFile, keyFile string
157	cert              *Certificate
158}{
159	{
160		id:       testCertRSA,
161		certFile: rsaCertificateFile,
162		keyFile:  rsaKeyFile,
163		cert:     &rsaCertificate,
164	},
165	{
166		id:       testCertRSA1024,
167		certFile: rsa1024CertificateFile,
168		keyFile:  rsa1024KeyFile,
169		cert:     &rsa1024Certificate,
170	},
171	{
172		id:       testCertRSAChain,
173		certFile: rsaChainCertificateFile,
174		keyFile:  rsaChainKeyFile,
175		cert:     &rsaChainCertificate,
176	},
177	{
178		id:       testCertECDSAP224,
179		certFile: ecdsaP224CertificateFile,
180		keyFile:  ecdsaP224KeyFile,
181		cert:     &ecdsaP224Certificate,
182	},
183	{
184		id:       testCertECDSAP256,
185		certFile: ecdsaP256CertificateFile,
186		keyFile:  ecdsaP256KeyFile,
187		cert:     &ecdsaP256Certificate,
188	},
189	{
190		id:       testCertECDSAP384,
191		certFile: ecdsaP384CertificateFile,
192		keyFile:  ecdsaP384KeyFile,
193		cert:     &ecdsaP384Certificate,
194	},
195	{
196		id:       testCertECDSAP521,
197		certFile: ecdsaP521CertificateFile,
198		keyFile:  ecdsaP521KeyFile,
199		cert:     &ecdsaP521Certificate,
200	},
201	{
202		id:       testCertEd25519,
203		certFile: ed25519CertificateFile,
204		keyFile:  ed25519KeyFile,
205		cert:     &ed25519Certificate,
206	},
207}
208
209var channelIDKey *ecdsa.PrivateKey
210var channelIDBytes []byte
211
212var testOCSPResponse = []byte{1, 2, 3, 4}
213var testOCSPResponse2 = []byte{5, 6, 7, 8}
214var testSCTList = []byte{0, 6, 0, 4, 5, 6, 7, 8}
215var testSCTList2 = []byte{0, 6, 0, 4, 1, 2, 3, 4}
216
217var testOCSPExtension = append([]byte{byte(extensionStatusRequest) >> 8, byte(extensionStatusRequest), 0, 8, statusTypeOCSP, 0, 0, 4}, testOCSPResponse...)
218var testSCTExtension = append([]byte{byte(extensionSignedCertificateTimestamp) >> 8, byte(extensionSignedCertificateTimestamp), 0, byte(len(testSCTList))}, testSCTList...)
219
220func initCertificates() {
221	for i := range testCerts {
222		cert, err := LoadX509KeyPair(path.Join(*resourceDir, testCerts[i].certFile), path.Join(*resourceDir, testCerts[i].keyFile))
223		if err != nil {
224			panic(err)
225		}
226		cert.OCSPStaple = testOCSPResponse
227		cert.SignedCertificateTimestampList = testSCTList
228		*testCerts[i].cert = cert
229	}
230
231	channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile))
232	if err != nil {
233		panic(err)
234	}
235	channelIDDERBlock, _ := pem.Decode(channelIDPEMBlock)
236	if channelIDDERBlock.Type != "EC PRIVATE KEY" {
237		panic("bad key type")
238	}
239	channelIDKey, err = x509.ParseECPrivateKey(channelIDDERBlock.Bytes)
240	if err != nil {
241		panic(err)
242	}
243	if channelIDKey.Curve != elliptic.P256() {
244		panic("bad curve")
245	}
246
247	channelIDBytes = make([]byte, 64)
248	writeIntPadded(channelIDBytes[:32], channelIDKey.X)
249	writeIntPadded(channelIDBytes[32:], channelIDKey.Y)
250
251	garbageCertificate.Certificate = [][]byte{[]byte("GARBAGE")}
252	garbageCertificate.PrivateKey = rsaCertificate.PrivateKey
253}
254
255func useDebugger() bool {
256	return *useGDB || *useLLDB || *waitForDebugger
257}
258
259// delegatedCredentialConfig specifies the shape of a delegated credential, not
260// including the keys themselves.
261type delegatedCredentialConfig struct {
262	// lifetime is the amount of time, from the notBefore of the parent
263	// certificate, that the delegated credential is valid for. If zero, then 24
264	// hours is assumed.
265	lifetime time.Duration
266	// expectedAlgo is the signature scheme that should be used with this
267	// delegated credential. If zero, ECDSA with P-256 is assumed.
268	expectedAlgo signatureAlgorithm
269	// tlsVersion is the version of TLS that should be used with this delegated
270	// credential. If zero, TLS 1.3 is assumed.
271	tlsVersion uint16
272	// algo is the signature algorithm that the delegated credential itself is
273	// signed with. Cannot be zero.
274	algo signatureAlgorithm
275}
276
277func loadRSAPrivateKey(filename string) (priv *rsa.PrivateKey, privPKCS8 []byte, err error) {
278	pemPath := path.Join(*resourceDir, filename)
279	pemBytes, err := ioutil.ReadFile(pemPath)
280	if err != nil {
281		return nil, nil, err
282	}
283
284	block, _ := pem.Decode(pemBytes)
285	if block == nil {
286		return nil, nil, fmt.Errorf("no PEM block found in %q", pemPath)
287	}
288	privPKCS8 = block.Bytes
289
290	parsed, err := x509.ParsePKCS8PrivateKey(privPKCS8)
291	if err != nil {
292		return nil, nil, fmt.Errorf("failed to parse PKCS#8 key from %q", pemPath)
293	}
294
295	priv, ok := parsed.(*rsa.PrivateKey)
296	if !ok {
297		return nil, nil, fmt.Errorf("found %T in %q rather than an RSA private key", parsed, pemPath)
298	}
299
300	return priv, privPKCS8, nil
301}
302
303func createDelegatedCredential(config delegatedCredentialConfig, parentDER []byte, parentPriv crypto.PrivateKey) (dc, privPKCS8 []uint8, err error) {
304	expectedAlgo := config.expectedAlgo
305	if expectedAlgo == signatureAlgorithm(0) {
306		expectedAlgo = signatureECDSAWithP256AndSHA256
307	}
308
309	var pub crypto.PublicKey
310
311	switch expectedAlgo {
312	case signatureRSAPKCS1WithMD5, signatureRSAPKCS1WithSHA1, signatureRSAPKCS1WithSHA256, signatureRSAPKCS1WithSHA384, signatureRSAPKCS1WithSHA512, signatureRSAPSSWithSHA256, signatureRSAPSSWithSHA384, signatureRSAPSSWithSHA512:
313		// RSA keys are expensive to generate so load from disk instead.
314		var priv *rsa.PrivateKey
315		if priv, privPKCS8, err = loadRSAPrivateKey(rsaKeyFile); err != nil {
316			return nil, nil, err
317		}
318
319		pub = &priv.PublicKey
320
321	case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256, signatureECDSAWithP384AndSHA384, signatureECDSAWithP521AndSHA512:
322		var curve elliptic.Curve
323		switch expectedAlgo {
324		case signatureECDSAWithSHA1, signatureECDSAWithP256AndSHA256:
325			curve = elliptic.P256()
326		case signatureECDSAWithP384AndSHA384:
327			curve = elliptic.P384()
328		case signatureECDSAWithP521AndSHA512:
329			curve = elliptic.P521()
330		default:
331			panic("internal error")
332		}
333
334		priv, err := ecdsa.GenerateKey(curve, rand.Reader)
335		if err != nil {
336			return nil, nil, err
337		}
338
339		if privPKCS8, err = x509.MarshalPKCS8PrivateKey(priv); err != nil {
340			return nil, nil, err
341		}
342
343		pub = &priv.PublicKey
344
345	default:
346		return nil, nil, fmt.Errorf("unsupported expected signature algorithm: %x", expectedAlgo)
347	}
348
349	lifetime := config.lifetime
350	if lifetime == 0 {
351		lifetime = 24 * time.Hour
352	}
353	lifetimeSecs := int64(lifetime.Seconds())
354	if lifetimeSecs > 1<<32 {
355		return nil, nil, fmt.Errorf("lifetime %s is too long to be expressed", lifetime)
356	}
357	tlsVersion := config.tlsVersion
358	if tlsVersion == 0 {
359		tlsVersion = VersionTLS13
360	}
361
362	if tlsVersion < VersionTLS13 {
363		return nil, nil, fmt.Errorf("delegated credentials require TLS 1.3")
364	}
365
366	// https://tools.ietf.org/html/draft-ietf-tls-subcerts-03#section-3
367	dc = append(dc, byte(lifetimeSecs>>24), byte(lifetimeSecs>>16), byte(lifetimeSecs>>8), byte(lifetimeSecs))
368	dc = append(dc, byte(expectedAlgo>>8), byte(expectedAlgo))
369
370	pubBytes, err := x509.MarshalPKIXPublicKey(pub)
371	if err != nil {
372		return nil, nil, err
373	}
374
375	dc = append(dc, byte(len(pubBytes)>>16), byte(len(pubBytes)>>8), byte(len(pubBytes)))
376	dc = append(dc, pubBytes...)
377
378	var dummyConfig Config
379	parentSigner, err := getSigner(tlsVersion, parentPriv, &dummyConfig, config.algo, false /* not for verification */)
380	if err != nil {
381		return nil, nil, err
382	}
383
384	parentSignature, err := parentSigner.signMessage(parentPriv, &dummyConfig, delegatedCredentialSignedMessage(dc, config.algo, parentDER))
385	if err != nil {
386		return nil, nil, err
387	}
388
389	dc = append(dc, byte(config.algo>>8), byte(config.algo))
390	dc = append(dc, byte(len(parentSignature)>>8), byte(len(parentSignature)))
391	dc = append(dc, parentSignature...)
392
393	return dc, privPKCS8, nil
394}
395
396func getRunnerCertificate(t testCert) Certificate {
397	for _, cert := range testCerts {
398		if cert.id == t {
399			return *cert.cert
400		}
401	}
402	panic("Unknown test certificate")
403}
404
405func getShimCertificate(t testCert) string {
406	for _, cert := range testCerts {
407		if cert.id == t {
408			return cert.certFile
409		}
410	}
411	panic("Unknown test certificate")
412}
413
414func getShimKey(t testCert) string {
415	for _, cert := range testCerts {
416		if cert.id == t {
417			return cert.keyFile
418		}
419	}
420	panic("Unknown test certificate")
421}
422
423// recordVersionToWire maps a record-layer protocol version to its wire
424// representation.
425func recordVersionToWire(vers uint16, protocol protocol) uint16 {
426	if protocol == dtls {
427		switch vers {
428		case VersionTLS12:
429			return VersionDTLS12
430		case VersionTLS10:
431			return VersionDTLS10
432		}
433	} else {
434		switch vers {
435		case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12:
436			return vers
437		}
438	}
439
440	panic("unknown version")
441}
442
443// encodeDERValues encodes a series of bytestrings in comma-separated-hex form.
444func encodeDERValues(values [][]byte) string {
445	var ret string
446	for i, v := range values {
447		if i > 0 {
448			ret += ","
449		}
450		ret += hex.EncodeToString(v)
451	}
452
453	return ret
454}
455
456func decodeHexOrPanic(in string) []byte {
457	ret, err := hex.DecodeString(in)
458	if err != nil {
459		panic(err)
460	}
461	return ret
462}
463
464type testType int
465
466const (
467	clientTest testType = iota
468	serverTest
469)
470
471type protocol int
472
473const (
474	tls protocol = iota
475	dtls
476	quic
477)
478
479func (p protocol) String() string {
480	switch p {
481	case tls:
482		return "TLS"
483	case dtls:
484		return "DTLS"
485	case quic:
486		return "QUIC"
487	}
488	return "unknown protocol"
489}
490
491const (
492	alpn = 1
493	npn  = 2
494)
495
496// connectionExpectations contains connection-level test expectations to check
497// on the runner side.
498type connectionExpectations struct {
499	// version, if non-zero, specifies the TLS version that must be negotiated.
500	version uint16
501	// cipher, if non-zero, specifies the TLS cipher suite that should be
502	// negotiated.
503	cipher uint16
504	// channelID controls whether the connection should have negotiated a
505	// Channel ID with channelIDKey.
506	channelID bool
507	// tokenBinding controls whether the connection should have negotiated Token
508	// Binding.
509	tokenBinding bool
510	// tokenBindingParam is the Token Binding parameter that should have been
511	// negotiated (if tokenBinding is true).
512	tokenBindingParam uint8
513	// nextProto controls whether the connection should negotiate a next
514	// protocol via NPN or ALPN.
515	nextProto string
516	// noNextProto, if true, means that no next protocol should be negotiated.
517	noNextProto bool
518	// nextProtoType, if non-zero, is the next protocol negotiation mechanism.
519	nextProtoType int
520	// srtpProtectionProfile is the DTLS-SRTP profile that should be negotiated.
521	// If zero, none should be negotiated.
522	srtpProtectionProfile uint16
523	// ocspResponse, if not nil, is the OCSP response to be received.
524	ocspResponse []uint8
525	// sctList, if not nil, is the SCT list to be received.
526	sctList []uint8
527	// peerSignatureAlgorithm, if not zero, is the signature algorithm that the
528	// peer should have used in the handshake.
529	peerSignatureAlgorithm signatureAlgorithm
530	// curveID, if not zero, is the curve that the handshake should have used.
531	curveID CurveID
532	// peerCertificate, if not nil, is the certificate chain the peer is
533	// expected to send.
534	peerCertificate *Certificate
535	// quicTransportParams contains the QUIC transport parameters that are to be
536	// sent by the peer using codepoint 57.
537	quicTransportParams []byte
538	// quicTransportParamsLegacy contains the QUIC transport parameters that are
539	// to be sent by the peer using legacy codepoint 0xffa5.
540	quicTransportParamsLegacy []byte
541	// peerApplicationSettings are the expected application settings for the
542	// connection. If nil, no application settings are expected.
543	peerApplicationSettings []byte
544}
545
546type testCase struct {
547	testType      testType
548	protocol      protocol
549	name          string
550	config        Config
551	shouldFail    bool
552	expectedError string
553	// expectedLocalError, if not empty, contains a substring that must be
554	// found in the local error.
555	expectedLocalError string
556	// expectations contains test expectations for the initial
557	// connection.
558	expectations connectionExpectations
559	// resumeExpectations, if non-nil, contains test expectations for the
560	// resumption connection. If nil, |expectations| is used.
561	resumeExpectations *connectionExpectations
562	// messageLen is the length, in bytes, of the test message that will be
563	// sent.
564	messageLen int
565	// messageCount is the number of test messages that will be sent.
566	messageCount int
567	// certFile is the path to the certificate to use for the server.
568	certFile string
569	// keyFile is the path to the private key to use for the server.
570	keyFile string
571	// resumeSession controls whether a second connection should be tested
572	// which attempts to resume the first session.
573	resumeSession bool
574	// resumeRenewedSession controls whether a third connection should be
575	// tested which attempts to resume the second connection's session.
576	resumeRenewedSession bool
577	// expectResumeRejected, if true, specifies that the attempted
578	// resumption must be rejected by the client. This is only valid for a
579	// serverTest.
580	expectResumeRejected bool
581	// resumeConfig, if not nil, points to a Config to be used on
582	// resumption. Unless newSessionsOnResume is set,
583	// SessionTicketKey, ServerSessionCache, and
584	// ClientSessionCache are copied from the initial connection's
585	// config. If nil, the initial connection's config is used.
586	resumeConfig *Config
587	// newSessionsOnResume, if true, will cause resumeConfig to
588	// use a different session resumption context.
589	newSessionsOnResume bool
590	// noSessionCache, if true, will cause the server to run without a
591	// session cache.
592	noSessionCache bool
593	// sendPrefix sends a prefix on the socket before actually performing a
594	// handshake.
595	sendPrefix string
596	// shimWritesFirst controls whether the shim sends an initial "hello"
597	// message before doing a roundtrip with the runner.
598	shimWritesFirst bool
599	// readWithUnfinishedWrite behaves like shimWritesFirst, but the shim
600	// does not complete the write until responding to the first runner
601	// message.
602	readWithUnfinishedWrite bool
603	// shimShutsDown, if true, runs a test where the shim shuts down the
604	// connection immediately after the handshake rather than echoing
605	// messages from the runner. The runner will default to not sending
606	// application data.
607	shimShutsDown bool
608	// renegotiate indicates the number of times the connection should be
609	// renegotiated during the exchange.
610	renegotiate int
611	// sendHalfHelloRequest, if true, causes the server to send half a
612	// HelloRequest when the handshake completes.
613	sendHalfHelloRequest bool
614	// renegotiateCiphers is a list of ciphersuite ids that will be
615	// switched in just before renegotiation.
616	renegotiateCiphers []uint16
617	// replayWrites, if true, configures the underlying transport
618	// to replay every write it makes in DTLS tests.
619	replayWrites bool
620	// damageFirstWrite, if true, configures the underlying transport to
621	// damage the final byte of the first application data write.
622	damageFirstWrite bool
623	// exportKeyingMaterial, if non-zero, configures the test to exchange
624	// keying material and verify they match.
625	exportKeyingMaterial int
626	exportLabel          string
627	exportContext        string
628	useExportContext     bool
629	// flags, if not empty, contains a list of command-line flags that will
630	// be passed to the shim program.
631	flags []string
632	// testTLSUnique, if true, causes the shim to send the tls-unique value
633	// which will be compared against the expected value.
634	testTLSUnique bool
635	// sendEmptyRecords is the number of consecutive empty records to send
636	// before each test message.
637	sendEmptyRecords int
638	// sendWarningAlerts is the number of consecutive warning alerts to send
639	// before each test message.
640	sendWarningAlerts int
641	// sendUserCanceledAlerts is the number of consecutive user_canceled alerts to
642	// send before each test message.
643	sendUserCanceledAlerts int
644	// sendBogusAlertType, if true, causes a bogus alert of invalid type to
645	// be sent before each test message.
646	sendBogusAlertType bool
647	// sendKeyUpdates is the number of consecutive key updates to send
648	// before and after the test message.
649	sendKeyUpdates int
650	// keyUpdateRequest is the KeyUpdateRequest value to send in KeyUpdate messages.
651	keyUpdateRequest byte
652	// expectUnsolicitedKeyUpdate makes the test expect a one or more KeyUpdate
653	// messages while reading data from the shim. Don't use this in combination
654	// with any of the fields that send a KeyUpdate otherwise any received
655	// KeyUpdate might not be as unsolicited as expected.
656	expectUnsolicitedKeyUpdate bool
657	// expectMessageDropped, if true, means the test message is expected to
658	// be dropped by the client rather than echoed back.
659	expectMessageDropped bool
660	// shimPrefix is the prefix that the shim will send to the server.
661	shimPrefix string
662	// resumeShimPrefix is the prefix that the shim will send to the server on a
663	// resumption.
664	resumeShimPrefix string
665	// exportTrafficSecrets, if true, configures the test to export the TLS 1.3
666	// traffic secrets and confirms that they match.
667	exportTrafficSecrets bool
668	// skipTransportParamsConfig, if true, will skip automatic configuration of
669	// sending QUIC transport parameters when protocol == quic.
670	skipTransportParamsConfig bool
671	// skipQUICALPNConfig, if true, will skip automatic configuration of
672	// sending a fake ALPN when protocol == quic.
673	skipQUICALPNConfig bool
674	// earlyData, if true, configures default settings for an early data test.
675	// expectEarlyDataRejected controls whether the test is for early data
676	// accept or reject. In a client test, the shim will be configured to send
677	// an initial write in early data which, on accept, the runner will enforce.
678	// In a server test, the runner will send some default message in early
679	// data, which the shim is expected to echo in half-RTT.
680	earlyData bool
681	// expectEarlyDataRejected, if earlyData is true, is whether early data is
682	// expected to be rejected. In a client test, this controls whether the shim
683	// should retry for early rejection. In a server test, this is whether the
684	// test expects the shim to reject early data.
685	expectEarlyDataRejected bool
686}
687
688var testCases []testCase
689
690func appendTranscript(path string, data []byte) error {
691	if len(data) == 0 {
692		return nil
693	}
694
695	settings, err := ioutil.ReadFile(path)
696	if err != nil {
697		if !os.IsNotExist(err) {
698			return err
699		}
700		// If the shim aborted before writing a file, use a default
701		// settings block, so the transcript is still somewhat valid.
702		settings = []byte{0, 0} // kDataTag
703	}
704
705	settings = append(settings, data...)
706	return ioutil.WriteFile(path, settings, 0644)
707}
708
709// A timeoutConn implements an idle timeout on each Read and Write operation.
710type timeoutConn struct {
711	net.Conn
712	timeout time.Duration
713}
714
715func (t *timeoutConn) Read(b []byte) (int, error) {
716	if !*useGDB {
717		if err := t.SetReadDeadline(time.Now().Add(t.timeout)); err != nil {
718			return 0, err
719		}
720	}
721	return t.Conn.Read(b)
722}
723
724func (t *timeoutConn) Write(b []byte) (int, error) {
725	if !*useGDB {
726		if err := t.SetWriteDeadline(time.Now().Add(t.timeout)); err != nil {
727			return 0, err
728		}
729	}
730	return t.Conn.Write(b)
731}
732
733func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool, transcripts *[][]byte, num int) error {
734	if !test.noSessionCache {
735		if config.ClientSessionCache == nil {
736			config.ClientSessionCache = NewLRUClientSessionCache(1)
737		}
738		if config.ServerSessionCache == nil {
739			config.ServerSessionCache = NewLRUServerSessionCache(1)
740		}
741	}
742	if test.testType == clientTest {
743		if len(config.Certificates) == 0 {
744			config.Certificates = []Certificate{rsaCertificate}
745		}
746	} else {
747		// Supply a ServerName to ensure a constant session cache key,
748		// rather than falling back to net.Conn.RemoteAddr.
749		if len(config.ServerName) == 0 {
750			config.ServerName = "test"
751		}
752	}
753	if *fuzzer {
754		config.Bugs.NullAllCiphers = true
755	}
756	if *deterministic {
757		config.Time = func() time.Time { return time.Unix(1234, 1234) }
758	}
759
760	if !useDebugger() {
761		conn = &timeoutConn{conn, *idleTimeout}
762	}
763
764	if test.protocol == dtls {
765		config.Bugs.PacketAdaptor = newPacketAdaptor(conn)
766		conn = config.Bugs.PacketAdaptor
767	}
768
769	if *flagDebug || len(*transcriptDir) != 0 {
770		local, peer := "client", "server"
771		if test.testType == clientTest {
772			local, peer = peer, local
773		}
774		connDebug := &recordingConn{
775			Conn:       conn,
776			isDatagram: test.protocol == dtls,
777			local:      local,
778			peer:       peer,
779		}
780		conn = connDebug
781		if *flagDebug {
782			defer connDebug.WriteTo(os.Stdout)
783		}
784		if len(*transcriptDir) != 0 {
785			defer func() {
786				if num == len(*transcripts) {
787					*transcripts = append(*transcripts, connDebug.Transcript())
788				} else {
789					panic("transcripts are out of sync")
790				}
791			}()
792		}
793
794		if config.Bugs.PacketAdaptor != nil {
795			config.Bugs.PacketAdaptor.debug = connDebug
796		}
797	}
798	if test.protocol == quic {
799		config.Bugs.MockQUICTransport = newMockQUICTransport(conn)
800		// The MockQUICTransport will panic if Read or Write is
801		// called. When a MockQUICTransport is set, separate
802		// methods should be used to actually read and write
803		// records. By setting the conn to it here, it ensures
804		// Read or Write aren't accidentally used instead of the
805		// methods provided by MockQUICTransport.
806		conn = config.Bugs.MockQUICTransport
807	}
808
809	if test.replayWrites {
810		conn = newReplayAdaptor(conn)
811	}
812
813	var connDamage *damageAdaptor
814	if test.damageFirstWrite {
815		connDamage = newDamageAdaptor(conn)
816		conn = connDamage
817	}
818
819	if test.sendPrefix != "" {
820		if _, err := conn.Write([]byte(test.sendPrefix)); err != nil {
821			return err
822		}
823	}
824
825	var tlsConn *Conn
826	if test.testType == clientTest {
827		if test.protocol == dtls {
828			tlsConn = DTLSServer(conn, config)
829		} else {
830			tlsConn = Server(conn, config)
831		}
832	} else {
833		config.InsecureSkipVerify = true
834		if test.protocol == dtls {
835			tlsConn = DTLSClient(conn, config)
836		} else {
837			tlsConn = Client(conn, config)
838		}
839	}
840	defer tlsConn.Close()
841
842	if err := tlsConn.Handshake(); err != nil {
843		return err
844	}
845
846	expectations := &test.expectations
847	if isResume && test.resumeExpectations != nil {
848		expectations = test.resumeExpectations
849	}
850	connState := tlsConn.ConnectionState()
851	if vers := connState.Version; expectations.version != 0 && vers != expectations.version {
852		return fmt.Errorf("got version %x, expected %x", vers, expectations.version)
853	}
854
855	if cipher := connState.CipherSuite; expectations.cipher != 0 && cipher != expectations.cipher {
856		return fmt.Errorf("got cipher %x, expected %x", cipher, expectations.cipher)
857	}
858	if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected {
859		return fmt.Errorf("didResume is %t, but we expected the opposite", didResume)
860	}
861
862	if expectations.channelID {
863		channelID := connState.ChannelID
864		if channelID == nil {
865			return fmt.Errorf("no channel ID negotiated")
866		}
867		if channelID.Curve != channelIDKey.Curve ||
868			channelIDKey.X.Cmp(channelIDKey.X) != 0 ||
869			channelIDKey.Y.Cmp(channelIDKey.Y) != 0 {
870			return fmt.Errorf("incorrect channel ID")
871		}
872	} else if connState.ChannelID != nil {
873		return fmt.Errorf("channel ID unexpectedly negotiated")
874	}
875
876	if expectations.tokenBinding {
877		if !connState.TokenBindingNegotiated {
878			return errors.New("no Token Binding negotiated")
879		}
880		if connState.TokenBindingParam != expectations.tokenBindingParam {
881			return fmt.Errorf("expected param %02x, but got %02x", expectations.tokenBindingParam, connState.TokenBindingParam)
882		}
883	} else if connState.TokenBindingNegotiated {
884		return errors.New("Token Binding unexpectedly negotiated")
885	}
886
887	if expected := expectations.nextProto; expected != "" {
888		if actual := connState.NegotiatedProtocol; actual != expected {
889			return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected)
890		}
891	}
892
893	if expectations.noNextProto {
894		if actual := connState.NegotiatedProtocol; actual != "" {
895			return fmt.Errorf("got unexpected next proto %s", actual)
896		}
897	}
898
899	if expectations.nextProtoType != 0 {
900		if (expectations.nextProtoType == alpn) != connState.NegotiatedProtocolFromALPN {
901			return fmt.Errorf("next proto type mismatch")
902		}
903	}
904
905	if expectations.peerApplicationSettings != nil {
906		if !connState.HasApplicationSettings {
907			return errors.New("application settings should have been negotiated")
908		}
909		if !bytes.Equal(connState.PeerApplicationSettings, expectations.peerApplicationSettings) {
910			return fmt.Errorf("peer application settings mismatch: got %q, wanted %q", connState.PeerApplicationSettings, expectations.peerApplicationSettings)
911		}
912	} else if connState.HasApplicationSettings {
913		return errors.New("application settings unexpectedly negotiated")
914	}
915
916	if p := connState.SRTPProtectionProfile; p != expectations.srtpProtectionProfile {
917		return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, expectations.srtpProtectionProfile)
918	}
919
920	if expectations.ocspResponse != nil && !bytes.Equal(expectations.ocspResponse, connState.OCSPResponse) {
921		return fmt.Errorf("OCSP Response mismatch: got %x, wanted %x", connState.OCSPResponse, expectations.ocspResponse)
922	}
923
924	if expectations.sctList != nil && !bytes.Equal(expectations.sctList, connState.SCTList) {
925		return fmt.Errorf("SCT list mismatch")
926	}
927
928	if expected := expectations.peerSignatureAlgorithm; expected != 0 && expected != connState.PeerSignatureAlgorithm {
929		return fmt.Errorf("expected peer to use signature algorithm %04x, but got %04x", expected, connState.PeerSignatureAlgorithm)
930	}
931
932	if expected := expectations.curveID; expected != 0 && expected != connState.CurveID {
933		return fmt.Errorf("expected peer to use curve %04x, but got %04x", expected, connState.CurveID)
934	}
935
936	if expectations.peerCertificate != nil {
937		if len(connState.PeerCertificates) != len(expectations.peerCertificate.Certificate) {
938			return fmt.Errorf("expected peer to send %d certificates, but got %d", len(connState.PeerCertificates), len(expectations.peerCertificate.Certificate))
939		}
940		for i, cert := range connState.PeerCertificates {
941			if !bytes.Equal(cert.Raw, expectations.peerCertificate.Certificate[i]) {
942				return fmt.Errorf("peer certificate %d did not match", i+1)
943			}
944		}
945	}
946
947	if len(expectations.quicTransportParams) > 0 {
948		if !bytes.Equal(expectations.quicTransportParams, connState.QUICTransportParams) {
949			return errors.New("Peer did not send expected QUIC transport params")
950		}
951	}
952
953	if len(expectations.quicTransportParamsLegacy) > 0 {
954		if !bytes.Equal(expectations.quicTransportParamsLegacy, connState.QUICTransportParamsLegacy) {
955			return errors.New("Peer did not send expected legacy QUIC transport params")
956		}
957	}
958
959	if test.exportKeyingMaterial > 0 {
960		actual := make([]byte, test.exportKeyingMaterial)
961		if _, err := io.ReadFull(tlsConn, actual); err != nil {
962			return err
963		}
964		expected, err := tlsConn.ExportKeyingMaterial(test.exportKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext), test.useExportContext)
965		if err != nil {
966			return err
967		}
968		if !bytes.Equal(actual, expected) {
969			return fmt.Errorf("keying material mismatch; got %x, wanted %x", actual, expected)
970		}
971	}
972
973	if test.exportTrafficSecrets {
974		secretLenBytes := make([]byte, 2)
975		if _, err := io.ReadFull(tlsConn, secretLenBytes); err != nil {
976			return err
977		}
978		secretLen := binary.LittleEndian.Uint16(secretLenBytes)
979
980		theirReadSecret := make([]byte, secretLen)
981		theirWriteSecret := make([]byte, secretLen)
982		if _, err := io.ReadFull(tlsConn, theirReadSecret); err != nil {
983			return err
984		}
985		if _, err := io.ReadFull(tlsConn, theirWriteSecret); err != nil {
986			return err
987		}
988
989		myReadSecret := tlsConn.in.trafficSecret
990		myWriteSecret := tlsConn.out.trafficSecret
991		if !bytes.Equal(myWriteSecret, theirReadSecret) {
992			return fmt.Errorf("read traffic-secret mismatch; got %x, wanted %x", theirReadSecret, myWriteSecret)
993		}
994		if !bytes.Equal(myReadSecret, theirWriteSecret) {
995			return fmt.Errorf("write traffic-secret mismatch; got %x, wanted %x", theirWriteSecret, myReadSecret)
996		}
997	}
998
999	if test.testTLSUnique {
1000		var peersValue [12]byte
1001		if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil {
1002			return err
1003		}
1004		expected := tlsConn.ConnectionState().TLSUnique
1005		if !bytes.Equal(peersValue[:], expected) {
1006			return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected)
1007		}
1008	}
1009
1010	if test.sendHalfHelloRequest {
1011		tlsConn.SendHalfHelloRequest()
1012	}
1013
1014	shimPrefix := test.shimPrefix
1015	if isResume {
1016		shimPrefix = test.resumeShimPrefix
1017	}
1018	if test.shimWritesFirst || test.readWithUnfinishedWrite {
1019		shimPrefix = "hello"
1020	}
1021	if test.renegotiate > 0 {
1022		// If readWithUnfinishedWrite is set, the shim prefix will be
1023		// available later.
1024		if shimPrefix != "" && !test.readWithUnfinishedWrite {
1025			var buf = make([]byte, len(shimPrefix))
1026			_, err := io.ReadFull(tlsConn, buf)
1027			if err != nil {
1028				return err
1029			}
1030			if string(buf) != shimPrefix {
1031				return fmt.Errorf("bad initial message %v vs %v", string(buf), shimPrefix)
1032			}
1033			shimPrefix = ""
1034		}
1035
1036		if test.renegotiateCiphers != nil {
1037			config.CipherSuites = test.renegotiateCiphers
1038		}
1039		for i := 0; i < test.renegotiate; i++ {
1040			if err := tlsConn.Renegotiate(); err != nil {
1041				return err
1042			}
1043		}
1044	} else if test.renegotiateCiphers != nil {
1045		panic("renegotiateCiphers without renegotiate")
1046	}
1047
1048	if test.damageFirstWrite {
1049		connDamage.setDamage(true)
1050		tlsConn.Write([]byte("DAMAGED WRITE"))
1051		connDamage.setDamage(false)
1052	}
1053
1054	messageLen := test.messageLen
1055	if messageLen < 0 {
1056		if test.protocol == dtls {
1057			return fmt.Errorf("messageLen < 0 not supported for DTLS tests")
1058		}
1059		// Read until EOF.
1060		_, err := io.Copy(ioutil.Discard, tlsConn)
1061		return err
1062	}
1063	if messageLen == 0 {
1064		messageLen = 32
1065	}
1066
1067	messageCount := test.messageCount
1068	// shimShutsDown sets the default message count to zero.
1069	if messageCount == 0 && !test.shimShutsDown {
1070		messageCount = 1
1071	}
1072
1073	for j := 0; j < messageCount; j++ {
1074		for i := 0; i < test.sendKeyUpdates; i++ {
1075			tlsConn.SendKeyUpdate(test.keyUpdateRequest)
1076		}
1077
1078		for i := 0; i < test.sendEmptyRecords; i++ {
1079			tlsConn.Write(nil)
1080		}
1081
1082		for i := 0; i < test.sendWarningAlerts; i++ {
1083			tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
1084		}
1085
1086		for i := 0; i < test.sendUserCanceledAlerts; i++ {
1087			tlsConn.SendAlert(alertLevelWarning, alertUserCanceled)
1088		}
1089
1090		if test.sendBogusAlertType {
1091			tlsConn.SendAlert(0x42, alertUnexpectedMessage)
1092		}
1093
1094		testMessage := make([]byte, messageLen)
1095		for i := range testMessage {
1096			testMessage[i] = 0x42 ^ byte(j)
1097		}
1098		tlsConn.Write(testMessage)
1099
1100		// Consume the shim prefix if needed.
1101		if shimPrefix != "" {
1102			var buf = make([]byte, len(shimPrefix))
1103			_, err := io.ReadFull(tlsConn, buf)
1104			if err != nil {
1105				return err
1106			}
1107			if string(buf) != shimPrefix {
1108				return fmt.Errorf("bad initial message %v vs %v", string(buf), shimPrefix)
1109			}
1110			shimPrefix = ""
1111		}
1112
1113		if test.shimShutsDown || test.expectMessageDropped {
1114			// The shim will not respond.
1115			continue
1116		}
1117
1118		// Process the KeyUpdate ACK. However many KeyUpdates the runner
1119		// sends, the shim should respond only once.
1120		if test.sendKeyUpdates > 0 && test.keyUpdateRequest == keyUpdateRequested {
1121			if err := tlsConn.ReadKeyUpdateACK(); err != nil {
1122				return err
1123			}
1124		}
1125
1126		buf := make([]byte, len(testMessage))
1127		if test.protocol == dtls {
1128			bufTmp := make([]byte, len(buf)+1)
1129			n, err := tlsConn.Read(bufTmp)
1130			if err != nil {
1131				return err
1132			}
1133			if config.Bugs.SplitAndPackAppData {
1134				m, err := tlsConn.Read(bufTmp[n:])
1135				if err != nil {
1136					return err
1137				}
1138				n += m
1139			}
1140			if n != len(buf) {
1141				return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
1142			}
1143			copy(buf, bufTmp)
1144		} else {
1145			_, err := io.ReadFull(tlsConn, buf)
1146			if err != nil {
1147				return err
1148			}
1149		}
1150
1151		for i, v := range buf {
1152			if v != testMessage[i]^0xff {
1153				return fmt.Errorf("bad reply contents at byte %d; got %q and wanted %q", i, buf, testMessage)
1154			}
1155		}
1156
1157		if seen := tlsConn.keyUpdateSeen; seen != test.expectUnsolicitedKeyUpdate {
1158			return fmt.Errorf("keyUpdateSeen (%t) != expectUnsolicitedKeyUpdate", seen)
1159		}
1160	}
1161
1162	return nil
1163}
1164
1165const xtermSize = "140x50"
1166
1167func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd {
1168	valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full", "--quiet"}
1169	if dbAttach {
1170		valgrindArgs = append(valgrindArgs, "--db-attach=yes", "--db-command=xterm -geometry "+xtermSize+" -e gdb -nw %f %p")
1171	}
1172	valgrindArgs = append(valgrindArgs, path)
1173	valgrindArgs = append(valgrindArgs, args...)
1174
1175	return exec.Command("valgrind", valgrindArgs...)
1176}
1177
1178func gdbOf(path string, args ...string) *exec.Cmd {
1179	xtermArgs := []string{"-geometry", xtermSize, "-e", "gdb", "--args"}
1180	xtermArgs = append(xtermArgs, path)
1181	xtermArgs = append(xtermArgs, args...)
1182
1183	return exec.Command("xterm", xtermArgs...)
1184}
1185
1186func lldbOf(path string, args ...string) *exec.Cmd {
1187	xtermArgs := []string{"-geometry", xtermSize, "-e", "lldb", "--"}
1188	xtermArgs = append(xtermArgs, path)
1189	xtermArgs = append(xtermArgs, args...)
1190
1191	return exec.Command("xterm", xtermArgs...)
1192}
1193
1194func removeFirstLineIfSuffix(s, suffix string) string {
1195	idx := strings.IndexByte(s, '\n')
1196	if idx < 0 {
1197		return s
1198	}
1199	if strings.HasSuffix(s[:idx], suffix) {
1200		return s[idx+1:]
1201	}
1202	return s
1203}
1204
1205var (
1206	errMoreMallocs   = errors.New("child process did not exhaust all allocation calls")
1207	errUnimplemented = errors.New("child process does not implement needed flags")
1208)
1209
1210// accept accepts a connection from listener, unless waitChan signals a process
1211// exit first.
1212func acceptOrWait(listener *net.TCPListener, waitChan chan error) (net.Conn, error) {
1213	type connOrError struct {
1214		conn net.Conn
1215		err  error
1216	}
1217	connChan := make(chan connOrError, 1)
1218	go func() {
1219		if !useDebugger() {
1220			listener.SetDeadline(time.Now().Add(*idleTimeout))
1221		}
1222		conn, err := listener.Accept()
1223		connChan <- connOrError{conn, err}
1224		close(connChan)
1225	}()
1226	select {
1227	case result := <-connChan:
1228		return result.conn, result.err
1229	case childErr := <-waitChan:
1230		waitChan <- childErr
1231		return nil, fmt.Errorf("child exited early: %s", childErr)
1232	}
1233}
1234
1235func translateExpectedError(errorStr string) string {
1236	if translated, ok := shimConfig.ErrorMap[errorStr]; ok {
1237		return translated
1238	}
1239
1240	if *looseErrors {
1241		return ""
1242	}
1243
1244	return errorStr
1245}
1246
1247func runTest(statusChan chan statusMsg, test *testCase, shimPath string, mallocNumToFail int64) error {
1248	// Help debugging panics on the Go side.
1249	defer func() {
1250		if r := recover(); r != nil {
1251			fmt.Fprintf(os.Stderr, "Test '%s' panicked.\n", test.name)
1252			panic(r)
1253		}
1254	}()
1255
1256	if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) {
1257		panic("Error expected without shouldFail in " + test.name)
1258	}
1259
1260	if test.expectResumeRejected && !test.resumeSession {
1261		panic("expectResumeRejected without resumeSession in " + test.name)
1262	}
1263
1264	for _, ver := range tlsVersions {
1265		if !strings.Contains("-"+test.name+"-", "-"+ver.name+"-") {
1266			continue
1267		}
1268
1269		if test.config.MaxVersion == 0 && test.config.MinVersion == 0 && test.expectations.version == 0 {
1270			panic(fmt.Sprintf("The name of test %q suggests that it's version specific, but min/max version in the Config is %x/%x. One of them should probably be %x", test.name, test.config.MinVersion, test.config.MaxVersion, ver.version))
1271		}
1272	}
1273
1274	listener, err := net.ListenTCP("tcp", &net.TCPAddr{IP: net.IPv6loopback})
1275	if err != nil {
1276		listener, err = net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}})
1277	}
1278	if err != nil {
1279		panic(err)
1280	}
1281	defer func() {
1282		if listener != nil {
1283			listener.Close()
1284		}
1285	}()
1286
1287	flags := []string{"-port", strconv.Itoa(listener.Addr().(*net.TCPAddr).Port)}
1288	if test.testType == serverTest {
1289		flags = append(flags, "-server")
1290
1291		flags = append(flags, "-key-file")
1292		if test.keyFile == "" {
1293			flags = append(flags, path.Join(*resourceDir, rsaKeyFile))
1294		} else {
1295			flags = append(flags, path.Join(*resourceDir, test.keyFile))
1296		}
1297
1298		flags = append(flags, "-cert-file")
1299		if test.certFile == "" {
1300			flags = append(flags, path.Join(*resourceDir, rsaCertificateFile))
1301		} else {
1302			flags = append(flags, path.Join(*resourceDir, test.certFile))
1303		}
1304	}
1305
1306	if test.protocol == dtls {
1307		flags = append(flags, "-dtls")
1308	} else if test.protocol == quic {
1309		flags = append(flags, "-quic")
1310		if !test.skipTransportParamsConfig {
1311			test.config.QUICTransportParams = []byte{1, 2}
1312			test.config.QUICTransportParamsUseLegacyCodepoint = QUICUseCodepointStandard
1313			if test.resumeConfig != nil {
1314				test.resumeConfig.QUICTransportParams = []byte{1, 2}
1315				test.resumeConfig.QUICTransportParamsUseLegacyCodepoint = QUICUseCodepointStandard
1316			}
1317			test.expectations.quicTransportParams = []byte{3, 4}
1318			if test.resumeExpectations != nil {
1319				test.resumeExpectations.quicTransportParams = []byte{3, 4}
1320			}
1321			useCodepointFlag := "0"
1322			if test.config.QUICTransportParamsUseLegacyCodepoint == QUICUseCodepointLegacy {
1323				useCodepointFlag = "1"
1324			}
1325			flags = append(flags,
1326				"-quic-transport-params",
1327				base64.StdEncoding.EncodeToString([]byte{3, 4}),
1328				"-expect-quic-transport-params",
1329				base64.StdEncoding.EncodeToString([]byte{1, 2}),
1330				"-quic-use-legacy-codepoint", useCodepointFlag)
1331		}
1332		if !test.skipQUICALPNConfig {
1333			flags = append(flags,
1334				[]string{
1335					"-advertise-alpn", "\x03foo",
1336					"-select-alpn", "foo",
1337					"-expect-alpn", "foo",
1338				}...)
1339			test.config.NextProtos = []string{"foo"}
1340			if test.resumeConfig != nil {
1341				test.resumeConfig.NextProtos = []string{"foo"}
1342			}
1343			test.expectations.nextProto = "foo"
1344			test.expectations.nextProtoType = alpn
1345			if test.resumeExpectations != nil {
1346				test.resumeExpectations.nextProto = "foo"
1347				test.resumeExpectations.nextProtoType = alpn
1348			}
1349		}
1350	}
1351
1352	if test.earlyData {
1353		if !test.resumeSession {
1354			panic("earlyData set without resumeSession in " + test.name)
1355		}
1356
1357		resumeConfig := test.resumeConfig
1358		if resumeConfig == nil {
1359			resumeConfig = &test.config
1360		}
1361		if test.expectEarlyDataRejected {
1362			flags = append(flags, "-on-resume-expect-reject-early-data")
1363		} else {
1364			flags = append(flags, "-on-resume-expect-accept-early-data")
1365		}
1366
1367		if test.protocol == quic {
1368			// QUIC requires an early data context string.
1369			flags = append(flags, "-quic-early-data-context", "context")
1370		}
1371
1372		flags = append(flags, "-enable-early-data")
1373		if test.testType == clientTest {
1374			// Configure the runner with default maximum early data.
1375			flags = append(flags, "-expect-ticket-supports-early-data")
1376			if test.config.MaxEarlyDataSize == 0 {
1377				test.config.MaxEarlyDataSize = 16384
1378			}
1379			if resumeConfig.MaxEarlyDataSize == 0 {
1380				resumeConfig.MaxEarlyDataSize = 16384
1381			}
1382
1383			// Configure the shim to send some data in early data.
1384			flags = append(flags, "-on-resume-shim-writes-first")
1385			if resumeConfig.Bugs.ExpectEarlyData == nil {
1386				resumeConfig.Bugs.ExpectEarlyData = [][]byte{[]byte("hello")}
1387			}
1388		} else {
1389			// By default, send some early data and expect half-RTT data response.
1390			if resumeConfig.Bugs.SendEarlyData == nil {
1391				resumeConfig.Bugs.SendEarlyData = [][]byte{{1, 2, 3, 4}}
1392			}
1393			if resumeConfig.Bugs.ExpectHalfRTTData == nil {
1394				resumeConfig.Bugs.ExpectHalfRTTData = [][]byte{{254, 253, 252, 251}}
1395			}
1396			resumeConfig.Bugs.ExpectEarlyDataAccepted = !test.expectEarlyDataRejected
1397		}
1398	}
1399
1400	var resumeCount int
1401	if test.resumeSession {
1402		resumeCount++
1403		if test.resumeRenewedSession {
1404			resumeCount++
1405		}
1406	}
1407
1408	if resumeCount > 0 {
1409		flags = append(flags, "-resume-count", strconv.Itoa(resumeCount))
1410	}
1411
1412	if test.shimWritesFirst {
1413		flags = append(flags, "-shim-writes-first")
1414	}
1415
1416	if test.readWithUnfinishedWrite {
1417		flags = append(flags, "-read-with-unfinished-write")
1418	}
1419
1420	if test.shimShutsDown {
1421		flags = append(flags, "-shim-shuts-down")
1422	}
1423
1424	if test.exportKeyingMaterial > 0 {
1425		flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial))
1426		if test.useExportContext {
1427			flags = append(flags, "-use-export-context")
1428		}
1429	}
1430	if test.exportKeyingMaterial > 0 {
1431		flags = append(flags, "-export-label", test.exportLabel)
1432		flags = append(flags, "-export-context", test.exportContext)
1433	}
1434
1435	if test.exportTrafficSecrets {
1436		flags = append(flags, "-export-traffic-secrets")
1437	}
1438
1439	if test.expectResumeRejected {
1440		flags = append(flags, "-expect-session-miss")
1441	}
1442
1443	if test.testTLSUnique {
1444		flags = append(flags, "-tls-unique")
1445	}
1446
1447	flags = append(flags, "-handshaker-path", *handshakerPath)
1448
1449	if *waitForDebugger {
1450		flags = append(flags, "-wait-for-debugger")
1451	}
1452
1453	var transcriptPrefix string
1454	var transcripts [][]byte
1455	if len(*transcriptDir) != 0 {
1456		protocol := "tls"
1457		if test.protocol == dtls {
1458			protocol = "dtls"
1459		} else if test.protocol == quic {
1460			protocol = "quic"
1461		}
1462
1463		side := "client"
1464		if test.testType == serverTest {
1465			side = "server"
1466		}
1467
1468		dir := filepath.Join(*transcriptDir, protocol, side)
1469		if err := os.MkdirAll(dir, 0755); err != nil {
1470			return err
1471		}
1472		transcriptPrefix = filepath.Join(dir, test.name+"-")
1473		flags = append(flags, "-write-settings", transcriptPrefix)
1474	}
1475
1476	flags = append(flags, test.flags...)
1477
1478	var shim *exec.Cmd
1479	if *useValgrind {
1480		shim = valgrindOf(false, shimPath, flags...)
1481	} else if *useGDB {
1482		shim = gdbOf(shimPath, flags...)
1483	} else if *useLLDB {
1484		shim = lldbOf(shimPath, flags...)
1485	} else {
1486		shim = exec.Command(shimPath, flags...)
1487	}
1488	shim.Stdin = os.Stdin
1489	var stdoutBuf, stderrBuf bytes.Buffer
1490	shim.Stdout = &stdoutBuf
1491	shim.Stderr = &stderrBuf
1492	if mallocNumToFail >= 0 {
1493		shim.Env = os.Environ()
1494		shim.Env = append(shim.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10))
1495		if *mallocTestDebug {
1496			shim.Env = append(shim.Env, "MALLOC_BREAK_ON_FAIL=1")
1497		}
1498		shim.Env = append(shim.Env, "_MALLOC_CHECK=1")
1499	}
1500
1501	if err := shim.Start(); err != nil {
1502		panic(err)
1503	}
1504	statusChan <- statusMsg{test: test, statusType: statusShimStarted, pid: shim.Process.Pid}
1505	waitChan := make(chan error, 1)
1506	go func() { waitChan <- shim.Wait() }()
1507
1508	config := test.config
1509
1510	if *deterministic {
1511		config.Rand = &deterministicRand{}
1512	}
1513
1514	conn, err := acceptOrWait(listener, waitChan)
1515	if err == nil {
1516		err = doExchange(test, &config, conn, false /* not a resumption */, &transcripts, 0)
1517		conn.Close()
1518	}
1519
1520	for i := 0; err == nil && i < resumeCount; i++ {
1521		var resumeConfig Config
1522		if test.resumeConfig != nil {
1523			resumeConfig = *test.resumeConfig
1524			if !test.newSessionsOnResume {
1525				resumeConfig.SessionTicketKey = config.SessionTicketKey
1526				resumeConfig.ClientSessionCache = config.ClientSessionCache
1527				resumeConfig.ServerSessionCache = config.ServerSessionCache
1528			}
1529			resumeConfig.Rand = config.Rand
1530		} else {
1531			resumeConfig = config
1532		}
1533		var connResume net.Conn
1534		connResume, err = acceptOrWait(listener, waitChan)
1535		if err == nil {
1536			err = doExchange(test, &resumeConfig, connResume, true /* resumption */, &transcripts, i+1)
1537			connResume.Close()
1538		}
1539	}
1540
1541	// Close the listener now. This is to avoid hangs should the shim try to
1542	// open more connections than expected.
1543	listener.Close()
1544	listener = nil
1545
1546	var childErr error
1547	if !useDebugger() {
1548		childErr = <-waitChan
1549	} else {
1550		waitTimeout := time.AfterFunc(*idleTimeout, func() {
1551			shim.Process.Kill()
1552		})
1553		childErr = <-waitChan
1554		waitTimeout.Stop()
1555	}
1556
1557	// Now that the shim has exitted, all the settings files have been
1558	// written. Append the saved transcripts.
1559	for i, transcript := range transcripts {
1560		if err := appendTranscript(transcriptPrefix+strconv.Itoa(i), transcript); err != nil {
1561			return err
1562		}
1563	}
1564
1565	var isValgrindError, mustFail bool
1566	if exitError, ok := childErr.(*exec.ExitError); ok {
1567		switch exitError.Sys().(syscall.WaitStatus).ExitStatus() {
1568		case 88:
1569			return errMoreMallocs
1570		case 89:
1571			return errUnimplemented
1572		case 90:
1573			mustFail = true
1574		case 99:
1575			isValgrindError = true
1576		}
1577	}
1578
1579	// Account for Windows line endings.
1580	stdout := strings.Replace(string(stdoutBuf.Bytes()), "\r\n", "\n", -1)
1581	stderr := strings.Replace(string(stderrBuf.Bytes()), "\r\n", "\n", -1)
1582
1583	// Work around an NDK / Android bug. The NDK r16 sometimes generates
1584	// binaries with the DF_1_PIE, which the runtime linker on Android N
1585	// complains about. The next NDK revision should work around this but,
1586	// in the meantime, strip its error out.
1587	//
1588	// https://github.com/android-ndk/ndk/issues/602
1589	// https://android-review.googlesource.com/c/platform/bionic/+/259790
1590	// https://android-review.googlesource.com/c/toolchain/binutils/+/571550
1591	//
1592	// Remove this after switching to the r17 NDK.
1593	stderr = removeFirstLineIfSuffix(stderr, ": unsupported flags DT_FLAGS_1=0x8000001")
1594
1595	// Separate the errors from the shim and those from tools like
1596	// AddressSanitizer.
1597	var extraStderr string
1598	if stderrParts := strings.SplitN(stderr, "--- DONE ---\n", 2); len(stderrParts) == 2 {
1599		stderr = stderrParts[0]
1600		extraStderr = stderrParts[1]
1601	}
1602
1603	failed := err != nil || childErr != nil
1604	expectedError := translateExpectedError(test.expectedError)
1605	correctFailure := len(expectedError) == 0 || strings.Contains(stderr, expectedError)
1606
1607	localError := "none"
1608	if err != nil {
1609		localError = err.Error()
1610	}
1611	if len(test.expectedLocalError) != 0 {
1612		correctFailure = correctFailure && strings.Contains(localError, test.expectedLocalError)
1613	}
1614
1615	if failed != test.shouldFail || failed && !correctFailure || mustFail {
1616		childError := "none"
1617		if childErr != nil {
1618			childError = childErr.Error()
1619		}
1620
1621		var msg string
1622		switch {
1623		case failed && !test.shouldFail:
1624			msg = "unexpected failure"
1625		case !failed && test.shouldFail:
1626			msg = "unexpected success"
1627		case failed && !correctFailure:
1628			msg = "bad error (wanted '" + expectedError + "' / '" + test.expectedLocalError + "')"
1629		case mustFail:
1630			msg = "test failure"
1631		default:
1632			panic("internal error")
1633		}
1634
1635		return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s\n%s", msg, localError, childError, stdout, stderr, extraStderr)
1636	}
1637
1638	if len(extraStderr) > 0 || (!failed && len(stderr) > 0) {
1639		return fmt.Errorf("unexpected error output:\n%s\n%s", stderr, extraStderr)
1640	}
1641
1642	if *useValgrind && isValgrindError {
1643		return fmt.Errorf("valgrind error:\n%s\n%s", stderr, extraStderr)
1644	}
1645
1646	return nil
1647}
1648
1649type tlsVersion struct {
1650	name string
1651	// version is the protocol version.
1652	version uint16
1653	// excludeFlag is the legacy shim flag to disable the version.
1654	excludeFlag string
1655	hasDTLS     bool
1656	hasQUIC     bool
1657	// versionDTLS, if non-zero, is the DTLS-specific representation of the version.
1658	versionDTLS uint16
1659	// versionWire, if non-zero, is the wire representation of the
1660	// version. Otherwise the wire version is the protocol version or
1661	// versionDTLS.
1662	versionWire uint16
1663}
1664
1665func (vers tlsVersion) shimFlag(protocol protocol) string {
1666	// The shim uses the protocol version in its public API, but uses the
1667	// DTLS-specific version if it exists.
1668	if protocol == dtls && vers.versionDTLS != 0 {
1669		return strconv.Itoa(int(vers.versionDTLS))
1670	}
1671	return strconv.Itoa(int(vers.version))
1672}
1673
1674func (vers tlsVersion) wire(protocol protocol) uint16 {
1675	if protocol == dtls && vers.versionDTLS != 0 {
1676		return vers.versionDTLS
1677	}
1678	if vers.versionWire != 0 {
1679		return vers.versionWire
1680	}
1681	return vers.version
1682}
1683
1684func (vers tlsVersion) supportsProtocol(protocol protocol) bool {
1685	if protocol == dtls {
1686		return vers.hasDTLS
1687	}
1688	if protocol == quic {
1689		return vers.hasQUIC
1690	}
1691	return true
1692}
1693
1694var tlsVersions = []tlsVersion{
1695	{
1696		name:        "TLS1",
1697		version:     VersionTLS10,
1698		excludeFlag: "-no-tls1",
1699		hasDTLS:     true,
1700		versionDTLS: VersionDTLS10,
1701	},
1702	{
1703		name:        "TLS11",
1704		version:     VersionTLS11,
1705		excludeFlag: "-no-tls11",
1706	},
1707	{
1708		name:        "TLS12",
1709		version:     VersionTLS12,
1710		excludeFlag: "-no-tls12",
1711		hasDTLS:     true,
1712		versionDTLS: VersionDTLS12,
1713	},
1714	{
1715		name:        "TLS13",
1716		version:     VersionTLS13,
1717		excludeFlag: "-no-tls13",
1718		hasQUIC:     true,
1719		versionWire: VersionTLS13,
1720	},
1721}
1722
1723func allVersions(protocol protocol) []tlsVersion {
1724	if protocol == tls {
1725		return tlsVersions
1726	}
1727
1728	var ret []tlsVersion
1729	for _, vers := range tlsVersions {
1730		if vers.supportsProtocol(protocol) {
1731			ret = append(ret, vers)
1732		}
1733	}
1734	return ret
1735}
1736
1737type testCipherSuite struct {
1738	name string
1739	id   uint16
1740}
1741
1742var testCipherSuites = []testCipherSuite{
1743	{"RSA_WITH_3DES_EDE_CBC_SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA},
1744	{"RSA_WITH_AES_128_GCM_SHA256", TLS_RSA_WITH_AES_128_GCM_SHA256},
1745	{"RSA_WITH_AES_128_CBC_SHA", TLS_RSA_WITH_AES_128_CBC_SHA},
1746	{"RSA_WITH_AES_256_GCM_SHA384", TLS_RSA_WITH_AES_256_GCM_SHA384},
1747	{"RSA_WITH_AES_256_CBC_SHA", TLS_RSA_WITH_AES_256_CBC_SHA},
1748	{"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
1749	{"ECDHE_ECDSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
1750	{"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
1751	{"ECDHE_ECDSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
1752	{"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
1753	{"ECDHE_RSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1754	{"ECDHE_RSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
1755	{"ECDHE_RSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
1756	{"ECDHE_RSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
1757	{"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
1758	{"PSK_WITH_AES_128_CBC_SHA", TLS_PSK_WITH_AES_128_CBC_SHA},
1759	{"PSK_WITH_AES_256_CBC_SHA", TLS_PSK_WITH_AES_256_CBC_SHA},
1760	{"ECDHE_PSK_WITH_AES_128_CBC_SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
1761	{"ECDHE_PSK_WITH_AES_256_CBC_SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA},
1762	{"ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256},
1763	{"CHACHA20_POLY1305_SHA256", TLS_CHACHA20_POLY1305_SHA256},
1764	{"AES_128_GCM_SHA256", TLS_AES_128_GCM_SHA256},
1765	{"AES_256_GCM_SHA384", TLS_AES_256_GCM_SHA384},
1766	{"RSA_WITH_NULL_SHA", TLS_RSA_WITH_NULL_SHA},
1767}
1768
1769func hasComponent(suiteName, component string) bool {
1770	return strings.Contains("_"+suiteName+"_", "_"+component+"_")
1771}
1772
1773func isTLS12Only(suiteName string) bool {
1774	return hasComponent(suiteName, "GCM") ||
1775		hasComponent(suiteName, "SHA256") ||
1776		hasComponent(suiteName, "SHA384") ||
1777		hasComponent(suiteName, "POLY1305")
1778}
1779
1780func isTLS13Suite(suiteName string) bool {
1781	return !hasComponent(suiteName, "WITH")
1782}
1783
1784func bigFromHex(hex string) *big.Int {
1785	ret, ok := new(big.Int).SetString(hex, 16)
1786	if !ok {
1787		panic("failed to parse hex number 0x" + hex)
1788	}
1789	return ret
1790}
1791
1792func convertToSplitHandshakeTests(tests []testCase) (splitHandshakeTests []testCase) {
1793	var stdout bytes.Buffer
1794	shim := exec.Command(*shimPath, "-is-handshaker-supported")
1795	shim.Stdout = &stdout
1796	if err := shim.Run(); err != nil {
1797		panic(err)
1798	}
1799
1800	switch strings.TrimSpace(string(stdout.Bytes())) {
1801	case "No":
1802		return
1803	case "Yes":
1804		break
1805	default:
1806		panic("Unknown output from shim: 0x" + hex.EncodeToString(stdout.Bytes()))
1807	}
1808
1809NextTest:
1810	for _, test := range tests {
1811		if test.protocol != tls ||
1812			test.testType != serverTest ||
1813			strings.Contains(test.name, "DelegatedCredentials") ||
1814			strings.Contains(test.name, "QUICTransportParams") ||
1815			strings.HasPrefix(test.name, "VersionNegotiation-") {
1816			continue
1817		}
1818		// TODO(mab): Remove this when it's no longer needed.
1819		//
1820		// This flag exists to allow TLS 1.3 support to propagate to old
1821		// versions, before enabling cross-version compatibility tests.
1822		if !*tls13SplitHandshakeTests &&
1823			(test.config.MaxVersion >= VersionTLS13 ||
1824				test.config.MaxVersion < VersionTLS10 ||
1825				(test.resumeConfig != nil && (test.resumeConfig.MaxVersion < VersionTLS10 || test.resumeConfig.MaxVersion >= VersionTLS13))) {
1826			continue
1827		}
1828
1829		for _, flag := range test.flags {
1830			if flag == "-implicit-handshake" {
1831				continue NextTest
1832			}
1833		}
1834
1835		shTest := test
1836		shTest.name += "-Split"
1837		shTest.flags = make([]string, len(test.flags), len(test.flags)+1)
1838		copy(shTest.flags, test.flags)
1839		shTest.flags = append(shTest.flags, "-handoff")
1840
1841		splitHandshakeTests = append(splitHandshakeTests, shTest)
1842	}
1843
1844	return splitHandshakeTests
1845}
1846
1847func addBasicTests() {
1848	basicTests := []testCase{
1849		{
1850			name: "NoFallbackSCSV",
1851			config: Config{
1852				Bugs: ProtocolBugs{
1853					FailIfNotFallbackSCSV: true,
1854				},
1855			},
1856			shouldFail:         true,
1857			expectedLocalError: "no fallback SCSV found",
1858		},
1859		{
1860			name: "SendFallbackSCSV",
1861			config: Config{
1862				Bugs: ProtocolBugs{
1863					FailIfNotFallbackSCSV: true,
1864				},
1865			},
1866			flags: []string{"-fallback-scsv"},
1867		},
1868		{
1869			name: "ClientCertificateTypes",
1870			config: Config{
1871				MaxVersion: VersionTLS12,
1872				ClientAuth: RequestClientCert,
1873				ClientCertificateTypes: []byte{
1874					CertTypeDSSSign,
1875					CertTypeRSASign,
1876					CertTypeECDSASign,
1877				},
1878			},
1879			flags: []string{
1880				"-expect-certificate-types",
1881				base64.StdEncoding.EncodeToString([]byte{
1882					CertTypeDSSSign,
1883					CertTypeRSASign,
1884					CertTypeECDSASign,
1885				}),
1886			},
1887		},
1888		{
1889			name: "UnauthenticatedECDH",
1890			config: Config{
1891				MaxVersion:   VersionTLS12,
1892				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1893				Bugs: ProtocolBugs{
1894					UnauthenticatedECDH: true,
1895				},
1896			},
1897			shouldFail:    true,
1898			expectedError: ":UNEXPECTED_MESSAGE:",
1899		},
1900		{
1901			name: "SkipCertificateStatus",
1902			config: Config{
1903				MaxVersion:   VersionTLS12,
1904				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1905				Bugs: ProtocolBugs{
1906					SkipCertificateStatus: true,
1907				},
1908			},
1909			flags: []string{
1910				"-enable-ocsp-stapling",
1911				// This test involves an optional message. Test the message callback
1912				// trace to ensure we do not miss or double-report any.
1913				"-expect-msg-callback",
1914				`write hs 1
1915read hs 2
1916read hs 11
1917read hs 12
1918read hs 14
1919write hs 16
1920write ccs
1921write hs 20
1922read hs 4
1923read ccs
1924read hs 20
1925read alert 1 0
1926`,
1927			},
1928		},
1929		{
1930			protocol: dtls,
1931			name:     "SkipCertificateStatus-DTLS",
1932			config: Config{
1933				MaxVersion:   VersionTLS12,
1934				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1935				Bugs: ProtocolBugs{
1936					SkipCertificateStatus: true,
1937				},
1938			},
1939			flags: []string{
1940				"-enable-ocsp-stapling",
1941				// This test involves an optional message. Test the message callback
1942				// trace to ensure we do not miss or double-report any.
1943				"-expect-msg-callback",
1944				`write hs 1
1945read hs 3
1946write hs 1
1947read hs 2
1948read hs 11
1949read hs 12
1950read hs 14
1951write hs 16
1952write ccs
1953write hs 20
1954read hs 4
1955read ccs
1956read hs 20
1957read alert 1 0
1958`,
1959			},
1960		},
1961		{
1962			name: "SkipServerKeyExchange",
1963			config: Config{
1964				MaxVersion:   VersionTLS12,
1965				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
1966				Bugs: ProtocolBugs{
1967					SkipServerKeyExchange: true,
1968				},
1969			},
1970			shouldFail:    true,
1971			expectedError: ":UNEXPECTED_MESSAGE:",
1972		},
1973		{
1974			testType: serverTest,
1975			name:     "ServerSkipCertificateVerify",
1976			config: Config{
1977				MaxVersion:   VersionTLS12,
1978				Certificates: []Certificate{rsaChainCertificate},
1979				Bugs: ProtocolBugs{
1980					SkipCertificateVerify: true,
1981				},
1982			},
1983			expectations: connectionExpectations{
1984				peerCertificate: &rsaChainCertificate,
1985			},
1986			flags: []string{
1987				"-require-any-client-certificate",
1988			},
1989			shouldFail:         true,
1990			expectedError:      ":UNEXPECTED_RECORD:",
1991			expectedLocalError: "remote error: unexpected message",
1992		},
1993		{
1994			testType: serverTest,
1995			name:     "Alert",
1996			config: Config{
1997				Bugs: ProtocolBugs{
1998					SendSpuriousAlert: alertRecordOverflow,
1999				},
2000			},
2001			shouldFail:    true,
2002			expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
2003		},
2004		{
2005			protocol: dtls,
2006			testType: serverTest,
2007			name:     "Alert-DTLS",
2008			config: Config{
2009				Bugs: ProtocolBugs{
2010					SendSpuriousAlert: alertRecordOverflow,
2011				},
2012			},
2013			shouldFail:    true,
2014			expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
2015		},
2016		{
2017			testType: serverTest,
2018			name:     "FragmentAlert",
2019			config: Config{
2020				Bugs: ProtocolBugs{
2021					FragmentAlert:     true,
2022					SendSpuriousAlert: alertRecordOverflow,
2023				},
2024			},
2025			shouldFail:    true,
2026			expectedError: ":BAD_ALERT:",
2027		},
2028		{
2029			protocol: dtls,
2030			testType: serverTest,
2031			name:     "FragmentAlert-DTLS",
2032			config: Config{
2033				Bugs: ProtocolBugs{
2034					FragmentAlert:     true,
2035					SendSpuriousAlert: alertRecordOverflow,
2036				},
2037			},
2038			shouldFail:    true,
2039			expectedError: ":BAD_ALERT:",
2040		},
2041		{
2042			testType: serverTest,
2043			name:     "DoubleAlert",
2044			config: Config{
2045				Bugs: ProtocolBugs{
2046					DoubleAlert:       true,
2047					SendSpuriousAlert: alertRecordOverflow,
2048				},
2049			},
2050			shouldFail:    true,
2051			expectedError: ":BAD_ALERT:",
2052		},
2053		{
2054			protocol: dtls,
2055			testType: serverTest,
2056			name:     "DoubleAlert-DTLS",
2057			config: Config{
2058				Bugs: ProtocolBugs{
2059					DoubleAlert:       true,
2060					SendSpuriousAlert: alertRecordOverflow,
2061				},
2062			},
2063			shouldFail:    true,
2064			expectedError: ":BAD_ALERT:",
2065		},
2066		{
2067			name: "SkipNewSessionTicket",
2068			config: Config{
2069				MaxVersion: VersionTLS12,
2070				Bugs: ProtocolBugs{
2071					SkipNewSessionTicket: true,
2072				},
2073			},
2074			shouldFail:    true,
2075			expectedError: ":UNEXPECTED_RECORD:",
2076		},
2077		{
2078			testType: serverTest,
2079			name:     "FallbackSCSV",
2080			config: Config{
2081				MaxVersion: VersionTLS11,
2082				Bugs: ProtocolBugs{
2083					SendFallbackSCSV: true,
2084				},
2085			},
2086			shouldFail:         true,
2087			expectedError:      ":INAPPROPRIATE_FALLBACK:",
2088			expectedLocalError: "remote error: inappropriate fallback",
2089		},
2090		{
2091			testType: serverTest,
2092			name:     "FallbackSCSV-VersionMatch-TLS13",
2093			config: Config{
2094				MaxVersion: VersionTLS13,
2095				Bugs: ProtocolBugs{
2096					SendFallbackSCSV: true,
2097				},
2098			},
2099		},
2100		{
2101			testType: serverTest,
2102			name:     "FallbackSCSV-VersionMatch-TLS12",
2103			config: Config{
2104				MaxVersion: VersionTLS12,
2105				Bugs: ProtocolBugs{
2106					SendFallbackSCSV: true,
2107				},
2108			},
2109			flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
2110		},
2111		{
2112			testType: serverTest,
2113			name:     "FragmentedClientVersion",
2114			config: Config{
2115				Bugs: ProtocolBugs{
2116					MaxHandshakeRecordLength: 1,
2117					FragmentClientVersion:    true,
2118				},
2119			},
2120			expectations: connectionExpectations{
2121				version: VersionTLS13,
2122			},
2123		},
2124		{
2125			testType:      serverTest,
2126			name:          "HttpGET",
2127			sendPrefix:    "GET / HTTP/1.0\n",
2128			shouldFail:    true,
2129			expectedError: ":HTTP_REQUEST:",
2130		},
2131		{
2132			testType:      serverTest,
2133			name:          "HttpPOST",
2134			sendPrefix:    "POST / HTTP/1.0\n",
2135			shouldFail:    true,
2136			expectedError: ":HTTP_REQUEST:",
2137		},
2138		{
2139			testType:      serverTest,
2140			name:          "HttpHEAD",
2141			sendPrefix:    "HEAD / HTTP/1.0\n",
2142			shouldFail:    true,
2143			expectedError: ":HTTP_REQUEST:",
2144		},
2145		{
2146			testType:      serverTest,
2147			name:          "HttpPUT",
2148			sendPrefix:    "PUT / HTTP/1.0\n",
2149			shouldFail:    true,
2150			expectedError: ":HTTP_REQUEST:",
2151		},
2152		{
2153			testType:      serverTest,
2154			name:          "HttpCONNECT",
2155			sendPrefix:    "CONNECT www.google.com:443 HTTP/1.0\n",
2156			shouldFail:    true,
2157			expectedError: ":HTTPS_PROXY_REQUEST:",
2158		},
2159		{
2160			testType:      serverTest,
2161			name:          "Garbage",
2162			sendPrefix:    "blah",
2163			shouldFail:    true,
2164			expectedError: ":WRONG_VERSION_NUMBER:",
2165		},
2166		{
2167			name: "RSAEphemeralKey",
2168			config: Config{
2169				MaxVersion:   VersionTLS12,
2170				CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
2171				Bugs: ProtocolBugs{
2172					RSAEphemeralKey: true,
2173				},
2174			},
2175			shouldFail:    true,
2176			expectedError: ":UNEXPECTED_MESSAGE:",
2177		},
2178		{
2179			name:          "DisableEverything",
2180			flags:         []string{"-no-tls13", "-no-tls12", "-no-tls11", "-no-tls1"},
2181			shouldFail:    true,
2182			expectedError: ":NO_SUPPORTED_VERSIONS_ENABLED:",
2183		},
2184		{
2185			protocol:      dtls,
2186			name:          "DisableEverything-DTLS",
2187			flags:         []string{"-no-tls12", "-no-tls1"},
2188			shouldFail:    true,
2189			expectedError: ":NO_SUPPORTED_VERSIONS_ENABLED:",
2190		},
2191		{
2192			protocol: dtls,
2193			testType: serverTest,
2194			name:     "MTU",
2195			config: Config{
2196				Bugs: ProtocolBugs{
2197					MaxPacketLength: 256,
2198				},
2199			},
2200			flags: []string{"-mtu", "256"},
2201		},
2202		{
2203			protocol: dtls,
2204			testType: serverTest,
2205			name:     "MTUExceeded",
2206			config: Config{
2207				Bugs: ProtocolBugs{
2208					MaxPacketLength: 255,
2209				},
2210			},
2211			flags:              []string{"-mtu", "256"},
2212			shouldFail:         true,
2213			expectedLocalError: "dtls: exceeded maximum packet length",
2214		},
2215		{
2216			name: "EmptyCertificateList",
2217			config: Config{
2218				MaxVersion: VersionTLS12,
2219				Bugs: ProtocolBugs{
2220					EmptyCertificateList: true,
2221				},
2222			},
2223			shouldFail:    true,
2224			expectedError: ":DECODE_ERROR:",
2225		},
2226		{
2227			name: "EmptyCertificateList-TLS13",
2228			config: Config{
2229				MaxVersion: VersionTLS13,
2230				Bugs: ProtocolBugs{
2231					EmptyCertificateList: true,
2232				},
2233			},
2234			shouldFail:    true,
2235			expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
2236		},
2237		{
2238			name:             "TLSFatalBadPackets",
2239			damageFirstWrite: true,
2240			shouldFail:       true,
2241			expectedError:    ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
2242		},
2243		{
2244			protocol:         dtls,
2245			name:             "DTLSIgnoreBadPackets",
2246			damageFirstWrite: true,
2247		},
2248		{
2249			protocol:         dtls,
2250			name:             "DTLSIgnoreBadPackets-Async",
2251			damageFirstWrite: true,
2252			flags:            []string{"-async"},
2253		},
2254		{
2255			name: "AppDataBeforeHandshake",
2256			config: Config{
2257				Bugs: ProtocolBugs{
2258					AppDataBeforeHandshake: []byte("TEST MESSAGE"),
2259				},
2260			},
2261			shouldFail:    true,
2262			expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:",
2263		},
2264		{
2265			name: "AppDataBeforeHandshake-Empty",
2266			config: Config{
2267				Bugs: ProtocolBugs{
2268					AppDataBeforeHandshake: []byte{},
2269				},
2270			},
2271			shouldFail:    true,
2272			expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:",
2273		},
2274		{
2275			protocol: dtls,
2276			name:     "AppDataBeforeHandshake-DTLS",
2277			config: Config{
2278				Bugs: ProtocolBugs{
2279					AppDataBeforeHandshake: []byte("TEST MESSAGE"),
2280				},
2281			},
2282			shouldFail:    true,
2283			expectedError: ":UNEXPECTED_RECORD:",
2284		},
2285		{
2286			protocol: dtls,
2287			name:     "AppDataBeforeHandshake-DTLS-Empty",
2288			config: Config{
2289				Bugs: ProtocolBugs{
2290					AppDataBeforeHandshake: []byte{},
2291				},
2292			},
2293			shouldFail:    true,
2294			expectedError: ":UNEXPECTED_RECORD:",
2295		},
2296		{
2297			name: "AppDataAfterChangeCipherSpec",
2298			config: Config{
2299				MaxVersion: VersionTLS12,
2300				Bugs: ProtocolBugs{
2301					AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
2302				},
2303			},
2304			shouldFail:    true,
2305			expectedError: ":UNEXPECTED_RECORD:",
2306		},
2307		{
2308			name: "AppDataAfterChangeCipherSpec-Empty",
2309			config: Config{
2310				MaxVersion: VersionTLS12,
2311				Bugs: ProtocolBugs{
2312					AppDataAfterChangeCipherSpec: []byte{},
2313				},
2314			},
2315			shouldFail:    true,
2316			expectedError: ":UNEXPECTED_RECORD:",
2317		},
2318		{
2319			protocol: dtls,
2320			name:     "AppDataAfterChangeCipherSpec-DTLS",
2321			config: Config{
2322				MaxVersion: VersionTLS12,
2323				Bugs: ProtocolBugs{
2324					AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
2325				},
2326			},
2327			// BoringSSL's DTLS implementation will drop the out-of-order
2328			// application data.
2329		},
2330		{
2331			protocol: dtls,
2332			name:     "AppDataAfterChangeCipherSpec-DTLS-Empty",
2333			config: Config{
2334				MaxVersion: VersionTLS12,
2335				Bugs: ProtocolBugs{
2336					AppDataAfterChangeCipherSpec: []byte{},
2337				},
2338			},
2339			// BoringSSL's DTLS implementation will drop the out-of-order
2340			// application data.
2341		},
2342		{
2343			name: "AlertAfterChangeCipherSpec",
2344			config: Config{
2345				MaxVersion: VersionTLS12,
2346				Bugs: ProtocolBugs{
2347					AlertAfterChangeCipherSpec: alertRecordOverflow,
2348				},
2349			},
2350			shouldFail:    true,
2351			expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
2352		},
2353		{
2354			protocol: dtls,
2355			name:     "AlertAfterChangeCipherSpec-DTLS",
2356			config: Config{
2357				MaxVersion: VersionTLS12,
2358				Bugs: ProtocolBugs{
2359					AlertAfterChangeCipherSpec: alertRecordOverflow,
2360				},
2361			},
2362			shouldFail:    true,
2363			expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
2364		},
2365		{
2366			protocol: dtls,
2367			name:     "ReorderHandshakeFragments-Small-DTLS",
2368			config: Config{
2369				Bugs: ProtocolBugs{
2370					ReorderHandshakeFragments: true,
2371					// Small enough that every handshake message is
2372					// fragmented.
2373					MaxHandshakeRecordLength: 2,
2374				},
2375			},
2376		},
2377		{
2378			protocol: dtls,
2379			name:     "ReorderHandshakeFragments-Large-DTLS",
2380			config: Config{
2381				Bugs: ProtocolBugs{
2382					ReorderHandshakeFragments: true,
2383					// Large enough that no handshake message is
2384					// fragmented.
2385					MaxHandshakeRecordLength: 2048,
2386				},
2387			},
2388		},
2389		{
2390			protocol: dtls,
2391			name:     "MixCompleteMessageWithFragments-DTLS",
2392			config: Config{
2393				Bugs: ProtocolBugs{
2394					ReorderHandshakeFragments:       true,
2395					MixCompleteMessageWithFragments: true,
2396					MaxHandshakeRecordLength:        2,
2397				},
2398			},
2399		},
2400		{
2401			name: "SendInvalidRecordType",
2402			config: Config{
2403				Bugs: ProtocolBugs{
2404					SendInvalidRecordType: true,
2405				},
2406			},
2407			shouldFail:    true,
2408			expectedError: ":UNEXPECTED_RECORD:",
2409		},
2410		{
2411			protocol: dtls,
2412			name:     "SendInvalidRecordType-DTLS",
2413			config: Config{
2414				Bugs: ProtocolBugs{
2415					SendInvalidRecordType: true,
2416				},
2417			},
2418			shouldFail:    true,
2419			expectedError: ":UNEXPECTED_RECORD:",
2420		},
2421		{
2422			name: "FalseStart-SkipServerSecondLeg",
2423			config: Config{
2424				MaxVersion:   VersionTLS12,
2425				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2426				NextProtos:   []string{"foo"},
2427				Bugs: ProtocolBugs{
2428					SkipNewSessionTicket: true,
2429					SkipChangeCipherSpec: true,
2430					SkipFinished:         true,
2431					ExpectFalseStart:     true,
2432				},
2433			},
2434			flags: []string{
2435				"-false-start",
2436				"-handshake-never-done",
2437				"-advertise-alpn", "\x03foo",
2438				"-expect-alpn", "foo",
2439			},
2440			shimWritesFirst: true,
2441			shouldFail:      true,
2442			expectedError:   ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:",
2443		},
2444		{
2445			name: "FalseStart-SkipServerSecondLeg-Implicit",
2446			config: Config{
2447				MaxVersion:   VersionTLS12,
2448				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2449				NextProtos:   []string{"foo"},
2450				Bugs: ProtocolBugs{
2451					SkipNewSessionTicket: true,
2452					SkipChangeCipherSpec: true,
2453					SkipFinished:         true,
2454				},
2455			},
2456			flags: []string{
2457				"-implicit-handshake",
2458				"-false-start",
2459				"-handshake-never-done",
2460				"-advertise-alpn", "\x03foo",
2461			},
2462			shouldFail:    true,
2463			expectedError: ":APPLICATION_DATA_INSTEAD_OF_HANDSHAKE:",
2464		},
2465		{
2466			testType:           serverTest,
2467			name:               "FailEarlyCallback",
2468			flags:              []string{"-fail-early-callback"},
2469			shouldFail:         true,
2470			expectedError:      ":CONNECTION_REJECTED:",
2471			expectedLocalError: "remote error: handshake failure",
2472		},
2473		{
2474			name: "FailCertCallback-Client-TLS12",
2475			config: Config{
2476				MaxVersion: VersionTLS12,
2477				ClientAuth: RequestClientCert,
2478			},
2479			flags:              []string{"-fail-cert-callback"},
2480			shouldFail:         true,
2481			expectedError:      ":CERT_CB_ERROR:",
2482			expectedLocalError: "remote error: internal error",
2483		},
2484		{
2485			testType: serverTest,
2486			name:     "FailCertCallback-Server-TLS12",
2487			config: Config{
2488				MaxVersion: VersionTLS12,
2489			},
2490			flags:              []string{"-fail-cert-callback"},
2491			shouldFail:         true,
2492			expectedError:      ":CERT_CB_ERROR:",
2493			expectedLocalError: "remote error: internal error",
2494		},
2495		{
2496			name: "FailCertCallback-Client-TLS13",
2497			config: Config{
2498				MaxVersion: VersionTLS13,
2499				ClientAuth: RequestClientCert,
2500			},
2501			flags:              []string{"-fail-cert-callback"},
2502			shouldFail:         true,
2503			expectedError:      ":CERT_CB_ERROR:",
2504			expectedLocalError: "remote error: internal error",
2505		},
2506		{
2507			testType: serverTest,
2508			name:     "FailCertCallback-Server-TLS13",
2509			config: Config{
2510				MaxVersion: VersionTLS13,
2511			},
2512			flags:              []string{"-fail-cert-callback"},
2513			shouldFail:         true,
2514			expectedError:      ":CERT_CB_ERROR:",
2515			expectedLocalError: "remote error: internal error",
2516		},
2517		{
2518			protocol: dtls,
2519			name:     "FragmentMessageTypeMismatch-DTLS",
2520			config: Config{
2521				Bugs: ProtocolBugs{
2522					MaxHandshakeRecordLength:    2,
2523					FragmentMessageTypeMismatch: true,
2524				},
2525			},
2526			shouldFail:    true,
2527			expectedError: ":FRAGMENT_MISMATCH:",
2528		},
2529		{
2530			protocol: dtls,
2531			name:     "FragmentMessageLengthMismatch-DTLS",
2532			config: Config{
2533				Bugs: ProtocolBugs{
2534					MaxHandshakeRecordLength:      2,
2535					FragmentMessageLengthMismatch: true,
2536				},
2537			},
2538			shouldFail:    true,
2539			expectedError: ":FRAGMENT_MISMATCH:",
2540		},
2541		{
2542			protocol: dtls,
2543			name:     "SplitFragments-Header-DTLS",
2544			config: Config{
2545				Bugs: ProtocolBugs{
2546					SplitFragments: 2,
2547				},
2548			},
2549			shouldFail:    true,
2550			expectedError: ":BAD_HANDSHAKE_RECORD:",
2551		},
2552		{
2553			protocol: dtls,
2554			name:     "SplitFragments-Boundary-DTLS",
2555			config: Config{
2556				Bugs: ProtocolBugs{
2557					SplitFragments: dtlsRecordHeaderLen,
2558				},
2559			},
2560			shouldFail:    true,
2561			expectedError: ":BAD_HANDSHAKE_RECORD:",
2562		},
2563		{
2564			protocol: dtls,
2565			name:     "SplitFragments-Body-DTLS",
2566			config: Config{
2567				Bugs: ProtocolBugs{
2568					SplitFragments: dtlsRecordHeaderLen + 1,
2569				},
2570			},
2571			shouldFail:    true,
2572			expectedError: ":BAD_HANDSHAKE_RECORD:",
2573		},
2574		{
2575			protocol: dtls,
2576			name:     "SendEmptyFragments-DTLS",
2577			config: Config{
2578				Bugs: ProtocolBugs{
2579					SendEmptyFragments: true,
2580				},
2581			},
2582		},
2583		{
2584			testType: serverTest,
2585			protocol: dtls,
2586			name:     "SendEmptyFragments-Padded-DTLS",
2587			config: Config{
2588				Bugs: ProtocolBugs{
2589					// Test empty fragments for a message with a
2590					// nice power-of-two length.
2591					PadClientHello:     64,
2592					SendEmptyFragments: true,
2593				},
2594			},
2595		},
2596		{
2597			name: "BadFinished-Client",
2598			config: Config{
2599				MaxVersion: VersionTLS12,
2600				Bugs: ProtocolBugs{
2601					BadFinished: true,
2602				},
2603			},
2604			shouldFail:    true,
2605			expectedError: ":DIGEST_CHECK_FAILED:",
2606		},
2607		{
2608			name: "BadFinished-Client-TLS13",
2609			config: Config{
2610				MaxVersion: VersionTLS13,
2611				Bugs: ProtocolBugs{
2612					BadFinished: true,
2613				},
2614			},
2615			shouldFail:    true,
2616			expectedError: ":DIGEST_CHECK_FAILED:",
2617		},
2618		{
2619			testType: serverTest,
2620			name:     "BadFinished-Server",
2621			config: Config{
2622				MaxVersion: VersionTLS12,
2623				Bugs: ProtocolBugs{
2624					BadFinished: true,
2625				},
2626			},
2627			shouldFail:    true,
2628			expectedError: ":DIGEST_CHECK_FAILED:",
2629		},
2630		{
2631			testType: serverTest,
2632			name:     "BadFinished-Server-TLS13",
2633			config: Config{
2634				MaxVersion: VersionTLS13,
2635				Bugs: ProtocolBugs{
2636					BadFinished: true,
2637				},
2638			},
2639			shouldFail:    true,
2640			expectedError: ":DIGEST_CHECK_FAILED:",
2641		},
2642		{
2643			name: "FalseStart-BadFinished",
2644			config: Config{
2645				MaxVersion:   VersionTLS12,
2646				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2647				NextProtos:   []string{"foo"},
2648				Bugs: ProtocolBugs{
2649					BadFinished:      true,
2650					ExpectFalseStart: true,
2651				},
2652			},
2653			flags: []string{
2654				"-false-start",
2655				"-handshake-never-done",
2656				"-advertise-alpn", "\x03foo",
2657				"-expect-alpn", "foo",
2658			},
2659			shimWritesFirst: true,
2660			shouldFail:      true,
2661			expectedError:   ":DIGEST_CHECK_FAILED:",
2662		},
2663		{
2664			name: "NoFalseStart-NoALPN",
2665			config: Config{
2666				MaxVersion:   VersionTLS12,
2667				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2668				Bugs: ProtocolBugs{
2669					ExpectFalseStart:          true,
2670					AlertBeforeFalseStartTest: alertAccessDenied,
2671				},
2672			},
2673			flags: []string{
2674				"-false-start",
2675			},
2676			shimWritesFirst:    true,
2677			shouldFail:         true,
2678			expectedError:      ":TLSV1_ALERT_ACCESS_DENIED:",
2679			expectedLocalError: "tls: peer did not false start: EOF",
2680		},
2681		{
2682			name: "FalseStart-NoALPNAllowed",
2683			config: Config{
2684				MaxVersion:   VersionTLS12,
2685				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
2686				Bugs: ProtocolBugs{
2687					ExpectFalseStart: true,
2688				},
2689			},
2690			flags: []string{
2691				"-false-start",
2692				"-allow-false-start-without-alpn",
2693			},
2694			shimWritesFirst: true,
2695		},
2696		{
2697			name: "NoFalseStart-NoAEAD",
2698			config: Config{
2699				MaxVersion:   VersionTLS12,
2700				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
2701				NextProtos:   []string{"foo"},
2702				Bugs: ProtocolBugs{
2703					ExpectFalseStart:          true,
2704					AlertBeforeFalseStartTest: alertAccessDenied,
2705				},
2706			},
2707			flags: []string{
2708				"-false-start",
2709				"-advertise-alpn", "\x03foo",
2710			},
2711			shimWritesFirst:    true,
2712			shouldFail:         true,
2713			expectedError:      ":TLSV1_ALERT_ACCESS_DENIED:",
2714			expectedLocalError: "tls: peer did not false start: EOF",
2715		},
2716		{
2717			name: "NoFalseStart-RSA",
2718			config: Config{
2719				MaxVersion:   VersionTLS12,
2720				CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
2721				NextProtos:   []string{"foo"},
2722				Bugs: ProtocolBugs{
2723					ExpectFalseStart:          true,
2724					AlertBeforeFalseStartTest: alertAccessDenied,
2725				},
2726			},
2727			flags: []string{
2728				"-false-start",
2729				"-advertise-alpn", "\x03foo",
2730			},
2731			shimWritesFirst:    true,
2732			shouldFail:         true,
2733			expectedError:      ":TLSV1_ALERT_ACCESS_DENIED:",
2734			expectedLocalError: "tls: peer did not false start: EOF",
2735		},
2736		{
2737			protocol: dtls,
2738			name:     "SendSplitAlert-Sync",
2739			config: Config{
2740				Bugs: ProtocolBugs{
2741					SendSplitAlert: true,
2742				},
2743			},
2744		},
2745		{
2746			protocol: dtls,
2747			name:     "SendSplitAlert-Async",
2748			config: Config{
2749				Bugs: ProtocolBugs{
2750					SendSplitAlert: true,
2751				},
2752			},
2753			flags: []string{"-async"},
2754		},
2755		{
2756			name:             "SendEmptyRecords-Pass",
2757			sendEmptyRecords: 32,
2758		},
2759		{
2760			name:             "SendEmptyRecords",
2761			sendEmptyRecords: 33,
2762			shouldFail:       true,
2763			expectedError:    ":TOO_MANY_EMPTY_FRAGMENTS:",
2764		},
2765		{
2766			name:             "SendEmptyRecords-Async",
2767			sendEmptyRecords: 33,
2768			flags:            []string{"-async"},
2769			shouldFail:       true,
2770			expectedError:    ":TOO_MANY_EMPTY_FRAGMENTS:",
2771		},
2772		{
2773			name: "SendWarningAlerts-Pass",
2774			config: Config{
2775				MaxVersion: VersionTLS12,
2776			},
2777			sendWarningAlerts: 4,
2778		},
2779		{
2780			protocol: dtls,
2781			name:     "SendWarningAlerts-DTLS-Pass",
2782			config: Config{
2783				MaxVersion: VersionTLS12,
2784			},
2785			sendWarningAlerts: 4,
2786		},
2787		{
2788			name: "SendWarningAlerts-TLS13",
2789			config: Config{
2790				MaxVersion: VersionTLS13,
2791			},
2792			sendWarningAlerts:  4,
2793			shouldFail:         true,
2794			expectedError:      ":BAD_ALERT:",
2795			expectedLocalError: "remote error: error decoding message",
2796		},
2797		// Although TLS 1.3 intended to remove warning alerts, it left in
2798		// user_canceled. JDK11 misuses this alert as a post-handshake
2799		// full-duplex signal. As a workaround, skip user_canceled as in
2800		// TLS 1.2, which is consistent with NSS and OpenSSL.
2801		{
2802			name: "SendUserCanceledAlerts-TLS13",
2803			config: Config{
2804				MaxVersion: VersionTLS13,
2805			},
2806			sendUserCanceledAlerts: 4,
2807		},
2808		{
2809			name: "SendUserCanceledAlerts-TooMany-TLS13",
2810			config: Config{
2811				MaxVersion: VersionTLS13,
2812			},
2813			sendUserCanceledAlerts: 5,
2814			shouldFail:             true,
2815			expectedError:          ":TOO_MANY_WARNING_ALERTS:",
2816		},
2817		{
2818			name: "SendWarningAlerts-TooMany",
2819			config: Config{
2820				MaxVersion: VersionTLS12,
2821			},
2822			sendWarningAlerts: 5,
2823			shouldFail:        true,
2824			expectedError:     ":TOO_MANY_WARNING_ALERTS:",
2825		},
2826		{
2827			name: "SendWarningAlerts-TooMany-Async",
2828			config: Config{
2829				MaxVersion: VersionTLS12,
2830			},
2831			sendWarningAlerts: 5,
2832			flags:             []string{"-async"},
2833			shouldFail:        true,
2834			expectedError:     ":TOO_MANY_WARNING_ALERTS:",
2835		},
2836		{
2837			name:               "SendBogusAlertType",
2838			sendBogusAlertType: true,
2839			shouldFail:         true,
2840			expectedError:      ":UNKNOWN_ALERT_TYPE:",
2841			expectedLocalError: "remote error: illegal parameter",
2842		},
2843		{
2844			protocol:           dtls,
2845			name:               "SendBogusAlertType-DTLS",
2846			sendBogusAlertType: true,
2847			shouldFail:         true,
2848			expectedError:      ":UNKNOWN_ALERT_TYPE:",
2849			expectedLocalError: "remote error: illegal parameter",
2850		},
2851		{
2852			name: "TooManyKeyUpdates",
2853			config: Config{
2854				MaxVersion: VersionTLS13,
2855			},
2856			sendKeyUpdates:   33,
2857			keyUpdateRequest: keyUpdateNotRequested,
2858			shouldFail:       true,
2859			expectedError:    ":TOO_MANY_KEY_UPDATES:",
2860		},
2861		{
2862			name: "EmptySessionID",
2863			config: Config{
2864				MaxVersion:             VersionTLS12,
2865				SessionTicketsDisabled: true,
2866			},
2867			noSessionCache: true,
2868			flags:          []string{"-expect-no-session"},
2869		},
2870		{
2871			name: "Unclean-Shutdown",
2872			config: Config{
2873				Bugs: ProtocolBugs{
2874					NoCloseNotify:     true,
2875					ExpectCloseNotify: true,
2876				},
2877			},
2878			shimShutsDown: true,
2879			flags:         []string{"-check-close-notify"},
2880			shouldFail:    true,
2881			expectedError: "Unexpected SSL_shutdown result: -1 != 1",
2882		},
2883		{
2884			name: "Unclean-Shutdown-Ignored",
2885			config: Config{
2886				Bugs: ProtocolBugs{
2887					NoCloseNotify: true,
2888				},
2889			},
2890			shimShutsDown: true,
2891		},
2892		{
2893			name: "Unclean-Shutdown-Alert",
2894			config: Config{
2895				Bugs: ProtocolBugs{
2896					SendAlertOnShutdown: alertDecompressionFailure,
2897					ExpectCloseNotify:   true,
2898				},
2899			},
2900			shimShutsDown: true,
2901			flags:         []string{"-check-close-notify"},
2902			shouldFail:    true,
2903			expectedError: ":SSLV3_ALERT_DECOMPRESSION_FAILURE:",
2904		},
2905		{
2906			name: "LargePlaintext",
2907			config: Config{
2908				Bugs: ProtocolBugs{
2909					SendLargeRecords: true,
2910				},
2911			},
2912			messageLen:         maxPlaintext + 1,
2913			shouldFail:         true,
2914			expectedError:      ":DATA_LENGTH_TOO_LONG:",
2915			expectedLocalError: "remote error: record overflow",
2916		},
2917		{
2918			protocol: dtls,
2919			name:     "LargePlaintext-DTLS",
2920			config: Config{
2921				Bugs: ProtocolBugs{
2922					SendLargeRecords: true,
2923				},
2924			},
2925			messageLen:         maxPlaintext + 1,
2926			shouldFail:         true,
2927			expectedError:      ":DATA_LENGTH_TOO_LONG:",
2928			expectedLocalError: "remote error: record overflow",
2929		},
2930		{
2931			name: "LargePlaintext-TLS13-Padded-8192-8192",
2932			config: Config{
2933				MinVersion: VersionTLS13,
2934				MaxVersion: VersionTLS13,
2935				Bugs: ProtocolBugs{
2936					RecordPadding:    8192,
2937					SendLargeRecords: true,
2938				},
2939			},
2940			messageLen: 8192,
2941		},
2942		{
2943			name: "LargePlaintext-TLS13-Padded-8193-8192",
2944			config: Config{
2945				MinVersion: VersionTLS13,
2946				MaxVersion: VersionTLS13,
2947				Bugs: ProtocolBugs{
2948					RecordPadding:    8193,
2949					SendLargeRecords: true,
2950				},
2951			},
2952			messageLen:         8192,
2953			shouldFail:         true,
2954			expectedError:      ":DATA_LENGTH_TOO_LONG:",
2955			expectedLocalError: "remote error: record overflow",
2956		},
2957		{
2958			name: "LargePlaintext-TLS13-Padded-16383-1",
2959			config: Config{
2960				MinVersion: VersionTLS13,
2961				MaxVersion: VersionTLS13,
2962				Bugs: ProtocolBugs{
2963					RecordPadding:    1,
2964					SendLargeRecords: true,
2965				},
2966			},
2967			messageLen: 16383,
2968		},
2969		{
2970			name: "LargePlaintext-TLS13-Padded-16384-1",
2971			config: Config{
2972				MinVersion: VersionTLS13,
2973				MaxVersion: VersionTLS13,
2974				Bugs: ProtocolBugs{
2975					RecordPadding:    1,
2976					SendLargeRecords: true,
2977				},
2978			},
2979			messageLen:         16384,
2980			shouldFail:         true,
2981			expectedError:      ":DATA_LENGTH_TOO_LONG:",
2982			expectedLocalError: "remote error: record overflow",
2983		},
2984		{
2985			name: "LargeCiphertext",
2986			config: Config{
2987				Bugs: ProtocolBugs{
2988					SendLargeRecords: true,
2989				},
2990			},
2991			messageLen:    maxPlaintext * 2,
2992			shouldFail:    true,
2993			expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:",
2994		},
2995		{
2996			protocol: dtls,
2997			name:     "LargeCiphertext-DTLS",
2998			config: Config{
2999				Bugs: ProtocolBugs{
3000					SendLargeRecords: true,
3001				},
3002			},
3003			messageLen: maxPlaintext * 2,
3004			// Unlike the other four cases, DTLS drops records which
3005			// are invalid before authentication, so the connection
3006			// does not fail.
3007			expectMessageDropped: true,
3008		},
3009		{
3010			name:        "BadHelloRequest-1",
3011			renegotiate: 1,
3012			config: Config{
3013				MaxVersion: VersionTLS12,
3014				Bugs: ProtocolBugs{
3015					BadHelloRequest: []byte{typeHelloRequest, 0, 0, 1, 1},
3016				},
3017			},
3018			flags: []string{
3019				"-renegotiate-freely",
3020				"-expect-total-renegotiations", "1",
3021			},
3022			shouldFail:    true,
3023			expectedError: ":BAD_HELLO_REQUEST:",
3024		},
3025		{
3026			name:        "BadHelloRequest-2",
3027			renegotiate: 1,
3028			config: Config{
3029				MaxVersion: VersionTLS12,
3030				Bugs: ProtocolBugs{
3031					BadHelloRequest: []byte{typeServerKeyExchange, 0, 0, 0},
3032				},
3033			},
3034			flags: []string{
3035				"-renegotiate-freely",
3036				"-expect-total-renegotiations", "1",
3037			},
3038			shouldFail:    true,
3039			expectedError: ":BAD_HELLO_REQUEST:",
3040		},
3041		{
3042			testType: serverTest,
3043			name:     "SupportTicketsWithSessionID",
3044			config: Config{
3045				MaxVersion:             VersionTLS12,
3046				SessionTicketsDisabled: true,
3047			},
3048			resumeConfig: &Config{
3049				MaxVersion: VersionTLS12,
3050			},
3051			resumeSession: true,
3052		},
3053		{
3054			protocol: dtls,
3055			name:     "DTLS-SendExtraFinished",
3056			config: Config{
3057				Bugs: ProtocolBugs{
3058					SendExtraFinished: true,
3059				},
3060			},
3061			shouldFail:    true,
3062			expectedError: ":UNEXPECTED_RECORD:",
3063		},
3064		{
3065			protocol: dtls,
3066			name:     "DTLS-SendExtraFinished-Reordered",
3067			config: Config{
3068				Bugs: ProtocolBugs{
3069					MaxHandshakeRecordLength:  2,
3070					ReorderHandshakeFragments: true,
3071					SendExtraFinished:         true,
3072				},
3073			},
3074			shouldFail:    true,
3075			expectedError: ":UNEXPECTED_RECORD:",
3076		},
3077		{
3078			testType: serverTest,
3079			name:     "V2ClientHello-EmptyRecordPrefix",
3080			config: Config{
3081				// Choose a cipher suite that does not involve
3082				// elliptic curves, so no extensions are
3083				// involved.
3084				MaxVersion:   VersionTLS12,
3085				CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
3086				Bugs: ProtocolBugs{
3087					SendV2ClientHello: true,
3088				},
3089			},
3090			sendPrefix: string([]byte{
3091				byte(recordTypeHandshake),
3092				3, 1, // version
3093				0, 0, // length
3094			}),
3095			// A no-op empty record may not be sent before V2ClientHello.
3096			shouldFail:    true,
3097			expectedError: ":WRONG_VERSION_NUMBER:",
3098		},
3099		{
3100			testType: serverTest,
3101			name:     "V2ClientHello-WarningAlertPrefix",
3102			config: Config{
3103				// Choose a cipher suite that does not involve
3104				// elliptic curves, so no extensions are
3105				// involved.
3106				MaxVersion:   VersionTLS12,
3107				CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
3108				Bugs: ProtocolBugs{
3109					SendV2ClientHello: true,
3110				},
3111			},
3112			sendPrefix: string([]byte{
3113				byte(recordTypeAlert),
3114				3, 1, // version
3115				0, 2, // length
3116				alertLevelWarning, byte(alertDecompressionFailure),
3117			}),
3118			// A no-op warning alert may not be sent before V2ClientHello.
3119			shouldFail:    true,
3120			expectedError: ":WRONG_VERSION_NUMBER:",
3121		},
3122		{
3123			name: "KeyUpdate-ToClient",
3124			config: Config{
3125				MaxVersion: VersionTLS13,
3126			},
3127			sendKeyUpdates:   1,
3128			keyUpdateRequest: keyUpdateNotRequested,
3129		},
3130		{
3131			testType: serverTest,
3132			name:     "KeyUpdate-ToServer",
3133			config: Config{
3134				MaxVersion: VersionTLS13,
3135			},
3136			sendKeyUpdates:   1,
3137			keyUpdateRequest: keyUpdateNotRequested,
3138		},
3139		{
3140			name: "KeyUpdate-FromClient",
3141			config: Config{
3142				MaxVersion: VersionTLS13,
3143			},
3144			expectUnsolicitedKeyUpdate: true,
3145			flags:                      []string{"-key-update"},
3146		},
3147		{
3148			testType: serverTest,
3149			name:     "KeyUpdate-FromServer",
3150			config: Config{
3151				MaxVersion: VersionTLS13,
3152			},
3153			expectUnsolicitedKeyUpdate: true,
3154			flags:                      []string{"-key-update"},
3155		},
3156		{
3157			name: "KeyUpdate-InvalidRequestMode",
3158			config: Config{
3159				MaxVersion: VersionTLS13,
3160			},
3161			sendKeyUpdates:   1,
3162			keyUpdateRequest: 42,
3163			shouldFail:       true,
3164			expectedError:    ":DECODE_ERROR:",
3165		},
3166		{
3167			// Test that KeyUpdates are acknowledged properly.
3168			name: "KeyUpdate-RequestACK",
3169			config: Config{
3170				MaxVersion: VersionTLS13,
3171				Bugs: ProtocolBugs{
3172					RejectUnsolicitedKeyUpdate: true,
3173				},
3174			},
3175			// Test the shim receiving many KeyUpdates in a row.
3176			sendKeyUpdates:   5,
3177			messageCount:     5,
3178			keyUpdateRequest: keyUpdateRequested,
3179		},
3180		{
3181			// Test that KeyUpdates are acknowledged properly if the
3182			// peer's KeyUpdate is discovered while a write is
3183			// pending.
3184			name: "KeyUpdate-RequestACK-UnfinishedWrite",
3185			config: Config{
3186				MaxVersion: VersionTLS13,
3187				Bugs: ProtocolBugs{
3188					RejectUnsolicitedKeyUpdate: true,
3189				},
3190			},
3191			// Test the shim receiving many KeyUpdates in a row.
3192			sendKeyUpdates:          5,
3193			messageCount:            5,
3194			keyUpdateRequest:        keyUpdateRequested,
3195			readWithUnfinishedWrite: true,
3196			flags:                   []string{"-async"},
3197		},
3198		{
3199			name: "SendSNIWarningAlert",
3200			config: Config{
3201				MaxVersion: VersionTLS12,
3202				Bugs: ProtocolBugs{
3203					SendSNIWarningAlert: true,
3204				},
3205			},
3206		},
3207		{
3208			testType: serverTest,
3209			name:     "ExtraCompressionMethods-TLS12",
3210			config: Config{
3211				MaxVersion: VersionTLS12,
3212				Bugs: ProtocolBugs{
3213					SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6},
3214				},
3215			},
3216		},
3217		{
3218			testType: serverTest,
3219			name:     "ExtraCompressionMethods-TLS13",
3220			config: Config{
3221				MaxVersion: VersionTLS13,
3222				Bugs: ProtocolBugs{
3223					SendCompressionMethods: []byte{1, 2, 3, compressionNone, 4, 5, 6},
3224				},
3225			},
3226			shouldFail:         true,
3227			expectedError:      ":INVALID_COMPRESSION_LIST:",
3228			expectedLocalError: "remote error: illegal parameter",
3229		},
3230		{
3231			testType: serverTest,
3232			name:     "NoNullCompression-TLS12",
3233			config: Config{
3234				MaxVersion: VersionTLS12,
3235				Bugs: ProtocolBugs{
3236					SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6},
3237				},
3238			},
3239			shouldFail:         true,
3240			expectedError:      ":INVALID_COMPRESSION_LIST:",
3241			expectedLocalError: "remote error: illegal parameter",
3242		},
3243		{
3244			testType: serverTest,
3245			name:     "NoNullCompression-TLS13",
3246			config: Config{
3247				MaxVersion: VersionTLS13,
3248				Bugs: ProtocolBugs{
3249					SendCompressionMethods: []byte{1, 2, 3, 4, 5, 6},
3250				},
3251			},
3252			shouldFail:         true,
3253			expectedError:      ":INVALID_COMPRESSION_LIST:",
3254			expectedLocalError: "remote error: illegal parameter",
3255		},
3256		// Test that the client rejects invalid compression methods
3257		// from the server.
3258		{
3259			testType: clientTest,
3260			name:     "InvalidCompressionMethod",
3261			config: Config{
3262				MaxVersion: VersionTLS12,
3263				Bugs: ProtocolBugs{
3264					SendCompressionMethod: 1,
3265				},
3266			},
3267			shouldFail:         true,
3268			expectedError:      ":UNSUPPORTED_COMPRESSION_ALGORITHM:",
3269			expectedLocalError: "remote error: illegal parameter",
3270		},
3271		{
3272			testType: clientTest,
3273			name:     "TLS13-InvalidCompressionMethod",
3274			config: Config{
3275				MaxVersion: VersionTLS13,
3276				Bugs: ProtocolBugs{
3277					SendCompressionMethod: 1,
3278				},
3279			},
3280			shouldFail:    true,
3281			expectedError: ":DECODE_ERROR:",
3282		},
3283		{
3284			testType: clientTest,
3285			name:     "TLS13-HRR-InvalidCompressionMethod",
3286			config: Config{
3287				MaxVersion:       VersionTLS13,
3288				CurvePreferences: []CurveID{CurveP384},
3289				Bugs: ProtocolBugs{
3290					SendCompressionMethod: 1,
3291				},
3292			},
3293			shouldFail:         true,
3294			expectedError:      ":DECODE_ERROR:",
3295			expectedLocalError: "remote error: error decoding message",
3296		},
3297		{
3298			name: "GREASE-Client-TLS12",
3299			config: Config{
3300				MaxVersion: VersionTLS12,
3301				Bugs: ProtocolBugs{
3302					ExpectGREASE: true,
3303				},
3304			},
3305			flags: []string{"-enable-grease"},
3306		},
3307		{
3308			name: "GREASE-Client-TLS13",
3309			config: Config{
3310				MaxVersion: VersionTLS13,
3311				Bugs: ProtocolBugs{
3312					ExpectGREASE: true,
3313				},
3314			},
3315			flags: []string{"-enable-grease"},
3316		},
3317		{
3318			testType: serverTest,
3319			name:     "GREASE-Server-TLS13",
3320			config: Config{
3321				MaxVersion: VersionTLS13,
3322				Bugs: ProtocolBugs{
3323					// TLS 1.3 servers are expected to
3324					// always enable GREASE. TLS 1.3 is new,
3325					// so there is no existing ecosystem to
3326					// worry about.
3327					ExpectGREASE: true,
3328				},
3329			},
3330		},
3331		{
3332			// Test the TLS 1.2 server so there is a large
3333			// unencrypted certificate as well as application data.
3334			testType: serverTest,
3335			name:     "MaxSendFragment-TLS12",
3336			config: Config{
3337				MaxVersion: VersionTLS12,
3338				Bugs: ProtocolBugs{
3339					MaxReceivePlaintext: 512,
3340				},
3341			},
3342			messageLen: 1024,
3343			flags: []string{
3344				"-max-send-fragment", "512",
3345				"-read-size", "1024",
3346			},
3347		},
3348		{
3349			// Test the TLS 1.2 server so there is a large
3350			// unencrypted certificate as well as application data.
3351			testType: serverTest,
3352			name:     "MaxSendFragment-TLS12-TooLarge",
3353			config: Config{
3354				MaxVersion: VersionTLS12,
3355				Bugs: ProtocolBugs{
3356					// Ensure that some of the records are
3357					// 512.
3358					MaxReceivePlaintext: 511,
3359				},
3360			},
3361			messageLen: 1024,
3362			flags: []string{
3363				"-max-send-fragment", "512",
3364				"-read-size", "1024",
3365			},
3366			shouldFail:         true,
3367			expectedLocalError: "local error: record overflow",
3368		},
3369		{
3370			// Test the TLS 1.3 server so there is a large encrypted
3371			// certificate as well as application data.
3372			testType: serverTest,
3373			name:     "MaxSendFragment-TLS13",
3374			config: Config{
3375				MaxVersion: VersionTLS13,
3376				Bugs: ProtocolBugs{
3377					MaxReceivePlaintext:            512,
3378					ExpectPackedEncryptedHandshake: 512,
3379				},
3380			},
3381			messageLen: 1024,
3382			flags: []string{
3383				"-max-send-fragment", "512",
3384				"-read-size", "1024",
3385			},
3386		},
3387		{
3388			// Test the TLS 1.3 server so there is a large encrypted
3389			// certificate as well as application data.
3390			testType: serverTest,
3391			name:     "MaxSendFragment-TLS13-TooLarge",
3392			config: Config{
3393				MaxVersion: VersionTLS13,
3394				Bugs: ProtocolBugs{
3395					// Ensure that some of the records are
3396					// 512.
3397					MaxReceivePlaintext: 511,
3398				},
3399			},
3400			messageLen: 1024,
3401			flags: []string{
3402				"-max-send-fragment", "512",
3403				"-read-size", "1024",
3404			},
3405			shouldFail:         true,
3406			expectedLocalError: "local error: record overflow",
3407		},
3408		{
3409			// Test that handshake data is tightly packed in TLS 1.3.
3410			testType: serverTest,
3411			name:     "PackedEncryptedHandshake-TLS13",
3412			config: Config{
3413				MaxVersion: VersionTLS13,
3414				Bugs: ProtocolBugs{
3415					ExpectPackedEncryptedHandshake: 16384,
3416				},
3417			},
3418		},
3419		{
3420			// Test that DTLS can handle multiple application data
3421			// records in a single packet.
3422			protocol: dtls,
3423			name:     "SplitAndPackAppData-DTLS",
3424			config: Config{
3425				Bugs: ProtocolBugs{
3426					SplitAndPackAppData: true,
3427				},
3428			},
3429		},
3430		{
3431			protocol: dtls,
3432			name:     "SplitAndPackAppData-DTLS-Async",
3433			config: Config{
3434				Bugs: ProtocolBugs{
3435					SplitAndPackAppData: true,
3436				},
3437			},
3438			flags: []string{"-async"},
3439		},
3440	}
3441	testCases = append(testCases, basicTests...)
3442
3443	// Test that very large messages can be received.
3444	cert := rsaCertificate
3445	for i := 0; i < 50; i++ {
3446		cert.Certificate = append(cert.Certificate, cert.Certificate[0])
3447	}
3448	testCases = append(testCases, testCase{
3449		name: "LargeMessage",
3450		config: Config{
3451			Certificates: []Certificate{cert},
3452		},
3453	})
3454	testCases = append(testCases, testCase{
3455		protocol: dtls,
3456		name:     "LargeMessage-DTLS",
3457		config: Config{
3458			Certificates: []Certificate{cert},
3459		},
3460	})
3461
3462	// They are rejected if the maximum certificate chain length is capped.
3463	testCases = append(testCases, testCase{
3464		name: "LargeMessage-Reject",
3465		config: Config{
3466			Certificates: []Certificate{cert},
3467		},
3468		flags:         []string{"-max-cert-list", "16384"},
3469		shouldFail:    true,
3470		expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
3471	})
3472	testCases = append(testCases, testCase{
3473		protocol: dtls,
3474		name:     "LargeMessage-Reject-DTLS",
3475		config: Config{
3476			Certificates: []Certificate{cert},
3477		},
3478		flags:         []string{"-max-cert-list", "16384"},
3479		shouldFail:    true,
3480		expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
3481	})
3482
3483	// Servers echoing the TLS 1.3 compatibility mode session ID should be
3484	// rejected.
3485	testCases = append(testCases, testCase{
3486		name: "EchoTLS13CompatibilitySessionID",
3487		config: Config{
3488			MaxVersion: VersionTLS12,
3489			Bugs: ProtocolBugs{
3490				EchoSessionIDInFullHandshake: true,
3491			},
3492		},
3493		shouldFail:         true,
3494		expectedError:      ":SERVER_ECHOED_INVALID_SESSION_ID:",
3495		expectedLocalError: "remote error: illegal parameter",
3496	})
3497
3498	// Servers should reject QUIC client hellos that have a legacy
3499	// session ID.
3500	testCases = append(testCases, testCase{
3501		name:     "QUICCompatibilityMode",
3502		testType: serverTest,
3503		protocol: quic,
3504		config: Config{
3505			MinVersion: VersionTLS13,
3506			Bugs: ProtocolBugs{
3507				CompatModeWithQUIC: true,
3508			},
3509		},
3510		shouldFail:    true,
3511		expectedError: ":UNEXPECTED_COMPATIBILITY_MODE:",
3512	})
3513}
3514
3515func addTestForCipherSuite(suite testCipherSuite, ver tlsVersion, protocol protocol) {
3516	const psk = "12345"
3517	const pskIdentity = "luggage combo"
3518
3519	if !ver.supportsProtocol(protocol) {
3520		return
3521	}
3522	prefix := protocol.String() + "-"
3523
3524	var cert Certificate
3525	var certFile string
3526	var keyFile string
3527	if hasComponent(suite.name, "ECDSA") {
3528		cert = ecdsaP256Certificate
3529		certFile = ecdsaP256CertificateFile
3530		keyFile = ecdsaP256KeyFile
3531	} else {
3532		cert = rsaCertificate
3533		certFile = rsaCertificateFile
3534		keyFile = rsaKeyFile
3535	}
3536
3537	var flags []string
3538	if hasComponent(suite.name, "PSK") {
3539		flags = append(flags,
3540			"-psk", psk,
3541			"-psk-identity", pskIdentity)
3542	}
3543	if hasComponent(suite.name, "NULL") {
3544		// NULL ciphers must be explicitly enabled.
3545		flags = append(flags, "-cipher", "DEFAULT:NULL-SHA")
3546	}
3547
3548	var shouldFail bool
3549	if isTLS12Only(suite.name) && ver.version < VersionTLS12 {
3550		shouldFail = true
3551	}
3552	if !isTLS13Suite(suite.name) && ver.version >= VersionTLS13 {
3553		shouldFail = true
3554	}
3555	if isTLS13Suite(suite.name) && ver.version < VersionTLS13 {
3556		shouldFail = true
3557	}
3558
3559	var sendCipherSuite uint16
3560	var expectedServerError, expectedClientError string
3561	serverCipherSuites := []uint16{suite.id}
3562	if shouldFail {
3563		expectedServerError = ":NO_SHARED_CIPHER:"
3564		expectedClientError = ":WRONG_CIPHER_RETURNED:"
3565		// Configure the server to select ciphers as normal but
3566		// select an incompatible cipher in ServerHello.
3567		serverCipherSuites = nil
3568		sendCipherSuite = suite.id
3569	}
3570
3571	// Verify exporters interoperate.
3572	exportKeyingMaterial := 1024
3573
3574	testCases = append(testCases, testCase{
3575		testType: serverTest,
3576		protocol: protocol,
3577		name:     prefix + ver.name + "-" + suite.name + "-server",
3578		config: Config{
3579			MinVersion:           ver.version,
3580			MaxVersion:           ver.version,
3581			CipherSuites:         []uint16{suite.id},
3582			Certificates:         []Certificate{cert},
3583			PreSharedKey:         []byte(psk),
3584			PreSharedKeyIdentity: pskIdentity,
3585			Bugs: ProtocolBugs{
3586				AdvertiseAllConfiguredCiphers: true,
3587			},
3588		},
3589		certFile:             certFile,
3590		keyFile:              keyFile,
3591		flags:                flags,
3592		resumeSession:        true,
3593		shouldFail:           shouldFail,
3594		expectedError:        expectedServerError,
3595		exportKeyingMaterial: exportKeyingMaterial,
3596	})
3597
3598	testCases = append(testCases, testCase{
3599		testType: clientTest,
3600		protocol: protocol,
3601		name:     prefix + ver.name + "-" + suite.name + "-client",
3602		config: Config{
3603			MinVersion:           ver.version,
3604			MaxVersion:           ver.version,
3605			CipherSuites:         serverCipherSuites,
3606			Certificates:         []Certificate{cert},
3607			PreSharedKey:         []byte(psk),
3608			PreSharedKeyIdentity: pskIdentity,
3609			Bugs: ProtocolBugs{
3610				IgnorePeerCipherPreferences: shouldFail,
3611				SendCipherSuite:             sendCipherSuite,
3612			},
3613		},
3614		flags:                flags,
3615		resumeSession:        true,
3616		shouldFail:           shouldFail,
3617		expectedError:        expectedClientError,
3618		exportKeyingMaterial: exportKeyingMaterial,
3619	})
3620
3621	if shouldFail {
3622		return
3623	}
3624
3625	// Ensure the maximum record size is accepted.
3626	testCases = append(testCases, testCase{
3627		protocol: protocol,
3628		name:     prefix + ver.name + "-" + suite.name + "-LargeRecord",
3629		config: Config{
3630			MinVersion:           ver.version,
3631			MaxVersion:           ver.version,
3632			CipherSuites:         []uint16{suite.id},
3633			Certificates:         []Certificate{cert},
3634			PreSharedKey:         []byte(psk),
3635			PreSharedKeyIdentity: pskIdentity,
3636		},
3637		flags:      flags,
3638		messageLen: maxPlaintext,
3639	})
3640
3641	// Test bad records for all ciphers. Bad records are fatal in TLS
3642	// and ignored in DTLS.
3643	shouldFail = protocol == tls
3644	var expectedError string
3645	if shouldFail {
3646		expectedError = ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:"
3647	}
3648
3649	// When QUIC is used, the QUIC stack handles record encryption/decryption.
3650	// Thus it is not possible for the TLS stack in QUIC mode to receive a
3651	// bad record (i.e. one that fails to decrypt).
3652	if protocol != quic {
3653		testCases = append(testCases, testCase{
3654			protocol: protocol,
3655			name:     prefix + ver.name + "-" + suite.name + "-BadRecord",
3656			config: Config{
3657				MinVersion:           ver.version,
3658				MaxVersion:           ver.version,
3659				CipherSuites:         []uint16{suite.id},
3660				Certificates:         []Certificate{cert},
3661				PreSharedKey:         []byte(psk),
3662				PreSharedKeyIdentity: pskIdentity,
3663			},
3664			flags:            flags,
3665			damageFirstWrite: true,
3666			messageLen:       maxPlaintext,
3667			shouldFail:       shouldFail,
3668			expectedError:    expectedError,
3669		})
3670	}
3671}
3672
3673func addCipherSuiteTests() {
3674	const bogusCipher = 0xfe00
3675
3676	for _, suite := range testCipherSuites {
3677		for _, ver := range tlsVersions {
3678			for _, protocol := range []protocol{tls, dtls, quic} {
3679				addTestForCipherSuite(suite, ver, protocol)
3680			}
3681		}
3682	}
3683
3684	testCases = append(testCases, testCase{
3685		name: "NoSharedCipher",
3686		config: Config{
3687			MaxVersion:   VersionTLS12,
3688			CipherSuites: []uint16{},
3689		},
3690		shouldFail:    true,
3691		expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
3692	})
3693
3694	testCases = append(testCases, testCase{
3695		name: "NoSharedCipher-TLS13",
3696		config: Config{
3697			MaxVersion:   VersionTLS13,
3698			CipherSuites: []uint16{},
3699		},
3700		shouldFail:    true,
3701		expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
3702	})
3703
3704	testCases = append(testCases, testCase{
3705		name: "UnsupportedCipherSuite",
3706		config: Config{
3707			MaxVersion:   VersionTLS12,
3708			CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
3709			Bugs: ProtocolBugs{
3710				IgnorePeerCipherPreferences: true,
3711			},
3712		},
3713		flags:         []string{"-cipher", "DEFAULT:!AES"},
3714		shouldFail:    true,
3715		expectedError: ":WRONG_CIPHER_RETURNED:",
3716	})
3717
3718	testCases = append(testCases, testCase{
3719		name: "ServerHelloBogusCipher",
3720		config: Config{
3721			MaxVersion: VersionTLS12,
3722			Bugs: ProtocolBugs{
3723				SendCipherSuite: bogusCipher,
3724			},
3725		},
3726		shouldFail:    true,
3727		expectedError: ":UNKNOWN_CIPHER_RETURNED:",
3728	})
3729	testCases = append(testCases, testCase{
3730		name: "ServerHelloBogusCipher-TLS13",
3731		config: Config{
3732			MaxVersion: VersionTLS13,
3733			Bugs: ProtocolBugs{
3734				SendCipherSuite: bogusCipher,
3735			},
3736		},
3737		shouldFail:    true,
3738		expectedError: ":WRONG_CIPHER_RETURNED:",
3739	})
3740
3741	// The server must be tolerant to bogus ciphers.
3742	testCases = append(testCases, testCase{
3743		testType: serverTest,
3744		name:     "UnknownCipher",
3745		config: Config{
3746			MaxVersion:   VersionTLS12,
3747			CipherSuites: []uint16{bogusCipher, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3748			Bugs: ProtocolBugs{
3749				AdvertiseAllConfiguredCiphers: true,
3750			},
3751		},
3752	})
3753
3754	// The server must be tolerant to bogus ciphers.
3755	testCases = append(testCases, testCase{
3756		testType: serverTest,
3757		name:     "UnknownCipher-TLS13",
3758		config: Config{
3759			MaxVersion:   VersionTLS13,
3760			CipherSuites: []uint16{bogusCipher, TLS_AES_128_GCM_SHA256},
3761			Bugs: ProtocolBugs{
3762				AdvertiseAllConfiguredCiphers: true,
3763			},
3764		},
3765	})
3766
3767	// Test empty ECDHE_PSK identity hints work as expected.
3768	testCases = append(testCases, testCase{
3769		name: "EmptyECDHEPSKHint",
3770		config: Config{
3771			MaxVersion:   VersionTLS12,
3772			CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
3773			PreSharedKey: []byte("secret"),
3774		},
3775		flags: []string{"-psk", "secret"},
3776	})
3777
3778	// Test empty PSK identity hints work as expected, even if an explicit
3779	// ServerKeyExchange is sent.
3780	testCases = append(testCases, testCase{
3781		name: "ExplicitEmptyPSKHint",
3782		config: Config{
3783			MaxVersion:   VersionTLS12,
3784			CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
3785			PreSharedKey: []byte("secret"),
3786			Bugs: ProtocolBugs{
3787				AlwaysSendPreSharedKeyIdentityHint: true,
3788			},
3789		},
3790		flags: []string{"-psk", "secret"},
3791	})
3792
3793	// Test that clients enforce that the server-sent certificate and cipher
3794	// suite match in TLS 1.2.
3795	testCases = append(testCases, testCase{
3796		name: "CertificateCipherMismatch-RSA",
3797		config: Config{
3798			MaxVersion:   VersionTLS12,
3799			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3800			Certificates: []Certificate{rsaCertificate},
3801			Bugs: ProtocolBugs{
3802				SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
3803			},
3804		},
3805		shouldFail:    true,
3806		expectedError: ":WRONG_CERTIFICATE_TYPE:",
3807	})
3808	testCases = append(testCases, testCase{
3809		name: "CertificateCipherMismatch-ECDSA",
3810		config: Config{
3811			MaxVersion:   VersionTLS12,
3812			CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
3813			Certificates: []Certificate{ecdsaP256Certificate},
3814			Bugs: ProtocolBugs{
3815				SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
3816			},
3817		},
3818		shouldFail:    true,
3819		expectedError: ":WRONG_CERTIFICATE_TYPE:",
3820	})
3821	testCases = append(testCases, testCase{
3822		name: "CertificateCipherMismatch-Ed25519",
3823		config: Config{
3824			MaxVersion:   VersionTLS12,
3825			CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
3826			Certificates: []Certificate{ed25519Certificate},
3827			Bugs: ProtocolBugs{
3828				SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
3829			},
3830		},
3831		shouldFail:    true,
3832		expectedError: ":WRONG_CERTIFICATE_TYPE:",
3833	})
3834
3835	// Test that servers decline to select a cipher suite which is
3836	// inconsistent with their configured certificate.
3837	testCases = append(testCases, testCase{
3838		testType: serverTest,
3839		name:     "ServerCipherFilter-RSA",
3840		config: Config{
3841			MaxVersion:   VersionTLS12,
3842			CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
3843		},
3844		flags: []string{
3845			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
3846			"-key-file", path.Join(*resourceDir, rsaKeyFile),
3847		},
3848		shouldFail:    true,
3849		expectedError: ":NO_SHARED_CIPHER:",
3850	})
3851	testCases = append(testCases, testCase{
3852		testType: serverTest,
3853		name:     "ServerCipherFilter-ECDSA",
3854		config: Config{
3855			MaxVersion:   VersionTLS12,
3856			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3857		},
3858		flags: []string{
3859			"-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
3860			"-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
3861		},
3862		shouldFail:    true,
3863		expectedError: ":NO_SHARED_CIPHER:",
3864	})
3865	testCases = append(testCases, testCase{
3866		testType: serverTest,
3867		name:     "ServerCipherFilter-Ed25519",
3868		config: Config{
3869			MaxVersion:   VersionTLS12,
3870			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
3871		},
3872		flags: []string{
3873			"-cert-file", path.Join(*resourceDir, ed25519CertificateFile),
3874			"-key-file", path.Join(*resourceDir, ed25519KeyFile),
3875		},
3876		shouldFail:    true,
3877		expectedError: ":NO_SHARED_CIPHER:",
3878	})
3879
3880	// Test cipher suite negotiation works as expected. Configure a
3881	// complicated cipher suite configuration.
3882	const negotiationTestCiphers = "" +
3883		"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:" +
3884		"[TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384|TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256|TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]:" +
3885		"TLS_RSA_WITH_AES_128_GCM_SHA256:" +
3886		"TLS_RSA_WITH_AES_128_CBC_SHA:" +
3887		"[TLS_RSA_WITH_AES_256_GCM_SHA384|TLS_RSA_WITH_AES_256_CBC_SHA]"
3888	negotiationTests := []struct {
3889		ciphers  []uint16
3890		expected uint16
3891	}{
3892		// Server preferences are honored, including when
3893		// equipreference groups are involved.
3894		{
3895			[]uint16{
3896				TLS_RSA_WITH_AES_256_GCM_SHA384,
3897				TLS_RSA_WITH_AES_128_CBC_SHA,
3898				TLS_RSA_WITH_AES_128_GCM_SHA256,
3899				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
3900				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
3901			},
3902			TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
3903		},
3904		{
3905			[]uint16{
3906				TLS_RSA_WITH_AES_256_GCM_SHA384,
3907				TLS_RSA_WITH_AES_128_CBC_SHA,
3908				TLS_RSA_WITH_AES_128_GCM_SHA256,
3909				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
3910			},
3911			TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
3912		},
3913		{
3914			[]uint16{
3915				TLS_RSA_WITH_AES_256_GCM_SHA384,
3916				TLS_RSA_WITH_AES_128_CBC_SHA,
3917				TLS_RSA_WITH_AES_128_GCM_SHA256,
3918			},
3919			TLS_RSA_WITH_AES_128_GCM_SHA256,
3920		},
3921		{
3922			[]uint16{
3923				TLS_RSA_WITH_AES_256_GCM_SHA384,
3924				TLS_RSA_WITH_AES_128_CBC_SHA,
3925			},
3926			TLS_RSA_WITH_AES_128_CBC_SHA,
3927		},
3928		// Equipreference groups use the client preference.
3929		{
3930			[]uint16{
3931				TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
3932				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
3933				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
3934			},
3935			TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
3936		},
3937		{
3938			[]uint16{
3939				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
3940				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
3941			},
3942			TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
3943		},
3944		{
3945			[]uint16{
3946				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
3947				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
3948			},
3949			TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
3950		},
3951		{
3952			[]uint16{
3953				TLS_RSA_WITH_AES_256_GCM_SHA384,
3954				TLS_RSA_WITH_AES_256_CBC_SHA,
3955			},
3956			TLS_RSA_WITH_AES_256_GCM_SHA384,
3957		},
3958		{
3959			[]uint16{
3960				TLS_RSA_WITH_AES_256_CBC_SHA,
3961				TLS_RSA_WITH_AES_256_GCM_SHA384,
3962			},
3963			TLS_RSA_WITH_AES_256_CBC_SHA,
3964		},
3965		// If there are two equipreference groups, the preferred one
3966		// takes precedence.
3967		{
3968			[]uint16{
3969				TLS_RSA_WITH_AES_256_GCM_SHA384,
3970				TLS_RSA_WITH_AES_256_CBC_SHA,
3971				TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
3972				TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
3973			},
3974			TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
3975		},
3976	}
3977	for i, t := range negotiationTests {
3978		testCases = append(testCases, testCase{
3979			testType: serverTest,
3980			name:     "CipherNegotiation-" + strconv.Itoa(i),
3981			config: Config{
3982				MaxVersion:   VersionTLS12,
3983				CipherSuites: t.ciphers,
3984			},
3985			flags: []string{"-cipher", negotiationTestCiphers},
3986			expectations: connectionExpectations{
3987				cipher: t.expected,
3988			},
3989		})
3990	}
3991}
3992
3993func addBadECDSASignatureTests() {
3994	for badR := BadValue(1); badR < NumBadValues; badR++ {
3995		for badS := BadValue(1); badS < NumBadValues; badS++ {
3996			testCases = append(testCases, testCase{
3997				name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS),
3998				config: Config{
3999					MaxVersion:   VersionTLS12,
4000					CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
4001					Certificates: []Certificate{ecdsaP256Certificate},
4002					Bugs: ProtocolBugs{
4003						BadECDSAR: badR,
4004						BadECDSAS: badS,
4005					},
4006				},
4007				shouldFail:    true,
4008				expectedError: ":BAD_SIGNATURE:",
4009			})
4010			testCases = append(testCases, testCase{
4011				name: fmt.Sprintf("BadECDSA-%d-%d-TLS13", badR, badS),
4012				config: Config{
4013					MaxVersion:   VersionTLS13,
4014					Certificates: []Certificate{ecdsaP256Certificate},
4015					Bugs: ProtocolBugs{
4016						BadECDSAR: badR,
4017						BadECDSAS: badS,
4018					},
4019				},
4020				shouldFail:    true,
4021				expectedError: ":BAD_SIGNATURE:",
4022			})
4023		}
4024	}
4025}
4026
4027func addCBCPaddingTests() {
4028	testCases = append(testCases, testCase{
4029		name: "MaxCBCPadding",
4030		config: Config{
4031			MaxVersion:   VersionTLS12,
4032			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
4033			Bugs: ProtocolBugs{
4034				MaxPadding: true,
4035			},
4036		},
4037		messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
4038	})
4039	testCases = append(testCases, testCase{
4040		name: "BadCBCPadding",
4041		config: Config{
4042			MaxVersion:   VersionTLS12,
4043			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
4044			Bugs: ProtocolBugs{
4045				PaddingFirstByteBad: true,
4046			},
4047		},
4048		shouldFail:    true,
4049		expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
4050	})
4051	// OpenSSL previously had an issue where the first byte of padding in
4052	// 255 bytes of padding wasn't checked.
4053	testCases = append(testCases, testCase{
4054		name: "BadCBCPadding255",
4055		config: Config{
4056			MaxVersion:   VersionTLS12,
4057			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
4058			Bugs: ProtocolBugs{
4059				MaxPadding:               true,
4060				PaddingFirstByteBadIf255: true,
4061			},
4062		},
4063		messageLen:    12, // 20 bytes of SHA-1 + 12 == 0 % block size
4064		shouldFail:    true,
4065		expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
4066	})
4067}
4068
4069func addCBCSplittingTests() {
4070	var cbcCiphers = []struct {
4071		name   string
4072		cipher uint16
4073	}{
4074		{"3DES", TLS_RSA_WITH_3DES_EDE_CBC_SHA},
4075		{"AES128", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
4076		{"AES256", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
4077	}
4078	for _, t := range cbcCiphers {
4079		testCases = append(testCases, testCase{
4080			name: "CBCRecordSplitting-" + t.name,
4081			config: Config{
4082				MaxVersion:   VersionTLS10,
4083				MinVersion:   VersionTLS10,
4084				CipherSuites: []uint16{t.cipher},
4085				Bugs: ProtocolBugs{
4086					ExpectRecordSplitting: true,
4087				},
4088			},
4089			messageLen:    -1, // read until EOF
4090			resumeSession: true,
4091			flags: []string{
4092				"-async",
4093				"-write-different-record-sizes",
4094				"-cbc-record-splitting",
4095			},
4096		})
4097		testCases = append(testCases, testCase{
4098			name: "CBCRecordSplittingPartialWrite-" + t.name,
4099			config: Config{
4100				MaxVersion:   VersionTLS10,
4101				MinVersion:   VersionTLS10,
4102				CipherSuites: []uint16{t.cipher},
4103				Bugs: ProtocolBugs{
4104					ExpectRecordSplitting: true,
4105				},
4106			},
4107			messageLen: -1, // read until EOF
4108			flags: []string{
4109				"-async",
4110				"-write-different-record-sizes",
4111				"-cbc-record-splitting",
4112				"-partial-write",
4113			},
4114		})
4115	}
4116}
4117
4118func addClientAuthTests() {
4119	// Add a dummy cert pool to stress certificate authority parsing.
4120	certPool := x509.NewCertPool()
4121	for _, cert := range []Certificate{rsaCertificate, rsa1024Certificate} {
4122		cert, err := x509.ParseCertificate(cert.Certificate[0])
4123		if err != nil {
4124			panic(err)
4125		}
4126		certPool.AddCert(cert)
4127	}
4128	caNames := certPool.Subjects()
4129
4130	for _, ver := range tlsVersions {
4131		testCases = append(testCases, testCase{
4132			testType: clientTest,
4133			name:     ver.name + "-Client-ClientAuth-RSA",
4134			config: Config{
4135				MinVersion: ver.version,
4136				MaxVersion: ver.version,
4137				ClientAuth: RequireAnyClientCert,
4138				ClientCAs:  certPool,
4139			},
4140			flags: []string{
4141				"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4142				"-key-file", path.Join(*resourceDir, rsaKeyFile),
4143			},
4144		})
4145		testCases = append(testCases, testCase{
4146			testType: serverTest,
4147			name:     ver.name + "-Server-ClientAuth-RSA",
4148			config: Config{
4149				MinVersion:   ver.version,
4150				MaxVersion:   ver.version,
4151				Certificates: []Certificate{rsaCertificate},
4152			},
4153			flags: []string{"-require-any-client-certificate"},
4154		})
4155		testCases = append(testCases, testCase{
4156			testType: serverTest,
4157			name:     ver.name + "-Server-ClientAuth-ECDSA",
4158			config: Config{
4159				MinVersion:   ver.version,
4160				MaxVersion:   ver.version,
4161				Certificates: []Certificate{ecdsaP256Certificate},
4162			},
4163			flags: []string{"-require-any-client-certificate"},
4164		})
4165		testCases = append(testCases, testCase{
4166			testType: clientTest,
4167			name:     ver.name + "-Client-ClientAuth-ECDSA",
4168			config: Config{
4169				MinVersion: ver.version,
4170				MaxVersion: ver.version,
4171				ClientAuth: RequireAnyClientCert,
4172				ClientCAs:  certPool,
4173			},
4174			flags: []string{
4175				"-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
4176				"-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
4177			},
4178		})
4179
4180		testCases = append(testCases, testCase{
4181			name: "NoClientCertificate-" + ver.name,
4182			config: Config{
4183				MinVersion: ver.version,
4184				MaxVersion: ver.version,
4185				ClientAuth: RequireAnyClientCert,
4186			},
4187			shouldFail:         true,
4188			expectedLocalError: "client didn't provide a certificate",
4189		})
4190
4191		testCases = append(testCases, testCase{
4192			// Even if not configured to expect a certificate, OpenSSL will
4193			// return X509_V_OK as the verify_result.
4194			testType: serverTest,
4195			name:     "NoClientCertificateRequested-Server-" + ver.name,
4196			config: Config{
4197				MinVersion: ver.version,
4198				MaxVersion: ver.version,
4199			},
4200			flags: []string{
4201				"-expect-verify-result",
4202			},
4203			resumeSession: true,
4204		})
4205
4206		testCases = append(testCases, testCase{
4207			// If a client certificate is not provided, OpenSSL will still
4208			// return X509_V_OK as the verify_result.
4209			testType: serverTest,
4210			name:     "NoClientCertificate-Server-" + ver.name,
4211			config: Config{
4212				MinVersion: ver.version,
4213				MaxVersion: ver.version,
4214			},
4215			flags: []string{
4216				"-expect-verify-result",
4217				"-verify-peer",
4218			},
4219			resumeSession: true,
4220		})
4221
4222		certificateRequired := "remote error: certificate required"
4223		if ver.version < VersionTLS13 {
4224			// Prior to TLS 1.3, the generic handshake_failure alert
4225			// was used.
4226			certificateRequired = "remote error: handshake failure"
4227		}
4228		testCases = append(testCases, testCase{
4229			testType: serverTest,
4230			name:     "RequireAnyClientCertificate-" + ver.name,
4231			config: Config{
4232				MinVersion: ver.version,
4233				MaxVersion: ver.version,
4234			},
4235			flags:              []string{"-require-any-client-certificate"},
4236			shouldFail:         true,
4237			expectedError:      ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
4238			expectedLocalError: certificateRequired,
4239		})
4240
4241		testCases = append(testCases, testCase{
4242			testType: serverTest,
4243			name:     "SkipClientCertificate-" + ver.name,
4244			config: Config{
4245				MinVersion: ver.version,
4246				MaxVersion: ver.version,
4247				Bugs: ProtocolBugs{
4248					SkipClientCertificate: true,
4249				},
4250			},
4251			// Setting SSL_VERIFY_PEER allows anonymous clients.
4252			flags:         []string{"-verify-peer"},
4253			shouldFail:    true,
4254			expectedError: ":UNEXPECTED_MESSAGE:",
4255		})
4256
4257		testCases = append(testCases, testCase{
4258			testType: serverTest,
4259			name:     "VerifyPeerIfNoOBC-NoChannelID-" + ver.name,
4260			config: Config{
4261				MinVersion: ver.version,
4262				MaxVersion: ver.version,
4263			},
4264			flags: []string{
4265				"-enable-channel-id",
4266				"-verify-peer-if-no-obc",
4267			},
4268			shouldFail:         true,
4269			expectedError:      ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
4270			expectedLocalError: certificateRequired,
4271		})
4272
4273		testCases = append(testCases, testCase{
4274			testType: serverTest,
4275			name:     "VerifyPeerIfNoOBC-ChannelID-" + ver.name,
4276			config: Config{
4277				MinVersion: ver.version,
4278				MaxVersion: ver.version,
4279				ChannelID:  channelIDKey,
4280			},
4281			expectations: connectionExpectations{
4282				channelID: true,
4283			},
4284			flags: []string{
4285				"-enable-channel-id",
4286				"-verify-peer-if-no-obc",
4287			},
4288		})
4289
4290		testCases = append(testCases, testCase{
4291			testType: serverTest,
4292			name:     ver.name + "-Server-CertReq-CA-List",
4293			config: Config{
4294				MinVersion:   ver.version,
4295				MaxVersion:   ver.version,
4296				Certificates: []Certificate{rsaCertificate},
4297				Bugs: ProtocolBugs{
4298					ExpectCertificateReqNames: caNames,
4299				},
4300			},
4301			flags: []string{
4302				"-require-any-client-certificate",
4303				"-use-client-ca-list", encodeDERValues(caNames),
4304			},
4305		})
4306
4307		testCases = append(testCases, testCase{
4308			testType: clientTest,
4309			name:     ver.name + "-Client-CertReq-CA-List",
4310			config: Config{
4311				MinVersion:   ver.version,
4312				MaxVersion:   ver.version,
4313				Certificates: []Certificate{rsaCertificate},
4314				ClientAuth:   RequireAnyClientCert,
4315				ClientCAs:    certPool,
4316			},
4317			flags: []string{
4318				"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4319				"-key-file", path.Join(*resourceDir, rsaKeyFile),
4320				"-expect-client-ca-list", encodeDERValues(caNames),
4321			},
4322		})
4323	}
4324
4325	// Client auth is only legal in certificate-based ciphers.
4326	testCases = append(testCases, testCase{
4327		testType: clientTest,
4328		name:     "ClientAuth-PSK",
4329		config: Config{
4330			MaxVersion:   VersionTLS12,
4331			CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
4332			PreSharedKey: []byte("secret"),
4333			ClientAuth:   RequireAnyClientCert,
4334		},
4335		flags: []string{
4336			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4337			"-key-file", path.Join(*resourceDir, rsaKeyFile),
4338			"-psk", "secret",
4339		},
4340		shouldFail:    true,
4341		expectedError: ":UNEXPECTED_MESSAGE:",
4342	})
4343	testCases = append(testCases, testCase{
4344		testType: clientTest,
4345		name:     "ClientAuth-ECDHE_PSK",
4346		config: Config{
4347			MaxVersion:   VersionTLS12,
4348			CipherSuites: []uint16{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
4349			PreSharedKey: []byte("secret"),
4350			ClientAuth:   RequireAnyClientCert,
4351		},
4352		flags: []string{
4353			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4354			"-key-file", path.Join(*resourceDir, rsaKeyFile),
4355			"-psk", "secret",
4356		},
4357		shouldFail:    true,
4358		expectedError: ":UNEXPECTED_MESSAGE:",
4359	})
4360
4361	// Regression test for a bug where the client CA list, if explicitly
4362	// set to NULL, was mis-encoded.
4363	testCases = append(testCases, testCase{
4364		testType: serverTest,
4365		name:     "Null-Client-CA-List",
4366		config: Config{
4367			MaxVersion:   VersionTLS12,
4368			Certificates: []Certificate{rsaCertificate},
4369			Bugs: ProtocolBugs{
4370				ExpectCertificateReqNames: [][]byte{},
4371			},
4372		},
4373		flags: []string{
4374			"-require-any-client-certificate",
4375			"-use-client-ca-list", "<NULL>",
4376		},
4377	})
4378
4379	// Test that an empty client CA list doesn't send a CA extension.
4380	testCases = append(testCases, testCase{
4381		testType: serverTest,
4382		name:     "TLS13-Empty-Client-CA-List",
4383		config: Config{
4384			MaxVersion:   VersionTLS13,
4385			Certificates: []Certificate{rsaCertificate},
4386			Bugs: ProtocolBugs{
4387				ExpectNoCertificateAuthoritiesExtension: true,
4388			},
4389		},
4390		flags: []string{
4391			"-require-any-client-certificate",
4392			"-use-client-ca-list", "<EMPTY>",
4393		},
4394	})
4395
4396}
4397
4398func addExtendedMasterSecretTests() {
4399	const expectEMSFlag = "-expect-extended-master-secret"
4400
4401	for _, with := range []bool{false, true} {
4402		prefix := "No"
4403		if with {
4404			prefix = ""
4405		}
4406
4407		for _, isClient := range []bool{false, true} {
4408			suffix := "-Server"
4409			testType := serverTest
4410			if isClient {
4411				suffix = "-Client"
4412				testType = clientTest
4413			}
4414
4415			for _, ver := range tlsVersions {
4416				// In TLS 1.3, the extension is irrelevant and
4417				// always reports as enabled.
4418				var flags []string
4419				if with || ver.version >= VersionTLS13 {
4420					flags = []string{expectEMSFlag}
4421				}
4422
4423				testCases = append(testCases, testCase{
4424					testType: testType,
4425					name:     prefix + "ExtendedMasterSecret-" + ver.name + suffix,
4426					config: Config{
4427						MinVersion: ver.version,
4428						MaxVersion: ver.version,
4429						Bugs: ProtocolBugs{
4430							NoExtendedMasterSecret:      !with,
4431							RequireExtendedMasterSecret: with,
4432						},
4433					},
4434					flags: flags,
4435				})
4436			}
4437		}
4438	}
4439
4440	for _, isClient := range []bool{false, true} {
4441		for _, supportedInFirstConnection := range []bool{false, true} {
4442			for _, supportedInResumeConnection := range []bool{false, true} {
4443				boolToWord := func(b bool) string {
4444					if b {
4445						return "Yes"
4446					}
4447					return "No"
4448				}
4449				suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-"
4450				if isClient {
4451					suffix += "Client"
4452				} else {
4453					suffix += "Server"
4454				}
4455
4456				supportedConfig := Config{
4457					MaxVersion: VersionTLS12,
4458					Bugs: ProtocolBugs{
4459						RequireExtendedMasterSecret: true,
4460					},
4461				}
4462
4463				noSupportConfig := Config{
4464					MaxVersion: VersionTLS12,
4465					Bugs: ProtocolBugs{
4466						NoExtendedMasterSecret: true,
4467					},
4468				}
4469
4470				test := testCase{
4471					name:          "ExtendedMasterSecret-" + suffix,
4472					resumeSession: true,
4473				}
4474
4475				if !isClient {
4476					test.testType = serverTest
4477				}
4478
4479				if supportedInFirstConnection {
4480					test.config = supportedConfig
4481				} else {
4482					test.config = noSupportConfig
4483				}
4484
4485				if supportedInResumeConnection {
4486					test.resumeConfig = &supportedConfig
4487				} else {
4488					test.resumeConfig = &noSupportConfig
4489				}
4490
4491				switch suffix {
4492				case "YesToYes-Client", "YesToYes-Server":
4493					// When a session is resumed, it should
4494					// still be aware that its master
4495					// secret was generated via EMS and
4496					// thus it's safe to use tls-unique.
4497					test.flags = []string{expectEMSFlag}
4498				case "NoToYes-Server":
4499					// If an original connection did not
4500					// contain EMS, but a resumption
4501					// handshake does, then a server should
4502					// not resume the session.
4503					test.expectResumeRejected = true
4504				case "YesToNo-Server":
4505					// Resuming an EMS session without the
4506					// EMS extension should cause the
4507					// server to abort the connection.
4508					test.shouldFail = true
4509					test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
4510				case "NoToYes-Client":
4511					// A client should abort a connection
4512					// where the server resumed a non-EMS
4513					// session but echoed the EMS
4514					// extension.
4515					test.shouldFail = true
4516					test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:"
4517				case "YesToNo-Client":
4518					// A client should abort a connection
4519					// where the server didn't echo EMS
4520					// when the session used it.
4521					test.shouldFail = true
4522					test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
4523				}
4524
4525				testCases = append(testCases, test)
4526			}
4527		}
4528	}
4529
4530	// Switching EMS on renegotiation is forbidden.
4531	testCases = append(testCases, testCase{
4532		name: "ExtendedMasterSecret-Renego-NoEMS",
4533		config: Config{
4534			MaxVersion: VersionTLS12,
4535			Bugs: ProtocolBugs{
4536				NoExtendedMasterSecret:                true,
4537				NoExtendedMasterSecretOnRenegotiation: true,
4538			},
4539		},
4540		renegotiate: 1,
4541		flags: []string{
4542			"-renegotiate-freely",
4543			"-expect-total-renegotiations", "1",
4544		},
4545	})
4546
4547	testCases = append(testCases, testCase{
4548		name: "ExtendedMasterSecret-Renego-Upgrade",
4549		config: Config{
4550			MaxVersion: VersionTLS12,
4551			Bugs: ProtocolBugs{
4552				NoExtendedMasterSecret: true,
4553			},
4554		},
4555		renegotiate: 1,
4556		flags: []string{
4557			"-renegotiate-freely",
4558			"-expect-total-renegotiations", "1",
4559		},
4560		shouldFail:    true,
4561		expectedError: ":RENEGOTIATION_EMS_MISMATCH:",
4562	})
4563
4564	testCases = append(testCases, testCase{
4565		name: "ExtendedMasterSecret-Renego-Downgrade",
4566		config: Config{
4567			MaxVersion: VersionTLS12,
4568			Bugs: ProtocolBugs{
4569				NoExtendedMasterSecretOnRenegotiation: true,
4570			},
4571		},
4572		renegotiate: 1,
4573		flags: []string{
4574			"-renegotiate-freely",
4575			"-expect-total-renegotiations", "1",
4576		},
4577		shouldFail:    true,
4578		expectedError: ":RENEGOTIATION_EMS_MISMATCH:",
4579	})
4580}
4581
4582type stateMachineTestConfig struct {
4583	protocol          protocol
4584	async             bool
4585	splitHandshake    bool
4586	packHandshake     bool
4587	implicitHandshake bool
4588}
4589
4590// Adds tests that try to cover the range of the handshake state machine, under
4591// various conditions. Some of these are redundant with other tests, but they
4592// only cover the synchronous case.
4593func addAllStateMachineCoverageTests() {
4594	for _, async := range []bool{false, true} {
4595		for _, protocol := range []protocol{tls, dtls, quic} {
4596			addStateMachineCoverageTests(stateMachineTestConfig{
4597				protocol: protocol,
4598				async:    async,
4599			})
4600			// QUIC doesn't work with the implicit handshake API. Additionally,
4601			// splitting or packing handshake records is meaningless in QUIC.
4602			if protocol != quic {
4603				addStateMachineCoverageTests(stateMachineTestConfig{
4604					protocol:          protocol,
4605					async:             async,
4606					implicitHandshake: true,
4607				})
4608				addStateMachineCoverageTests(stateMachineTestConfig{
4609					protocol:       protocol,
4610					async:          async,
4611					splitHandshake: true,
4612				})
4613				addStateMachineCoverageTests(stateMachineTestConfig{
4614					protocol:      protocol,
4615					async:         async,
4616					packHandshake: true,
4617				})
4618			}
4619		}
4620	}
4621}
4622
4623func addStateMachineCoverageTests(config stateMachineTestConfig) {
4624	var tests []testCase
4625
4626	// Basic handshake, with resumption. Client and server,
4627	// session ID and session ticket.
4628	// The following tests have a max version of 1.2, so they are not suitable
4629	// for use with QUIC.
4630	if config.protocol != quic {
4631		tests = append(tests, testCase{
4632			name: "Basic-Client",
4633			config: Config{
4634				MaxVersion: VersionTLS12,
4635			},
4636			resumeSession: true,
4637			// Ensure session tickets are used, not session IDs.
4638			noSessionCache: true,
4639			flags:          []string{"-expect-no-hrr"},
4640		})
4641		tests = append(tests, testCase{
4642			name: "Basic-Client-RenewTicket",
4643			config: Config{
4644				MaxVersion: VersionTLS12,
4645				Bugs: ProtocolBugs{
4646					RenewTicketOnResume: true,
4647				},
4648			},
4649			flags:                []string{"-expect-ticket-renewal"},
4650			resumeSession:        true,
4651			resumeRenewedSession: true,
4652		})
4653		tests = append(tests, testCase{
4654			name: "Basic-Client-NoTicket",
4655			config: Config{
4656				MaxVersion:             VersionTLS12,
4657				SessionTicketsDisabled: true,
4658			},
4659			resumeSession: true,
4660		})
4661		tests = append(tests, testCase{
4662			testType: serverTest,
4663			name:     "Basic-Server",
4664			config: Config{
4665				MaxVersion: VersionTLS12,
4666				Bugs: ProtocolBugs{
4667					RequireSessionTickets: true,
4668				},
4669			},
4670			resumeSession: true,
4671			flags: []string{
4672				"-expect-no-session-id",
4673				"-expect-no-hrr",
4674			},
4675		})
4676		tests = append(tests, testCase{
4677			testType: serverTest,
4678			name:     "Basic-Server-NoTickets",
4679			config: Config{
4680				MaxVersion:             VersionTLS12,
4681				SessionTicketsDisabled: true,
4682			},
4683			resumeSession: true,
4684			flags:         []string{"-expect-session-id"},
4685		})
4686		tests = append(tests, testCase{
4687			testType: serverTest,
4688			name:     "Basic-Server-EarlyCallback",
4689			config: Config{
4690				MaxVersion: VersionTLS12,
4691			},
4692			flags:         []string{"-use-early-callback"},
4693			resumeSession: true,
4694		})
4695	}
4696
4697	// TLS 1.3 basic handshake shapes. DTLS 1.3 isn't supported yet.
4698	if config.protocol != dtls {
4699		tests = append(tests, testCase{
4700			name: "TLS13-1RTT-Client",
4701			config: Config{
4702				MaxVersion: VersionTLS13,
4703				MinVersion: VersionTLS13,
4704			},
4705			resumeSession:        true,
4706			resumeRenewedSession: true,
4707			// 0-RTT being disabled overrides all other 0-RTT reasons.
4708			flags: []string{"-expect-early-data-reason", "disabled"},
4709		})
4710
4711		tests = append(tests, testCase{
4712			testType: serverTest,
4713			name:     "TLS13-1RTT-Server",
4714			config: Config{
4715				MaxVersion: VersionTLS13,
4716				MinVersion: VersionTLS13,
4717			},
4718			resumeSession:        true,
4719			resumeRenewedSession: true,
4720			flags: []string{
4721				// TLS 1.3 uses tickets, so the session should not be
4722				// cached statefully.
4723				"-expect-no-session-id",
4724				// 0-RTT being disabled overrides all other 0-RTT reasons.
4725				"-expect-early-data-reason", "disabled",
4726			},
4727		})
4728
4729		tests = append(tests, testCase{
4730			name: "TLS13-HelloRetryRequest-Client",
4731			config: Config{
4732				MaxVersion: VersionTLS13,
4733				MinVersion: VersionTLS13,
4734				// P-384 requires a HelloRetryRequest against BoringSSL's default
4735				// configuration. Assert this with ExpectMissingKeyShare.
4736				CurvePreferences: []CurveID{CurveP384},
4737				Bugs: ProtocolBugs{
4738					ExpectMissingKeyShare: true,
4739				},
4740			},
4741			// Cover HelloRetryRequest during an ECDHE-PSK resumption.
4742			resumeSession: true,
4743			flags:         []string{"-expect-hrr"},
4744		})
4745
4746		tests = append(tests, testCase{
4747			testType: serverTest,
4748			name:     "TLS13-HelloRetryRequest-Server",
4749			config: Config{
4750				MaxVersion: VersionTLS13,
4751				MinVersion: VersionTLS13,
4752				// Require a HelloRetryRequest for every curve.
4753				DefaultCurves: []CurveID{},
4754			},
4755			// Cover HelloRetryRequest during an ECDHE-PSK resumption.
4756			resumeSession: true,
4757			flags:         []string{"-expect-hrr"},
4758		})
4759
4760		// Tests that specify a MaxEarlyDataSize don't work with QUIC.
4761		if config.protocol != quic {
4762			tests = append(tests, testCase{
4763				testType: clientTest,
4764				name:     "TLS13-EarlyData-TooMuchData-Client",
4765				config: Config{
4766					MaxVersion:       VersionTLS13,
4767					MinVersion:       VersionTLS13,
4768					MaxEarlyDataSize: 2,
4769				},
4770				resumeConfig: &Config{
4771					MaxVersion:       VersionTLS13,
4772					MinVersion:       VersionTLS13,
4773					MaxEarlyDataSize: 2,
4774					Bugs: ProtocolBugs{
4775						ExpectEarlyData: [][]byte{{'h', 'e'}},
4776					},
4777				},
4778				resumeShimPrefix: "llo",
4779				resumeSession:    true,
4780				earlyData:        true,
4781			})
4782		}
4783
4784		// Unfinished writes can only be tested when operations are async. EarlyData
4785		// can't be tested as part of an ImplicitHandshake in this case since
4786		// otherwise the early data will be sent as normal data.
4787		//
4788		// Note application data is external in QUIC, so unfinished writes do not
4789		// apply.
4790		if config.async && !config.implicitHandshake && config.protocol != quic {
4791			tests = append(tests, testCase{
4792				testType: clientTest,
4793				name:     "TLS13-EarlyData-UnfinishedWrite-Client",
4794				config: Config{
4795					MaxVersion: VersionTLS13,
4796					MinVersion: VersionTLS13,
4797					Bugs: ProtocolBugs{
4798						ExpectEarlyData:     [][]byte{},
4799						ExpectLateEarlyData: [][]byte{{'h', 'e', 'l', 'l', 'o'}},
4800					},
4801				},
4802				resumeSession: true,
4803				earlyData:     true,
4804				flags:         []string{"-on-resume-read-with-unfinished-write"},
4805			})
4806
4807			// Rejected unfinished writes are discarded (from the
4808			// perspective of the calling application) on 0-RTT
4809			// reject.
4810			tests = append(tests, testCase{
4811				testType: clientTest,
4812				name:     "TLS13-EarlyData-RejectUnfinishedWrite-Client",
4813				config: Config{
4814					MaxVersion: VersionTLS13,
4815					MinVersion: VersionTLS13,
4816					Bugs: ProtocolBugs{
4817						AlwaysRejectEarlyData: true,
4818					},
4819				},
4820				resumeSession:           true,
4821				earlyData:               true,
4822				expectEarlyDataRejected: true,
4823				flags:                   []string{"-on-resume-read-with-unfinished-write"},
4824			})
4825		}
4826
4827		// Early data has no size limit in QUIC.
4828		if config.protocol != quic {
4829			tests = append(tests, testCase{
4830				testType: serverTest,
4831				name:     "TLS13-MaxEarlyData-Server",
4832				config: Config{
4833					MaxVersion: VersionTLS13,
4834					MinVersion: VersionTLS13,
4835					Bugs: ProtocolBugs{
4836						SendEarlyData:           [][]byte{bytes.Repeat([]byte{1}, 14336+1)},
4837						ExpectEarlyDataAccepted: true,
4838					},
4839				},
4840				messageCount:  2,
4841				resumeSession: true,
4842				earlyData:     true,
4843				shouldFail:    true,
4844				expectedError: ":TOO_MUCH_READ_EARLY_DATA:",
4845			})
4846		}
4847	}
4848
4849	// TLS client auth.
4850	// The following tests have a max version of 1.2, so they are not suitable
4851	// for use with QUIC.
4852	if config.protocol != quic {
4853		tests = append(tests, testCase{
4854			testType: clientTest,
4855			name:     "ClientAuth-NoCertificate-Client",
4856			config: Config{
4857				MaxVersion: VersionTLS12,
4858				ClientAuth: RequestClientCert,
4859			},
4860		})
4861		tests = append(tests, testCase{
4862			testType: serverTest,
4863			name:     "ClientAuth-NoCertificate-Server",
4864			config: Config{
4865				MaxVersion: VersionTLS12,
4866			},
4867			// Setting SSL_VERIFY_PEER allows anonymous clients.
4868			flags: []string{"-verify-peer"},
4869		})
4870	}
4871	if config.protocol != dtls {
4872		tests = append(tests, testCase{
4873			testType: clientTest,
4874			name:     "ClientAuth-NoCertificate-Client-TLS13",
4875			config: Config{
4876				MaxVersion: VersionTLS13,
4877				ClientAuth: RequestClientCert,
4878			},
4879		})
4880		tests = append(tests, testCase{
4881			testType: serverTest,
4882			name:     "ClientAuth-NoCertificate-Server-TLS13",
4883			config: Config{
4884				MaxVersion: VersionTLS13,
4885			},
4886			// Setting SSL_VERIFY_PEER allows anonymous clients.
4887			flags: []string{"-verify-peer"},
4888		})
4889	}
4890	if config.protocol != quic {
4891		tests = append(tests, testCase{
4892			testType: clientTest,
4893			name:     "ClientAuth-RSA-Client",
4894			config: Config{
4895				MaxVersion: VersionTLS12,
4896				ClientAuth: RequireAnyClientCert,
4897			},
4898			flags: []string{
4899				"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4900				"-key-file", path.Join(*resourceDir, rsaKeyFile),
4901			},
4902		})
4903	}
4904	tests = append(tests, testCase{
4905		testType: clientTest,
4906		name:     "ClientAuth-RSA-Client-TLS13",
4907		config: Config{
4908			MaxVersion: VersionTLS13,
4909			ClientAuth: RequireAnyClientCert,
4910		},
4911		flags: []string{
4912			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4913			"-key-file", path.Join(*resourceDir, rsaKeyFile),
4914		},
4915	})
4916	if config.protocol != quic {
4917		tests = append(tests, testCase{
4918			testType: clientTest,
4919			name:     "ClientAuth-ECDSA-Client",
4920			config: Config{
4921				MaxVersion: VersionTLS12,
4922				ClientAuth: RequireAnyClientCert,
4923			},
4924			flags: []string{
4925				"-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
4926				"-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
4927			},
4928		})
4929	}
4930	tests = append(tests, testCase{
4931		testType: clientTest,
4932		name:     "ClientAuth-ECDSA-Client-TLS13",
4933		config: Config{
4934			MaxVersion: VersionTLS13,
4935			ClientAuth: RequireAnyClientCert,
4936		},
4937		flags: []string{
4938			"-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
4939			"-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
4940		},
4941	})
4942	if config.protocol != quic {
4943		tests = append(tests, testCase{
4944			testType: clientTest,
4945			name:     "ClientAuth-NoCertificate-OldCallback",
4946			config: Config{
4947				MaxVersion: VersionTLS12,
4948				ClientAuth: RequestClientCert,
4949			},
4950			flags: []string{"-use-old-client-cert-callback"},
4951		})
4952	}
4953	tests = append(tests, testCase{
4954		testType: clientTest,
4955		name:     "ClientAuth-NoCertificate-OldCallback-TLS13",
4956		config: Config{
4957			MaxVersion: VersionTLS13,
4958			ClientAuth: RequestClientCert,
4959		},
4960		flags: []string{"-use-old-client-cert-callback"},
4961	})
4962	if config.protocol != quic {
4963		tests = append(tests, testCase{
4964			testType: clientTest,
4965			name:     "ClientAuth-OldCallback",
4966			config: Config{
4967				MaxVersion: VersionTLS12,
4968				ClientAuth: RequireAnyClientCert,
4969			},
4970			flags: []string{
4971				"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4972				"-key-file", path.Join(*resourceDir, rsaKeyFile),
4973				"-use-old-client-cert-callback",
4974			},
4975		})
4976	}
4977	tests = append(tests, testCase{
4978		testType: clientTest,
4979		name:     "ClientAuth-OldCallback-TLS13",
4980		config: Config{
4981			MaxVersion: VersionTLS13,
4982			ClientAuth: RequireAnyClientCert,
4983		},
4984		flags: []string{
4985			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
4986			"-key-file", path.Join(*resourceDir, rsaKeyFile),
4987			"-use-old-client-cert-callback",
4988		},
4989	})
4990	if config.protocol != quic {
4991		tests = append(tests, testCase{
4992			testType: serverTest,
4993			name:     "ClientAuth-Server",
4994			config: Config{
4995				MaxVersion:   VersionTLS12,
4996				Certificates: []Certificate{rsaCertificate},
4997			},
4998			flags: []string{"-require-any-client-certificate"},
4999		})
5000	}
5001	tests = append(tests, testCase{
5002		testType: serverTest,
5003		name:     "ClientAuth-Server-TLS13",
5004		config: Config{
5005			MaxVersion:   VersionTLS13,
5006			Certificates: []Certificate{rsaCertificate},
5007		},
5008		flags: []string{"-require-any-client-certificate"},
5009	})
5010
5011	// Test each key exchange on the server side for async keys.
5012	if config.protocol != quic {
5013		tests = append(tests, testCase{
5014			testType: serverTest,
5015			name:     "Basic-Server-RSA",
5016			config: Config{
5017				MaxVersion:   VersionTLS12,
5018				CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
5019			},
5020			flags: []string{
5021				"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5022				"-key-file", path.Join(*resourceDir, rsaKeyFile),
5023			},
5024		})
5025		tests = append(tests, testCase{
5026			testType: serverTest,
5027			name:     "Basic-Server-ECDHE-RSA",
5028			config: Config{
5029				MaxVersion:   VersionTLS12,
5030				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5031			},
5032			flags: []string{
5033				"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
5034				"-key-file", path.Join(*resourceDir, rsaKeyFile),
5035			},
5036		})
5037		tests = append(tests, testCase{
5038			testType: serverTest,
5039			name:     "Basic-Server-ECDHE-ECDSA",
5040			config: Config{
5041				MaxVersion:   VersionTLS12,
5042				CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
5043			},
5044			flags: []string{
5045				"-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
5046				"-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
5047			},
5048		})
5049		tests = append(tests, testCase{
5050			testType: serverTest,
5051			name:     "Basic-Server-Ed25519",
5052			config: Config{
5053				MaxVersion:   VersionTLS12,
5054				CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
5055			},
5056			flags: []string{
5057				"-cert-file", path.Join(*resourceDir, ed25519CertificateFile),
5058				"-key-file", path.Join(*resourceDir, ed25519KeyFile),
5059				"-verify-prefs", strconv.Itoa(int(signatureEd25519)),
5060			},
5061		})
5062
5063		// No session ticket support; server doesn't send NewSessionTicket.
5064		tests = append(tests, testCase{
5065			name: "SessionTicketsDisabled-Client",
5066			config: Config{
5067				MaxVersion:             VersionTLS12,
5068				SessionTicketsDisabled: true,
5069			},
5070		})
5071		tests = append(tests, testCase{
5072			testType: serverTest,
5073			name:     "SessionTicketsDisabled-Server",
5074			config: Config{
5075				MaxVersion:             VersionTLS12,
5076				SessionTicketsDisabled: true,
5077			},
5078		})
5079
5080		// Skip ServerKeyExchange in PSK key exchange if there's no
5081		// identity hint.
5082		tests = append(tests, testCase{
5083			name: "EmptyPSKHint-Client",
5084			config: Config{
5085				MaxVersion:   VersionTLS12,
5086				CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
5087				PreSharedKey: []byte("secret"),
5088			},
5089			flags: []string{"-psk", "secret"},
5090		})
5091		tests = append(tests, testCase{
5092			testType: serverTest,
5093			name:     "EmptyPSKHint-Server",
5094			config: Config{
5095				MaxVersion:   VersionTLS12,
5096				CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
5097				PreSharedKey: []byte("secret"),
5098			},
5099			flags: []string{"-psk", "secret"},
5100		})
5101	}
5102
5103	// OCSP stapling tests.
5104	for _, vers := range allVersions(config.protocol) {
5105		tests = append(tests, testCase{
5106			testType: clientTest,
5107			name:     "OCSPStapling-Client-" + vers.name,
5108			config: Config{
5109				MaxVersion: vers.version,
5110			},
5111			flags: []string{
5112				"-enable-ocsp-stapling",
5113				"-expect-ocsp-response",
5114				base64.StdEncoding.EncodeToString(testOCSPResponse),
5115				"-verify-peer",
5116			},
5117			resumeSession: true,
5118		})
5119		tests = append(tests, testCase{
5120			testType: serverTest,
5121			name:     "OCSPStapling-Server-" + vers.name,
5122			config: Config{
5123				MaxVersion: vers.version,
5124			},
5125			expectations: connectionExpectations{
5126				ocspResponse: testOCSPResponse,
5127			},
5128			flags: []string{
5129				"-ocsp-response",
5130				base64.StdEncoding.EncodeToString(testOCSPResponse),
5131			},
5132			resumeSession: true,
5133		})
5134
5135		// The client OCSP callback is an alternate certificate
5136		// verification callback.
5137		tests = append(tests, testCase{
5138			testType: clientTest,
5139			name:     "ClientOCSPCallback-Pass-" + vers.name,
5140			config: Config{
5141				MaxVersion:   vers.version,
5142				Certificates: []Certificate{rsaCertificate},
5143			},
5144			flags: []string{
5145				"-enable-ocsp-stapling",
5146				"-use-ocsp-callback",
5147			},
5148		})
5149		var expectedLocalError string
5150		if !config.async {
5151			// TODO(davidben): Asynchronous fatal alerts are never
5152			// sent. https://crbug.com/boringssl/130.
5153			expectedLocalError = "remote error: bad certificate status response"
5154		}
5155		tests = append(tests, testCase{
5156			testType: clientTest,
5157			name:     "ClientOCSPCallback-Fail-" + vers.name,
5158			config: Config{
5159				MaxVersion:   vers.version,
5160				Certificates: []Certificate{rsaCertificate},
5161			},
5162			flags: []string{
5163				"-enable-ocsp-stapling",
5164				"-use-ocsp-callback",
5165				"-fail-ocsp-callback",
5166			},
5167			shouldFail:         true,
5168			expectedLocalError: expectedLocalError,
5169			expectedError:      ":OCSP_CB_ERROR:",
5170		})
5171		// The callback still runs if the server does not send an OCSP
5172		// response.
5173		certNoStaple := rsaCertificate
5174		certNoStaple.OCSPStaple = nil
5175		tests = append(tests, testCase{
5176			testType: clientTest,
5177			name:     "ClientOCSPCallback-FailNoStaple-" + vers.name,
5178			config: Config{
5179				MaxVersion:   vers.version,
5180				Certificates: []Certificate{certNoStaple},
5181			},
5182			flags: []string{
5183				"-enable-ocsp-stapling",
5184				"-use-ocsp-callback",
5185				"-fail-ocsp-callback",
5186			},
5187			shouldFail:         true,
5188			expectedLocalError: expectedLocalError,
5189			expectedError:      ":OCSP_CB_ERROR:",
5190		})
5191
5192		// The server OCSP callback is a legacy mechanism for
5193		// configuring OCSP, used by unreliable server software.
5194		tests = append(tests, testCase{
5195			testType: serverTest,
5196			name:     "ServerOCSPCallback-SetInCallback-" + vers.name,
5197			config: Config{
5198				MaxVersion: vers.version,
5199			},
5200			expectations: connectionExpectations{
5201				ocspResponse: testOCSPResponse,
5202			},
5203			flags: []string{
5204				"-use-ocsp-callback",
5205				"-set-ocsp-in-callback",
5206				"-ocsp-response",
5207				base64.StdEncoding.EncodeToString(testOCSPResponse),
5208			},
5209			resumeSession: true,
5210		})
5211
5212		// The callback may decline OCSP, in which case  we act as if
5213		// the client did not support it, even if a response was
5214		// configured.
5215		tests = append(tests, testCase{
5216			testType: serverTest,
5217			name:     "ServerOCSPCallback-Decline-" + vers.name,
5218			config: Config{
5219				MaxVersion: vers.version,
5220			},
5221			expectations: connectionExpectations{
5222				ocspResponse: []byte{},
5223			},
5224			flags: []string{
5225				"-use-ocsp-callback",
5226				"-decline-ocsp-callback",
5227				"-ocsp-response",
5228				base64.StdEncoding.EncodeToString(testOCSPResponse),
5229			},
5230			resumeSession: true,
5231		})
5232
5233		// The callback may also signal an internal error.
5234		tests = append(tests, testCase{
5235			testType: serverTest,
5236			name:     "ServerOCSPCallback-Fail-" + vers.name,
5237			config: Config{
5238				MaxVersion: vers.version,
5239			},
5240			flags: []string{
5241				"-use-ocsp-callback",
5242				"-fail-ocsp-callback",
5243				"-ocsp-response",
5244				base64.StdEncoding.EncodeToString(testOCSPResponse),
5245			},
5246			shouldFail:    true,
5247			expectedError: ":OCSP_CB_ERROR:",
5248		})
5249	}
5250
5251	// Certificate verification tests.
5252	for _, vers := range allVersions(config.protocol) {
5253		for _, useCustomCallback := range []bool{false, true} {
5254			for _, testType := range []testType{clientTest, serverTest} {
5255				suffix := "-Client"
5256				if testType == serverTest {
5257					suffix = "-Server"
5258				}
5259				suffix += "-" + vers.name
5260				if useCustomCallback {
5261					suffix += "-CustomCallback"
5262				}
5263
5264				// The custom callback and legacy callback have different default
5265				// alerts.
5266				verifyFailLocalError := "remote error: handshake failure"
5267				if useCustomCallback {
5268					verifyFailLocalError = "remote error: unknown certificate"
5269				}
5270
5271				// We do not reliably send asynchronous fatal alerts. See
5272				// https://crbug.com/boringssl/130.
5273				if config.async {
5274					verifyFailLocalError = ""
5275				}
5276
5277				flags := []string{"-verify-peer"}
5278				if testType == serverTest {
5279					flags = append(flags, "-require-any-client-certificate")
5280				}
5281				if useCustomCallback {
5282					flags = append(flags, "-use-custom-verify-callback")
5283				}
5284
5285				tests = append(tests, testCase{
5286					testType: testType,
5287					name:     "CertificateVerificationSucceed" + suffix,
5288					config: Config{
5289						MaxVersion:   vers.version,
5290						Certificates: []Certificate{rsaCertificate},
5291					},
5292					flags:         append([]string{"-expect-verify-result"}, flags...),
5293					resumeSession: true,
5294				})
5295				tests = append(tests, testCase{
5296					testType: testType,
5297					name:     "CertificateVerificationFail" + suffix,
5298					config: Config{
5299						MaxVersion:   vers.version,
5300						Certificates: []Certificate{rsaCertificate},
5301					},
5302					flags:              append([]string{"-verify-fail"}, flags...),
5303					shouldFail:         true,
5304					expectedError:      ":CERTIFICATE_VERIFY_FAILED:",
5305					expectedLocalError: verifyFailLocalError,
5306				})
5307				// Tests that although the verify callback fails on resumption, by default we don't call it.
5308				tests = append(tests, testCase{
5309					testType: testType,
5310					name:     "CertificateVerificationDoesNotFailOnResume" + suffix,
5311					config: Config{
5312						MaxVersion:   vers.version,
5313						Certificates: []Certificate{rsaCertificate},
5314					},
5315					flags:         append([]string{"-on-resume-verify-fail"}, flags...),
5316					resumeSession: true,
5317				})
5318				if testType == clientTest && useCustomCallback {
5319					tests = append(tests, testCase{
5320						testType: testType,
5321						name:     "CertificateVerificationFailsOnResume" + suffix,
5322						config: Config{
5323							MaxVersion:   vers.version,
5324							Certificates: []Certificate{rsaCertificate},
5325						},
5326						flags: append([]string{
5327							"-on-resume-verify-fail",
5328							"-reverify-on-resume",
5329						}, flags...),
5330						resumeSession:      true,
5331						shouldFail:         true,
5332						expectedError:      ":CERTIFICATE_VERIFY_FAILED:",
5333						expectedLocalError: verifyFailLocalError,
5334					})
5335					tests = append(tests, testCase{
5336						testType: testType,
5337						name:     "CertificateVerificationPassesOnResume" + suffix,
5338						config: Config{
5339							MaxVersion:   vers.version,
5340							Certificates: []Certificate{rsaCertificate},
5341						},
5342						flags: append([]string{
5343							"-reverify-on-resume",
5344						}, flags...),
5345						resumeSession: true,
5346					})
5347					if vers.version >= VersionTLS13 {
5348						tests = append(tests, testCase{
5349							testType: testType,
5350							name:     "EarlyData-RejectTicket-Client-Reverify" + suffix,
5351							config: Config{
5352								MaxVersion: vers.version,
5353							},
5354							resumeConfig: &Config{
5355								MaxVersion:             vers.version,
5356								SessionTicketsDisabled: true,
5357							},
5358							resumeSession:           true,
5359							expectResumeRejected:    true,
5360							earlyData:               true,
5361							expectEarlyDataRejected: true,
5362							flags: append([]string{
5363								"-reverify-on-resume",
5364								// Session tickets are disabled, so the runner will not send a ticket.
5365								"-on-retry-expect-no-session",
5366							}, flags...),
5367						})
5368						tests = append(tests, testCase{
5369							testType: testType,
5370							name:     "EarlyData-Reject0RTT-Client-Reverify" + suffix,
5371							config: Config{
5372								MaxVersion: vers.version,
5373								Bugs: ProtocolBugs{
5374									AlwaysRejectEarlyData: true,
5375								},
5376							},
5377							resumeSession:           true,
5378							expectResumeRejected:    false,
5379							earlyData:               true,
5380							expectEarlyDataRejected: true,
5381							flags: append([]string{
5382								"-reverify-on-resume",
5383							}, flags...),
5384						})
5385						tests = append(tests, testCase{
5386							testType: testType,
5387							name:     "EarlyData-RejectTicket-Client-ReverifyFails" + suffix,
5388							config: Config{
5389								MaxVersion: vers.version,
5390							},
5391							resumeConfig: &Config{
5392								MaxVersion:             vers.version,
5393								SessionTicketsDisabled: true,
5394							},
5395							resumeSession:           true,
5396							expectResumeRejected:    true,
5397							earlyData:               true,
5398							expectEarlyDataRejected: true,
5399							shouldFail:              true,
5400							expectedError:           ":CERTIFICATE_VERIFY_FAILED:",
5401							flags: append([]string{
5402								"-reverify-on-resume",
5403								// Session tickets are disabled, so the runner will not send a ticket.
5404								"-on-retry-expect-no-session",
5405								"-on-retry-verify-fail",
5406							}, flags...),
5407						})
5408						tests = append(tests, testCase{
5409							testType: testType,
5410							name:     "EarlyData-Reject0RTT-Client-ReverifyFails" + suffix,
5411							config: Config{
5412								MaxVersion: vers.version,
5413								Bugs: ProtocolBugs{
5414									AlwaysRejectEarlyData: true,
5415								},
5416							},
5417							resumeSession:           true,
5418							expectResumeRejected:    false,
5419							earlyData:               true,
5420							expectEarlyDataRejected: true,
5421							shouldFail:              true,
5422							expectedError:           ":CERTIFICATE_VERIFY_FAILED:",
5423							expectedLocalError:      verifyFailLocalError,
5424							flags: append([]string{
5425								"-reverify-on-resume",
5426								"-on-retry-verify-fail",
5427							}, flags...),
5428						})
5429						// This tests that we only call the verify callback once.
5430						tests = append(tests, testCase{
5431							testType: testType,
5432							name:     "EarlyData-Accept0RTT-Client-Reverify" + suffix,
5433							config: Config{
5434								MaxVersion: vers.version,
5435							},
5436							resumeSession: true,
5437							earlyData:     true,
5438							flags: append([]string{
5439								"-reverify-on-resume",
5440							}, flags...),
5441						})
5442						tests = append(tests, testCase{
5443							testType: testType,
5444							name:     "EarlyData-Accept0RTT-Client-ReverifyFails" + suffix,
5445							config: Config{
5446								MaxVersion: vers.version,
5447							},
5448							resumeSession: true,
5449							earlyData:     true,
5450							shouldFail:    true,
5451							expectedError: ":CERTIFICATE_VERIFY_FAILED:",
5452							// We do not set expectedLocalError here because the shim rejects
5453							// the connection without an alert.
5454							flags: append([]string{
5455								"-reverify-on-resume",
5456								"-on-resume-verify-fail",
5457							}, flags...),
5458						})
5459					}
5460				}
5461			}
5462		}
5463
5464		// By default, the client is in a soft fail mode where the peer
5465		// certificate is verified but failures are non-fatal.
5466		tests = append(tests, testCase{
5467			testType: clientTest,
5468			name:     "CertificateVerificationSoftFail-" + vers.name,
5469			config: Config{
5470				MaxVersion:   vers.version,
5471				Certificates: []Certificate{rsaCertificate},
5472			},
5473			flags: []string{
5474				"-verify-fail",
5475				"-expect-verify-result",
5476			},
5477			resumeSession: true,
5478		})
5479	}
5480
5481	tests = append(tests, testCase{
5482		name:               "ShimSendAlert",
5483		flags:              []string{"-send-alert"},
5484		shimWritesFirst:    true,
5485		shouldFail:         true,
5486		expectedLocalError: "remote error: decompression failure",
5487	})
5488
5489	if config.protocol == tls {
5490		tests = append(tests, testCase{
5491			name: "Renegotiate-Client",
5492			config: Config{
5493				MaxVersion: VersionTLS12,
5494			},
5495			renegotiate: 1,
5496			flags: []string{
5497				"-renegotiate-freely",
5498				"-expect-total-renegotiations", "1",
5499			},
5500		})
5501
5502		tests = append(tests, testCase{
5503			name: "Renegotiate-Client-Explicit",
5504			config: Config{
5505				MaxVersion: VersionTLS12,
5506			},
5507			renegotiate: 1,
5508			flags: []string{
5509				"-renegotiate-explicit",
5510				"-expect-total-renegotiations", "1",
5511			},
5512		})
5513
5514		halfHelloRequestError := ":UNEXPECTED_RECORD:"
5515		if config.packHandshake {
5516			// If the HelloRequest is sent in the same record as the server Finished,
5517			// BoringSSL rejects it before the handshake completes.
5518			halfHelloRequestError = ":EXCESS_HANDSHAKE_DATA:"
5519		}
5520		tests = append(tests, testCase{
5521			name: "SendHalfHelloRequest",
5522			config: Config{
5523				MaxVersion: VersionTLS12,
5524				Bugs: ProtocolBugs{
5525					PackHelloRequestWithFinished: config.packHandshake,
5526				},
5527			},
5528			sendHalfHelloRequest: true,
5529			flags:                []string{"-renegotiate-ignore"},
5530			shouldFail:           true,
5531			expectedError:        halfHelloRequestError,
5532		})
5533
5534		// NPN on client and server; results in post-handshake message.
5535		tests = append(tests, testCase{
5536			name: "NPN-Client",
5537			config: Config{
5538				MaxVersion: VersionTLS12,
5539				NextProtos: []string{"foo"},
5540			},
5541			flags:         []string{"-select-next-proto", "foo"},
5542			resumeSession: true,
5543			expectations: connectionExpectations{
5544				nextProto:     "foo",
5545				nextProtoType: npn,
5546			},
5547		})
5548		tests = append(tests, testCase{
5549			testType: serverTest,
5550			name:     "NPN-Server",
5551			config: Config{
5552				MaxVersion: VersionTLS12,
5553				NextProtos: []string{"bar"},
5554			},
5555			flags: []string{
5556				"-advertise-npn", "\x03foo\x03bar\x03baz",
5557				"-expect-next-proto", "bar",
5558			},
5559			resumeSession: true,
5560			expectations: connectionExpectations{
5561				nextProto:     "bar",
5562				nextProtoType: npn,
5563			},
5564		})
5565
5566		// Client does False Start and negotiates NPN.
5567		tests = append(tests, testCase{
5568			name: "FalseStart",
5569			config: Config{
5570				MaxVersion:   VersionTLS12,
5571				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5572				NextProtos:   []string{"foo"},
5573				Bugs: ProtocolBugs{
5574					ExpectFalseStart: true,
5575				},
5576			},
5577			flags: []string{
5578				"-false-start",
5579				"-select-next-proto", "foo",
5580			},
5581			shimWritesFirst: true,
5582			resumeSession:   true,
5583		})
5584
5585		// Client does False Start and negotiates ALPN.
5586		tests = append(tests, testCase{
5587			name: "FalseStart-ALPN",
5588			config: Config{
5589				MaxVersion:   VersionTLS12,
5590				CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5591				NextProtos:   []string{"foo"},
5592				Bugs: ProtocolBugs{
5593					ExpectFalseStart: true,
5594				},
5595			},
5596			flags: []string{
5597				"-false-start",
5598				"-advertise-alpn", "\x03foo",
5599				"-expect-alpn", "foo",
5600			},
5601			shimWritesFirst: true,
5602			resumeSession:   true,
5603		})
5604
5605		// False Start without session tickets.
5606		tests = append(tests, testCase{
5607			name: "FalseStart-SessionTicketsDisabled",
5608			config: Config{
5609				MaxVersion:             VersionTLS12,
5610				CipherSuites:           []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
5611				NextProtos:             []string{"foo"},
5612				SessionTicketsDisabled: true,
5613				Bugs: ProtocolBugs{
5614					ExpectFalseStart: true,
5615				},
5616			},
5617			flags: []string{
5618				"-false-start",
5619				"-select-next-proto", "foo",
5620			},
5621			shimWritesFirst: true,
5622		})
5623
5624		// Server parses a V2ClientHello.
5625		tests = append(tests, testCase{
5626			testType: serverTest,
5627			name:     "SendV2ClientHello",
5628			config: Config{
5629				// Choose a cipher suite that does not involve
5630				// elliptic curves, so no extensions are
5631				// involved.
5632				MaxVersion:   VersionTLS12,
5633				CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
5634				Bugs: ProtocolBugs{
5635					SendV2ClientHello: true,
5636				},
5637			},
5638			flags: []string{
5639				"-expect-msg-callback",
5640				`read v2clienthello
5641write hs 2
5642write hs 11
5643write hs 14
5644read hs 16
5645read ccs
5646read hs 20
5647write ccs
5648write hs 20
5649read alert 1 0
5650`,
5651			},
5652		})
5653
5654		// Channel ID and NPN at the same time, to ensure their relative
5655		// ordering is correct.
5656		tests = append(tests, testCase{
5657			name: "ChannelID-NPN-Client",
5658			config: Config{
5659				MaxVersion:       VersionTLS12,
5660				RequestChannelID: true,
5661				NextProtos:       []string{"foo"},
5662			},
5663			flags: []string{
5664				"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile),
5665				"-select-next-proto", "foo",
5666			},
5667			resumeSession: true,
5668			expectations: connectionExpectations{
5669				channelID:     true,
5670				nextProto:     "foo",
5671				nextProtoType: npn,
5672			},
5673		})
5674		tests = append(tests, testCase{
5675			testType: serverTest,
5676			name:     "ChannelID-NPN-Server",
5677			config: Config{
5678				MaxVersion: VersionTLS12,
5679				ChannelID:  channelIDKey,
5680				NextProtos: []string{"bar"},
5681			},
5682			flags: []string{
5683				"-expect-channel-id",
5684				base64.StdEncoding.EncodeToString(channelIDBytes),
5685				"-advertise-npn", "\x03foo\x03bar\x03baz",
5686				"-expect-next-proto", "bar",
5687			},
5688			resumeSession: true,
5689			expectations: connectionExpectations{
5690				channelID:     true,
5691				nextProto:     "bar",
5692				nextProtoType: npn,
5693			},
5694		})
5695
5696		// Bidirectional shutdown with the runner initiating.
5697		tests = append(tests, testCase{
5698			name: "Shutdown-Runner",
5699			config: Config{
5700				Bugs: ProtocolBugs{
5701					ExpectCloseNotify: true,
5702				},
5703			},
5704			flags: []string{"-check-close-notify"},
5705		})
5706	}
5707	if config.protocol != dtls {
5708		// Test Channel ID
5709		for _, ver := range allVersions(config.protocol) {
5710			if ver.version < VersionTLS10 {
5711				continue
5712			}
5713			// Client sends a Channel ID.
5714			tests = append(tests, testCase{
5715				name: "ChannelID-Client-" + ver.name,
5716				config: Config{
5717					MaxVersion:       ver.version,
5718					RequestChannelID: true,
5719				},
5720				flags:         []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)},
5721				resumeSession: true,
5722				expectations: connectionExpectations{
5723					channelID: true,
5724				},
5725			})
5726
5727			// Server accepts a Channel ID.
5728			tests = append(tests, testCase{
5729				testType: serverTest,
5730				name:     "ChannelID-Server-" + ver.name,
5731				config: Config{
5732					MaxVersion: ver.version,
5733					ChannelID:  channelIDKey,
5734				},
5735				flags: []string{
5736					"-expect-channel-id",
5737					base64.StdEncoding.EncodeToString(channelIDBytes),
5738				},
5739				resumeSession: true,
5740				expectations: connectionExpectations{
5741					channelID: true,
5742				},
5743			})
5744
5745			tests = append(tests, testCase{
5746				testType: serverTest,
5747				name:     "InvalidChannelIDSignature-" + ver.name,
5748				config: Config{
5749					MaxVersion: ver.version,
5750					ChannelID:  channelIDKey,
5751					Bugs: ProtocolBugs{
5752						InvalidChannelIDSignature: true,
5753					},
5754				},
5755				flags:         []string{"-enable-channel-id"},
5756				shouldFail:    true,
5757				expectedError: ":CHANNEL_ID_SIGNATURE_INVALID:",
5758			})
5759
5760			if ver.version < VersionTLS13 {
5761				// Channel ID requires ECDHE ciphers.
5762				tests = append(tests, testCase{
5763					testType: serverTest,
5764					name:     "ChannelID-NoECDHE-" + ver.name,
5765					config: Config{
5766						MaxVersion:   ver.version,
5767						CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
5768						ChannelID:    channelIDKey,
5769					},
5770					expectations: connectionExpectations{
5771						channelID: false,
5772					},
5773					flags: []string{"-enable-channel-id"},
5774				})
5775
5776				// Sanity-check setting expectations.channelID false works.
5777				tests = append(tests, testCase{
5778					testType: serverTest,
5779					name:     "ChannelID-ECDHE-" + ver.name,
5780					config: Config{
5781						MaxVersion:   ver.version,
5782						CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
5783						ChannelID:    channelIDKey,
5784					},
5785					expectations: connectionExpectations{
5786						channelID: false,
5787					},
5788					flags:              []string{"-enable-channel-id"},
5789					shouldFail:         true,
5790					expectedLocalError: "channel ID unexpectedly negotiated",
5791				})
5792			}
5793		}
5794
5795		if !config.implicitHandshake {
5796			// Bidirectional shutdown with the shim initiating. The runner,
5797			// in the meantime, sends garbage before the close_notify which
5798			// the shim must ignore. This test is disabled under implicit
5799			// handshake tests because the shim never reads or writes.
5800
5801			// Tests that require checking for a close notify alert don't work with
5802			// QUIC because alerts are handled outside of the TLS stack in QUIC.
5803			if config.protocol != quic {
5804				tests = append(tests, testCase{
5805					name: "Shutdown-Shim",
5806					config: Config{
5807						MaxVersion: VersionTLS12,
5808						Bugs: ProtocolBugs{
5809							ExpectCloseNotify: true,
5810						},
5811					},
5812					shimShutsDown:     true,
5813					sendEmptyRecords:  1,
5814					sendWarningAlerts: 1,
5815					flags:             []string{"-check-close-notify"},
5816				})
5817
5818				// The shim should reject unexpected application data
5819				// when shutting down.
5820				tests = append(tests, testCase{
5821					name: "Shutdown-Shim-ApplicationData",
5822					config: Config{
5823						MaxVersion: VersionTLS12,
5824						Bugs: ProtocolBugs{
5825							ExpectCloseNotify: true,
5826						},
5827					},
5828					shimShutsDown:     true,
5829					messageCount:      1,
5830					sendEmptyRecords:  1,
5831					sendWarningAlerts: 1,
5832					flags:             []string{"-check-close-notify"},
5833					shouldFail:        true,
5834					expectedError:     ":APPLICATION_DATA_ON_SHUTDOWN:",
5835				})
5836
5837				// Test that SSL_shutdown still processes KeyUpdate.
5838				tests = append(tests, testCase{
5839					name: "Shutdown-Shim-KeyUpdate",
5840					config: Config{
5841						MinVersion: VersionTLS13,
5842						MaxVersion: VersionTLS13,
5843						Bugs: ProtocolBugs{
5844							ExpectCloseNotify: true,
5845						},
5846					},
5847					shimShutsDown:    true,
5848					sendKeyUpdates:   1,
5849					keyUpdateRequest: keyUpdateRequested,
5850					flags:            []string{"-check-close-notify"},
5851				})
5852
5853				// Test that SSL_shutdown processes HelloRequest
5854				// correctly.
5855				tests = append(tests, testCase{
5856					name: "Shutdown-Shim-HelloRequest-Ignore",
5857					config: Config{
5858						MinVersion: VersionTLS12,
5859						MaxVersion: VersionTLS12,
5860						Bugs: ProtocolBugs{
5861							SendHelloRequestBeforeEveryAppDataRecord: true,
5862							ExpectCloseNotify:                        true,
5863						},
5864					},
5865					shimShutsDown: true,
5866					flags: []string{
5867						"-renegotiate-ignore",
5868						"-check-close-notify",
5869					},
5870				})
5871				tests = append(tests, testCase{
5872					name: "Shutdown-Shim-HelloRequest-Reject",
5873					config: Config{
5874						MinVersion: VersionTLS12,
5875						MaxVersion: VersionTLS12,
5876						Bugs: ProtocolBugs{
5877							ExpectCloseNotify: true,
5878						},
5879					},
5880					shimShutsDown: true,
5881					renegotiate:   1,
5882					shouldFail:    true,
5883					expectedError: ":NO_RENEGOTIATION:",
5884					flags:         []string{"-check-close-notify"},
5885				})
5886				tests = append(tests, testCase{
5887					name: "Shutdown-Shim-HelloRequest-CannotHandshake",
5888					config: Config{
5889						MinVersion: VersionTLS12,
5890						MaxVersion: VersionTLS12,
5891						Bugs: ProtocolBugs{
5892							ExpectCloseNotify: true,
5893						},
5894					},
5895					shimShutsDown: true,
5896					renegotiate:   1,
5897					shouldFail:    true,
5898					expectedError: ":NO_RENEGOTIATION:",
5899					flags: []string{
5900						"-check-close-notify",
5901						"-renegotiate-freely",
5902					},
5903				})
5904
5905				tests = append(tests, testCase{
5906					testType: serverTest,
5907					name:     "Shutdown-Shim-Renegotiate-Server-Forbidden",
5908					config: Config{
5909						MaxVersion: VersionTLS12,
5910						Bugs: ProtocolBugs{
5911							ExpectCloseNotify: true,
5912						},
5913					},
5914					shimShutsDown: true,
5915					renegotiate:   1,
5916					shouldFail:    true,
5917					expectedError: ":NO_RENEGOTIATION:",
5918					flags: []string{
5919						"-check-close-notify",
5920					},
5921				})
5922			}
5923		}
5924	}
5925	if config.protocol == dtls {
5926		// TODO(davidben): DTLS 1.3 will want a similar thing for
5927		// HelloRetryRequest.
5928		tests = append(tests, testCase{
5929			name: "SkipHelloVerifyRequest",
5930			config: Config{
5931				MaxVersion: VersionTLS12,
5932				Bugs: ProtocolBugs{
5933					SkipHelloVerifyRequest: true,
5934				},
5935			},
5936		})
5937	}
5938
5939	for _, test := range tests {
5940		test.protocol = config.protocol
5941		test.name += "-" + config.protocol.String()
5942		if config.async {
5943			test.name += "-Async"
5944			test.flags = append(test.flags, "-async")
5945		} else {
5946			test.name += "-Sync"
5947		}
5948		if config.splitHandshake {
5949			test.name += "-SplitHandshakeRecords"
5950			test.config.Bugs.MaxHandshakeRecordLength = 1
5951			if config.protocol == dtls {
5952				test.config.Bugs.MaxPacketLength = 256
5953				test.flags = append(test.flags, "-mtu", "256")
5954			}
5955		}
5956		if config.packHandshake {
5957			test.name += "-PackHandshake"
5958			if config.protocol == dtls {
5959				test.config.Bugs.MaxHandshakeRecordLength = 2
5960				test.config.Bugs.PackHandshakeFragments = 20
5961				test.config.Bugs.PackHandshakeRecords = 1500
5962				test.config.Bugs.PackAppDataWithHandshake = true
5963			} else {
5964				test.config.Bugs.PackHandshakeFlight = true
5965			}
5966		}
5967		if config.implicitHandshake {
5968			test.name += "-ImplicitHandshake"
5969			test.flags = append(test.flags, "-implicit-handshake")
5970		}
5971		testCases = append(testCases, test)
5972	}
5973}
5974
5975func addDDoSCallbackTests() {
5976	// DDoS callback.
5977	for _, resume := range []bool{false, true} {
5978		suffix := "Resume"
5979		if resume {
5980			suffix = "No" + suffix
5981		}
5982
5983		testCases = append(testCases, testCase{
5984			testType: serverTest,
5985			name:     "Server-DDoS-OK-" + suffix,
5986			config: Config{
5987				MaxVersion: VersionTLS12,
5988			},
5989			flags:         []string{"-install-ddos-callback"},
5990			resumeSession: resume,
5991		})
5992		testCases = append(testCases, testCase{
5993			testType: serverTest,
5994			name:     "Server-DDoS-OK-" + suffix + "-TLS13",
5995			config: Config{
5996				MaxVersion: VersionTLS13,
5997			},
5998			flags:         []string{"-install-ddos-callback"},
5999			resumeSession: resume,
6000		})
6001
6002		failFlag := "-fail-ddos-callback"
6003		if resume {
6004			failFlag = "-on-resume-fail-ddos-callback"
6005		}
6006		testCases = append(testCases, testCase{
6007			testType: serverTest,
6008			name:     "Server-DDoS-Reject-" + suffix,
6009			config: Config{
6010				MaxVersion: VersionTLS12,
6011			},
6012			flags:              []string{"-install-ddos-callback", failFlag},
6013			resumeSession:      resume,
6014			shouldFail:         true,
6015			expectedError:      ":CONNECTION_REJECTED:",
6016			expectedLocalError: "remote error: internal error",
6017		})
6018		testCases = append(testCases, testCase{
6019			testType: serverTest,
6020			name:     "Server-DDoS-Reject-" + suffix + "-TLS13",
6021			config: Config{
6022				MaxVersion: VersionTLS13,
6023			},
6024			flags:              []string{"-install-ddos-callback", failFlag},
6025			resumeSession:      resume,
6026			shouldFail:         true,
6027			expectedError:      ":CONNECTION_REJECTED:",
6028			expectedLocalError: "remote error: internal error",
6029		})
6030	}
6031}
6032
6033func addVersionNegotiationTests() {
6034	for _, protocol := range []protocol{tls, dtls, quic} {
6035		for _, shimVers := range allVersions(protocol) {
6036			// Assemble flags to disable all newer versions on the shim.
6037			var flags []string
6038			for _, vers := range allVersions(protocol) {
6039				if vers.version > shimVers.version {
6040					flags = append(flags, vers.excludeFlag)
6041				}
6042			}
6043
6044			flags2 := []string{"-max-version", shimVers.shimFlag(protocol)}
6045
6046			// Test configuring the runner's maximum version.
6047			for _, runnerVers := range allVersions(protocol) {
6048				expectedVersion := shimVers.version
6049				if runnerVers.version < shimVers.version {
6050					expectedVersion = runnerVers.version
6051				}
6052
6053				suffix := shimVers.name + "-" + runnerVers.name
6054				suffix += "-" + protocol.String()
6055
6056				// Determine the expected initial record-layer versions.
6057				clientVers := shimVers.version
6058				if clientVers > VersionTLS10 {
6059					clientVers = VersionTLS10
6060				}
6061				clientVers = recordVersionToWire(clientVers, protocol)
6062				serverVers := expectedVersion
6063				if expectedVersion >= VersionTLS13 {
6064					serverVers = VersionTLS12
6065				}
6066				serverVers = recordVersionToWire(serverVers, protocol)
6067
6068				testCases = append(testCases, testCase{
6069					protocol: protocol,
6070					testType: clientTest,
6071					name:     "VersionNegotiation-Client-" + suffix,
6072					config: Config{
6073						MaxVersion: runnerVers.version,
6074						Bugs: ProtocolBugs{
6075							ExpectInitialRecordVersion: clientVers,
6076						},
6077					},
6078					flags: flags,
6079					expectations: connectionExpectations{
6080						version: expectedVersion,
6081					},
6082				})
6083				testCases = append(testCases, testCase{
6084					protocol: protocol,
6085					testType: clientTest,
6086					name:     "VersionNegotiation-Client2-" + suffix,
6087					config: Config{
6088						MaxVersion: runnerVers.version,
6089						Bugs: ProtocolBugs{
6090							ExpectInitialRecordVersion: clientVers,
6091						},
6092					},
6093					flags: flags2,
6094					expectations: connectionExpectations{
6095						version: expectedVersion,
6096					},
6097				})
6098
6099				testCases = append(testCases, testCase{
6100					protocol: protocol,
6101					testType: serverTest,
6102					name:     "VersionNegotiation-Server-" + suffix,
6103					config: Config{
6104						MaxVersion: runnerVers.version,
6105						Bugs: ProtocolBugs{
6106							ExpectInitialRecordVersion: serverVers,
6107						},
6108					},
6109					flags: flags,
6110					expectations: connectionExpectations{
6111						version: expectedVersion,
6112					},
6113				})
6114				testCases = append(testCases, testCase{
6115					protocol: protocol,
6116					testType: serverTest,
6117					name:     "VersionNegotiation-Server2-" + suffix,
6118					config: Config{
6119						MaxVersion: runnerVers.version,
6120						Bugs: ProtocolBugs{
6121							ExpectInitialRecordVersion: serverVers,
6122						},
6123					},
6124					flags: flags2,
6125					expectations: connectionExpectations{
6126						version: expectedVersion,
6127					},
6128				})
6129			}
6130		}
6131	}
6132
6133	// Test the version extension at all versions.
6134	for _, protocol := range []protocol{tls, dtls, quic} {
6135		for _, vers := range allVersions(protocol) {
6136			suffix := vers.name + "-" + protocol.String()
6137
6138			testCases = append(testCases, testCase{
6139				protocol: protocol,
6140				testType: serverTest,
6141				name:     "VersionNegotiationExtension-" + suffix,
6142				config: Config{
6143					Bugs: ProtocolBugs{
6144						SendSupportedVersions:      []uint16{0x1111, vers.wire(protocol), 0x2222},
6145						IgnoreTLS13DowngradeRandom: true,
6146					},
6147				},
6148				expectations: connectionExpectations{
6149					version: vers.version,
6150				},
6151			})
6152		}
6153	}
6154
6155	// If all versions are unknown, negotiation fails.
6156	testCases = append(testCases, testCase{
6157		testType: serverTest,
6158		name:     "NoSupportedVersions",
6159		config: Config{
6160			Bugs: ProtocolBugs{
6161				SendSupportedVersions: []uint16{0x1111},
6162			},
6163		},
6164		shouldFail:    true,
6165		expectedError: ":UNSUPPORTED_PROTOCOL:",
6166	})
6167	testCases = append(testCases, testCase{
6168		protocol: dtls,
6169		testType: serverTest,
6170		name:     "NoSupportedVersions-DTLS",
6171		config: Config{
6172			Bugs: ProtocolBugs{
6173				SendSupportedVersions: []uint16{0x1111},
6174			},
6175		},
6176		shouldFail:    true,
6177		expectedError: ":UNSUPPORTED_PROTOCOL:",
6178	})
6179
6180	testCases = append(testCases, testCase{
6181		testType: serverTest,
6182		name:     "ClientHelloVersionTooHigh",
6183		config: Config{
6184			MaxVersion: VersionTLS13,
6185			Bugs: ProtocolBugs{
6186				SendClientVersion:          0x0304,
6187				OmitSupportedVersions:      true,
6188				IgnoreTLS13DowngradeRandom: true,
6189			},
6190		},
6191		expectations: connectionExpectations{
6192			version: VersionTLS12,
6193		},
6194	})
6195
6196	testCases = append(testCases, testCase{
6197		testType: serverTest,
6198		name:     "ConflictingVersionNegotiation",
6199		config: Config{
6200			Bugs: ProtocolBugs{
6201				SendClientVersion:          VersionTLS12,
6202				SendSupportedVersions:      []uint16{VersionTLS11},
6203				IgnoreTLS13DowngradeRandom: true,
6204			},
6205		},
6206		// The extension takes precedence over the ClientHello version.
6207		expectations: connectionExpectations{
6208			version: VersionTLS11,
6209		},
6210	})
6211
6212	testCases = append(testCases, testCase{
6213		testType: serverTest,
6214		name:     "ConflictingVersionNegotiation-2",
6215		config: Config{
6216			Bugs: ProtocolBugs{
6217				SendClientVersion:          VersionTLS11,
6218				SendSupportedVersions:      []uint16{VersionTLS12},
6219				IgnoreTLS13DowngradeRandom: true,
6220			},
6221		},
6222		// The extension takes precedence over the ClientHello version.
6223		expectations: connectionExpectations{
6224			version: VersionTLS12,
6225		},
6226	})
6227
6228	// Test that TLS 1.2 isn't negotiated by the supported_versions extension in
6229	// the ServerHello.
6230	testCases = append(testCases, testCase{
6231		testType: clientTest,
6232		name:     "SupportedVersionSelection-TLS12",
6233		config: Config{
6234			MaxVersion: VersionTLS12,
6235			Bugs: ProtocolBugs{
6236				SendServerSupportedVersionExtension: VersionTLS12,
6237			},
6238		},
6239		shouldFail:    true,
6240		expectedError: ":UNEXPECTED_EXTENSION:",
6241	})
6242
6243	// Test that the maximum version is selected regardless of the
6244	// client-sent order.
6245	testCases = append(testCases, testCase{
6246		testType: serverTest,
6247		name:     "IgnoreClientVersionOrder",
6248		config: Config{
6249			Bugs: ProtocolBugs{
6250				SendSupportedVersions: []uint16{VersionTLS12, VersionTLS13},
6251			},
6252		},
6253		expectations: connectionExpectations{
6254			version: VersionTLS13,
6255		},
6256	})
6257
6258	// Test for version tolerance.
6259	testCases = append(testCases, testCase{
6260		testType: serverTest,
6261		name:     "MinorVersionTolerance",
6262		config: Config{
6263			Bugs: ProtocolBugs{
6264				SendClientVersion:          0x03ff,
6265				OmitSupportedVersions:      true,
6266				IgnoreTLS13DowngradeRandom: true,
6267			},
6268		},
6269		expectations: connectionExpectations{
6270			version: VersionTLS12,
6271		},
6272	})
6273	testCases = append(testCases, testCase{
6274		testType: serverTest,
6275		name:     "MajorVersionTolerance",
6276		config: Config{
6277			Bugs: ProtocolBugs{
6278				SendClientVersion:          0x0400,
6279				OmitSupportedVersions:      true,
6280				IgnoreTLS13DowngradeRandom: true,
6281			},
6282		},
6283		// TLS 1.3 must be negotiated with the supported_versions
6284		// extension, not ClientHello.version.
6285		expectations: connectionExpectations{
6286			version: VersionTLS12,
6287		},
6288	})
6289	testCases = append(testCases, testCase{
6290		testType: serverTest,
6291		name:     "VersionTolerance-TLS13",
6292		config: Config{
6293			Bugs: ProtocolBugs{
6294				// Although TLS 1.3 does not use
6295				// ClientHello.version, it still tolerates high
6296				// values there.
6297				SendClientVersion: 0x0400,
6298			},
6299		},
6300		expectations: connectionExpectations{
6301			version: VersionTLS13,
6302		},
6303	})
6304
6305	testCases = append(testCases, testCase{
6306		protocol: dtls,
6307		testType: serverTest,
6308		name:     "MinorVersionTolerance-DTLS",
6309		config: Config{
6310			Bugs: ProtocolBugs{
6311				SendClientVersion:     0xfe00,
6312				OmitSupportedVersions: true,
6313			},
6314		},
6315		expectations: connectionExpectations{
6316			version: VersionTLS12,
6317		},
6318	})
6319	testCases = append(testCases, testCase{
6320		protocol: dtls,
6321		testType: serverTest,
6322		name:     "MajorVersionTolerance-DTLS",
6323		config: Config{
6324			Bugs: ProtocolBugs{
6325				SendClientVersion:     0xfdff,
6326				OmitSupportedVersions: true,
6327			},
6328		},
6329		expectations: connectionExpectations{
6330			version: VersionTLS12,
6331		},
6332	})
6333
6334	// Test that versions below 3.0 are rejected.
6335	testCases = append(testCases, testCase{
6336		testType: serverTest,
6337		name:     "VersionTooLow",
6338		config: Config{
6339			Bugs: ProtocolBugs{
6340				SendClientVersion:     0x0200,
6341				OmitSupportedVersions: true,
6342			},
6343		},
6344		shouldFail:    true,
6345		expectedError: ":UNSUPPORTED_PROTOCOL:",
6346	})
6347	testCases = append(testCases, testCase{
6348		protocol: dtls,
6349		testType: serverTest,
6350		name:     "VersionTooLow-DTLS",
6351		config: Config{
6352			Bugs: ProtocolBugs{
6353				SendClientVersion: 0xffff,
6354			},
6355		},
6356		shouldFail:    true,
6357		expectedError: ":UNSUPPORTED_PROTOCOL:",
6358	})
6359
6360	testCases = append(testCases, testCase{
6361		name: "ServerBogusVersion",
6362		config: Config{
6363			Bugs: ProtocolBugs{
6364				SendServerHelloVersion: 0x1234,
6365			},
6366		},
6367		shouldFail:    true,
6368		expectedError: ":UNSUPPORTED_PROTOCOL:",
6369	})
6370
6371	// Test TLS 1.3's downgrade signal.
6372	var downgradeTests = []struct {
6373		name            string
6374		version         uint16
6375		clientShimError string
6376	}{
6377		{"TLS12", VersionTLS12, "tls: downgrade from TLS 1.3 detected"},
6378		{"TLS11", VersionTLS11, "tls: downgrade from TLS 1.2 detected"},
6379		// TLS 1.0 does not have a dedicated value.
6380		{"TLS10", VersionTLS10, "tls: downgrade from TLS 1.2 detected"},
6381	}
6382
6383	for _, test := range downgradeTests {
6384		// The client should enforce the downgrade sentinel.
6385		testCases = append(testCases, testCase{
6386			name: "Downgrade-" + test.name + "-Client",
6387			config: Config{
6388				Bugs: ProtocolBugs{
6389					NegotiateVersion: test.version,
6390				},
6391			},
6392			expectations: connectionExpectations{
6393				version: test.version,
6394			},
6395			shouldFail:         true,
6396			expectedError:      ":TLS13_DOWNGRADE:",
6397			expectedLocalError: "remote error: illegal parameter",
6398		})
6399
6400		// The server should emit the downgrade signal.
6401		testCases = append(testCases, testCase{
6402			testType: serverTest,
6403			name:     "Downgrade-" + test.name + "-Server",
6404			config: Config{
6405				Bugs: ProtocolBugs{
6406					SendSupportedVersions: []uint16{test.version},
6407				},
6408			},
6409			expectations: connectionExpectations{
6410				version: test.version,
6411			},
6412			shouldFail:         true,
6413			expectedLocalError: test.clientShimError,
6414		})
6415	}
6416
6417	// SSL 3.0 support has been removed. Test that the shim does not
6418	// support it.
6419	testCases = append(testCases, testCase{
6420		name: "NoSSL3-Client",
6421		config: Config{
6422			MinVersion: VersionSSL30,
6423			MaxVersion: VersionSSL30,
6424		},
6425		shouldFail:         true,
6426		expectedLocalError: "tls: client did not offer any supported protocol versions",
6427	})
6428	testCases = append(testCases, testCase{
6429		name: "NoSSL3-Client-Unsolicited",
6430		config: Config{
6431			MinVersion: VersionSSL30,
6432			MaxVersion: VersionSSL30,
6433			Bugs: ProtocolBugs{
6434				// The above test asserts the client does not
6435				// offer SSL 3.0 in the supported_versions
6436				// list. Additionally assert that it rejects an
6437				// unsolicited SSL 3.0 ServerHello.
6438				NegotiateVersion: VersionSSL30,
6439			},
6440		},
6441		shouldFail:         true,
6442		expectedError:      ":UNSUPPORTED_PROTOCOL:",
6443		expectedLocalError: "remote error: protocol version not supported",
6444	})
6445	testCases = append(testCases, testCase{
6446		testType: serverTest,
6447		name:     "NoSSL3-Server",
6448		config: Config{
6449			MinVersion: VersionSSL30,
6450			MaxVersion: VersionSSL30,
6451		},
6452		shouldFail:         true,
6453		expectedError:      ":UNSUPPORTED_PROTOCOL:",
6454		expectedLocalError: "remote error: protocol version not supported",
6455	})
6456}
6457
6458func addMinimumVersionTests() {
6459	for _, protocol := range []protocol{tls, dtls, quic} {
6460		for _, shimVers := range allVersions(protocol) {
6461			// Assemble flags to disable all older versions on the shim.
6462			var flags []string
6463			for _, vers := range allVersions(protocol) {
6464				if vers.version < shimVers.version {
6465					flags = append(flags, vers.excludeFlag)
6466				}
6467			}
6468
6469			flags2 := []string{"-min-version", shimVers.shimFlag(protocol)}
6470
6471			for _, runnerVers := range allVersions(protocol) {
6472				suffix := shimVers.name + "-" + runnerVers.name
6473				suffix += "-" + protocol.String()
6474
6475				var expectedVersion uint16
6476				var shouldFail bool
6477				var expectedError, expectedLocalError string
6478				if runnerVers.version >= shimVers.version {
6479					expectedVersion = runnerVers.version
6480				} else {
6481					shouldFail = true
6482					expectedError = ":UNSUPPORTED_PROTOCOL:"
6483					expectedLocalError = "remote error: protocol version not supported"
6484				}
6485
6486				testCases = append(testCases, testCase{
6487					protocol: protocol,
6488					testType: clientTest,
6489					name:     "MinimumVersion-Client-" + suffix,
6490					config: Config{
6491						MaxVersion: runnerVers.version,
6492						Bugs: ProtocolBugs{
6493							// Ensure the server does not decline to
6494							// select a version (versions extension) or
6495							// cipher (some ciphers depend on versions).
6496							NegotiateVersion:            runnerVers.wire(protocol),
6497							IgnorePeerCipherPreferences: shouldFail,
6498						},
6499					},
6500					flags: flags,
6501					expectations: connectionExpectations{
6502						version: expectedVersion,
6503					},
6504					shouldFail:         shouldFail,
6505					expectedError:      expectedError,
6506					expectedLocalError: expectedLocalError,
6507				})
6508				testCases = append(testCases, testCase{
6509					protocol: protocol,
6510					testType: clientTest,
6511					name:     "MinimumVersion-Client2-" + suffix,
6512					config: Config{
6513						MaxVersion: runnerVers.version,
6514						Bugs: ProtocolBugs{
6515							// Ensure the server does not decline to
6516							// select a version (versions extension) or
6517							// cipher (some ciphers depend on versions).
6518							NegotiateVersion:            runnerVers.wire(protocol),
6519							IgnorePeerCipherPreferences: shouldFail,
6520						},
6521					},
6522					flags: flags2,
6523					expectations: connectionExpectations{
6524						version: expectedVersion,
6525					},
6526					shouldFail:         shouldFail,
6527					expectedError:      expectedError,
6528					expectedLocalError: expectedLocalError,
6529				})
6530
6531				testCases = append(testCases, testCase{
6532					protocol: protocol,
6533					testType: serverTest,
6534					name:     "MinimumVersion-Server-" + suffix,
6535					config: Config{
6536						MaxVersion: runnerVers.version,
6537					},
6538					flags: flags,
6539					expectations: connectionExpectations{
6540						version: expectedVersion,
6541					},
6542					shouldFail:         shouldFail,
6543					expectedError:      expectedError,
6544					expectedLocalError: expectedLocalError,
6545				})
6546				testCases = append(testCases, testCase{
6547					protocol: protocol,
6548					testType: serverTest,
6549					name:     "MinimumVersion-Server2-" + suffix,
6550					config: Config{
6551						MaxVersion: runnerVers.version,
6552					},
6553					flags: flags2,
6554					expectations: connectionExpectations{
6555						version: expectedVersion,
6556					},
6557					shouldFail:         shouldFail,
6558					expectedError:      expectedError,
6559					expectedLocalError: expectedLocalError,
6560				})
6561			}
6562		}
6563	}
6564}
6565
6566func addExtensionTests() {
6567	// Repeat extensions tests at all versions.
6568	for _, protocol := range []protocol{tls, dtls, quic} {
6569		for _, ver := range allVersions(protocol) {
6570			suffix := fmt.Sprintf("%s-%s", protocol.String(), ver.name)
6571
6572			// Test that duplicate extensions are rejected.
6573			testCases = append(testCases, testCase{
6574				protocol: protocol,
6575				testType: clientTest,
6576				name:     "DuplicateExtensionClient-" + suffix,
6577				config: Config{
6578					MaxVersion: ver.version,
6579					Bugs: ProtocolBugs{
6580						DuplicateExtension: true,
6581					},
6582				},
6583				shouldFail:         true,
6584				expectedLocalError: "remote error: error decoding message",
6585			})
6586			testCases = append(testCases, testCase{
6587				protocol: protocol,
6588				testType: serverTest,
6589				name:     "DuplicateExtensionServer-" + suffix,
6590				config: Config{
6591					MaxVersion: ver.version,
6592					Bugs: ProtocolBugs{
6593						DuplicateExtension: true,
6594					},
6595				},
6596				shouldFail:         true,
6597				expectedLocalError: "remote error: error decoding message",
6598			})
6599
6600			// Test SNI.
6601			testCases = append(testCases, testCase{
6602				protocol: protocol,
6603				testType: clientTest,
6604				name:     "ServerNameExtensionClient-" + suffix,
6605				config: Config{
6606					MaxVersion: ver.version,
6607					Bugs: ProtocolBugs{
6608						ExpectServerName: "example.com",
6609					},
6610				},
6611				flags: []string{"-host-name", "example.com"},
6612			})
6613			testCases = append(testCases, testCase{
6614				protocol: protocol,
6615				testType: clientTest,
6616				name:     "ServerNameExtensionClientMismatch-" + suffix,
6617				config: Config{
6618					MaxVersion: ver.version,
6619					Bugs: ProtocolBugs{
6620						ExpectServerName: "mismatch.com",
6621					},
6622				},
6623				flags:              []string{"-host-name", "example.com"},
6624				shouldFail:         true,
6625				expectedLocalError: "tls: unexpected server name",
6626			})
6627			testCases = append(testCases, testCase{
6628				protocol: protocol,
6629				testType: clientTest,
6630				name:     "ServerNameExtensionClientMissing-" + suffix,
6631				config: Config{
6632					MaxVersion: ver.version,
6633					Bugs: ProtocolBugs{
6634						ExpectServerName: "missing.com",
6635					},
6636				},
6637				shouldFail:         true,
6638				expectedLocalError: "tls: unexpected server name",
6639			})
6640			testCases = append(testCases, testCase{
6641				protocol: protocol,
6642				testType: clientTest,
6643				name:     "TolerateServerNameAck-" + suffix,
6644				config: Config{
6645					MaxVersion: ver.version,
6646					Bugs: ProtocolBugs{
6647						SendServerNameAck: true,
6648					},
6649				},
6650				flags:         []string{"-host-name", "example.com"},
6651				resumeSession: true,
6652			})
6653			testCases = append(testCases, testCase{
6654				protocol: protocol,
6655				testType: clientTest,
6656				name:     "UnsolicitedServerNameAck-" + suffix,
6657				config: Config{
6658					MaxVersion: ver.version,
6659					Bugs: ProtocolBugs{
6660						SendServerNameAck: true,
6661					},
6662				},
6663				shouldFail:         true,
6664				expectedError:      ":UNEXPECTED_EXTENSION:",
6665				expectedLocalError: "remote error: unsupported extension",
6666			})
6667			testCases = append(testCases, testCase{
6668				protocol: protocol,
6669				testType: serverTest,
6670				name:     "ServerNameExtensionServer-" + suffix,
6671				config: Config{
6672					MaxVersion: ver.version,
6673					ServerName: "example.com",
6674				},
6675				flags:         []string{"-expect-server-name", "example.com"},
6676				resumeSession: true,
6677			})
6678
6679			// Test ALPN.
6680			testCases = append(testCases, testCase{
6681				protocol:           protocol,
6682				testType:           clientTest,
6683				skipQUICALPNConfig: true,
6684				name:               "ALPNClient-" + suffix,
6685				config: Config{
6686					MaxVersion: ver.version,
6687					NextProtos: []string{"foo"},
6688				},
6689				flags: []string{
6690					"-advertise-alpn", "\x03foo\x03bar\x03baz",
6691					"-expect-alpn", "foo",
6692				},
6693				expectations: connectionExpectations{
6694					nextProto:     "foo",
6695					nextProtoType: alpn,
6696				},
6697				resumeSession: true,
6698			})
6699			testCases = append(testCases, testCase{
6700				protocol:           protocol,
6701				testType:           clientTest,
6702				skipQUICALPNConfig: true,
6703				name:               "ALPNClient-RejectUnknown-" + suffix,
6704				config: Config{
6705					MaxVersion: ver.version,
6706					Bugs: ProtocolBugs{
6707						SendALPN: "baz",
6708					},
6709				},
6710				flags: []string{
6711					"-advertise-alpn", "\x03foo\x03bar",
6712				},
6713				shouldFail:         true,
6714				expectedError:      ":INVALID_ALPN_PROTOCOL:",
6715				expectedLocalError: "remote error: illegal parameter",
6716			})
6717			testCases = append(testCases, testCase{
6718				protocol:           protocol,
6719				testType:           clientTest,
6720				skipQUICALPNConfig: true,
6721				name:               "ALPNClient-AllowUnknown-" + suffix,
6722				config: Config{
6723					MaxVersion: ver.version,
6724					Bugs: ProtocolBugs{
6725						SendALPN: "baz",
6726					},
6727				},
6728				flags: []string{
6729					"-advertise-alpn", "\x03foo\x03bar",
6730					"-allow-unknown-alpn-protos",
6731					"-expect-alpn", "baz",
6732				},
6733			})
6734			testCases = append(testCases, testCase{
6735				protocol:           protocol,
6736				testType:           serverTest,
6737				skipQUICALPNConfig: true,
6738				name:               "ALPNServer-" + suffix,
6739				config: Config{
6740					MaxVersion: ver.version,
6741					NextProtos: []string{"foo", "bar", "baz"},
6742				},
6743				flags: []string{
6744					"-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
6745					"-select-alpn", "foo",
6746				},
6747				expectations: connectionExpectations{
6748					nextProto:     "foo",
6749					nextProtoType: alpn,
6750				},
6751				resumeSession: true,
6752			})
6753
6754			var shouldDeclineALPNFail bool
6755			var declineALPNError, declineALPNLocalError string
6756			if protocol == quic {
6757				// ALPN is mandatory in QUIC.
6758				shouldDeclineALPNFail = true
6759				declineALPNError = ":MISSING_ALPN:"
6760				declineALPNLocalError = "remote error: no application protocol"
6761			}
6762			testCases = append(testCases, testCase{
6763				protocol:           protocol,
6764				testType:           serverTest,
6765				skipQUICALPNConfig: true,
6766				name:               "ALPNServer-Decline-" + suffix,
6767				config: Config{
6768					MaxVersion: ver.version,
6769					NextProtos: []string{"foo", "bar", "baz"},
6770				},
6771				flags: []string{"-decline-alpn"},
6772				expectations: connectionExpectations{
6773					noNextProto: true,
6774				},
6775				resumeSession:      true,
6776				shouldFail:         shouldDeclineALPNFail,
6777				expectedError:      declineALPNError,
6778				expectedLocalError: declineALPNLocalError,
6779			})
6780
6781			// Test that the server implementation catches itself if the
6782			// callback tries to return an invalid empty ALPN protocol.
6783			testCases = append(testCases, testCase{
6784				protocol:           protocol,
6785				testType:           serverTest,
6786				skipQUICALPNConfig: true,
6787				name:               "ALPNServer-SelectEmpty-" + suffix,
6788				config: Config{
6789					MaxVersion: ver.version,
6790					NextProtos: []string{"foo", "bar", "baz"},
6791				},
6792				flags: []string{
6793					"-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
6794					"-select-empty-alpn",
6795				},
6796				shouldFail:         true,
6797				expectedLocalError: "remote error: internal error",
6798				expectedError:      ":INVALID_ALPN_PROTOCOL:",
6799			})
6800
6801			// Test ALPN in async mode as well to ensure that extensions callbacks are only
6802			// called once.
6803			testCases = append(testCases, testCase{
6804				protocol:           protocol,
6805				testType:           serverTest,
6806				skipQUICALPNConfig: true,
6807				name:               "ALPNServer-Async-" + suffix,
6808				config: Config{
6809					MaxVersion: ver.version,
6810					NextProtos: []string{"foo", "bar", "baz"},
6811					// Prior to TLS 1.3, exercise the asynchronous session callback.
6812					SessionTicketsDisabled: ver.version < VersionTLS13,
6813				},
6814				flags: []string{
6815					"-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
6816					"-select-alpn", "foo",
6817					"-async",
6818				},
6819				expectations: connectionExpectations{
6820					nextProto:     "foo",
6821					nextProtoType: alpn,
6822				},
6823				resumeSession: true,
6824			})
6825
6826			var emptyString string
6827			testCases = append(testCases, testCase{
6828				protocol:           protocol,
6829				testType:           clientTest,
6830				skipQUICALPNConfig: true,
6831				name:               "ALPNClient-EmptyProtocolName-" + suffix,
6832				config: Config{
6833					MaxVersion: ver.version,
6834					NextProtos: []string{""},
6835					Bugs: ProtocolBugs{
6836						// A server returning an empty ALPN protocol
6837						// should be rejected.
6838						ALPNProtocol: &emptyString,
6839					},
6840				},
6841				flags: []string{
6842					"-advertise-alpn", "\x03foo",
6843				},
6844				shouldFail:    true,
6845				expectedError: ":PARSE_TLSEXT:",
6846			})
6847			testCases = append(testCases, testCase{
6848				protocol:           protocol,
6849				testType:           serverTest,
6850				skipQUICALPNConfig: true,
6851				name:               "ALPNServer-EmptyProtocolName-" + suffix,
6852				config: Config{
6853					MaxVersion: ver.version,
6854					// A ClientHello containing an empty ALPN protocol
6855					// should be rejected.
6856					NextProtos: []string{"foo", "", "baz"},
6857				},
6858				flags: []string{
6859					"-select-alpn", "foo",
6860				},
6861				shouldFail:    true,
6862				expectedError: ":PARSE_TLSEXT:",
6863			})
6864
6865			// Test NPN and the interaction with ALPN.
6866			if ver.version < VersionTLS13 && protocol == tls {
6867				// Test that the server prefers ALPN over NPN.
6868				testCases = append(testCases, testCase{
6869					protocol: protocol,
6870					testType: serverTest,
6871					name:     "ALPNServer-Preferred-" + suffix,
6872					config: Config{
6873						MaxVersion: ver.version,
6874						NextProtos: []string{"foo", "bar", "baz"},
6875					},
6876					flags: []string{
6877						"-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
6878						"-select-alpn", "foo",
6879						"-advertise-npn", "\x03foo\x03bar\x03baz",
6880					},
6881					expectations: connectionExpectations{
6882						nextProto:     "foo",
6883						nextProtoType: alpn,
6884					},
6885					resumeSession: true,
6886				})
6887				testCases = append(testCases, testCase{
6888					protocol: protocol,
6889					testType: serverTest,
6890					name:     "ALPNServer-Preferred-Swapped-" + suffix,
6891					config: Config{
6892						MaxVersion: ver.version,
6893						NextProtos: []string{"foo", "bar", "baz"},
6894						Bugs: ProtocolBugs{
6895							SwapNPNAndALPN: true,
6896						},
6897					},
6898					flags: []string{
6899						"-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
6900						"-select-alpn", "foo",
6901						"-advertise-npn", "\x03foo\x03bar\x03baz",
6902					},
6903					expectations: connectionExpectations{
6904						nextProto:     "foo",
6905						nextProtoType: alpn,
6906					},
6907					resumeSession: true,
6908				})
6909
6910				// Test that negotiating both NPN and ALPN is forbidden.
6911				testCases = append(testCases, testCase{
6912					protocol: protocol,
6913					name:     "NegotiateALPNAndNPN-" + suffix,
6914					config: Config{
6915						MaxVersion: ver.version,
6916						NextProtos: []string{"foo", "bar", "baz"},
6917						Bugs: ProtocolBugs{
6918							NegotiateALPNAndNPN: true,
6919						},
6920					},
6921					flags: []string{
6922						"-advertise-alpn", "\x03foo",
6923						"-select-next-proto", "foo",
6924					},
6925					shouldFail:    true,
6926					expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
6927				})
6928				testCases = append(testCases, testCase{
6929					protocol: protocol,
6930					name:     "NegotiateALPNAndNPN-Swapped-" + suffix,
6931					config: Config{
6932						MaxVersion: ver.version,
6933						NextProtos: []string{"foo", "bar", "baz"},
6934						Bugs: ProtocolBugs{
6935							NegotiateALPNAndNPN: true,
6936							SwapNPNAndALPN:      true,
6937						},
6938					},
6939					flags: []string{
6940						"-advertise-alpn", "\x03foo",
6941						"-select-next-proto", "foo",
6942					},
6943					shouldFail:    true,
6944					expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
6945				})
6946			}
6947
6948			// Test missing ALPN in QUIC
6949			if protocol == quic {
6950				testCases = append(testCases, testCase{
6951					testType: clientTest,
6952					protocol: protocol,
6953					name:     "Client-ALPNMissingFromConfig-" + suffix,
6954					config: Config{
6955						MinVersion: ver.version,
6956						MaxVersion: ver.version,
6957					},
6958					skipQUICALPNConfig: true,
6959					shouldFail:         true,
6960					expectedError:      ":MISSING_ALPN:",
6961				})
6962				testCases = append(testCases, testCase{
6963					testType: clientTest,
6964					protocol: protocol,
6965					name:     "Client-ALPNMissing-" + suffix,
6966					config: Config{
6967						MinVersion: ver.version,
6968						MaxVersion: ver.version,
6969					},
6970					flags: []string{
6971						"-advertise-alpn", "\x03foo",
6972					},
6973					skipQUICALPNConfig: true,
6974					shouldFail:         true,
6975					expectedError:      ":MISSING_ALPN:",
6976					expectedLocalError: "remote error: no application protocol",
6977				})
6978				testCases = append(testCases, testCase{
6979					testType: serverTest,
6980					protocol: protocol,
6981					name:     "Server-ALPNMissing-" + suffix,
6982					config: Config{
6983						MinVersion: ver.version,
6984						MaxVersion: ver.version,
6985					},
6986					skipQUICALPNConfig: true,
6987					shouldFail:         true,
6988					expectedError:      ":MISSING_ALPN:",
6989					expectedLocalError: "remote error: no application protocol",
6990				})
6991				testCases = append(testCases, testCase{
6992					testType: serverTest,
6993					protocol: protocol,
6994					name:     "Server-ALPNMismatch-" + suffix,
6995					config: Config{
6996						MinVersion: ver.version,
6997						MaxVersion: ver.version,
6998						NextProtos: []string{"foo"},
6999					},
7000					flags: []string{
7001						"-decline-alpn",
7002					},
7003					skipQUICALPNConfig: true,
7004					shouldFail:         true,
7005					expectedError:      ":MISSING_ALPN:",
7006					expectedLocalError: "remote error: no application protocol",
7007				})
7008			}
7009
7010			// Test ALPS.
7011			if ver.version >= VersionTLS13 {
7012				// Test that client and server can negotiate ALPS, including
7013				// different values on resumption.
7014				testCases = append(testCases, testCase{
7015					protocol:           protocol,
7016					testType:           clientTest,
7017					name:               "ALPS-Basic-Client-" + suffix,
7018					skipQUICALPNConfig: true,
7019					config: Config{
7020						MaxVersion:          ver.version,
7021						NextProtos:          []string{"proto"},
7022						ApplicationSettings: map[string][]byte{"proto": []byte("runner1")},
7023					},
7024					resumeConfig: &Config{
7025						MaxVersion:          ver.version,
7026						NextProtos:          []string{"proto"},
7027						ApplicationSettings: map[string][]byte{"proto": []byte("runner2")},
7028					},
7029					resumeSession: true,
7030					expectations: connectionExpectations{
7031						peerApplicationSettings: []byte("shim1"),
7032					},
7033					resumeExpectations: &connectionExpectations{
7034						peerApplicationSettings: []byte("shim2"),
7035					},
7036					flags: []string{
7037						"-advertise-alpn", "\x05proto",
7038						"-expect-alpn", "proto",
7039						"-on-initial-application-settings", "proto,shim1",
7040						"-on-initial-expect-peer-application-settings", "runner1",
7041						"-on-resume-application-settings", "proto,shim2",
7042						"-on-resume-expect-peer-application-settings", "runner2",
7043					},
7044				})
7045				testCases = append(testCases, testCase{
7046					protocol:           protocol,
7047					testType:           serverTest,
7048					name:               "ALPS-Basic-Server-" + suffix,
7049					skipQUICALPNConfig: true,
7050					config: Config{
7051						MaxVersion:          ver.version,
7052						NextProtos:          []string{"proto"},
7053						ApplicationSettings: map[string][]byte{"proto": []byte("runner1")},
7054					},
7055					resumeConfig: &Config{
7056						MaxVersion:          ver.version,
7057						NextProtos:          []string{"proto"},
7058						ApplicationSettings: map[string][]byte{"proto": []byte("runner2")},
7059					},
7060					resumeSession: true,
7061					expectations: connectionExpectations{
7062						peerApplicationSettings: []byte("shim1"),
7063					},
7064					resumeExpectations: &connectionExpectations{
7065						peerApplicationSettings: []byte("shim2"),
7066					},
7067					flags: []string{
7068						"-select-alpn", "proto",
7069						"-on-initial-application-settings", "proto,shim1",
7070						"-on-initial-expect-peer-application-settings", "runner1",
7071						"-on-resume-application-settings", "proto,shim2",
7072						"-on-resume-expect-peer-application-settings", "runner2",
7073					},
7074				})
7075
7076				// Test that the server can defer its ALPS configuration to the ALPN
7077				// selection callback.
7078				testCases = append(testCases, testCase{
7079					protocol:           protocol,
7080					testType:           serverTest,
7081					name:               "ALPS-Basic-Server-Defer-" + suffix,
7082					skipQUICALPNConfig: true,
7083					config: Config{
7084						MaxVersion:          ver.version,
7085						NextProtos:          []string{"proto"},
7086						ApplicationSettings: map[string][]byte{"proto": []byte("runner1")},
7087					},
7088					resumeConfig: &Config{
7089						MaxVersion:          ver.version,
7090						NextProtos:          []string{"proto"},
7091						ApplicationSettings: map[string][]byte{"proto": []byte("runner2")},
7092					},
7093					resumeSession: true,
7094					expectations: connectionExpectations{
7095						peerApplicationSettings: []byte("shim1"),
7096					},
7097					resumeExpectations: &connectionExpectations{
7098						peerApplicationSettings: []byte("shim2"),
7099					},
7100					flags: []string{
7101						"-select-alpn", "proto",
7102						"-defer-alps",
7103						"-on-initial-application-settings", "proto,shim1",
7104						"-on-initial-expect-peer-application-settings", "runner1",
7105						"-on-resume-application-settings", "proto,shim2",
7106						"-on-resume-expect-peer-application-settings", "runner2",
7107					},
7108				})
7109
7110				// Test the client and server correctly handle empty settings.
7111				testCases = append(testCases, testCase{
7112					protocol:           protocol,
7113					testType:           clientTest,
7114					name:               "ALPS-Empty-Client-" + suffix,
7115					skipQUICALPNConfig: true,
7116					config: Config{
7117						MaxVersion:          ver.version,
7118						NextProtos:          []string{"proto"},
7119						ApplicationSettings: map[string][]byte{"proto": []byte{}},
7120					},
7121					resumeSession: true,
7122					expectations: connectionExpectations{
7123						peerApplicationSettings: []byte{},
7124					},
7125					flags: []string{
7126						"-advertise-alpn", "\x05proto",
7127						"-expect-alpn", "proto",
7128						"-application-settings", "proto,",
7129						"-expect-peer-application-settings", "",
7130					},
7131				})
7132				testCases = append(testCases, testCase{
7133					protocol:           protocol,
7134					testType:           serverTest,
7135					name:               "ALPS-Empty-Server-" + suffix,
7136					skipQUICALPNConfig: true,
7137					config: Config{
7138						MaxVersion:          ver.version,
7139						NextProtos:          []string{"proto"},
7140						ApplicationSettings: map[string][]byte{"proto": []byte{}},
7141					},
7142					resumeSession: true,
7143					expectations: connectionExpectations{
7144						peerApplicationSettings: []byte{},
7145					},
7146					flags: []string{
7147						"-select-alpn", "proto",
7148						"-application-settings", "proto,",
7149						"-expect-peer-application-settings", "",
7150					},
7151				})
7152
7153				// Test the client rejects application settings from the server on
7154				// protocols it doesn't have them.
7155				testCases = append(testCases, testCase{
7156					protocol:           protocol,
7157					testType:           clientTest,
7158					name:               "ALPS-UnsupportedProtocol-Client-" + suffix,
7159					skipQUICALPNConfig: true,
7160					config: Config{
7161						MaxVersion:          ver.version,
7162						NextProtos:          []string{"proto1"},
7163						ApplicationSettings: map[string][]byte{"proto1": []byte("runner")},
7164						Bugs: ProtocolBugs{
7165							AlwaysNegotiateApplicationSettings: true,
7166						},
7167					},
7168					// The client supports ALPS with "proto2", but not "proto1".
7169					flags: []string{
7170						"-advertise-alpn", "\x06proto1\x06proto2",
7171						"-application-settings", "proto2,shim",
7172						"-expect-alpn", "proto1",
7173					},
7174					// The server sends ALPS with "proto1", which is invalid.
7175					shouldFail:         true,
7176					expectedError:      ":INVALID_ALPN_PROTOCOL:",
7177					expectedLocalError: "remote error: illegal parameter",
7178				})
7179
7180				// Test the server declines ALPS if it doesn't support it for the
7181				// specified protocol.
7182				testCases = append(testCases, testCase{
7183					protocol:           protocol,
7184					testType:           serverTest,
7185					name:               "ALPS-UnsupportedProtocol-Server-" + suffix,
7186					skipQUICALPNConfig: true,
7187					config: Config{
7188						MaxVersion:          ver.version,
7189						NextProtos:          []string{"proto1"},
7190						ApplicationSettings: map[string][]byte{"proto1": []byte("runner")},
7191					},
7192					// The server supports ALPS with "proto2", but not "proto1".
7193					flags: []string{
7194						"-select-alpn", "proto1",
7195						"-application-settings", "proto2,shim",
7196					},
7197				})
7198
7199				// Test that the server rejects a missing application_settings extension.
7200				testCases = append(testCases, testCase{
7201					protocol:           protocol,
7202					testType:           serverTest,
7203					name:               "ALPS-OmitClientApplicationSettings-" + suffix,
7204					skipQUICALPNConfig: true,
7205					config: Config{
7206						MaxVersion:          ver.version,
7207						NextProtos:          []string{"proto"},
7208						ApplicationSettings: map[string][]byte{"proto": []byte("runner")},
7209						Bugs: ProtocolBugs{
7210							OmitClientApplicationSettings: true,
7211						},
7212					},
7213					flags: []string{
7214						"-select-alpn", "proto",
7215						"-application-settings", "proto,shim",
7216					},
7217					// The runner is a client, so it only processes the shim's alert
7218					// after checking connection state.
7219					expectations: connectionExpectations{
7220						peerApplicationSettings: []byte("shim"),
7221					},
7222					shouldFail:         true,
7223					expectedError:      ":MISSING_EXTENSION:",
7224					expectedLocalError: "remote error: missing extension",
7225				})
7226
7227				// Test that the server rejects a missing EncryptedExtensions message.
7228				testCases = append(testCases, testCase{
7229					protocol:           protocol,
7230					testType:           serverTest,
7231					name:               "ALPS-OmitClientEncryptedExtensions-" + suffix,
7232					skipQUICALPNConfig: true,
7233					config: Config{
7234						MaxVersion:          ver.version,
7235						NextProtos:          []string{"proto"},
7236						ApplicationSettings: map[string][]byte{"proto": []byte("runner")},
7237						Bugs: ProtocolBugs{
7238							OmitClientEncryptedExtensions: true,
7239						},
7240					},
7241					flags: []string{
7242						"-select-alpn", "proto",
7243						"-application-settings", "proto,shim",
7244					},
7245					// The runner is a client, so it only processes the shim's alert
7246					// after checking connection state.
7247					expectations: connectionExpectations{
7248						peerApplicationSettings: []byte("shim"),
7249					},
7250					shouldFail:         true,
7251					expectedError:      ":UNEXPECTED_MESSAGE:",
7252					expectedLocalError: "remote error: unexpected message",
7253				})
7254
7255				// Test that the server rejects an unexpected EncryptedExtensions message.
7256				testCases = append(testCases, testCase{
7257					protocol: protocol,
7258					testType: serverTest,
7259					name:     "UnexpectedClientEncryptedExtensions-" + suffix,
7260					config: Config{
7261						MaxVersion: ver.version,
7262						Bugs: ProtocolBugs{
7263							AlwaysSendClientEncryptedExtensions: true,
7264						},
7265					},
7266					shouldFail:         true,
7267					expectedError:      ":UNEXPECTED_MESSAGE:",
7268					expectedLocalError: "remote error: unexpected message",
7269				})
7270
7271				// Test that the server rejects an unexpected extension in an
7272				// expected EncryptedExtensions message.
7273				testCases = append(testCases, testCase{
7274					protocol:           protocol,
7275					testType:           serverTest,
7276					name:               "ExtraClientEncryptedExtension-" + suffix,
7277					skipQUICALPNConfig: true,
7278					config: Config{
7279						MaxVersion:          ver.version,
7280						NextProtos:          []string{"proto"},
7281						ApplicationSettings: map[string][]byte{"proto": []byte("runner")},
7282						Bugs: ProtocolBugs{
7283							SendExtraClientEncryptedExtension: true,
7284						},
7285					},
7286					flags: []string{
7287						"-select-alpn", "proto",
7288						"-application-settings", "proto,shim",
7289					},
7290					// The runner is a client, so it only processes the shim's alert
7291					// after checking connection state.
7292					expectations: connectionExpectations{
7293						peerApplicationSettings: []byte("shim"),
7294					},
7295					shouldFail:         true,
7296					expectedError:      ":UNEXPECTED_EXTENSION:",
7297					expectedLocalError: "remote error: unsupported extension",
7298				})
7299
7300				// Test that ALPS is carried over on 0-RTT.
7301				for _, empty := range []bool{false, true} {
7302					maybeEmpty := ""
7303					runnerSettings := "runner"
7304					shimSettings := "shim"
7305					if empty {
7306						maybeEmpty = "Empty-"
7307						runnerSettings = ""
7308						shimSettings = ""
7309					}
7310
7311					testCases = append(testCases, testCase{
7312						protocol:           protocol,
7313						testType:           clientTest,
7314						name:               "ALPS-EarlyData-Client-" + maybeEmpty + suffix,
7315						skipQUICALPNConfig: true,
7316						config: Config{
7317							MaxVersion:          ver.version,
7318							NextProtos:          []string{"proto"},
7319							ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)},
7320						},
7321						resumeSession: true,
7322						earlyData:     true,
7323						flags: []string{
7324							"-advertise-alpn", "\x05proto",
7325							"-expect-alpn", "proto",
7326							"-application-settings", "proto," + shimSettings,
7327							"-expect-peer-application-settings", runnerSettings,
7328						},
7329						expectations: connectionExpectations{
7330							peerApplicationSettings: []byte(shimSettings),
7331						},
7332					})
7333					testCases = append(testCases, testCase{
7334						protocol:           protocol,
7335						testType:           serverTest,
7336						name:               "ALPS-EarlyData-Server-" + maybeEmpty + suffix,
7337						skipQUICALPNConfig: true,
7338						config: Config{
7339							MaxVersion:          ver.version,
7340							NextProtos:          []string{"proto"},
7341							ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)},
7342						},
7343						resumeSession: true,
7344						earlyData:     true,
7345						flags: []string{
7346							"-select-alpn", "proto",
7347							"-application-settings", "proto," + shimSettings,
7348							"-expect-peer-application-settings", runnerSettings,
7349						},
7350						expectations: connectionExpectations{
7351							peerApplicationSettings: []byte(shimSettings),
7352						},
7353					})
7354
7355					// Sending application settings in 0-RTT handshakes is forbidden.
7356					testCases = append(testCases, testCase{
7357						protocol:           protocol,
7358						testType:           clientTest,
7359						name:               "ALPS-EarlyData-SendApplicationSettingsWithEarlyData-Client-" + maybeEmpty + suffix,
7360						skipQUICALPNConfig: true,
7361						config: Config{
7362							MaxVersion:          ver.version,
7363							NextProtos:          []string{"proto"},
7364							ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)},
7365							Bugs: ProtocolBugs{
7366								SendApplicationSettingsWithEarlyData: true,
7367							},
7368						},
7369						resumeSession: true,
7370						earlyData:     true,
7371						flags: []string{
7372							"-advertise-alpn", "\x05proto",
7373							"-expect-alpn", "proto",
7374							"-application-settings", "proto," + shimSettings,
7375							"-expect-peer-application-settings", runnerSettings,
7376						},
7377						expectations: connectionExpectations{
7378							peerApplicationSettings: []byte(shimSettings),
7379						},
7380						shouldFail:         true,
7381						expectedError:      ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:",
7382						expectedLocalError: "remote error: illegal parameter",
7383					})
7384					testCases = append(testCases, testCase{
7385						protocol:           protocol,
7386						testType:           serverTest,
7387						name:               "ALPS-EarlyData-SendApplicationSettingsWithEarlyData-Server-" + maybeEmpty + suffix,
7388						skipQUICALPNConfig: true,
7389						config: Config{
7390							MaxVersion:          ver.version,
7391							NextProtos:          []string{"proto"},
7392							ApplicationSettings: map[string][]byte{"proto": []byte(runnerSettings)},
7393							Bugs: ProtocolBugs{
7394								SendApplicationSettingsWithEarlyData: true,
7395							},
7396						},
7397						resumeSession: true,
7398						earlyData:     true,
7399						flags: []string{
7400							"-select-alpn", "proto",
7401							"-application-settings", "proto," + shimSettings,
7402							"-expect-peer-application-settings", runnerSettings,
7403						},
7404						expectations: connectionExpectations{
7405							peerApplicationSettings: []byte(shimSettings),
7406						},
7407						shouldFail:         true,
7408						expectedError:      ":UNEXPECTED_MESSAGE:",
7409						expectedLocalError: "remote error: unexpected message",
7410					})
7411				}
7412
7413				// Test that the client and server each decline early data if local
7414				// ALPS preferences has changed for the current connection.
7415				alpsMismatchTests := []struct {
7416					name                            string
7417					initialSettings, resumeSettings []byte
7418				}{
7419					{"DifferentValues", []byte("settings1"), []byte("settings2")},
7420					{"OnOff", []byte("settings"), nil},
7421					{"OffOn", nil, []byte("settings")},
7422					// The empty settings value should not be mistaken for ALPS not
7423					// being negotiated.
7424					{"OnEmpty", []byte("settings"), []byte{}},
7425					{"EmptyOn", []byte{}, []byte("settings")},
7426					{"EmptyOff", []byte{}, nil},
7427					{"OffEmpty", nil, []byte{}},
7428				}
7429				for _, test := range alpsMismatchTests {
7430					flags := []string{"-on-resume-expect-early-data-reason", "alps_mismatch"}
7431					if test.initialSettings != nil {
7432						flags = append(flags, "-on-initial-application-settings", "proto,"+string(test.initialSettings))
7433						flags = append(flags, "-on-initial-expect-peer-application-settings", "runner")
7434					}
7435					if test.resumeSettings != nil {
7436						flags = append(flags, "-on-resume-application-settings", "proto,"+string(test.resumeSettings))
7437						flags = append(flags, "-on-resume-expect-peer-application-settings", "runner")
7438					}
7439
7440					// The client should not offer early data if the session is
7441					// inconsistent with the new configuration. Note that if
7442					// the session did not negotiate ALPS (test.initialSettings
7443					// is nil), the client always offers early data.
7444					if test.initialSettings != nil {
7445						testCases = append(testCases, testCase{
7446							protocol:           protocol,
7447							testType:           clientTest,
7448							name:               fmt.Sprintf("ALPS-EarlyData-Mismatch-%s-Client-%s", test.name, suffix),
7449							skipQUICALPNConfig: true,
7450							config: Config{
7451								MaxVersion:          ver.version,
7452								MaxEarlyDataSize:    16384,
7453								NextProtos:          []string{"proto"},
7454								ApplicationSettings: map[string][]byte{"proto": []byte("runner")},
7455							},
7456							resumeSession: true,
7457							flags: append([]string{
7458								"-enable-early-data",
7459								"-expect-ticket-supports-early-data",
7460								"-expect-no-offer-early-data",
7461								"-advertise-alpn", "\x05proto",
7462								"-expect-alpn", "proto",
7463							}, flags...),
7464							expectations: connectionExpectations{
7465								peerApplicationSettings: test.initialSettings,
7466							},
7467							resumeExpectations: &connectionExpectations{
7468								peerApplicationSettings: test.resumeSettings,
7469							},
7470						})
7471					}
7472
7473					// The server should reject early data if the session is
7474					// inconsistent with the new selection.
7475					testCases = append(testCases, testCase{
7476						protocol:           protocol,
7477						testType:           serverTest,
7478						name:               fmt.Sprintf("ALPS-EarlyData-Mismatch-%s-Server-%s", test.name, suffix),
7479						skipQUICALPNConfig: true,
7480						config: Config{
7481							MaxVersion:          ver.version,
7482							NextProtos:          []string{"proto"},
7483							ApplicationSettings: map[string][]byte{"proto": []byte("runner")},
7484						},
7485						resumeSession:           true,
7486						earlyData:               true,
7487						expectEarlyDataRejected: true,
7488						flags: append([]string{
7489							"-select-alpn", "proto",
7490						}, flags...),
7491						expectations: connectionExpectations{
7492							peerApplicationSettings: test.initialSettings,
7493						},
7494						resumeExpectations: &connectionExpectations{
7495							peerApplicationSettings: test.resumeSettings,
7496						},
7497					})
7498				}
7499
7500				// Test that 0-RTT continues working when the shim configures
7501				// ALPS but the peer does not.
7502				testCases = append(testCases, testCase{
7503					protocol:           protocol,
7504					testType:           clientTest,
7505					name:               "ALPS-EarlyData-Client-ServerDecline-" + suffix,
7506					skipQUICALPNConfig: true,
7507					config: Config{
7508						MaxVersion: ver.version,
7509						NextProtos: []string{"proto"},
7510					},
7511					resumeSession: true,
7512					earlyData:     true,
7513					flags: []string{
7514						"-advertise-alpn", "\x05proto",
7515						"-expect-alpn", "proto",
7516						"-application-settings", "proto,shim",
7517					},
7518				})
7519				testCases = append(testCases, testCase{
7520					protocol:           protocol,
7521					testType:           serverTest,
7522					name:               "ALPS-EarlyData-Server-ClientNoOffer-" + suffix,
7523					skipQUICALPNConfig: true,
7524					config: Config{
7525						MaxVersion: ver.version,
7526						NextProtos: []string{"proto"},
7527					},
7528					resumeSession: true,
7529					earlyData:     true,
7530					flags: []string{
7531						"-select-alpn", "proto",
7532						"-application-settings", "proto,shim",
7533					},
7534				})
7535			} else {
7536				// Test the client rejects the ALPS extension if the server
7537				// negotiated TLS 1.2 or below.
7538				testCases = append(testCases, testCase{
7539					protocol: protocol,
7540					testType: clientTest,
7541					name:     "ALPS-Reject-Client-" + suffix,
7542					config: Config{
7543						MaxVersion:          ver.version,
7544						NextProtos:          []string{"foo"},
7545						ApplicationSettings: map[string][]byte{"foo": []byte("runner")},
7546						Bugs: ProtocolBugs{
7547							AlwaysNegotiateApplicationSettings: true,
7548						},
7549					},
7550					flags: []string{
7551						"-advertise-alpn", "\x03foo",
7552						"-expect-alpn", "foo",
7553						"-application-settings", "foo,shim",
7554					},
7555					shouldFail:         true,
7556					expectedError:      ":UNEXPECTED_EXTENSION:",
7557					expectedLocalError: "remote error: unsupported extension",
7558				})
7559				testCases = append(testCases, testCase{
7560					protocol: protocol,
7561					testType: clientTest,
7562					name:     "ALPS-Reject-Client-Resume-" + suffix,
7563					config: Config{
7564						MaxVersion: ver.version,
7565					},
7566					resumeConfig: &Config{
7567						MaxVersion:          ver.version,
7568						NextProtos:          []string{"foo"},
7569						ApplicationSettings: map[string][]byte{"foo": []byte("runner")},
7570						Bugs: ProtocolBugs{
7571							AlwaysNegotiateApplicationSettings: true,
7572						},
7573					},
7574					resumeSession: true,
7575					flags: []string{
7576						"-on-resume-advertise-alpn", "\x03foo",
7577						"-on-resume-expect-alpn", "foo",
7578						"-on-resume-application-settings", "foo,shim",
7579					},
7580					shouldFail:         true,
7581					expectedError:      ":UNEXPECTED_EXTENSION:",
7582					expectedLocalError: "remote error: unsupported extension",
7583				})
7584
7585				// Test the server declines ALPS if it negotiates TLS 1.2 or below.
7586				testCases = append(testCases, testCase{
7587					protocol: protocol,
7588					testType: serverTest,
7589					name:     "ALPS-Decline-Server-" + suffix,
7590					config: Config{
7591						MaxVersion:          ver.version,
7592						NextProtos:          []string{"foo"},
7593						ApplicationSettings: map[string][]byte{"foo": []byte("runner")},
7594					},
7595					// Test both TLS 1.2 full and resumption handshakes.
7596					resumeSession: true,
7597					flags: []string{
7598						"-select-alpn", "foo",
7599						"-application-settings", "foo,shim",
7600					},
7601					// If not specified, runner and shim both implicitly expect ALPS
7602					// is not negotiated.
7603				})
7604			}
7605
7606			// Test Token Binding.
7607			if protocol != dtls {
7608				const maxTokenBindingVersion = 16
7609				const minTokenBindingVersion = 13
7610				testCases = append(testCases, testCase{
7611					protocol: protocol,
7612					testType: serverTest,
7613					name:     "TokenBinding-Server-" + suffix,
7614
7615					config: Config{
7616						MinVersion:          ver.version,
7617						MaxVersion:          ver.version,
7618						TokenBindingParams:  []byte{0, 1, 2},
7619						TokenBindingVersion: maxTokenBindingVersion,
7620					},
7621					expectations: connectionExpectations{
7622						tokenBinding:      true,
7623						tokenBindingParam: 2,
7624					},
7625					flags: []string{
7626						"-token-binding-params",
7627						base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7628						"-expect-token-binding-param",
7629						"2",
7630					},
7631				})
7632				testCases = append(testCases, testCase{
7633					protocol: protocol,
7634					testType: serverTest,
7635					name:     "TokenBinding-Server-UnsupportedParam-" + suffix,
7636
7637					config: Config{
7638						MinVersion:          ver.version,
7639						MaxVersion:          ver.version,
7640						TokenBindingParams:  []byte{3},
7641						TokenBindingVersion: maxTokenBindingVersion,
7642					},
7643					flags: []string{
7644						"-token-binding-params",
7645						base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7646					},
7647				})
7648				testCases = append(testCases, testCase{
7649					protocol: protocol,
7650					testType: serverTest,
7651					name:     "TokenBinding-Server-OldVersion-" + suffix,
7652
7653					config: Config{
7654						MinVersion:          ver.version,
7655						MaxVersion:          ver.version,
7656						TokenBindingParams:  []byte{0, 1, 2},
7657						TokenBindingVersion: minTokenBindingVersion - 1,
7658					},
7659					flags: []string{
7660						"-token-binding-params",
7661						base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7662					},
7663				})
7664				testCases = append(testCases, testCase{
7665					protocol: protocol,
7666					testType: serverTest,
7667					name:     "TokenBinding-Server-NewVersion-" + suffix,
7668
7669					config: Config{
7670						MinVersion:          ver.version,
7671						MaxVersion:          ver.version,
7672						TokenBindingParams:  []byte{0, 1, 2},
7673						TokenBindingVersion: maxTokenBindingVersion + 1,
7674					},
7675					expectations: connectionExpectations{
7676						tokenBinding:      true,
7677						tokenBindingParam: 2,
7678					},
7679					flags: []string{
7680						"-token-binding-params",
7681						base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7682						"-expect-token-binding-param",
7683						"2",
7684					},
7685				})
7686				testCases = append(testCases, testCase{
7687					protocol: protocol,
7688					testType: serverTest,
7689					name:     "TokenBinding-Server-NoParams-" + suffix,
7690
7691					config: Config{
7692						MinVersion:          ver.version,
7693						MaxVersion:          ver.version,
7694						TokenBindingParams:  []byte{},
7695						TokenBindingVersion: maxTokenBindingVersion,
7696					},
7697					flags: []string{
7698						"-token-binding-params",
7699						base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7700					},
7701					shouldFail:    true,
7702					expectedError: ":ERROR_PARSING_EXTENSION:",
7703				})
7704				testCases = append(testCases, testCase{
7705					protocol: protocol,
7706					testType: serverTest,
7707					name:     "TokenBinding-Server-RepeatedParam" + suffix,
7708
7709					config: Config{
7710						MinVersion:          ver.version,
7711						MaxVersion:          ver.version,
7712						TokenBindingParams:  []byte{0, 1, 2, 2},
7713						TokenBindingVersion: maxTokenBindingVersion,
7714					},
7715					expectations: connectionExpectations{
7716						tokenBinding:      true,
7717						tokenBindingParam: 2,
7718					},
7719					flags: []string{
7720						"-token-binding-params",
7721						base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7722						"-expect-token-binding-param",
7723						"2",
7724					},
7725				})
7726				testCases = append(testCases, testCase{
7727					protocol: protocol,
7728					testType: clientTest,
7729					name:     "TokenBinding-Client-" + suffix,
7730
7731					config: Config{
7732						MinVersion:               ver.version,
7733						MaxVersion:               ver.version,
7734						TokenBindingParams:       []byte{2},
7735						TokenBindingVersion:      maxTokenBindingVersion,
7736						ExpectTokenBindingParams: []byte{0, 1, 2},
7737					},
7738					flags: []string{
7739						"-token-binding-params",
7740						base64.StdEncoding.EncodeToString([]byte{0, 1, 2}),
7741						"-expect-token-binding-param",
7742						"2",
7743					},
7744				})
7745				testCases = append(testCases, testCase{
7746					protocol: protocol,
7747					testType: clientTest,
7748					name:     "TokenBinding-Client-Unexpected-" + suffix,
7749
7750					config: Config{
7751						MinVersion:          ver.version,
7752						MaxVersion:          ver.version,
7753						TokenBindingParams:  []byte{2},
7754						TokenBindingVersion: maxTokenBindingVersion,
7755					},
7756					shouldFail:    true,
7757					expectedError: ":UNEXPECTED_EXTENSION:",
7758				})
7759				testCases = append(testCases, testCase{
7760					protocol: protocol,
7761					testType: clientTest,
7762					name:     "TokenBinding-Client-ExtraParams-" + suffix,
7763
7764					config: Config{
7765						MinVersion:               ver.version,
7766						MaxVersion:               ver.version,
7767						TokenBindingParams:       []byte{2, 1},
7768						TokenBindingVersion:      maxTokenBindingVersion,
7769						ExpectTokenBindingParams: []byte{0, 1, 2},
7770					},
7771					flags: []string{
7772						"-token-binding-params",
7773						base64.StdEncoding.EncodeToString([]byte{0, 1, 2}),
7774						"-expect-token-binding-param",
7775						"2",
7776					},
7777					shouldFail:    true,
7778					expectedError: ":ERROR_PARSING_EXTENSION:",
7779				})
7780				testCases = append(testCases, testCase{
7781					protocol: protocol,
7782					testType: clientTest,
7783					name:     "TokenBinding-Client-NoParams-" + suffix,
7784
7785					config: Config{
7786						MinVersion:               ver.version,
7787						MaxVersion:               ver.version,
7788						TokenBindingParams:       []byte{},
7789						TokenBindingVersion:      maxTokenBindingVersion,
7790						ExpectTokenBindingParams: []byte{0, 1, 2},
7791					},
7792					flags: []string{
7793						"-token-binding-params",
7794						base64.StdEncoding.EncodeToString([]byte{0, 1, 2}),
7795						"-expect-token-binding-param",
7796						"2",
7797					},
7798					shouldFail:    true,
7799					expectedError: ":ERROR_PARSING_EXTENSION:",
7800				})
7801				testCases = append(testCases, testCase{
7802					protocol: protocol,
7803					testType: clientTest,
7804					name:     "TokenBinding-Client-WrongParam-" + suffix,
7805
7806					config: Config{
7807						MinVersion:               ver.version,
7808						MaxVersion:               ver.version,
7809						TokenBindingParams:       []byte{3},
7810						TokenBindingVersion:      maxTokenBindingVersion,
7811						ExpectTokenBindingParams: []byte{0, 1, 2},
7812					},
7813					flags: []string{
7814						"-token-binding-params",
7815						base64.StdEncoding.EncodeToString([]byte{0, 1, 2}),
7816						"-expect-token-binding-param",
7817						"2",
7818					},
7819					shouldFail:    true,
7820					expectedError: ":ERROR_PARSING_EXTENSION:",
7821				})
7822				testCases = append(testCases, testCase{
7823					protocol: protocol,
7824					testType: clientTest,
7825					name:     "TokenBinding-Client-OldVersion-" + suffix,
7826
7827					config: Config{
7828						MinVersion:               ver.version,
7829						MaxVersion:               ver.version,
7830						TokenBindingParams:       []byte{2},
7831						TokenBindingVersion:      minTokenBindingVersion - 1,
7832						ExpectTokenBindingParams: []byte{0, 1, 2},
7833					},
7834					flags: []string{
7835						"-token-binding-params",
7836						base64.StdEncoding.EncodeToString([]byte{0, 1, 2}),
7837					},
7838				})
7839				testCases = append(testCases, testCase{
7840					protocol: protocol,
7841					testType: clientTest,
7842					name:     "TokenBinding-Client-MinVersion-" + suffix,
7843
7844					config: Config{
7845						MinVersion:               ver.version,
7846						MaxVersion:               ver.version,
7847						TokenBindingParams:       []byte{2},
7848						TokenBindingVersion:      minTokenBindingVersion,
7849						ExpectTokenBindingParams: []byte{0, 1, 2},
7850					},
7851					flags: []string{
7852						"-token-binding-params",
7853						base64.StdEncoding.EncodeToString([]byte{0, 1, 2}),
7854						"-expect-token-binding-param",
7855						"2",
7856					},
7857				})
7858				testCases = append(testCases, testCase{
7859					protocol: protocol,
7860					testType: clientTest,
7861					name:     "TokenBinding-Client-VersionTooNew-" + suffix,
7862
7863					config: Config{
7864						MinVersion:               ver.version,
7865						MaxVersion:               ver.version,
7866						TokenBindingParams:       []byte{2},
7867						TokenBindingVersion:      maxTokenBindingVersion + 1,
7868						ExpectTokenBindingParams: []byte{0, 1, 2},
7869					},
7870					flags: []string{
7871						"-token-binding-params",
7872						base64.StdEncoding.EncodeToString([]byte{0, 1, 2}),
7873					},
7874					shouldFail:    true,
7875					expectedError: "ERROR_PARSING_EXTENSION",
7876				})
7877				if ver.version < VersionTLS13 {
7878					testCases = append(testCases, testCase{
7879						protocol: protocol,
7880						testType: clientTest,
7881						name:     "TokenBinding-Client-NoEMS-" + suffix,
7882
7883						config: Config{
7884							MinVersion:               ver.version,
7885							MaxVersion:               ver.version,
7886							TokenBindingParams:       []byte{2},
7887							TokenBindingVersion:      maxTokenBindingVersion,
7888							ExpectTokenBindingParams: []byte{2, 1, 0},
7889							Bugs: ProtocolBugs{
7890								NoExtendedMasterSecret: true,
7891							},
7892						},
7893						flags: []string{
7894							"-token-binding-params",
7895							base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7896						},
7897						shouldFail:    true,
7898						expectedError: ":NEGOTIATED_TB_WITHOUT_EMS_OR_RI:",
7899					})
7900					testCases = append(testCases, testCase{
7901						protocol: protocol,
7902						testType: serverTest,
7903						name:     "TokenBinding-Server-NoEMS-" + suffix,
7904
7905						config: Config{
7906							MinVersion:          ver.version,
7907							MaxVersion:          ver.version,
7908							TokenBindingParams:  []byte{0, 1, 2},
7909							TokenBindingVersion: maxTokenBindingVersion,
7910							Bugs: ProtocolBugs{
7911								NoExtendedMasterSecret: true,
7912							},
7913						},
7914						flags: []string{
7915							"-token-binding-params",
7916							base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7917						},
7918						shouldFail:    true,
7919						expectedError: ":NEGOTIATED_TB_WITHOUT_EMS_OR_RI:",
7920					})
7921					testCases = append(testCases, testCase{
7922						protocol: protocol,
7923						testType: clientTest,
7924						name:     "TokenBinding-Client-NoRI-" + suffix,
7925
7926						config: Config{
7927							MinVersion:               ver.version,
7928							MaxVersion:               ver.version,
7929							TokenBindingParams:       []byte{2},
7930							TokenBindingVersion:      maxTokenBindingVersion,
7931							ExpectTokenBindingParams: []byte{2, 1, 0},
7932							Bugs: ProtocolBugs{
7933								NoRenegotiationInfo: true,
7934							},
7935						},
7936						flags: []string{
7937							"-token-binding-params",
7938							base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7939						},
7940						shouldFail:    true,
7941						expectedError: ":NEGOTIATED_TB_WITHOUT_EMS_OR_RI:",
7942					})
7943					testCases = append(testCases, testCase{
7944						protocol: protocol,
7945						testType: serverTest,
7946						name:     "TokenBinding-Server-NoRI-" + suffix,
7947
7948						config: Config{
7949							MinVersion:          ver.version,
7950							MaxVersion:          ver.version,
7951							TokenBindingParams:  []byte{0, 1, 2},
7952							TokenBindingVersion: maxTokenBindingVersion,
7953							Bugs: ProtocolBugs{
7954								NoRenegotiationInfo: true,
7955							},
7956						},
7957						flags: []string{
7958							"-token-binding-params",
7959							base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7960						},
7961						shouldFail:    true,
7962						expectedError: ":NEGOTIATED_TB_WITHOUT_EMS_OR_RI:",
7963					})
7964				} else {
7965					testCases = append(testCases, testCase{
7966						protocol: protocol,
7967						testType: clientTest,
7968						name:     "TokenBinding-WithEarlyDataFails-" + suffix,
7969						config: Config{
7970							MinVersion:               ver.version,
7971							MaxVersion:               ver.version,
7972							TokenBindingParams:       []byte{2},
7973							TokenBindingVersion:      maxTokenBindingVersion,
7974							ExpectTokenBindingParams: []byte{2, 1, 0},
7975						},
7976						resumeSession: true,
7977						earlyData:     true,
7978						flags: []string{
7979							"-token-binding-params",
7980							base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
7981						},
7982						shouldFail:    true,
7983						expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:",
7984					})
7985					testCases = append(testCases, testCase{
7986						protocol: protocol,
7987						testType: serverTest,
7988						name:     "TokenBinding-EarlyDataRejected-" + suffix,
7989						config: Config{
7990							MinVersion:          ver.version,
7991							MaxVersion:          ver.version,
7992							TokenBindingParams:  []byte{0, 1, 2},
7993							TokenBindingVersion: maxTokenBindingVersion,
7994						},
7995						resumeSession:           true,
7996						earlyData:               true,
7997						expectEarlyDataRejected: true,
7998						expectations: connectionExpectations{
7999							tokenBinding:      true,
8000							tokenBindingParam: 2,
8001						},
8002						flags: []string{
8003							"-token-binding-params",
8004							base64.StdEncoding.EncodeToString([]byte{2, 1, 0}),
8005							"-on-retry-expect-early-data-reason", "token_binding",
8006						},
8007					})
8008				}
8009			}
8010
8011			// Test QUIC transport params
8012			if protocol == quic {
8013				// Client sends params
8014				for _, clientConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} {
8015					for _, serverSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} {
8016						useCodepointFlag := "0"
8017						if clientConfig == QUICUseCodepointLegacy {
8018							useCodepointFlag = "1"
8019						}
8020						flags := []string{
8021							"-quic-transport-params",
8022							base64.StdEncoding.EncodeToString([]byte{1, 2}),
8023							"-quic-use-legacy-codepoint", useCodepointFlag,
8024						}
8025						expectations := connectionExpectations{
8026							quicTransportParams: []byte{1, 2},
8027						}
8028						shouldFail := false
8029						expectedError := ""
8030						expectedLocalError := ""
8031						if clientConfig == QUICUseCodepointLegacy {
8032							expectations = connectionExpectations{
8033								quicTransportParamsLegacy: []byte{1, 2},
8034							}
8035						}
8036						if serverSends != clientConfig {
8037							expectations = connectionExpectations{}
8038							shouldFail = true
8039							if serverSends == QUICUseCodepointNeither {
8040								expectedError = ":MISSING_EXTENSION:"
8041							} else {
8042								expectedLocalError = "remote error: unsupported extension"
8043							}
8044						} else {
8045							flags = append(flags,
8046								"-expect-quic-transport-params",
8047								base64.StdEncoding.EncodeToString([]byte{3, 4}))
8048						}
8049						testCases = append(testCases, testCase{
8050							testType: clientTest,
8051							protocol: protocol,
8052							name:     fmt.Sprintf("QUICTransportParams-Client-Client%s-Server%s-%s", clientConfig, serverSends, suffix),
8053							config: Config{
8054								MinVersion:                            ver.version,
8055								MaxVersion:                            ver.version,
8056								QUICTransportParams:                   []byte{3, 4},
8057								QUICTransportParamsUseLegacyCodepoint: serverSends,
8058							},
8059							flags:                     flags,
8060							expectations:              expectations,
8061							shouldFail:                shouldFail,
8062							expectedError:             expectedError,
8063							expectedLocalError:        expectedLocalError,
8064							skipTransportParamsConfig: true,
8065						})
8066					}
8067				}
8068				// Server sends params
8069				for _, clientSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} {
8070					for _, serverConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} {
8071						expectations := connectionExpectations{
8072							quicTransportParams: []byte{3, 4},
8073						}
8074						shouldFail := false
8075						expectedError := ""
8076						useCodepointFlag := "0"
8077						if serverConfig == QUICUseCodepointLegacy {
8078							useCodepointFlag = "1"
8079							expectations = connectionExpectations{
8080								quicTransportParamsLegacy: []byte{3, 4},
8081							}
8082						}
8083						flags := []string{
8084							"-quic-transport-params",
8085							base64.StdEncoding.EncodeToString([]byte{3, 4}),
8086							"-quic-use-legacy-codepoint", useCodepointFlag,
8087						}
8088						if clientSends != QUICUseCodepointBoth && clientSends != serverConfig {
8089							expectations = connectionExpectations{}
8090							shouldFail = true
8091							expectedError = ":MISSING_EXTENSION:"
8092						} else {
8093							flags = append(flags,
8094								"-expect-quic-transport-params",
8095								base64.StdEncoding.EncodeToString([]byte{1, 2}),
8096							)
8097						}
8098						testCases = append(testCases, testCase{
8099							testType: serverTest,
8100							protocol: protocol,
8101							name:     fmt.Sprintf("QUICTransportParams-Server-Client%s-Server%s-%s", clientSends, serverConfig, suffix),
8102							config: Config{
8103								MinVersion:                            ver.version,
8104								MaxVersion:                            ver.version,
8105								QUICTransportParams:                   []byte{1, 2},
8106								QUICTransportParamsUseLegacyCodepoint: clientSends,
8107							},
8108							flags:                     flags,
8109							expectations:              expectations,
8110							shouldFail:                shouldFail,
8111							expectedError:             expectedError,
8112							skipTransportParamsConfig: true,
8113						})
8114					}
8115				}
8116			} else {
8117				// Ensure non-QUIC client doesn't send QUIC transport parameters.
8118				for _, clientConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} {
8119					useCodepointFlag := "0"
8120					if clientConfig == QUICUseCodepointLegacy {
8121						useCodepointFlag = "1"
8122					}
8123					testCases = append(testCases, testCase{
8124						protocol: protocol,
8125						testType: clientTest,
8126						name:     fmt.Sprintf("QUICTransportParams-Client-NotSentInNonQUIC-%s-%s", clientConfig, suffix),
8127						config: Config{
8128							MinVersion:                            ver.version,
8129							MaxVersion:                            ver.version,
8130							QUICTransportParamsUseLegacyCodepoint: clientConfig,
8131						},
8132						flags: []string{
8133							"-max-version",
8134							strconv.Itoa(int(ver.versionWire)),
8135							"-quic-transport-params",
8136							base64.StdEncoding.EncodeToString([]byte{3, 4}),
8137							"-quic-use-legacy-codepoint", useCodepointFlag,
8138						},
8139						shouldFail:                true,
8140						expectedError:             ":QUIC_TRANSPORT_PARAMETERS_MISCONFIGURED:",
8141						skipTransportParamsConfig: true,
8142					})
8143				}
8144				// Ensure non-QUIC server rejects codepoint 57 but ignores legacy 0xffa5.
8145				for _, clientSends := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy, QUICUseCodepointBoth, QUICUseCodepointNeither} {
8146					for _, serverConfig := range []QUICUseCodepoint{QUICUseCodepointStandard, QUICUseCodepointLegacy} {
8147						shouldFail := false
8148						expectedLocalError := ""
8149						useCodepointFlag := "0"
8150						if serverConfig == QUICUseCodepointLegacy {
8151							useCodepointFlag = "1"
8152						}
8153						if clientSends == QUICUseCodepointStandard || clientSends == QUICUseCodepointBoth {
8154							shouldFail = true
8155							expectedLocalError = "remote error: unsupported extension"
8156						}
8157						testCases = append(testCases, testCase{
8158							protocol: protocol,
8159							testType: serverTest,
8160							name:     fmt.Sprintf("QUICTransportParams-NonQUICServer-Client%s-Server%s-%s", clientSends, serverConfig, suffix),
8161							config: Config{
8162								MinVersion:                            ver.version,
8163								MaxVersion:                            ver.version,
8164								QUICTransportParams:                   []byte{1, 2},
8165								QUICTransportParamsUseLegacyCodepoint: clientSends,
8166							},
8167							flags: []string{
8168								"-quic-use-legacy-codepoint", useCodepointFlag,
8169							},
8170							shouldFail:                shouldFail,
8171							expectedLocalError:        expectedLocalError,
8172							skipTransportParamsConfig: true,
8173						})
8174					}
8175				}
8176
8177			}
8178
8179			// Test ticket behavior.
8180
8181			// Resume with a corrupt ticket.
8182			testCases = append(testCases, testCase{
8183				protocol: protocol,
8184				testType: serverTest,
8185				name:     "CorruptTicket-" + suffix,
8186				config: Config{
8187					MaxVersion: ver.version,
8188					Bugs: ProtocolBugs{
8189						FilterTicket: func(in []byte) ([]byte, error) {
8190							in[len(in)-1] ^= 1
8191							return in, nil
8192						},
8193					},
8194				},
8195				resumeSession:        true,
8196				expectResumeRejected: true,
8197			})
8198			// Test the ticket callback, with and without renewal.
8199			testCases = append(testCases, testCase{
8200				protocol: protocol,
8201				testType: serverTest,
8202				name:     "TicketCallback-" + suffix,
8203				config: Config{
8204					MaxVersion: ver.version,
8205				},
8206				resumeSession: true,
8207				flags:         []string{"-use-ticket-callback"},
8208			})
8209			testCases = append(testCases, testCase{
8210				protocol: protocol,
8211				testType: serverTest,
8212				name:     "TicketCallback-Renew-" + suffix,
8213				config: Config{
8214					MaxVersion: ver.version,
8215					Bugs: ProtocolBugs{
8216						ExpectNewTicket: true,
8217					},
8218				},
8219				flags:         []string{"-use-ticket-callback", "-renew-ticket"},
8220				resumeSession: true,
8221			})
8222
8223			// Test that the ticket callback is only called once when everything before
8224			// it in the ClientHello is asynchronous. This corrupts the ticket so
8225			// certificate selection callbacks run.
8226			testCases = append(testCases, testCase{
8227				protocol: protocol,
8228				testType: serverTest,
8229				name:     "TicketCallback-SingleCall-" + suffix,
8230				config: Config{
8231					MaxVersion: ver.version,
8232					Bugs: ProtocolBugs{
8233						FilterTicket: func(in []byte) ([]byte, error) {
8234							in[len(in)-1] ^= 1
8235							return in, nil
8236						},
8237					},
8238				},
8239				resumeSession:        true,
8240				expectResumeRejected: true,
8241				flags: []string{
8242					"-use-ticket-callback",
8243					"-async",
8244				},
8245			})
8246
8247			// Resume with various lengths of ticket session id.
8248			if ver.version < VersionTLS13 {
8249				testCases = append(testCases, testCase{
8250					protocol: protocol,
8251					testType: serverTest,
8252					name:     "TicketSessionIDLength-0-" + suffix,
8253					config: Config{
8254						MaxVersion: ver.version,
8255						Bugs: ProtocolBugs{
8256							EmptyTicketSessionID: true,
8257						},
8258					},
8259					resumeSession: true,
8260				})
8261				testCases = append(testCases, testCase{
8262					protocol: protocol,
8263					testType: serverTest,
8264					name:     "TicketSessionIDLength-16-" + suffix,
8265					config: Config{
8266						MaxVersion: ver.version,
8267						Bugs: ProtocolBugs{
8268							TicketSessionIDLength: 16,
8269						},
8270					},
8271					resumeSession: true,
8272				})
8273				testCases = append(testCases, testCase{
8274					protocol: protocol,
8275					testType: serverTest,
8276					name:     "TicketSessionIDLength-32-" + suffix,
8277					config: Config{
8278						MaxVersion: ver.version,
8279						Bugs: ProtocolBugs{
8280							TicketSessionIDLength: 32,
8281						},
8282					},
8283					resumeSession: true,
8284				})
8285				testCases = append(testCases, testCase{
8286					protocol: protocol,
8287					testType: serverTest,
8288					name:     "TicketSessionIDLength-33-" + suffix,
8289					config: Config{
8290						MaxVersion: ver.version,
8291						Bugs: ProtocolBugs{
8292							TicketSessionIDLength: 33,
8293						},
8294					},
8295					resumeSession: true,
8296					shouldFail:    true,
8297					// The maximum session ID length is 32.
8298					expectedError: ":DECODE_ERROR:",
8299				})
8300			}
8301
8302			// Basic DTLS-SRTP tests. Include fake profiles to ensure they
8303			// are ignored.
8304			if protocol == dtls {
8305				testCases = append(testCases, testCase{
8306					protocol: protocol,
8307					name:     "SRTP-Client-" + suffix,
8308					config: Config{
8309						MaxVersion:             ver.version,
8310						SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
8311					},
8312					flags: []string{
8313						"-srtp-profiles",
8314						"SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
8315					},
8316					expectations: connectionExpectations{
8317						srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
8318					},
8319				})
8320				testCases = append(testCases, testCase{
8321					protocol: protocol,
8322					testType: serverTest,
8323					name:     "SRTP-Server-" + suffix,
8324					config: Config{
8325						MaxVersion:             ver.version,
8326						SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
8327					},
8328					flags: []string{
8329						"-srtp-profiles",
8330						"SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
8331					},
8332					expectations: connectionExpectations{
8333						srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
8334					},
8335				})
8336				// Test that the MKI is ignored.
8337				testCases = append(testCases, testCase{
8338					protocol: protocol,
8339					testType: serverTest,
8340					name:     "SRTP-Server-IgnoreMKI-" + suffix,
8341					config: Config{
8342						MaxVersion:             ver.version,
8343						SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80},
8344						Bugs: ProtocolBugs{
8345							SRTPMasterKeyIdentifer: "bogus",
8346						},
8347					},
8348					flags: []string{
8349						"-srtp-profiles",
8350						"SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
8351					},
8352					expectations: connectionExpectations{
8353						srtpProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
8354					},
8355				})
8356				// Test that SRTP isn't negotiated on the server if there were
8357				// no matching profiles.
8358				testCases = append(testCases, testCase{
8359					protocol: protocol,
8360					testType: serverTest,
8361					name:     "SRTP-Server-NoMatch-" + suffix,
8362					config: Config{
8363						MaxVersion:             ver.version,
8364						SRTPProtectionProfiles: []uint16{100, 101, 102},
8365					},
8366					flags: []string{
8367						"-srtp-profiles",
8368						"SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
8369					},
8370					expectations: connectionExpectations{
8371						srtpProtectionProfile: 0,
8372					},
8373				})
8374				// Test that the server returning an invalid SRTP profile is
8375				// flagged as an error by the client.
8376				testCases = append(testCases, testCase{
8377					protocol: protocol,
8378					name:     "SRTP-Client-NoMatch-" + suffix,
8379					config: Config{
8380						MaxVersion: ver.version,
8381						Bugs: ProtocolBugs{
8382							SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32,
8383						},
8384					},
8385					flags: []string{
8386						"-srtp-profiles",
8387						"SRTP_AES128_CM_SHA1_80",
8388					},
8389					shouldFail:    true,
8390					expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:",
8391				})
8392			}
8393
8394			// Test SCT list.
8395			testCases = append(testCases, testCase{
8396				protocol: protocol,
8397				name:     "SignedCertificateTimestampList-Client-" + suffix,
8398				testType: clientTest,
8399				config: Config{
8400					MaxVersion: ver.version,
8401				},
8402				flags: []string{
8403					"-enable-signed-cert-timestamps",
8404					"-expect-signed-cert-timestamps",
8405					base64.StdEncoding.EncodeToString(testSCTList),
8406				},
8407				resumeSession: true,
8408			})
8409
8410			var differentSCTList []byte
8411			differentSCTList = append(differentSCTList, testSCTList...)
8412			differentSCTList[len(differentSCTList)-1] ^= 1
8413
8414			// The SCT extension did not specify that it must only be sent on resumption as it
8415			// should have, so test that we tolerate but ignore it.
8416			testCases = append(testCases, testCase{
8417				protocol: protocol,
8418				name:     "SendSCTListOnResume-" + suffix,
8419				config: Config{
8420					MaxVersion: ver.version,
8421					Bugs: ProtocolBugs{
8422						SendSCTListOnResume: differentSCTList,
8423					},
8424				},
8425				flags: []string{
8426					"-enable-signed-cert-timestamps",
8427					"-expect-signed-cert-timestamps",
8428					base64.StdEncoding.EncodeToString(testSCTList),
8429				},
8430				resumeSession: true,
8431			})
8432
8433			testCases = append(testCases, testCase{
8434				protocol: protocol,
8435				name:     "SignedCertificateTimestampList-Server-" + suffix,
8436				testType: serverTest,
8437				config: Config{
8438					MaxVersion: ver.version,
8439				},
8440				flags: []string{
8441					"-signed-cert-timestamps",
8442					base64.StdEncoding.EncodeToString(testSCTList),
8443				},
8444				expectations: connectionExpectations{
8445					sctList: testSCTList,
8446				},
8447				resumeSession: true,
8448			})
8449
8450			emptySCTListCert := *testCerts[0].cert
8451			emptySCTListCert.SignedCertificateTimestampList = []byte{0, 0}
8452
8453			// Test empty SCT list.
8454			testCases = append(testCases, testCase{
8455				protocol: protocol,
8456				name:     "SignedCertificateTimestampListEmpty-Client-" + suffix,
8457				testType: clientTest,
8458				config: Config{
8459					MaxVersion:   ver.version,
8460					Certificates: []Certificate{emptySCTListCert},
8461				},
8462				flags: []string{
8463					"-enable-signed-cert-timestamps",
8464				},
8465				shouldFail:    true,
8466				expectedError: ":ERROR_PARSING_EXTENSION:",
8467			})
8468
8469			emptySCTCert := *testCerts[0].cert
8470			emptySCTCert.SignedCertificateTimestampList = []byte{0, 6, 0, 2, 1, 2, 0, 0}
8471
8472			// Test empty SCT in non-empty list.
8473			testCases = append(testCases, testCase{
8474				protocol: protocol,
8475				name:     "SignedCertificateTimestampListEmptySCT-Client-" + suffix,
8476				testType: clientTest,
8477				config: Config{
8478					MaxVersion:   ver.version,
8479					Certificates: []Certificate{emptySCTCert},
8480				},
8481				flags: []string{
8482					"-enable-signed-cert-timestamps",
8483				},
8484				shouldFail:    true,
8485				expectedError: ":ERROR_PARSING_EXTENSION:",
8486			})
8487
8488			// Test that certificate-related extensions are not sent unsolicited.
8489			testCases = append(testCases, testCase{
8490				protocol: protocol,
8491				testType: serverTest,
8492				name:     "UnsolicitedCertificateExtensions-" + suffix,
8493				config: Config{
8494					MaxVersion: ver.version,
8495					Bugs: ProtocolBugs{
8496						NoOCSPStapling:                true,
8497						NoSignedCertificateTimestamps: true,
8498					},
8499				},
8500				flags: []string{
8501					"-ocsp-response",
8502					base64.StdEncoding.EncodeToString(testOCSPResponse),
8503					"-signed-cert-timestamps",
8504					base64.StdEncoding.EncodeToString(testSCTList),
8505				},
8506			})
8507		}
8508	}
8509
8510	testCases = append(testCases, testCase{
8511		testType: clientTest,
8512		name:     "ClientHelloPadding",
8513		config: Config{
8514			Bugs: ProtocolBugs{
8515				RequireClientHelloSize: 512,
8516			},
8517		},
8518		// This hostname just needs to be long enough to push the
8519		// ClientHello into F5's danger zone between 256 and 511 bytes
8520		// long.
8521		flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"},
8522	})
8523
8524	// Test that illegal extensions in TLS 1.3 are rejected by the client if
8525	// in ServerHello.
8526	testCases = append(testCases, testCase{
8527		name: "NPN-Forbidden-TLS13",
8528		config: Config{
8529			MaxVersion: VersionTLS13,
8530			NextProtos: []string{"foo"},
8531			Bugs: ProtocolBugs{
8532				NegotiateNPNAtAllVersions: true,
8533			},
8534		},
8535		flags:         []string{"-select-next-proto", "foo"},
8536		shouldFail:    true,
8537		expectedError: ":ERROR_PARSING_EXTENSION:",
8538	})
8539	testCases = append(testCases, testCase{
8540		name: "EMS-Forbidden-TLS13",
8541		config: Config{
8542			MaxVersion: VersionTLS13,
8543			Bugs: ProtocolBugs{
8544				NegotiateEMSAtAllVersions: true,
8545			},
8546		},
8547		shouldFail:    true,
8548		expectedError: ":ERROR_PARSING_EXTENSION:",
8549	})
8550	testCases = append(testCases, testCase{
8551		name: "RenegotiationInfo-Forbidden-TLS13",
8552		config: Config{
8553			MaxVersion: VersionTLS13,
8554			Bugs: ProtocolBugs{
8555				NegotiateRenegotiationInfoAtAllVersions: true,
8556			},
8557		},
8558		shouldFail:    true,
8559		expectedError: ":ERROR_PARSING_EXTENSION:",
8560	})
8561	testCases = append(testCases, testCase{
8562		name: "Ticket-Forbidden-TLS13",
8563		config: Config{
8564			MaxVersion: VersionTLS12,
8565		},
8566		resumeConfig: &Config{
8567			MaxVersion: VersionTLS13,
8568			Bugs: ProtocolBugs{
8569				AdvertiseTicketExtension: true,
8570			},
8571		},
8572		resumeSession: true,
8573		shouldFail:    true,
8574		expectedError: ":ERROR_PARSING_EXTENSION:",
8575	})
8576
8577	// Test that illegal extensions in TLS 1.3 are declined by the server if
8578	// offered in ClientHello. The runner's server will fail if this occurs,
8579	// so we exercise the offering path. (EMS and Renegotiation Info are
8580	// implicit in every test.)
8581	testCases = append(testCases, testCase{
8582		testType: serverTest,
8583		name:     "NPN-Declined-TLS13",
8584		config: Config{
8585			MaxVersion: VersionTLS13,
8586			NextProtos: []string{"bar"},
8587		},
8588		flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"},
8589	})
8590
8591	// OpenSSL sends the status_request extension on resumption in TLS 1.2. Test that this is
8592	// tolerated.
8593	testCases = append(testCases, testCase{
8594		name: "SendOCSPResponseOnResume-TLS12",
8595		config: Config{
8596			MaxVersion: VersionTLS12,
8597			Bugs: ProtocolBugs{
8598				SendOCSPResponseOnResume: []byte("bogus"),
8599			},
8600		},
8601		flags: []string{
8602			"-enable-ocsp-stapling",
8603			"-expect-ocsp-response",
8604			base64.StdEncoding.EncodeToString(testOCSPResponse),
8605		},
8606		resumeSession: true,
8607	})
8608
8609	testCases = append(testCases, testCase{
8610		name: "SendUnsolicitedOCSPOnCertificate-TLS13",
8611		config: Config{
8612			MaxVersion: VersionTLS13,
8613			Bugs: ProtocolBugs{
8614				SendExtensionOnCertificate: testOCSPExtension,
8615			},
8616		},
8617		shouldFail:    true,
8618		expectedError: ":UNEXPECTED_EXTENSION:",
8619	})
8620
8621	testCases = append(testCases, testCase{
8622		name: "SendUnsolicitedSCTOnCertificate-TLS13",
8623		config: Config{
8624			MaxVersion: VersionTLS13,
8625			Bugs: ProtocolBugs{
8626				SendExtensionOnCertificate: testSCTExtension,
8627			},
8628		},
8629		shouldFail:    true,
8630		expectedError: ":UNEXPECTED_EXTENSION:",
8631	})
8632
8633	// Test that extensions on client certificates are never accepted.
8634	testCases = append(testCases, testCase{
8635		name:     "SendExtensionOnClientCertificate-TLS13",
8636		testType: serverTest,
8637		config: Config{
8638			MaxVersion:   VersionTLS13,
8639			Certificates: []Certificate{rsaCertificate},
8640			Bugs: ProtocolBugs{
8641				SendExtensionOnCertificate: testOCSPExtension,
8642			},
8643		},
8644		flags: []string{
8645			"-enable-ocsp-stapling",
8646			"-require-any-client-certificate",
8647		},
8648		shouldFail:    true,
8649		expectedError: ":UNEXPECTED_EXTENSION:",
8650	})
8651
8652	testCases = append(testCases, testCase{
8653		name: "SendUnknownExtensionOnCertificate-TLS13",
8654		config: Config{
8655			MaxVersion: VersionTLS13,
8656			Bugs: ProtocolBugs{
8657				SendExtensionOnCertificate: []byte{0x00, 0x7f, 0, 0},
8658			},
8659		},
8660		shouldFail:    true,
8661		expectedError: ":UNEXPECTED_EXTENSION:",
8662	})
8663
8664	// Test that extensions on intermediates are allowed but ignored.
8665	testCases = append(testCases, testCase{
8666		name: "IgnoreExtensionsOnIntermediates-TLS13",
8667		config: Config{
8668			MaxVersion:   VersionTLS13,
8669			Certificates: []Certificate{rsaChainCertificate},
8670			Bugs: ProtocolBugs{
8671				// Send different values on the intermediate. This tests
8672				// the intermediate's extensions do not override the
8673				// leaf's.
8674				SendOCSPOnIntermediates: testOCSPResponse2,
8675				SendSCTOnIntermediates:  testSCTList2,
8676			},
8677		},
8678		flags: []string{
8679			"-enable-ocsp-stapling",
8680			"-expect-ocsp-response",
8681			base64.StdEncoding.EncodeToString(testOCSPResponse),
8682			"-enable-signed-cert-timestamps",
8683			"-expect-signed-cert-timestamps",
8684			base64.StdEncoding.EncodeToString(testSCTList),
8685		},
8686		resumeSession: true,
8687	})
8688
8689	// Test that extensions are not sent on intermediates when configured
8690	// only for a leaf.
8691	testCases = append(testCases, testCase{
8692		testType: serverTest,
8693		name:     "SendNoExtensionsOnIntermediate-TLS13",
8694		config: Config{
8695			MaxVersion: VersionTLS13,
8696			Bugs: ProtocolBugs{
8697				ExpectNoExtensionsOnIntermediate: true,
8698			},
8699		},
8700		flags: []string{
8701			"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
8702			"-key-file", path.Join(*resourceDir, rsaChainKeyFile),
8703			"-ocsp-response",
8704			base64.StdEncoding.EncodeToString(testOCSPResponse),
8705			"-signed-cert-timestamps",
8706			base64.StdEncoding.EncodeToString(testSCTList),
8707		},
8708	})
8709
8710	// Test that extensions are not sent on client certificates.
8711	testCases = append(testCases, testCase{
8712		name: "SendNoClientCertificateExtensions-TLS13",
8713		config: Config{
8714			MaxVersion: VersionTLS13,
8715			ClientAuth: RequireAnyClientCert,
8716		},
8717		flags: []string{
8718			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
8719			"-key-file", path.Join(*resourceDir, rsaKeyFile),
8720			"-ocsp-response",
8721			base64.StdEncoding.EncodeToString(testOCSPResponse),
8722			"-signed-cert-timestamps",
8723			base64.StdEncoding.EncodeToString(testSCTList),
8724		},
8725	})
8726
8727	testCases = append(testCases, testCase{
8728		name: "SendDuplicateExtensionsOnCerts-TLS13",
8729		config: Config{
8730			MaxVersion: VersionTLS13,
8731			Bugs: ProtocolBugs{
8732				SendDuplicateCertExtensions: true,
8733			},
8734		},
8735		flags: []string{
8736			"-enable-ocsp-stapling",
8737			"-enable-signed-cert-timestamps",
8738		},
8739		resumeSession: true,
8740		shouldFail:    true,
8741		expectedError: ":DUPLICATE_EXTENSION:",
8742	})
8743
8744	testCases = append(testCases, testCase{
8745		name:     "SignedCertificateTimestampListInvalid-Server",
8746		testType: serverTest,
8747		flags: []string{
8748			"-signed-cert-timestamps",
8749			base64.StdEncoding.EncodeToString([]byte{0, 0}),
8750		},
8751		shouldFail:    true,
8752		expectedError: ":INVALID_SCT_LIST:",
8753	})
8754}
8755
8756func addResumptionVersionTests() {
8757	for _, sessionVers := range tlsVersions {
8758		for _, resumeVers := range tlsVersions {
8759			protocols := []protocol{tls}
8760			if sessionVers.hasDTLS && resumeVers.hasDTLS {
8761				protocols = append(protocols, dtls)
8762			}
8763			if sessionVers.hasQUIC && resumeVers.hasQUIC {
8764				protocols = append(protocols, quic)
8765			}
8766			for _, protocol := range protocols {
8767				suffix := "-" + sessionVers.name + "-" + resumeVers.name
8768				suffix += "-" + protocol.String()
8769
8770				if sessionVers.version == resumeVers.version {
8771					testCases = append(testCases, testCase{
8772						protocol:      protocol,
8773						name:          "Resume-Client" + suffix,
8774						resumeSession: true,
8775						config: Config{
8776							MaxVersion: sessionVers.version,
8777							Bugs: ProtocolBugs{
8778								ExpectNoTLS13PSK: sessionVers.version < VersionTLS13,
8779							},
8780						},
8781						expectations: connectionExpectations{
8782							version: sessionVers.version,
8783						},
8784						resumeExpectations: &connectionExpectations{
8785							version: resumeVers.version,
8786						},
8787					})
8788				} else {
8789					testCases = append(testCases, testCase{
8790						protocol:      protocol,
8791						name:          "Resume-Client-Mismatch" + suffix,
8792						resumeSession: true,
8793						config: Config{
8794							MaxVersion: sessionVers.version,
8795						},
8796						expectations: connectionExpectations{
8797							version: sessionVers.version,
8798						},
8799						resumeConfig: &Config{
8800							MaxVersion: resumeVers.version,
8801							Bugs: ProtocolBugs{
8802								AcceptAnySession: true,
8803							},
8804						},
8805						resumeExpectations: &connectionExpectations{
8806							version: resumeVers.version,
8807						},
8808						shouldFail:    true,
8809						expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:",
8810					})
8811				}
8812
8813				testCases = append(testCases, testCase{
8814					protocol:      protocol,
8815					name:          "Resume-Client-NoResume" + suffix,
8816					resumeSession: true,
8817					config: Config{
8818						MaxVersion: sessionVers.version,
8819					},
8820					expectations: connectionExpectations{
8821						version: sessionVers.version,
8822					},
8823					resumeConfig: &Config{
8824						MaxVersion: resumeVers.version,
8825					},
8826					newSessionsOnResume:  true,
8827					expectResumeRejected: true,
8828					resumeExpectations: &connectionExpectations{
8829						version: resumeVers.version,
8830					},
8831				})
8832
8833				testCases = append(testCases, testCase{
8834					protocol:      protocol,
8835					testType:      serverTest,
8836					name:          "Resume-Server" + suffix,
8837					resumeSession: true,
8838					config: Config{
8839						MaxVersion: sessionVers.version,
8840					},
8841					expectations: connectionExpectations{
8842						version: sessionVers.version,
8843					},
8844					expectResumeRejected: sessionVers != resumeVers,
8845					resumeConfig: &Config{
8846						MaxVersion: resumeVers.version,
8847						Bugs: ProtocolBugs{
8848							SendBothTickets: true,
8849						},
8850					},
8851					resumeExpectations: &connectionExpectations{
8852						version: resumeVers.version,
8853					},
8854				})
8855
8856				// Repeat the test using session IDs, rather than tickets.
8857				if sessionVers.version < VersionTLS13 && resumeVers.version < VersionTLS13 {
8858					testCases = append(testCases, testCase{
8859						protocol:      protocol,
8860						testType:      serverTest,
8861						name:          "Resume-Server-NoTickets" + suffix,
8862						resumeSession: true,
8863						config: Config{
8864							MaxVersion:             sessionVers.version,
8865							SessionTicketsDisabled: true,
8866						},
8867						expectations: connectionExpectations{
8868							version: sessionVers.version,
8869						},
8870						expectResumeRejected: sessionVers != resumeVers,
8871						resumeConfig: &Config{
8872							MaxVersion:             resumeVers.version,
8873							SessionTicketsDisabled: true,
8874						},
8875						resumeExpectations: &connectionExpectations{
8876							version: resumeVers.version,
8877						},
8878					})
8879				}
8880			}
8881		}
8882	}
8883
8884	// Make sure shim ticket mutations are functional.
8885	testCases = append(testCases, testCase{
8886		testType:      serverTest,
8887		name:          "ShimTicketRewritable",
8888		resumeSession: true,
8889		config: Config{
8890			MaxVersion:   VersionTLS12,
8891			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
8892			Bugs: ProtocolBugs{
8893				FilterTicket: func(in []byte) ([]byte, error) {
8894					in, err := SetShimTicketVersion(in, VersionTLS12)
8895					if err != nil {
8896						return nil, err
8897					}
8898					return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
8899				},
8900			},
8901		},
8902		flags: []string{
8903			"-ticket-key",
8904			base64.StdEncoding.EncodeToString(TestShimTicketKey),
8905		},
8906	})
8907
8908	// Resumptions are declined if the version does not match.
8909	testCases = append(testCases, testCase{
8910		testType:      serverTest,
8911		name:          "Resume-Server-DeclineCrossVersion",
8912		resumeSession: true,
8913		config: Config{
8914			MaxVersion: VersionTLS12,
8915			Bugs: ProtocolBugs{
8916				ExpectNewTicket: true,
8917				FilterTicket: func(in []byte) ([]byte, error) {
8918					return SetShimTicketVersion(in, VersionTLS13)
8919				},
8920			},
8921		},
8922		flags: []string{
8923			"-ticket-key",
8924			base64.StdEncoding.EncodeToString(TestShimTicketKey),
8925		},
8926		expectResumeRejected: true,
8927	})
8928
8929	testCases = append(testCases, testCase{
8930		testType:      serverTest,
8931		name:          "Resume-Server-DeclineCrossVersion-TLS13",
8932		resumeSession: true,
8933		config: Config{
8934			MaxVersion: VersionTLS13,
8935			Bugs: ProtocolBugs{
8936				FilterTicket: func(in []byte) ([]byte, error) {
8937					return SetShimTicketVersion(in, VersionTLS12)
8938				},
8939			},
8940		},
8941		flags: []string{
8942			"-ticket-key",
8943			base64.StdEncoding.EncodeToString(TestShimTicketKey),
8944		},
8945		expectResumeRejected: true,
8946	})
8947
8948	// Resumptions are declined if the cipher is invalid or disabled.
8949	testCases = append(testCases, testCase{
8950		testType:      serverTest,
8951		name:          "Resume-Server-DeclineBadCipher",
8952		resumeSession: true,
8953		config: Config{
8954			MaxVersion: VersionTLS12,
8955			Bugs: ProtocolBugs{
8956				ExpectNewTicket: true,
8957				FilterTicket: func(in []byte) ([]byte, error) {
8958					return SetShimTicketCipherSuite(in, TLS_AES_128_GCM_SHA256)
8959				},
8960			},
8961		},
8962		flags: []string{
8963			"-ticket-key",
8964			base64.StdEncoding.EncodeToString(TestShimTicketKey),
8965		},
8966		expectResumeRejected: true,
8967	})
8968
8969	testCases = append(testCases, testCase{
8970		testType:      serverTest,
8971		name:          "Resume-Server-DeclineBadCipher-2",
8972		resumeSession: true,
8973		config: Config{
8974			MaxVersion: VersionTLS12,
8975			Bugs: ProtocolBugs{
8976				ExpectNewTicket: true,
8977				FilterTicket: func(in []byte) ([]byte, error) {
8978					return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384)
8979				},
8980			},
8981		},
8982		flags: []string{
8983			"-cipher", "AES128",
8984			"-ticket-key",
8985			base64.StdEncoding.EncodeToString(TestShimTicketKey),
8986		},
8987		expectResumeRejected: true,
8988	})
8989
8990	// Sessions are not resumed if they do not use the preferred cipher.
8991	testCases = append(testCases, testCase{
8992		testType:      serverTest,
8993		name:          "Resume-Server-CipherNotPreferred",
8994		resumeSession: true,
8995		config: Config{
8996			MaxVersion: VersionTLS12,
8997			Bugs: ProtocolBugs{
8998				ExpectNewTicket: true,
8999				FilterTicket: func(in []byte) ([]byte, error) {
9000					return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA)
9001				},
9002			},
9003		},
9004		flags: []string{
9005			"-ticket-key",
9006			base64.StdEncoding.EncodeToString(TestShimTicketKey),
9007		},
9008		shouldFail:           false,
9009		expectResumeRejected: true,
9010	})
9011
9012	// TLS 1.3 allows sessions to be resumed at a different cipher if their
9013	// PRF hashes match, but BoringSSL will always decline such resumptions.
9014	testCases = append(testCases, testCase{
9015		testType:      serverTest,
9016		name:          "Resume-Server-CipherNotPreferred-TLS13",
9017		resumeSession: true,
9018		config: Config{
9019			MaxVersion:   VersionTLS13,
9020			CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256, TLS_AES_128_GCM_SHA256},
9021			Bugs: ProtocolBugs{
9022				FilterTicket: func(in []byte) ([]byte, error) {
9023					// If the client (runner) offers ChaCha20-Poly1305 first, the
9024					// server (shim) always prefers it. Switch it to AES-GCM.
9025					return SetShimTicketCipherSuite(in, TLS_AES_128_GCM_SHA256)
9026				},
9027			},
9028		},
9029		flags: []string{
9030			"-ticket-key",
9031			base64.StdEncoding.EncodeToString(TestShimTicketKey),
9032		},
9033		shouldFail:           false,
9034		expectResumeRejected: true,
9035	})
9036
9037	// Sessions may not be resumed if they contain another version's cipher.
9038	testCases = append(testCases, testCase{
9039		testType:      serverTest,
9040		name:          "Resume-Server-DeclineBadCipher-TLS13",
9041		resumeSession: true,
9042		config: Config{
9043			MaxVersion: VersionTLS13,
9044			Bugs: ProtocolBugs{
9045				FilterTicket: func(in []byte) ([]byte, error) {
9046					return SetShimTicketCipherSuite(in, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)
9047				},
9048			},
9049		},
9050		flags: []string{
9051			"-ticket-key",
9052			base64.StdEncoding.EncodeToString(TestShimTicketKey),
9053		},
9054		expectResumeRejected: true,
9055	})
9056
9057	// If the client does not offer the cipher from the session, decline to
9058	// resume. Clients are forbidden from doing this, but BoringSSL selects
9059	// the cipher first, so we only decline.
9060	testCases = append(testCases, testCase{
9061		testType:      serverTest,
9062		name:          "Resume-Server-UnofferedCipher",
9063		resumeSession: true,
9064		config: Config{
9065			MaxVersion:   VersionTLS12,
9066			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
9067		},
9068		resumeConfig: &Config{
9069			MaxVersion:   VersionTLS12,
9070			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
9071			Bugs: ProtocolBugs{
9072				SendCipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
9073			},
9074		},
9075		expectResumeRejected: true,
9076	})
9077
9078	// In TLS 1.3, clients may advertise a cipher list which does not
9079	// include the selected cipher. Test that we tolerate this. Servers may
9080	// resume at another cipher if the PRF matches and are not doing 0-RTT, but
9081	// BoringSSL will always decline.
9082	testCases = append(testCases, testCase{
9083		testType:      serverTest,
9084		name:          "Resume-Server-UnofferedCipher-TLS13",
9085		resumeSession: true,
9086		config: Config{
9087			MaxVersion:   VersionTLS13,
9088			CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256},
9089		},
9090		resumeConfig: &Config{
9091			MaxVersion:   VersionTLS13,
9092			CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256},
9093			Bugs: ProtocolBugs{
9094				SendCipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
9095			},
9096		},
9097		expectResumeRejected: true,
9098	})
9099
9100	// Sessions may not be resumed at a different cipher.
9101	testCases = append(testCases, testCase{
9102		name:          "Resume-Client-CipherMismatch",
9103		resumeSession: true,
9104		config: Config{
9105			MaxVersion:   VersionTLS12,
9106			CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
9107		},
9108		resumeConfig: &Config{
9109			MaxVersion:   VersionTLS12,
9110			CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
9111			Bugs: ProtocolBugs{
9112				SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA,
9113			},
9114		},
9115		shouldFail:    true,
9116		expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
9117	})
9118
9119	// Session resumption in TLS 1.3 may change the cipher suite if the PRF
9120	// matches.
9121	testCases = append(testCases, testCase{
9122		name:          "Resume-Client-CipherMismatch-TLS13",
9123		resumeSession: true,
9124		config: Config{
9125			MaxVersion:   VersionTLS13,
9126			CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
9127		},
9128		resumeConfig: &Config{
9129			MaxVersion:   VersionTLS13,
9130			CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256},
9131		},
9132	})
9133
9134	// Session resumption in TLS 1.3 is forbidden if the PRF does not match.
9135	testCases = append(testCases, testCase{
9136		name:          "Resume-Client-PRFMismatch-TLS13",
9137		resumeSession: true,
9138		config: Config{
9139			MaxVersion:   VersionTLS13,
9140			CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
9141		},
9142		resumeConfig: &Config{
9143			MaxVersion:   VersionTLS13,
9144			CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
9145			Bugs: ProtocolBugs{
9146				SendCipherSuite: TLS_AES_256_GCM_SHA384,
9147			},
9148		},
9149		shouldFail:    true,
9150		expectedError: ":OLD_SESSION_PRF_HASH_MISMATCH:",
9151	})
9152
9153	for _, secondBinder := range []bool{false, true} {
9154		var suffix string
9155		var defaultCurves []CurveID
9156		if secondBinder {
9157			suffix = "-SecondBinder"
9158			// Force a HelloRetryRequest by predicting an empty curve list.
9159			defaultCurves = []CurveID{}
9160		}
9161
9162		testCases = append(testCases, testCase{
9163			testType:      serverTest,
9164			name:          "Resume-Server-BinderWrongLength" + suffix,
9165			resumeSession: true,
9166			config: Config{
9167				MaxVersion:    VersionTLS13,
9168				DefaultCurves: defaultCurves,
9169				Bugs: ProtocolBugs{
9170					SendShortPSKBinder:         true,
9171					OnlyCorruptSecondPSKBinder: secondBinder,
9172				},
9173			},
9174			shouldFail:         true,
9175			expectedLocalError: "remote error: error decrypting message",
9176			expectedError:      ":DIGEST_CHECK_FAILED:",
9177		})
9178
9179		testCases = append(testCases, testCase{
9180			testType:      serverTest,
9181			name:          "Resume-Server-NoPSKBinder" + suffix,
9182			resumeSession: true,
9183			config: Config{
9184				MaxVersion:    VersionTLS13,
9185				DefaultCurves: defaultCurves,
9186				Bugs: ProtocolBugs{
9187					SendNoPSKBinder:            true,
9188					OnlyCorruptSecondPSKBinder: secondBinder,
9189				},
9190			},
9191			shouldFail:         true,
9192			expectedLocalError: "remote error: error decoding message",
9193			expectedError:      ":DECODE_ERROR:",
9194		})
9195
9196		testCases = append(testCases, testCase{
9197			testType:      serverTest,
9198			name:          "Resume-Server-ExtraPSKBinder" + suffix,
9199			resumeSession: true,
9200			config: Config{
9201				MaxVersion:    VersionTLS13,
9202				DefaultCurves: defaultCurves,
9203				Bugs: ProtocolBugs{
9204					SendExtraPSKBinder:         true,
9205					OnlyCorruptSecondPSKBinder: secondBinder,
9206				},
9207			},
9208			shouldFail:         true,
9209			expectedLocalError: "remote error: illegal parameter",
9210			expectedError:      ":PSK_IDENTITY_BINDER_COUNT_MISMATCH:",
9211		})
9212
9213		testCases = append(testCases, testCase{
9214			testType:      serverTest,
9215			name:          "Resume-Server-ExtraIdentityNoBinder" + suffix,
9216			resumeSession: true,
9217			config: Config{
9218				MaxVersion:    VersionTLS13,
9219				DefaultCurves: defaultCurves,
9220				Bugs: ProtocolBugs{
9221					ExtraPSKIdentity:           true,
9222					OnlyCorruptSecondPSKBinder: secondBinder,
9223				},
9224			},
9225			shouldFail:         true,
9226			expectedLocalError: "remote error: illegal parameter",
9227			expectedError:      ":PSK_IDENTITY_BINDER_COUNT_MISMATCH:",
9228		})
9229
9230		testCases = append(testCases, testCase{
9231			testType:      serverTest,
9232			name:          "Resume-Server-InvalidPSKBinder" + suffix,
9233			resumeSession: true,
9234			config: Config{
9235				MaxVersion:    VersionTLS13,
9236				DefaultCurves: defaultCurves,
9237				Bugs: ProtocolBugs{
9238					SendInvalidPSKBinder:       true,
9239					OnlyCorruptSecondPSKBinder: secondBinder,
9240				},
9241			},
9242			shouldFail:         true,
9243			expectedLocalError: "remote error: error decrypting message",
9244			expectedError:      ":DIGEST_CHECK_FAILED:",
9245		})
9246
9247		testCases = append(testCases, testCase{
9248			testType:      serverTest,
9249			name:          "Resume-Server-PSKBinderFirstExtension" + suffix,
9250			resumeSession: true,
9251			config: Config{
9252				MaxVersion:    VersionTLS13,
9253				DefaultCurves: defaultCurves,
9254				Bugs: ProtocolBugs{
9255					PSKBinderFirst:             true,
9256					OnlyCorruptSecondPSKBinder: secondBinder,
9257				},
9258			},
9259			shouldFail:         true,
9260			expectedLocalError: "remote error: illegal parameter",
9261			expectedError:      ":PRE_SHARED_KEY_MUST_BE_LAST:",
9262		})
9263	}
9264
9265	testCases = append(testCases, testCase{
9266		testType:      serverTest,
9267		name:          "Resume-Server-OmitPSKsOnSecondClientHello",
9268		resumeSession: true,
9269		config: Config{
9270			MaxVersion:    VersionTLS13,
9271			DefaultCurves: []CurveID{},
9272			Bugs: ProtocolBugs{
9273				OmitPSKsOnSecondClientHello: true,
9274			},
9275		},
9276		shouldFail:         true,
9277		expectedLocalError: "remote error: illegal parameter",
9278		expectedError:      ":INCONSISTENT_CLIENT_HELLO:",
9279	})
9280}
9281
9282func addRenegotiationTests() {
9283	// Servers cannot renegotiate.
9284	testCases = append(testCases, testCase{
9285		testType: serverTest,
9286		name:     "Renegotiate-Server-Forbidden",
9287		config: Config{
9288			MaxVersion: VersionTLS12,
9289		},
9290		renegotiate:        1,
9291		shouldFail:         true,
9292		expectedError:      ":NO_RENEGOTIATION:",
9293		expectedLocalError: "remote error: no renegotiation",
9294	})
9295	// The server shouldn't echo the renegotiation extension unless
9296	// requested by the client.
9297	testCases = append(testCases, testCase{
9298		testType: serverTest,
9299		name:     "Renegotiate-Server-NoExt",
9300		config: Config{
9301			MaxVersion: VersionTLS12,
9302			Bugs: ProtocolBugs{
9303				NoRenegotiationInfo:      true,
9304				RequireRenegotiationInfo: true,
9305			},
9306		},
9307		shouldFail:         true,
9308		expectedLocalError: "renegotiation extension missing",
9309	})
9310	// The renegotiation SCSV should be sufficient for the server to echo
9311	// the extension.
9312	testCases = append(testCases, testCase{
9313		testType: serverTest,
9314		name:     "Renegotiate-Server-NoExt-SCSV",
9315		config: Config{
9316			MaxVersion: VersionTLS12,
9317			Bugs: ProtocolBugs{
9318				NoRenegotiationInfo:      true,
9319				SendRenegotiationSCSV:    true,
9320				RequireRenegotiationInfo: true,
9321			},
9322		},
9323	})
9324	testCases = append(testCases, testCase{
9325		name: "Renegotiate-Client",
9326		config: Config{
9327			MaxVersion: VersionTLS12,
9328			Bugs: ProtocolBugs{
9329				FailIfResumeOnRenego: true,
9330			},
9331		},
9332		renegotiate: 1,
9333		// Test renegotiation after both an initial and resumption
9334		// handshake.
9335		resumeSession: true,
9336		flags: []string{
9337			"-renegotiate-freely",
9338			"-expect-total-renegotiations", "1",
9339			"-expect-secure-renegotiation",
9340		},
9341	})
9342	testCases = append(testCases, testCase{
9343		name: "Renegotiate-Client-TLS12",
9344		config: Config{
9345			MaxVersion: VersionTLS12,
9346			Bugs: ProtocolBugs{
9347				FailIfResumeOnRenego: true,
9348			},
9349		},
9350		renegotiate: 1,
9351		// Test renegotiation after both an initial and resumption
9352		// handshake.
9353		resumeSession: true,
9354		flags: []string{
9355			"-renegotiate-freely",
9356			"-expect-total-renegotiations", "1",
9357			"-expect-secure-renegotiation",
9358		},
9359	})
9360	testCases = append(testCases, testCase{
9361		name:        "Renegotiate-Client-EmptyExt",
9362		renegotiate: 1,
9363		config: Config{
9364			MaxVersion: VersionTLS12,
9365			Bugs: ProtocolBugs{
9366				EmptyRenegotiationInfo: true,
9367			},
9368		},
9369		flags:              []string{"-renegotiate-freely"},
9370		shouldFail:         true,
9371		expectedError:      ":RENEGOTIATION_MISMATCH:",
9372		expectedLocalError: "handshake failure",
9373	})
9374	testCases = append(testCases, testCase{
9375		name:        "Renegotiate-Client-BadExt",
9376		renegotiate: 1,
9377		config: Config{
9378			MaxVersion: VersionTLS12,
9379			Bugs: ProtocolBugs{
9380				BadRenegotiationInfo: true,
9381			},
9382		},
9383		flags:              []string{"-renegotiate-freely"},
9384		shouldFail:         true,
9385		expectedError:      ":RENEGOTIATION_MISMATCH:",
9386		expectedLocalError: "handshake failure",
9387	})
9388	testCases = append(testCases, testCase{
9389		name:        "Renegotiate-Client-BadExt2",
9390		renegotiate: 1,
9391		config: Config{
9392			MaxVersion: VersionTLS12,
9393			Bugs: ProtocolBugs{
9394				BadRenegotiationInfoEnd: true,
9395			},
9396		},
9397		flags:              []string{"-renegotiate-freely"},
9398		shouldFail:         true,
9399		expectedError:      ":RENEGOTIATION_MISMATCH:",
9400		expectedLocalError: "handshake failure",
9401	})
9402	testCases = append(testCases, testCase{
9403		name:        "Renegotiate-Client-Downgrade",
9404		renegotiate: 1,
9405		config: Config{
9406			MaxVersion: VersionTLS12,
9407			Bugs: ProtocolBugs{
9408				NoRenegotiationInfoAfterInitial: true,
9409			},
9410		},
9411		flags:              []string{"-renegotiate-freely"},
9412		shouldFail:         true,
9413		expectedError:      ":RENEGOTIATION_MISMATCH:",
9414		expectedLocalError: "handshake failure",
9415	})
9416	testCases = append(testCases, testCase{
9417		name:        "Renegotiate-Client-Upgrade",
9418		renegotiate: 1,
9419		config: Config{
9420			MaxVersion: VersionTLS12,
9421			Bugs: ProtocolBugs{
9422				NoRenegotiationInfoInInitial: true,
9423			},
9424		},
9425		flags:              []string{"-renegotiate-freely"},
9426		shouldFail:         true,
9427		expectedError:      ":RENEGOTIATION_MISMATCH:",
9428		expectedLocalError: "handshake failure",
9429	})
9430	testCases = append(testCases, testCase{
9431		name:        "Renegotiate-Client-NoExt-Allowed",
9432		renegotiate: 1,
9433		config: Config{
9434			MaxVersion: VersionTLS12,
9435			Bugs: ProtocolBugs{
9436				NoRenegotiationInfo: true,
9437			},
9438		},
9439		flags: []string{
9440			"-renegotiate-freely",
9441			"-expect-total-renegotiations", "1",
9442			"-expect-no-secure-renegotiation",
9443		},
9444	})
9445
9446	// Test that the server may switch ciphers on renegotiation without
9447	// problems.
9448	testCases = append(testCases, testCase{
9449		name:        "Renegotiate-Client-SwitchCiphers",
9450		renegotiate: 1,
9451		config: Config{
9452			MaxVersion:   VersionTLS12,
9453			CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
9454		},
9455		renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
9456		flags: []string{
9457			"-renegotiate-freely",
9458			"-expect-total-renegotiations", "1",
9459		},
9460	})
9461	testCases = append(testCases, testCase{
9462		name:        "Renegotiate-Client-SwitchCiphers2",
9463		renegotiate: 1,
9464		config: Config{
9465			MaxVersion:   VersionTLS12,
9466			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
9467		},
9468		renegotiateCiphers: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
9469		flags: []string{
9470			"-renegotiate-freely",
9471			"-expect-total-renegotiations", "1",
9472		},
9473	})
9474
9475	// Test that the server may not switch versions on renegotiation.
9476	testCases = append(testCases, testCase{
9477		name: "Renegotiate-Client-SwitchVersion",
9478		config: Config{
9479			MaxVersion: VersionTLS12,
9480			// Pick a cipher which exists at both versions.
9481			CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
9482			Bugs: ProtocolBugs{
9483				NegotiateVersionOnRenego: VersionTLS11,
9484				// Avoid failing early at the record layer.
9485				SendRecordVersion: VersionTLS12,
9486			},
9487		},
9488		renegotiate: 1,
9489		flags: []string{
9490			"-renegotiate-freely",
9491			"-expect-total-renegotiations", "1",
9492		},
9493		shouldFail:    true,
9494		expectedError: ":WRONG_SSL_VERSION:",
9495	})
9496
9497	testCases = append(testCases, testCase{
9498		name:        "Renegotiate-SameClientVersion",
9499		renegotiate: 1,
9500		config: Config{
9501			MaxVersion: VersionTLS10,
9502			Bugs: ProtocolBugs{
9503				RequireSameRenegoClientVersion: true,
9504			},
9505		},
9506		flags: []string{
9507			"-renegotiate-freely",
9508			"-expect-total-renegotiations", "1",
9509		},
9510	})
9511	testCases = append(testCases, testCase{
9512		name:        "Renegotiate-FalseStart",
9513		renegotiate: 1,
9514		config: Config{
9515			MaxVersion:   VersionTLS12,
9516			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
9517			NextProtos:   []string{"foo"},
9518		},
9519		flags: []string{
9520			"-false-start",
9521			"-select-next-proto", "foo",
9522			"-renegotiate-freely",
9523			"-expect-total-renegotiations", "1",
9524		},
9525		shimWritesFirst: true,
9526	})
9527
9528	// Client-side renegotiation controls.
9529	testCases = append(testCases, testCase{
9530		name: "Renegotiate-Client-Forbidden-1",
9531		config: Config{
9532			MaxVersion: VersionTLS12,
9533		},
9534		renegotiate:        1,
9535		shouldFail:         true,
9536		expectedError:      ":NO_RENEGOTIATION:",
9537		expectedLocalError: "remote error: no renegotiation",
9538	})
9539	testCases = append(testCases, testCase{
9540		name: "Renegotiate-Client-Once-1",
9541		config: Config{
9542			MaxVersion: VersionTLS12,
9543		},
9544		renegotiate: 1,
9545		flags: []string{
9546			"-renegotiate-once",
9547			"-expect-total-renegotiations", "1",
9548		},
9549	})
9550	testCases = append(testCases, testCase{
9551		name: "Renegotiate-Client-Freely-1",
9552		config: Config{
9553			MaxVersion: VersionTLS12,
9554		},
9555		renegotiate: 1,
9556		flags: []string{
9557			"-renegotiate-freely",
9558			"-expect-total-renegotiations", "1",
9559		},
9560	})
9561	testCases = append(testCases, testCase{
9562		name: "Renegotiate-Client-Once-2",
9563		config: Config{
9564			MaxVersion: VersionTLS12,
9565		},
9566		renegotiate:        2,
9567		flags:              []string{"-renegotiate-once"},
9568		shouldFail:         true,
9569		expectedError:      ":NO_RENEGOTIATION:",
9570		expectedLocalError: "remote error: no renegotiation",
9571	})
9572	testCases = append(testCases, testCase{
9573		name: "Renegotiate-Client-Freely-2",
9574		config: Config{
9575			MaxVersion: VersionTLS12,
9576		},
9577		renegotiate: 2,
9578		flags: []string{
9579			"-renegotiate-freely",
9580			"-expect-total-renegotiations", "2",
9581		},
9582	})
9583	testCases = append(testCases, testCase{
9584		name: "Renegotiate-Client-NoIgnore",
9585		config: Config{
9586			MaxVersion: VersionTLS12,
9587			Bugs: ProtocolBugs{
9588				SendHelloRequestBeforeEveryAppDataRecord: true,
9589			},
9590		},
9591		shouldFail:    true,
9592		expectedError: ":NO_RENEGOTIATION:",
9593	})
9594	testCases = append(testCases, testCase{
9595		name: "Renegotiate-Client-Ignore",
9596		config: Config{
9597			MaxVersion: VersionTLS12,
9598			Bugs: ProtocolBugs{
9599				SendHelloRequestBeforeEveryAppDataRecord: true,
9600			},
9601		},
9602		flags: []string{
9603			"-renegotiate-ignore",
9604			"-expect-total-renegotiations", "0",
9605		},
9606	})
9607
9608	// Renegotiation may be enabled and then disabled immediately after the
9609	// handshake.
9610	testCases = append(testCases, testCase{
9611		name: "Renegotiate-ForbidAfterHandshake",
9612		config: Config{
9613			MaxVersion: VersionTLS12,
9614		},
9615		renegotiate:        1,
9616		flags:              []string{"-forbid-renegotiation-after-handshake"},
9617		shouldFail:         true,
9618		expectedError:      ":NO_RENEGOTIATION:",
9619		expectedLocalError: "remote error: no renegotiation",
9620	})
9621
9622	// Renegotiation is not allowed when there is an unfinished write.
9623	testCases = append(testCases, testCase{
9624		name: "Renegotiate-Client-UnfinishedWrite",
9625		config: Config{
9626			MaxVersion: VersionTLS12,
9627		},
9628		renegotiate:             1,
9629		readWithUnfinishedWrite: true,
9630		flags: []string{
9631			"-async",
9632			"-renegotiate-freely",
9633		},
9634		shouldFail:    true,
9635		expectedError: ":NO_RENEGOTIATION:",
9636		// We do not successfully send the no_renegotiation alert in
9637		// this case. https://crbug.com/boringssl/130
9638	})
9639
9640	// We reject stray HelloRequests during the handshake in TLS 1.2.
9641	testCases = append(testCases, testCase{
9642		name: "StrayHelloRequest",
9643		config: Config{
9644			MaxVersion: VersionTLS12,
9645			Bugs: ProtocolBugs{
9646				SendHelloRequestBeforeEveryHandshakeMessage: true,
9647			},
9648		},
9649		shouldFail:    true,
9650		expectedError: ":UNEXPECTED_MESSAGE:",
9651	})
9652	testCases = append(testCases, testCase{
9653		name: "StrayHelloRequest-Packed",
9654		config: Config{
9655			MaxVersion: VersionTLS12,
9656			Bugs: ProtocolBugs{
9657				PackHandshakeFlight:                         true,
9658				SendHelloRequestBeforeEveryHandshakeMessage: true,
9659			},
9660		},
9661		shouldFail:    true,
9662		expectedError: ":UNEXPECTED_MESSAGE:",
9663	})
9664
9665	// Test that HelloRequest is rejected if it comes in the same record as the
9666	// server Finished.
9667	testCases = append(testCases, testCase{
9668		name: "Renegotiate-Client-Packed",
9669		config: Config{
9670			MaxVersion: VersionTLS12,
9671			Bugs: ProtocolBugs{
9672				PackHandshakeFlight:          true,
9673				PackHelloRequestWithFinished: true,
9674			},
9675		},
9676		renegotiate:        1,
9677		flags:              []string{"-renegotiate-freely"},
9678		shouldFail:         true,
9679		expectedError:      ":EXCESS_HANDSHAKE_DATA:",
9680		expectedLocalError: "remote error: unexpected message",
9681	})
9682
9683	// Renegotiation is forbidden in TLS 1.3.
9684	testCases = append(testCases, testCase{
9685		name: "Renegotiate-Client-TLS13",
9686		config: Config{
9687			MaxVersion: VersionTLS13,
9688			Bugs: ProtocolBugs{
9689				SendHelloRequestBeforeEveryAppDataRecord: true,
9690			},
9691		},
9692		flags: []string{
9693			"-renegotiate-freely",
9694		},
9695		shouldFail:    true,
9696		expectedError: ":UNEXPECTED_MESSAGE:",
9697	})
9698
9699	// Stray HelloRequests during the handshake are forbidden in TLS 1.3.
9700	testCases = append(testCases, testCase{
9701		name: "StrayHelloRequest-TLS13",
9702		config: Config{
9703			MaxVersion: VersionTLS13,
9704			Bugs: ProtocolBugs{
9705				SendHelloRequestBeforeEveryHandshakeMessage: true,
9706			},
9707		},
9708		shouldFail:    true,
9709		expectedError: ":UNEXPECTED_MESSAGE:",
9710	})
9711
9712	// The renegotiation_info extension is not sent in TLS 1.3, but TLS 1.3
9713	// always reads as supporting it, regardless of whether it was
9714	// negotiated.
9715	testCases = append(testCases, testCase{
9716		name: "AlwaysReportRenegotiationInfo-TLS13",
9717		config: Config{
9718			MaxVersion: VersionTLS13,
9719			Bugs: ProtocolBugs{
9720				NoRenegotiationInfo: true,
9721			},
9722		},
9723		flags: []string{
9724			"-expect-secure-renegotiation",
9725		},
9726	})
9727
9728	// Certificates may not change on renegotiation.
9729	testCases = append(testCases, testCase{
9730		name: "Renegotiation-CertificateChange",
9731		config: Config{
9732			MaxVersion:   VersionTLS12,
9733			Certificates: []Certificate{rsaCertificate},
9734			Bugs: ProtocolBugs{
9735				RenegotiationCertificate: &rsaChainCertificate,
9736			},
9737		},
9738		renegotiate:   1,
9739		flags:         []string{"-renegotiate-freely"},
9740		shouldFail:    true,
9741		expectedError: ":SERVER_CERT_CHANGED:",
9742	})
9743	testCases = append(testCases, testCase{
9744		name: "Renegotiation-CertificateChange-2",
9745		config: Config{
9746			MaxVersion:   VersionTLS12,
9747			Certificates: []Certificate{rsaCertificate},
9748			Bugs: ProtocolBugs{
9749				RenegotiationCertificate: &rsa1024Certificate,
9750			},
9751		},
9752		renegotiate:   1,
9753		flags:         []string{"-renegotiate-freely"},
9754		shouldFail:    true,
9755		expectedError: ":SERVER_CERT_CHANGED:",
9756	})
9757
9758	// We do not negotiate ALPN after the initial handshake. This is
9759	// error-prone and only risks bugs in consumers.
9760	testCases = append(testCases, testCase{
9761		testType: clientTest,
9762		name:     "Renegotiation-ForbidALPN",
9763		config: Config{
9764			MaxVersion: VersionTLS12,
9765			Bugs: ProtocolBugs{
9766				// Forcibly negotiate ALPN on both initial and
9767				// renegotiation handshakes. The test stack will
9768				// internally check the client does not offer
9769				// it.
9770				SendALPN: "foo",
9771			},
9772		},
9773		flags: []string{
9774			"-advertise-alpn", "\x03foo\x03bar\x03baz",
9775			"-expect-alpn", "foo",
9776			"-renegotiate-freely",
9777		},
9778		renegotiate:   1,
9779		shouldFail:    true,
9780		expectedError: ":UNEXPECTED_EXTENSION:",
9781	})
9782
9783	// The server may send different stapled OCSP responses or SCT lists on
9784	// renegotiation, but BoringSSL ignores this and reports the old values.
9785	// Also test that non-fatal verify results are preserved.
9786	testCases = append(testCases, testCase{
9787		testType: clientTest,
9788		name:     "Renegotiation-ChangeAuthProperties",
9789		config: Config{
9790			MaxVersion: VersionTLS12,
9791			Bugs: ProtocolBugs{
9792				SendOCSPResponseOnRenegotiation: testOCSPResponse2,
9793				SendSCTListOnRenegotiation:      testSCTList2,
9794			},
9795		},
9796		renegotiate: 1,
9797		flags: []string{
9798			"-renegotiate-freely",
9799			"-expect-total-renegotiations", "1",
9800			"-enable-ocsp-stapling",
9801			"-expect-ocsp-response",
9802			base64.StdEncoding.EncodeToString(testOCSPResponse),
9803			"-enable-signed-cert-timestamps",
9804			"-expect-signed-cert-timestamps",
9805			base64.StdEncoding.EncodeToString(testSCTList),
9806			"-verify-fail",
9807			"-expect-verify-result",
9808		},
9809	})
9810}
9811
9812func addDTLSReplayTests() {
9813	// Test that sequence number replays are detected.
9814	testCases = append(testCases, testCase{
9815		protocol:     dtls,
9816		name:         "DTLS-Replay",
9817		messageCount: 200,
9818		replayWrites: true,
9819	})
9820
9821	// Test the incoming sequence number skipping by values larger
9822	// than the retransmit window.
9823	testCases = append(testCases, testCase{
9824		protocol: dtls,
9825		name:     "DTLS-Replay-LargeGaps",
9826		config: Config{
9827			Bugs: ProtocolBugs{
9828				SequenceNumberMapping: func(in uint64) uint64 {
9829					return in * 127
9830				},
9831			},
9832		},
9833		messageCount: 200,
9834		replayWrites: true,
9835	})
9836
9837	// Test the incoming sequence number changing non-monotonically.
9838	testCases = append(testCases, testCase{
9839		protocol: dtls,
9840		name:     "DTLS-Replay-NonMonotonic",
9841		config: Config{
9842			Bugs: ProtocolBugs{
9843				SequenceNumberMapping: func(in uint64) uint64 {
9844					return in ^ 31
9845				},
9846			},
9847		},
9848		messageCount: 200,
9849		replayWrites: true,
9850	})
9851}
9852
9853var testSignatureAlgorithms = []struct {
9854	name string
9855	id   signatureAlgorithm
9856	cert testCert
9857}{
9858	{"RSA_PKCS1_SHA1", signatureRSAPKCS1WithSHA1, testCertRSA},
9859	{"RSA_PKCS1_SHA256", signatureRSAPKCS1WithSHA256, testCertRSA},
9860	{"RSA_PKCS1_SHA384", signatureRSAPKCS1WithSHA384, testCertRSA},
9861	{"RSA_PKCS1_SHA512", signatureRSAPKCS1WithSHA512, testCertRSA},
9862	{"ECDSA_SHA1", signatureECDSAWithSHA1, testCertECDSAP256},
9863	// The “P256” in the following line is not a mistake. In TLS 1.2 the
9864	// hash function doesn't have to match the curve and so the same
9865	// signature algorithm works with P-224.
9866	{"ECDSA_P224_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP224},
9867	{"ECDSA_P256_SHA256", signatureECDSAWithP256AndSHA256, testCertECDSAP256},
9868	{"ECDSA_P384_SHA384", signatureECDSAWithP384AndSHA384, testCertECDSAP384},
9869	{"ECDSA_P521_SHA512", signatureECDSAWithP521AndSHA512, testCertECDSAP521},
9870	{"RSA_PSS_SHA256", signatureRSAPSSWithSHA256, testCertRSA},
9871	{"RSA_PSS_SHA384", signatureRSAPSSWithSHA384, testCertRSA},
9872	{"RSA_PSS_SHA512", signatureRSAPSSWithSHA512, testCertRSA},
9873	{"Ed25519", signatureEd25519, testCertEd25519},
9874	// Tests for key types prior to TLS 1.2.
9875	{"RSA", 0, testCertRSA},
9876	{"ECDSA", 0, testCertECDSAP256},
9877}
9878
9879const fakeSigAlg1 signatureAlgorithm = 0x2a01
9880const fakeSigAlg2 signatureAlgorithm = 0xff01
9881
9882func addSignatureAlgorithmTests() {
9883	// Not all ciphers involve a signature. Advertise a list which gives all
9884	// versions a signing cipher.
9885	signingCiphers := []uint16{
9886		TLS_AES_256_GCM_SHA384,
9887		TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
9888		TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
9889		TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
9890		TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
9891	}
9892
9893	var allAlgorithms []signatureAlgorithm
9894	for _, alg := range testSignatureAlgorithms {
9895		if alg.id != 0 {
9896			allAlgorithms = append(allAlgorithms, alg.id)
9897		}
9898	}
9899
9900	// Make sure each signature algorithm works. Include some fake values in
9901	// the list and ensure they're ignored.
9902	for _, alg := range testSignatureAlgorithms {
9903		for _, ver := range tlsVersions {
9904			if (ver.version < VersionTLS12) != (alg.id == 0) {
9905				continue
9906			}
9907
9908			var shouldFail, rejectByDefault bool
9909			// ecdsa_sha1 does not exist in TLS 1.3.
9910			if ver.version >= VersionTLS13 && alg.id == signatureECDSAWithSHA1 {
9911				shouldFail = true
9912			}
9913			// RSA-PKCS1 does not exist in TLS 1.3.
9914			if ver.version >= VersionTLS13 && hasComponent(alg.name, "PKCS1") {
9915				shouldFail = true
9916			}
9917			// SHA-224 has been removed from TLS 1.3 and, in 1.3,
9918			// the curve has to match the hash size.
9919			if ver.version >= VersionTLS13 && alg.cert == testCertECDSAP224 {
9920				shouldFail = true
9921			}
9922
9923			// By default, BoringSSL does not enable ecdsa_sha1, ecdsa_secp521_sha512, and ed25519.
9924			if alg.id == signatureECDSAWithSHA1 || alg.id == signatureECDSAWithP521AndSHA512 || alg.id == signatureEd25519 {
9925				rejectByDefault = true
9926			}
9927
9928			var signError, signLocalError, verifyError, verifyLocalError, defaultError, defaultLocalError string
9929			if shouldFail {
9930				signError = ":NO_COMMON_SIGNATURE_ALGORITHMS:"
9931				signLocalError = "remote error: handshake failure"
9932				verifyError = ":WRONG_SIGNATURE_TYPE:"
9933				verifyLocalError = "remote error"
9934				rejectByDefault = true
9935			}
9936			if rejectByDefault {
9937				defaultError = ":WRONG_SIGNATURE_TYPE:"
9938				defaultLocalError = "remote error"
9939			}
9940
9941			suffix := "-" + alg.name + "-" + ver.name
9942
9943			for _, testType := range []testType{clientTest, serverTest} {
9944				prefix := "Client-"
9945				if testType == serverTest {
9946					prefix = "Server-"
9947				}
9948
9949				// Test the shim using the algorithm for signing.
9950				signTest := testCase{
9951					testType: testType,
9952					name:     prefix + "Sign" + suffix,
9953					config: Config{
9954						MaxVersion: ver.version,
9955						VerifySignatureAlgorithms: []signatureAlgorithm{
9956							fakeSigAlg1,
9957							alg.id,
9958							fakeSigAlg2,
9959						},
9960					},
9961					flags: []string{
9962						"-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
9963						"-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
9964						"-enable-all-curves",
9965					},
9966					shouldFail:         shouldFail,
9967					expectedError:      signError,
9968					expectedLocalError: signLocalError,
9969					expectations: connectionExpectations{
9970						peerSignatureAlgorithm: alg.id,
9971					},
9972				}
9973
9974				// Test that the shim will select the algorithm when configured to only
9975				// support it.
9976				negotiateTest := testCase{
9977					testType: testType,
9978					name:     prefix + "Sign-Negotiate" + suffix,
9979					config: Config{
9980						MaxVersion:                ver.version,
9981						VerifySignatureAlgorithms: allAlgorithms,
9982					},
9983					flags: []string{
9984						"-cert-file", path.Join(*resourceDir, getShimCertificate(alg.cert)),
9985						"-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
9986						"-enable-all-curves",
9987						"-signing-prefs", strconv.Itoa(int(alg.id)),
9988					},
9989					expectations: connectionExpectations{
9990						peerSignatureAlgorithm: alg.id,
9991					},
9992				}
9993
9994				if testType == serverTest {
9995					// TLS 1.2 servers only sign on some cipher suites.
9996					signTest.config.CipherSuites = signingCiphers
9997					negotiateTest.config.CipherSuites = signingCiphers
9998				} else {
9999					// TLS 1.2 clients only sign when the server requests certificates.
10000					signTest.config.ClientAuth = RequireAnyClientCert
10001					negotiateTest.config.ClientAuth = RequireAnyClientCert
10002				}
10003				testCases = append(testCases, signTest)
10004				if ver.version >= VersionTLS12 && !shouldFail {
10005					testCases = append(testCases, negotiateTest)
10006				}
10007
10008				// Test the shim using the algorithm for verifying.
10009				verifyTest := testCase{
10010					testType: testType,
10011					name:     prefix + "Verify" + suffix,
10012					config: Config{
10013						MaxVersion:   ver.version,
10014						Certificates: []Certificate{getRunnerCertificate(alg.cert)},
10015						SignSignatureAlgorithms: []signatureAlgorithm{
10016							alg.id,
10017						},
10018						Bugs: ProtocolBugs{
10019							SkipECDSACurveCheck:          shouldFail,
10020							IgnoreSignatureVersionChecks: shouldFail,
10021							// Some signature algorithms may not be advertised.
10022							IgnorePeerSignatureAlgorithmPreferences: shouldFail,
10023						},
10024					},
10025					flags: []string{
10026						"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
10027						"-enable-all-curves",
10028						// The algorithm may be disabled by default, so explicitly enable it.
10029						"-verify-prefs", strconv.Itoa(int(alg.id)),
10030					},
10031					// Resume the session to assert the peer signature
10032					// algorithm is reported on both handshakes.
10033					resumeSession:      !shouldFail,
10034					shouldFail:         shouldFail,
10035					expectedError:      verifyError,
10036					expectedLocalError: verifyLocalError,
10037				}
10038
10039				// Test whether the shim expects the algorithm enabled by default.
10040				defaultTest := testCase{
10041					testType: testType,
10042					name:     prefix + "VerifyDefault" + suffix,
10043					config: Config{
10044						MaxVersion:   ver.version,
10045						Certificates: []Certificate{getRunnerCertificate(alg.cert)},
10046						SignSignatureAlgorithms: []signatureAlgorithm{
10047							alg.id,
10048						},
10049						Bugs: ProtocolBugs{
10050							SkipECDSACurveCheck:          rejectByDefault,
10051							IgnoreSignatureVersionChecks: rejectByDefault,
10052							// Some signature algorithms may not be advertised.
10053							IgnorePeerSignatureAlgorithmPreferences: rejectByDefault,
10054						},
10055					},
10056					flags: []string{
10057						"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
10058						"-enable-all-curves",
10059					},
10060					// Resume the session to assert the peer signature
10061					// algorithm is reported on both handshakes.
10062					resumeSession:      !rejectByDefault,
10063					shouldFail:         rejectByDefault,
10064					expectedError:      defaultError,
10065					expectedLocalError: defaultLocalError,
10066				}
10067
10068				// Test whether the shim handles invalid signatures for this algorithm.
10069				invalidTest := testCase{
10070					testType: testType,
10071					name:     prefix + "InvalidSignature" + suffix,
10072					config: Config{
10073						MaxVersion:   ver.version,
10074						Certificates: []Certificate{getRunnerCertificate(alg.cert)},
10075						SignSignatureAlgorithms: []signatureAlgorithm{
10076							alg.id,
10077						},
10078						Bugs: ProtocolBugs{
10079							InvalidSignature: true,
10080						},
10081					},
10082					flags: []string{
10083						"-enable-all-curves",
10084						// The algorithm may be disabled by default, so explicitly enable it.
10085						"-verify-prefs", strconv.Itoa(int(alg.id)),
10086					},
10087					shouldFail:    true,
10088					expectedError: ":BAD_SIGNATURE:",
10089				}
10090
10091				if testType == serverTest {
10092					// TLS 1.2 servers only verify when they request client certificates.
10093					verifyTest.flags = append(verifyTest.flags, "-require-any-client-certificate")
10094					defaultTest.flags = append(defaultTest.flags, "-require-any-client-certificate")
10095					invalidTest.flags = append(invalidTest.flags, "-require-any-client-certificate")
10096				} else {
10097					// TLS 1.2 clients only verify on some cipher suites.
10098					verifyTest.config.CipherSuites = signingCiphers
10099					defaultTest.config.CipherSuites = signingCiphers
10100					invalidTest.config.CipherSuites = signingCiphers
10101				}
10102				testCases = append(testCases, verifyTest, defaultTest)
10103				if !shouldFail {
10104					testCases = append(testCases, invalidTest)
10105				}
10106			}
10107		}
10108	}
10109
10110	// Test the peer's verify preferences are available.
10111	for _, ver := range tlsVersions {
10112		if ver.version < VersionTLS12 {
10113			continue
10114		}
10115		testCases = append(testCases, testCase{
10116			name: "ClientAuth-PeerVerifyPrefs-" + ver.name,
10117			config: Config{
10118				MaxVersion: ver.version,
10119				ClientAuth: RequireAnyClientCert,
10120				VerifySignatureAlgorithms: []signatureAlgorithm{
10121					signatureRSAPSSWithSHA256,
10122					signatureEd25519,
10123					signatureECDSAWithP256AndSHA256,
10124				},
10125			},
10126			flags: []string{
10127				"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10128				"-key-file", path.Join(*resourceDir, rsaKeyFile),
10129				"-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)),
10130				"-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)),
10131				"-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)),
10132			},
10133		})
10134
10135		testCases = append(testCases, testCase{
10136			testType: serverTest,
10137			name:     "ServerAuth-PeerVerifyPrefs-" + ver.name,
10138			config: Config{
10139				MaxVersion: ver.version,
10140				VerifySignatureAlgorithms: []signatureAlgorithm{
10141					signatureRSAPSSWithSHA256,
10142					signatureEd25519,
10143					signatureECDSAWithP256AndSHA256,
10144				},
10145			},
10146			flags: []string{
10147				"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10148				"-key-file", path.Join(*resourceDir, rsaKeyFile),
10149				"-expect-peer-verify-pref", strconv.Itoa(int(signatureRSAPSSWithSHA256)),
10150				"-expect-peer-verify-pref", strconv.Itoa(int(signatureEd25519)),
10151				"-expect-peer-verify-pref", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)),
10152			},
10153		})
10154
10155	}
10156
10157	// Test that algorithm selection takes the key type into account.
10158	testCases = append(testCases, testCase{
10159		name: "ClientAuth-SignatureType",
10160		config: Config{
10161			ClientAuth: RequireAnyClientCert,
10162			MaxVersion: VersionTLS12,
10163			VerifySignatureAlgorithms: []signatureAlgorithm{
10164				signatureECDSAWithP521AndSHA512,
10165				signatureRSAPKCS1WithSHA384,
10166				signatureECDSAWithSHA1,
10167			},
10168		},
10169		flags: []string{
10170			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10171			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10172		},
10173		expectations: connectionExpectations{
10174			peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384,
10175		},
10176	})
10177
10178	testCases = append(testCases, testCase{
10179		name: "ClientAuth-SignatureType-TLS13",
10180		config: Config{
10181			ClientAuth: RequireAnyClientCert,
10182			MaxVersion: VersionTLS13,
10183			VerifySignatureAlgorithms: []signatureAlgorithm{
10184				signatureECDSAWithP521AndSHA512,
10185				signatureRSAPKCS1WithSHA384,
10186				signatureRSAPSSWithSHA384,
10187				signatureECDSAWithSHA1,
10188			},
10189		},
10190		flags: []string{
10191			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10192			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10193		},
10194		expectations: connectionExpectations{
10195			peerSignatureAlgorithm: signatureRSAPSSWithSHA384,
10196		},
10197	})
10198
10199	testCases = append(testCases, testCase{
10200		testType: serverTest,
10201		name:     "ServerAuth-SignatureType",
10202		config: Config{
10203			MaxVersion:   VersionTLS12,
10204			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
10205			VerifySignatureAlgorithms: []signatureAlgorithm{
10206				signatureECDSAWithP521AndSHA512,
10207				signatureRSAPKCS1WithSHA384,
10208				signatureECDSAWithSHA1,
10209			},
10210		},
10211		expectations: connectionExpectations{
10212			peerSignatureAlgorithm: signatureRSAPKCS1WithSHA384,
10213		},
10214	})
10215
10216	testCases = append(testCases, testCase{
10217		testType: serverTest,
10218		name:     "ServerAuth-SignatureType-TLS13",
10219		config: Config{
10220			MaxVersion: VersionTLS13,
10221			VerifySignatureAlgorithms: []signatureAlgorithm{
10222				signatureECDSAWithP521AndSHA512,
10223				signatureRSAPKCS1WithSHA384,
10224				signatureRSAPSSWithSHA384,
10225				signatureECDSAWithSHA1,
10226			},
10227		},
10228		expectations: connectionExpectations{
10229			peerSignatureAlgorithm: signatureRSAPSSWithSHA384,
10230		},
10231	})
10232
10233	// Test that signature verification takes the key type into account.
10234	testCases = append(testCases, testCase{
10235		testType: serverTest,
10236		name:     "Verify-ClientAuth-SignatureType",
10237		config: Config{
10238			MaxVersion:   VersionTLS12,
10239			Certificates: []Certificate{rsaCertificate},
10240			SignSignatureAlgorithms: []signatureAlgorithm{
10241				signatureRSAPKCS1WithSHA256,
10242			},
10243			Bugs: ProtocolBugs{
10244				SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
10245			},
10246		},
10247		flags: []string{
10248			"-require-any-client-certificate",
10249		},
10250		shouldFail:    true,
10251		expectedError: ":WRONG_SIGNATURE_TYPE:",
10252	})
10253
10254	testCases = append(testCases, testCase{
10255		testType: serverTest,
10256		name:     "Verify-ClientAuth-SignatureType-TLS13",
10257		config: Config{
10258			MaxVersion:   VersionTLS13,
10259			Certificates: []Certificate{rsaCertificate},
10260			SignSignatureAlgorithms: []signatureAlgorithm{
10261				signatureRSAPSSWithSHA256,
10262			},
10263			Bugs: ProtocolBugs{
10264				SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
10265			},
10266		},
10267		flags: []string{
10268			"-require-any-client-certificate",
10269		},
10270		shouldFail:    true,
10271		expectedError: ":WRONG_SIGNATURE_TYPE:",
10272	})
10273
10274	testCases = append(testCases, testCase{
10275		name: "Verify-ServerAuth-SignatureType",
10276		config: Config{
10277			MaxVersion:   VersionTLS12,
10278			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
10279			SignSignatureAlgorithms: []signatureAlgorithm{
10280				signatureRSAPKCS1WithSHA256,
10281			},
10282			Bugs: ProtocolBugs{
10283				SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
10284			},
10285		},
10286		shouldFail:    true,
10287		expectedError: ":WRONG_SIGNATURE_TYPE:",
10288	})
10289
10290	testCases = append(testCases, testCase{
10291		name: "Verify-ServerAuth-SignatureType-TLS13",
10292		config: Config{
10293			MaxVersion: VersionTLS13,
10294			SignSignatureAlgorithms: []signatureAlgorithm{
10295				signatureRSAPSSWithSHA256,
10296			},
10297			Bugs: ProtocolBugs{
10298				SendSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
10299			},
10300		},
10301		shouldFail:    true,
10302		expectedError: ":WRONG_SIGNATURE_TYPE:",
10303	})
10304
10305	// Test that, if the ClientHello list is missing, the server falls back
10306	// to SHA-1 in TLS 1.2, but not TLS 1.3.
10307	testCases = append(testCases, testCase{
10308		testType: serverTest,
10309		name:     "ServerAuth-SHA1-Fallback-RSA",
10310		config: Config{
10311			MaxVersion: VersionTLS12,
10312			VerifySignatureAlgorithms: []signatureAlgorithm{
10313				signatureRSAPKCS1WithSHA1,
10314			},
10315			Bugs: ProtocolBugs{
10316				NoSignatureAlgorithms: true,
10317			},
10318		},
10319		flags: []string{
10320			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10321			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10322		},
10323	})
10324
10325	testCases = append(testCases, testCase{
10326		testType: serverTest,
10327		name:     "ServerAuth-SHA1-Fallback-ECDSA",
10328		config: Config{
10329			MaxVersion: VersionTLS12,
10330			VerifySignatureAlgorithms: []signatureAlgorithm{
10331				signatureECDSAWithSHA1,
10332			},
10333			Bugs: ProtocolBugs{
10334				NoSignatureAlgorithms: true,
10335			},
10336		},
10337		flags: []string{
10338			"-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
10339			"-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
10340		},
10341	})
10342
10343	testCases = append(testCases, testCase{
10344		testType: serverTest,
10345		name:     "ServerAuth-NoFallback-TLS13",
10346		config: Config{
10347			MaxVersion: VersionTLS13,
10348			VerifySignatureAlgorithms: []signatureAlgorithm{
10349				signatureRSAPKCS1WithSHA1,
10350			},
10351			Bugs: ProtocolBugs{
10352				NoSignatureAlgorithms:       true,
10353				DisableDelegatedCredentials: true,
10354			},
10355		},
10356		shouldFail:    true,
10357		expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
10358	})
10359
10360	// The CertificateRequest list, however, may never be omitted. It is a
10361	// syntax error for it to be empty.
10362	testCases = append(testCases, testCase{
10363		name: "ClientAuth-NoFallback-RSA",
10364		config: Config{
10365			MaxVersion: VersionTLS12,
10366			ClientAuth: RequireAnyClientCert,
10367			VerifySignatureAlgorithms: []signatureAlgorithm{
10368				signatureRSAPKCS1WithSHA1,
10369			},
10370			Bugs: ProtocolBugs{
10371				NoSignatureAlgorithms: true,
10372			},
10373		},
10374		flags: []string{
10375			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10376			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10377		},
10378		shouldFail:         true,
10379		expectedError:      ":DECODE_ERROR:",
10380		expectedLocalError: "remote error: error decoding message",
10381	})
10382
10383	testCases = append(testCases, testCase{
10384		name: "ClientAuth-NoFallback-ECDSA",
10385		config: Config{
10386			MaxVersion: VersionTLS12,
10387			ClientAuth: RequireAnyClientCert,
10388			VerifySignatureAlgorithms: []signatureAlgorithm{
10389				signatureECDSAWithSHA1,
10390			},
10391			Bugs: ProtocolBugs{
10392				NoSignatureAlgorithms: true,
10393			},
10394		},
10395		flags: []string{
10396			"-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
10397			"-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
10398		},
10399		shouldFail:         true,
10400		expectedError:      ":DECODE_ERROR:",
10401		expectedLocalError: "remote error: error decoding message",
10402	})
10403
10404	testCases = append(testCases, testCase{
10405		name: "ClientAuth-NoFallback-TLS13",
10406		config: Config{
10407			MaxVersion: VersionTLS13,
10408			ClientAuth: RequireAnyClientCert,
10409			VerifySignatureAlgorithms: []signatureAlgorithm{
10410				signatureRSAPKCS1WithSHA1,
10411			},
10412			Bugs: ProtocolBugs{
10413				NoSignatureAlgorithms: true,
10414			},
10415		},
10416		flags: []string{
10417			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10418			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10419		},
10420		shouldFail:         true,
10421		expectedError:      ":DECODE_ERROR:",
10422		expectedLocalError: "remote error: error decoding message",
10423	})
10424
10425	// Test that signature preferences are enforced. BoringSSL does not
10426	// implement MD5 signatures.
10427	testCases = append(testCases, testCase{
10428		testType: serverTest,
10429		name:     "ClientAuth-Enforced",
10430		config: Config{
10431			MaxVersion:   VersionTLS12,
10432			Certificates: []Certificate{rsaCertificate},
10433			SignSignatureAlgorithms: []signatureAlgorithm{
10434				signatureRSAPKCS1WithMD5,
10435			},
10436			Bugs: ProtocolBugs{
10437				IgnorePeerSignatureAlgorithmPreferences: true,
10438			},
10439		},
10440		flags:         []string{"-require-any-client-certificate"},
10441		shouldFail:    true,
10442		expectedError: ":WRONG_SIGNATURE_TYPE:",
10443	})
10444
10445	testCases = append(testCases, testCase{
10446		name: "ServerAuth-Enforced",
10447		config: Config{
10448			MaxVersion:   VersionTLS12,
10449			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
10450			SignSignatureAlgorithms: []signatureAlgorithm{
10451				signatureRSAPKCS1WithMD5,
10452			},
10453			Bugs: ProtocolBugs{
10454				IgnorePeerSignatureAlgorithmPreferences: true,
10455			},
10456		},
10457		shouldFail:    true,
10458		expectedError: ":WRONG_SIGNATURE_TYPE:",
10459	})
10460	testCases = append(testCases, testCase{
10461		testType: serverTest,
10462		name:     "ClientAuth-Enforced-TLS13",
10463		config: Config{
10464			MaxVersion:   VersionTLS13,
10465			Certificates: []Certificate{rsaCertificate},
10466			SignSignatureAlgorithms: []signatureAlgorithm{
10467				signatureRSAPKCS1WithMD5,
10468			},
10469			Bugs: ProtocolBugs{
10470				IgnorePeerSignatureAlgorithmPreferences: true,
10471				IgnoreSignatureVersionChecks:            true,
10472			},
10473		},
10474		flags:         []string{"-require-any-client-certificate"},
10475		shouldFail:    true,
10476		expectedError: ":WRONG_SIGNATURE_TYPE:",
10477	})
10478
10479	testCases = append(testCases, testCase{
10480		name: "ServerAuth-Enforced-TLS13",
10481		config: Config{
10482			MaxVersion: VersionTLS13,
10483			SignSignatureAlgorithms: []signatureAlgorithm{
10484				signatureRSAPKCS1WithMD5,
10485			},
10486			Bugs: ProtocolBugs{
10487				IgnorePeerSignatureAlgorithmPreferences: true,
10488				IgnoreSignatureVersionChecks:            true,
10489			},
10490		},
10491		shouldFail:    true,
10492		expectedError: ":WRONG_SIGNATURE_TYPE:",
10493	})
10494
10495	// Test that the negotiated signature algorithm respects the client and
10496	// server preferences.
10497	testCases = append(testCases, testCase{
10498		name: "NoCommonAlgorithms",
10499		config: Config{
10500			MaxVersion: VersionTLS12,
10501			ClientAuth: RequireAnyClientCert,
10502			VerifySignatureAlgorithms: []signatureAlgorithm{
10503				signatureRSAPKCS1WithSHA512,
10504				signatureRSAPKCS1WithSHA1,
10505			},
10506		},
10507		flags: []string{
10508			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10509			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10510			"-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)),
10511		},
10512		shouldFail:    true,
10513		expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
10514	})
10515	testCases = append(testCases, testCase{
10516		name: "NoCommonAlgorithms-TLS13",
10517		config: Config{
10518			MaxVersion: VersionTLS13,
10519			ClientAuth: RequireAnyClientCert,
10520			VerifySignatureAlgorithms: []signatureAlgorithm{
10521				signatureRSAPSSWithSHA512,
10522				signatureRSAPSSWithSHA384,
10523			},
10524		},
10525		flags: []string{
10526			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10527			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10528			"-signing-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA256)),
10529		},
10530		shouldFail:    true,
10531		expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
10532	})
10533	testCases = append(testCases, testCase{
10534		name: "Agree-Digest-SHA256",
10535		config: Config{
10536			MaxVersion: VersionTLS12,
10537			ClientAuth: RequireAnyClientCert,
10538			VerifySignatureAlgorithms: []signatureAlgorithm{
10539				signatureRSAPKCS1WithSHA1,
10540				signatureRSAPKCS1WithSHA256,
10541			},
10542		},
10543		flags: []string{
10544			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10545			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10546			"-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)),
10547			"-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA1)),
10548		},
10549		expectations: connectionExpectations{
10550			peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
10551		},
10552	})
10553	testCases = append(testCases, testCase{
10554		name: "Agree-Digest-SHA1",
10555		config: Config{
10556			MaxVersion: VersionTLS12,
10557			ClientAuth: RequireAnyClientCert,
10558			VerifySignatureAlgorithms: []signatureAlgorithm{
10559				signatureRSAPKCS1WithSHA1,
10560			},
10561		},
10562		flags: []string{
10563			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10564			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10565			"-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA512)),
10566			"-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)),
10567			"-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA1)),
10568		},
10569		expectations: connectionExpectations{
10570			peerSignatureAlgorithm: signatureRSAPKCS1WithSHA1,
10571		},
10572	})
10573	testCases = append(testCases, testCase{
10574		name: "Agree-Digest-Default",
10575		config: Config{
10576			MaxVersion: VersionTLS12,
10577			ClientAuth: RequireAnyClientCert,
10578			VerifySignatureAlgorithms: []signatureAlgorithm{
10579				signatureRSAPKCS1WithSHA256,
10580				signatureECDSAWithP256AndSHA256,
10581				signatureRSAPKCS1WithSHA1,
10582				signatureECDSAWithSHA1,
10583			},
10584		},
10585		flags: []string{
10586			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10587			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10588		},
10589		expectations: connectionExpectations{
10590			peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
10591		},
10592	})
10593
10594	// Test that the signing preference list may include extra algorithms
10595	// without negotiation problems.
10596	testCases = append(testCases, testCase{
10597		testType: serverTest,
10598		name:     "FilterExtraAlgorithms",
10599		config: Config{
10600			MaxVersion: VersionTLS12,
10601			VerifySignatureAlgorithms: []signatureAlgorithm{
10602				signatureRSAPKCS1WithSHA256,
10603			},
10604		},
10605		flags: []string{
10606			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
10607			"-key-file", path.Join(*resourceDir, rsaKeyFile),
10608			"-signing-prefs", strconv.Itoa(int(fakeSigAlg1)),
10609			"-signing-prefs", strconv.Itoa(int(signatureECDSAWithP256AndSHA256)),
10610			"-signing-prefs", strconv.Itoa(int(signatureRSAPKCS1WithSHA256)),
10611			"-signing-prefs", strconv.Itoa(int(fakeSigAlg2)),
10612		},
10613		expectations: connectionExpectations{
10614			peerSignatureAlgorithm: signatureRSAPKCS1WithSHA256,
10615		},
10616	})
10617
10618	// In TLS 1.2 and below, ECDSA uses the curve list rather than the
10619	// signature algorithms.
10620	testCases = append(testCases, testCase{
10621		name: "CheckLeafCurve",
10622		config: Config{
10623			MaxVersion:   VersionTLS12,
10624			CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
10625			Certificates: []Certificate{ecdsaP256Certificate},
10626		},
10627		flags:         []string{"-curves", strconv.Itoa(int(CurveP384))},
10628		shouldFail:    true,
10629		expectedError: ":BAD_ECC_CERT:",
10630	})
10631
10632	// In TLS 1.3, ECDSA does not use the ECDHE curve list.
10633	testCases = append(testCases, testCase{
10634		name: "CheckLeafCurve-TLS13",
10635		config: Config{
10636			MaxVersion:   VersionTLS13,
10637			Certificates: []Certificate{ecdsaP256Certificate},
10638		},
10639		flags: []string{"-curves", strconv.Itoa(int(CurveP384))},
10640	})
10641
10642	// In TLS 1.2, the ECDSA curve is not in the signature algorithm.
10643	testCases = append(testCases, testCase{
10644		name: "ECDSACurveMismatch-Verify-TLS12",
10645		config: Config{
10646			MaxVersion:   VersionTLS12,
10647			CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
10648			Certificates: []Certificate{ecdsaP256Certificate},
10649			SignSignatureAlgorithms: []signatureAlgorithm{
10650				signatureECDSAWithP384AndSHA384,
10651			},
10652		},
10653	})
10654
10655	// In TLS 1.3, the ECDSA curve comes from the signature algorithm.
10656	testCases = append(testCases, testCase{
10657		name: "ECDSACurveMismatch-Verify-TLS13",
10658		config: Config{
10659			MaxVersion:   VersionTLS13,
10660			Certificates: []Certificate{ecdsaP256Certificate},
10661			SignSignatureAlgorithms: []signatureAlgorithm{
10662				signatureECDSAWithP384AndSHA384,
10663			},
10664			Bugs: ProtocolBugs{
10665				SkipECDSACurveCheck: true,
10666			},
10667		},
10668		shouldFail:    true,
10669		expectedError: ":WRONG_SIGNATURE_TYPE:",
10670	})
10671
10672	// Signature algorithm selection in TLS 1.3 should take the curve into
10673	// account.
10674	testCases = append(testCases, testCase{
10675		testType: serverTest,
10676		name:     "ECDSACurveMismatch-Sign-TLS13",
10677		config: Config{
10678			MaxVersion: VersionTLS13,
10679			VerifySignatureAlgorithms: []signatureAlgorithm{
10680				signatureECDSAWithP384AndSHA384,
10681				signatureECDSAWithP256AndSHA256,
10682			},
10683		},
10684		flags: []string{
10685			"-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
10686			"-key-file", path.Join(*resourceDir, ecdsaP256KeyFile),
10687		},
10688		expectations: connectionExpectations{
10689			peerSignatureAlgorithm: signatureECDSAWithP256AndSHA256,
10690		},
10691	})
10692
10693	// RSASSA-PSS with SHA-512 is too large for 1024-bit RSA. Test that the
10694	// server does not attempt to sign in that case.
10695	testCases = append(testCases, testCase{
10696		testType: serverTest,
10697		name:     "RSA-PSS-Large",
10698		config: Config{
10699			MaxVersion: VersionTLS13,
10700			VerifySignatureAlgorithms: []signatureAlgorithm{
10701				signatureRSAPSSWithSHA512,
10702			},
10703		},
10704		flags: []string{
10705			"-cert-file", path.Join(*resourceDir, rsa1024CertificateFile),
10706			"-key-file", path.Join(*resourceDir, rsa1024KeyFile),
10707		},
10708		shouldFail:    true,
10709		expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
10710	})
10711
10712	// Test that RSA-PSS is enabled by default for TLS 1.2.
10713	testCases = append(testCases, testCase{
10714		testType: clientTest,
10715		name:     "RSA-PSS-Default-Verify",
10716		config: Config{
10717			MaxVersion: VersionTLS12,
10718			SignSignatureAlgorithms: []signatureAlgorithm{
10719				signatureRSAPSSWithSHA256,
10720			},
10721		},
10722		flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
10723	})
10724
10725	testCases = append(testCases, testCase{
10726		testType: serverTest,
10727		name:     "RSA-PSS-Default-Sign",
10728		config: Config{
10729			MaxVersion: VersionTLS12,
10730			VerifySignatureAlgorithms: []signatureAlgorithm{
10731				signatureRSAPSSWithSHA256,
10732			},
10733		},
10734		flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
10735	})
10736
10737	// TLS 1.1 and below has no way to advertise support for or negotiate
10738	// Ed25519's signature algorithm.
10739	testCases = append(testCases, testCase{
10740		testType: clientTest,
10741		name:     "NoEd25519-TLS11-ServerAuth-Verify",
10742		config: Config{
10743			MaxVersion:   VersionTLS11,
10744			Certificates: []Certificate{ed25519Certificate},
10745			Bugs: ProtocolBugs{
10746				// Sign with Ed25519 even though it is TLS 1.1.
10747				UseLegacySigningAlgorithm: signatureEd25519,
10748			},
10749		},
10750		flags:         []string{"-verify-prefs", strconv.Itoa(int(signatureEd25519))},
10751		shouldFail:    true,
10752		expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:",
10753	})
10754	testCases = append(testCases, testCase{
10755		testType: serverTest,
10756		name:     "NoEd25519-TLS11-ServerAuth-Sign",
10757		config: Config{
10758			MaxVersion: VersionTLS11,
10759		},
10760		flags: []string{
10761			"-cert-file", path.Join(*resourceDir, ed25519CertificateFile),
10762			"-key-file", path.Join(*resourceDir, ed25519KeyFile),
10763		},
10764		shouldFail:    true,
10765		expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
10766	})
10767	testCases = append(testCases, testCase{
10768		testType: serverTest,
10769		name:     "NoEd25519-TLS11-ClientAuth-Verify",
10770		config: Config{
10771			MaxVersion:   VersionTLS11,
10772			Certificates: []Certificate{ed25519Certificate},
10773			Bugs: ProtocolBugs{
10774				// Sign with Ed25519 even though it is TLS 1.1.
10775				UseLegacySigningAlgorithm: signatureEd25519,
10776			},
10777		},
10778		flags: []string{
10779			"-verify-prefs", strconv.Itoa(int(signatureEd25519)),
10780			"-require-any-client-certificate",
10781		},
10782		shouldFail:    true,
10783		expectedError: ":PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE:",
10784	})
10785	testCases = append(testCases, testCase{
10786		testType: clientTest,
10787		name:     "NoEd25519-TLS11-ClientAuth-Sign",
10788		config: Config{
10789			MaxVersion: VersionTLS11,
10790			ClientAuth: RequireAnyClientCert,
10791		},
10792		flags: []string{
10793			"-cert-file", path.Join(*resourceDir, ed25519CertificateFile),
10794			"-key-file", path.Join(*resourceDir, ed25519KeyFile),
10795		},
10796		shouldFail:    true,
10797		expectedError: ":NO_COMMON_SIGNATURE_ALGORITHMS:",
10798	})
10799
10800	// Test Ed25519 is not advertised by default.
10801	testCases = append(testCases, testCase{
10802		testType: clientTest,
10803		name:     "Ed25519DefaultDisable-NoAdvertise",
10804		config: Config{
10805			Certificates: []Certificate{ed25519Certificate},
10806		},
10807		shouldFail:         true,
10808		expectedLocalError: "tls: no common signature algorithms",
10809	})
10810
10811	// Test Ed25519, when disabled, is not accepted if the peer ignores our
10812	// preferences.
10813	testCases = append(testCases, testCase{
10814		testType: clientTest,
10815		name:     "Ed25519DefaultDisable-NoAccept",
10816		config: Config{
10817			Certificates: []Certificate{ed25519Certificate},
10818			Bugs: ProtocolBugs{
10819				IgnorePeerSignatureAlgorithmPreferences: true,
10820			},
10821		},
10822		shouldFail:         true,
10823		expectedLocalError: "remote error: illegal parameter",
10824		expectedError:      ":WRONG_SIGNATURE_TYPE:",
10825	})
10826
10827	// Test that configuring verify preferences changes what the client
10828	// advertises.
10829	testCases = append(testCases, testCase{
10830		name: "VerifyPreferences-Advertised",
10831		config: Config{
10832			Certificates: []Certificate{rsaCertificate},
10833			SignSignatureAlgorithms: []signatureAlgorithm{
10834				signatureRSAPSSWithSHA256,
10835				signatureRSAPSSWithSHA384,
10836				signatureRSAPSSWithSHA512,
10837			},
10838		},
10839		flags: []string{
10840			"-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)),
10841			"-expect-peer-signature-algorithm", strconv.Itoa(int(signatureRSAPSSWithSHA384)),
10842		},
10843	})
10844
10845	// Test that the client advertises a set which the runner can find
10846	// nothing in common with.
10847	testCases = append(testCases, testCase{
10848		name: "VerifyPreferences-NoCommonAlgorithms",
10849		config: Config{
10850			Certificates: []Certificate{rsaCertificate},
10851			SignSignatureAlgorithms: []signatureAlgorithm{
10852				signatureRSAPSSWithSHA256,
10853				signatureRSAPSSWithSHA512,
10854			},
10855		},
10856		flags: []string{
10857			"-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)),
10858		},
10859		shouldFail:         true,
10860		expectedLocalError: "tls: no common signature algorithms",
10861	})
10862
10863	// Test that the client enforces its preferences when configured.
10864	testCases = append(testCases, testCase{
10865		name: "VerifyPreferences-Enforced",
10866		config: Config{
10867			Certificates: []Certificate{rsaCertificate},
10868			SignSignatureAlgorithms: []signatureAlgorithm{
10869				signatureRSAPSSWithSHA256,
10870				signatureRSAPSSWithSHA512,
10871			},
10872			Bugs: ProtocolBugs{
10873				IgnorePeerSignatureAlgorithmPreferences: true,
10874			},
10875		},
10876		flags: []string{
10877			"-verify-prefs", strconv.Itoa(int(signatureRSAPSSWithSHA384)),
10878		},
10879		shouldFail:         true,
10880		expectedLocalError: "remote error: illegal parameter",
10881		expectedError:      ":WRONG_SIGNATURE_TYPE:",
10882	})
10883
10884	// Test that explicitly configuring Ed25519 is as good as changing the
10885	// boolean toggle.
10886	testCases = append(testCases, testCase{
10887		name: "VerifyPreferences-Ed25519",
10888		config: Config{
10889			Certificates: []Certificate{ed25519Certificate},
10890		},
10891		flags: []string{
10892			"-verify-prefs", strconv.Itoa(int(signatureEd25519)),
10893		},
10894	})
10895}
10896
10897// timeouts is the retransmit schedule for BoringSSL. It doubles and
10898// caps at 60 seconds. On the 13th timeout, it gives up.
10899var timeouts = []time.Duration{
10900	1 * time.Second,
10901	2 * time.Second,
10902	4 * time.Second,
10903	8 * time.Second,
10904	16 * time.Second,
10905	32 * time.Second,
10906	60 * time.Second,
10907	60 * time.Second,
10908	60 * time.Second,
10909	60 * time.Second,
10910	60 * time.Second,
10911	60 * time.Second,
10912	60 * time.Second,
10913}
10914
10915// shortTimeouts is an alternate set of timeouts which would occur if the
10916// initial timeout duration was set to 250ms.
10917var shortTimeouts = []time.Duration{
10918	250 * time.Millisecond,
10919	500 * time.Millisecond,
10920	1 * time.Second,
10921	2 * time.Second,
10922	4 * time.Second,
10923	8 * time.Second,
10924	16 * time.Second,
10925	32 * time.Second,
10926	60 * time.Second,
10927	60 * time.Second,
10928	60 * time.Second,
10929	60 * time.Second,
10930	60 * time.Second,
10931}
10932
10933func addDTLSRetransmitTests() {
10934	// These tests work by coordinating some behavior on both the shim and
10935	// the runner.
10936	//
10937	// TimeoutSchedule configures the runner to send a series of timeout
10938	// opcodes to the shim (see packetAdaptor) immediately before reading
10939	// each peer handshake flight N. The timeout opcode both simulates a
10940	// timeout in the shim and acts as a synchronization point to help the
10941	// runner bracket each handshake flight.
10942	//
10943	// We assume the shim does not read from the channel eagerly. It must
10944	// first wait until it has sent flight N and is ready to receive
10945	// handshake flight N+1. At this point, it will process the timeout
10946	// opcode. It must then immediately respond with a timeout ACK and act
10947	// as if the shim was idle for the specified amount of time.
10948	//
10949	// The runner then drops all packets received before the ACK and
10950	// continues waiting for flight N. This ordering results in one attempt
10951	// at sending flight N to be dropped. For the test to complete, the
10952	// shim must send flight N again, testing that the shim implements DTLS
10953	// retransmit on a timeout.
10954
10955	// TODO(davidben): Add DTLS 1.3 versions of these tests. There will
10956	// likely be more epochs to cross and the final message's retransmit may
10957	// be more complex.
10958
10959	// Test that this is indeed the timeout schedule. Stress all
10960	// four patterns of handshake.
10961	for i := 1; i < len(timeouts); i++ {
10962		number := strconv.Itoa(i)
10963		testCases = append(testCases, testCase{
10964			protocol: dtls,
10965			name:     "DTLS-Retransmit-Client-" + number,
10966			config: Config{
10967				MaxVersion: VersionTLS12,
10968				Bugs: ProtocolBugs{
10969					TimeoutSchedule: timeouts[:i],
10970				},
10971			},
10972			resumeSession: true,
10973			flags:         []string{"-async"},
10974		})
10975		testCases = append(testCases, testCase{
10976			protocol: dtls,
10977			testType: serverTest,
10978			name:     "DTLS-Retransmit-Server-" + number,
10979			config: Config{
10980				MaxVersion: VersionTLS12,
10981				Bugs: ProtocolBugs{
10982					TimeoutSchedule: timeouts[:i],
10983				},
10984			},
10985			resumeSession: true,
10986			flags:         []string{"-async"},
10987		})
10988	}
10989
10990	// Test that exceeding the timeout schedule hits a read
10991	// timeout.
10992	testCases = append(testCases, testCase{
10993		protocol: dtls,
10994		name:     "DTLS-Retransmit-Timeout",
10995		config: Config{
10996			MaxVersion: VersionTLS12,
10997			Bugs: ProtocolBugs{
10998				TimeoutSchedule: timeouts,
10999			},
11000		},
11001		resumeSession: true,
11002		flags:         []string{"-async"},
11003		shouldFail:    true,
11004		expectedError: ":READ_TIMEOUT_EXPIRED:",
11005	})
11006
11007	// Test that timeout handling has a fudge factor, due to API
11008	// problems.
11009	testCases = append(testCases, testCase{
11010		protocol: dtls,
11011		name:     "DTLS-Retransmit-Fudge",
11012		config: Config{
11013			MaxVersion: VersionTLS12,
11014			Bugs: ProtocolBugs{
11015				TimeoutSchedule: []time.Duration{
11016					timeouts[0] - 10*time.Millisecond,
11017				},
11018			},
11019		},
11020		resumeSession: true,
11021		flags:         []string{"-async"},
11022	})
11023
11024	// Test that the final Finished retransmitting isn't
11025	// duplicated if the peer badly fragments everything.
11026	testCases = append(testCases, testCase{
11027		testType: serverTest,
11028		protocol: dtls,
11029		name:     "DTLS-Retransmit-Fragmented",
11030		config: Config{
11031			MaxVersion: VersionTLS12,
11032			Bugs: ProtocolBugs{
11033				TimeoutSchedule:          []time.Duration{timeouts[0]},
11034				MaxHandshakeRecordLength: 2,
11035			},
11036		},
11037		flags: []string{"-async"},
11038	})
11039
11040	// Test the timeout schedule when a shorter initial timeout duration is set.
11041	testCases = append(testCases, testCase{
11042		protocol: dtls,
11043		name:     "DTLS-Retransmit-Short-Client",
11044		config: Config{
11045			MaxVersion: VersionTLS12,
11046			Bugs: ProtocolBugs{
11047				TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1],
11048			},
11049		},
11050		resumeSession: true,
11051		flags: []string{
11052			"-async",
11053			"-initial-timeout-duration-ms", "250",
11054		},
11055	})
11056	testCases = append(testCases, testCase{
11057		protocol: dtls,
11058		testType: serverTest,
11059		name:     "DTLS-Retransmit-Short-Server",
11060		config: Config{
11061			MaxVersion: VersionTLS12,
11062			Bugs: ProtocolBugs{
11063				TimeoutSchedule: shortTimeouts[:len(shortTimeouts)-1],
11064			},
11065		},
11066		resumeSession: true,
11067		flags: []string{
11068			"-async",
11069			"-initial-timeout-duration-ms", "250",
11070		},
11071	})
11072
11073	// If the shim sends the last Finished (server full or client resume
11074	// handshakes), it must retransmit that Finished when it sees a
11075	// post-handshake penultimate Finished from the runner. The above tests
11076	// cover this. Conversely, if the shim sends the penultimate Finished
11077	// (client full or server resume), test that it does not retransmit.
11078	testCases = append(testCases, testCase{
11079		protocol: dtls,
11080		testType: clientTest,
11081		name:     "DTLS-StrayRetransmitFinished-ClientFull",
11082		config: Config{
11083			MaxVersion: VersionTLS12,
11084			Bugs: ProtocolBugs{
11085				RetransmitFinished: true,
11086			},
11087		},
11088	})
11089	testCases = append(testCases, testCase{
11090		protocol: dtls,
11091		testType: serverTest,
11092		name:     "DTLS-StrayRetransmitFinished-ServerResume",
11093		config: Config{
11094			MaxVersion: VersionTLS12,
11095		},
11096		resumeConfig: &Config{
11097			MaxVersion: VersionTLS12,
11098			Bugs: ProtocolBugs{
11099				RetransmitFinished: true,
11100			},
11101		},
11102		resumeSession: true,
11103	})
11104}
11105
11106func addExportKeyingMaterialTests() {
11107	for _, vers := range tlsVersions {
11108		testCases = append(testCases, testCase{
11109			name: "ExportKeyingMaterial-" + vers.name,
11110			config: Config{
11111				MaxVersion: vers.version,
11112			},
11113			// Test the exporter in both initial and resumption
11114			// handshakes.
11115			resumeSession:        true,
11116			exportKeyingMaterial: 1024,
11117			exportLabel:          "label",
11118			exportContext:        "context",
11119			useExportContext:     true,
11120		})
11121		testCases = append(testCases, testCase{
11122			name: "ExportKeyingMaterial-NoContext-" + vers.name,
11123			config: Config{
11124				MaxVersion: vers.version,
11125			},
11126			exportKeyingMaterial: 1024,
11127		})
11128		testCases = append(testCases, testCase{
11129			name: "ExportKeyingMaterial-EmptyContext-" + vers.name,
11130			config: Config{
11131				MaxVersion: vers.version,
11132			},
11133			exportKeyingMaterial: 1024,
11134			useExportContext:     true,
11135		})
11136		testCases = append(testCases, testCase{
11137			name: "ExportKeyingMaterial-Small-" + vers.name,
11138			config: Config{
11139				MaxVersion: vers.version,
11140			},
11141			exportKeyingMaterial: 1,
11142			exportLabel:          "label",
11143			exportContext:        "context",
11144			useExportContext:     true,
11145		})
11146
11147		if vers.version >= VersionTLS13 {
11148			// Test the exporters do not work while the client is
11149			// sending 0-RTT data.
11150			testCases = append(testCases, testCase{
11151				name: "NoEarlyKeyingMaterial-Client-InEarlyData-" + vers.name,
11152				config: Config{
11153					MaxVersion: vers.version,
11154				},
11155				resumeSession: true,
11156				earlyData:     true,
11157				flags: []string{
11158					"-on-resume-export-keying-material", "1024",
11159					"-on-resume-export-label", "label",
11160					"-on-resume-export-context", "context",
11161				},
11162				shouldFail:    true,
11163				expectedError: ":HANDSHAKE_NOT_COMPLETE:",
11164			})
11165
11166			// Test the normal exporter on the server in half-RTT.
11167			testCases = append(testCases, testCase{
11168				testType: serverTest,
11169				name:     "ExportKeyingMaterial-Server-HalfRTT-" + vers.name,
11170				config: Config{
11171					MaxVersion: vers.version,
11172					Bugs: ProtocolBugs{
11173						// The shim writes exported data immediately after
11174						// the handshake returns, so disable the built-in
11175						// early data test.
11176						SendEarlyData:     [][]byte{},
11177						ExpectHalfRTTData: [][]byte{},
11178					},
11179				},
11180				resumeSession:        true,
11181				earlyData:            true,
11182				exportKeyingMaterial: 1024,
11183				exportLabel:          "label",
11184				exportContext:        "context",
11185				useExportContext:     true,
11186			})
11187		}
11188	}
11189
11190	// Exporters work during a False Start.
11191	testCases = append(testCases, testCase{
11192		name: "ExportKeyingMaterial-FalseStart",
11193		config: Config{
11194			MaxVersion:   VersionTLS12,
11195			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
11196			NextProtos:   []string{"foo"},
11197			Bugs: ProtocolBugs{
11198				ExpectFalseStart: true,
11199			},
11200		},
11201		flags: []string{
11202			"-false-start",
11203			"-advertise-alpn", "\x03foo",
11204			"-expect-alpn", "foo",
11205		},
11206		shimWritesFirst:      true,
11207		exportKeyingMaterial: 1024,
11208		exportLabel:          "label",
11209		exportContext:        "context",
11210		useExportContext:     true,
11211	})
11212
11213	// Exporters do not work in the middle of a renegotiation. Test this by
11214	// triggering the exporter after every SSL_read call and configuring the
11215	// shim to run asynchronously.
11216	testCases = append(testCases, testCase{
11217		name: "ExportKeyingMaterial-Renegotiate",
11218		config: Config{
11219			MaxVersion: VersionTLS12,
11220		},
11221		renegotiate: 1,
11222		flags: []string{
11223			"-async",
11224			"-use-exporter-between-reads",
11225			"-renegotiate-freely",
11226			"-expect-total-renegotiations", "1",
11227		},
11228		shouldFail:    true,
11229		expectedError: "failed to export keying material",
11230	})
11231}
11232
11233func addExportTrafficSecretsTests() {
11234	for _, cipherSuite := range []testCipherSuite{
11235		// Test a SHA-256 and SHA-384 based cipher suite.
11236		{"AEAD-AES128-GCM-SHA256", TLS_AES_128_GCM_SHA256},
11237		{"AEAD-AES256-GCM-SHA384", TLS_AES_256_GCM_SHA384},
11238	} {
11239
11240		testCases = append(testCases, testCase{
11241			name: "ExportTrafficSecrets-" + cipherSuite.name,
11242			config: Config{
11243				MinVersion:   VersionTLS13,
11244				CipherSuites: []uint16{cipherSuite.id},
11245			},
11246			exportTrafficSecrets: true,
11247		})
11248	}
11249}
11250
11251func addTLSUniqueTests() {
11252	for _, isClient := range []bool{false, true} {
11253		for _, isResumption := range []bool{false, true} {
11254			for _, hasEMS := range []bool{false, true} {
11255				var suffix string
11256				if isResumption {
11257					suffix = "Resume-"
11258				} else {
11259					suffix = "Full-"
11260				}
11261
11262				if hasEMS {
11263					suffix += "EMS-"
11264				} else {
11265					suffix += "NoEMS-"
11266				}
11267
11268				if isClient {
11269					suffix += "Client"
11270				} else {
11271					suffix += "Server"
11272				}
11273
11274				test := testCase{
11275					name:          "TLSUnique-" + suffix,
11276					testTLSUnique: true,
11277					config: Config{
11278						MaxVersion: VersionTLS12,
11279						Bugs: ProtocolBugs{
11280							NoExtendedMasterSecret: !hasEMS,
11281						},
11282					},
11283				}
11284
11285				if isResumption {
11286					test.resumeSession = true
11287					test.resumeConfig = &Config{
11288						MaxVersion: VersionTLS12,
11289						Bugs: ProtocolBugs{
11290							NoExtendedMasterSecret: !hasEMS,
11291						},
11292					}
11293				}
11294
11295				if isResumption && !hasEMS {
11296					test.shouldFail = true
11297					test.expectedError = "failed to get tls-unique"
11298				}
11299
11300				testCases = append(testCases, test)
11301			}
11302		}
11303	}
11304}
11305
11306func addCustomExtensionTests() {
11307	// Test an unknown extension from the server.
11308	testCases = append(testCases, testCase{
11309		testType: clientTest,
11310		name:     "UnknownExtension-Client",
11311		config: Config{
11312			MaxVersion: VersionTLS12,
11313			Bugs: ProtocolBugs{
11314				CustomExtension: "custom extension",
11315			},
11316		},
11317		shouldFail:         true,
11318		expectedError:      ":UNEXPECTED_EXTENSION:",
11319		expectedLocalError: "remote error: unsupported extension",
11320	})
11321	testCases = append(testCases, testCase{
11322		testType: clientTest,
11323		name:     "UnknownExtension-Client-TLS13",
11324		config: Config{
11325			MaxVersion: VersionTLS13,
11326			Bugs: ProtocolBugs{
11327				CustomExtension: "custom extension",
11328			},
11329		},
11330		shouldFail:         true,
11331		expectedError:      ":UNEXPECTED_EXTENSION:",
11332		expectedLocalError: "remote error: unsupported extension",
11333	})
11334	testCases = append(testCases, testCase{
11335		testType: clientTest,
11336		name:     "UnknownUnencryptedExtension-Client-TLS13",
11337		config: Config{
11338			MaxVersion: VersionTLS13,
11339			Bugs: ProtocolBugs{
11340				CustomUnencryptedExtension: "custom extension",
11341			},
11342		},
11343		shouldFail:    true,
11344		expectedError: ":UNEXPECTED_EXTENSION:",
11345		// The shim must send an alert, but alerts at this point do not
11346		// get successfully decrypted by the runner.
11347		expectedLocalError: "local error: bad record MAC",
11348	})
11349	testCases = append(testCases, testCase{
11350		testType: clientTest,
11351		name:     "UnexpectedUnencryptedExtension-Client-TLS13",
11352		config: Config{
11353			MaxVersion: VersionTLS13,
11354			Bugs: ProtocolBugs{
11355				SendUnencryptedALPN: "foo",
11356			},
11357		},
11358		flags: []string{
11359			"-advertise-alpn", "\x03foo\x03bar",
11360		},
11361		shouldFail:    true,
11362		expectedError: ":UNEXPECTED_EXTENSION:",
11363		// The shim must send an alert, but alerts at this point do not
11364		// get successfully decrypted by the runner.
11365		expectedLocalError: "local error: bad record MAC",
11366	})
11367
11368	// Test a known but unoffered extension from the server.
11369	testCases = append(testCases, testCase{
11370		testType: clientTest,
11371		name:     "UnofferedExtension-Client",
11372		config: Config{
11373			MaxVersion: VersionTLS12,
11374			Bugs: ProtocolBugs{
11375				SendALPN: "alpn",
11376			},
11377		},
11378		shouldFail:         true,
11379		expectedError:      ":UNEXPECTED_EXTENSION:",
11380		expectedLocalError: "remote error: unsupported extension",
11381	})
11382	testCases = append(testCases, testCase{
11383		testType: clientTest,
11384		name:     "UnofferedExtension-Client-TLS13",
11385		config: Config{
11386			MaxVersion: VersionTLS13,
11387			Bugs: ProtocolBugs{
11388				SendALPN: "alpn",
11389			},
11390		},
11391		shouldFail:         true,
11392		expectedError:      ":UNEXPECTED_EXTENSION:",
11393		expectedLocalError: "remote error: unsupported extension",
11394	})
11395}
11396
11397func addRSAClientKeyExchangeTests() {
11398	for bad := RSABadValue(1); bad < NumRSABadValues; bad++ {
11399		testCases = append(testCases, testCase{
11400			testType: serverTest,
11401			name:     fmt.Sprintf("BadRSAClientKeyExchange-%d", bad),
11402			config: Config{
11403				// Ensure the ClientHello version and final
11404				// version are different, to detect if the
11405				// server uses the wrong one.
11406				MaxVersion:   VersionTLS11,
11407				CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
11408				Bugs: ProtocolBugs{
11409					BadRSAClientKeyExchange: bad,
11410				},
11411			},
11412			shouldFail:    true,
11413			expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
11414		})
11415	}
11416
11417	// The server must compare whatever was in ClientHello.version for the
11418	// RSA premaster.
11419	testCases = append(testCases, testCase{
11420		testType: serverTest,
11421		name:     "SendClientVersion-RSA",
11422		config: Config{
11423			CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
11424			Bugs: ProtocolBugs{
11425				SendClientVersion: 0x1234,
11426			},
11427		},
11428		flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
11429	})
11430}
11431
11432var testCurves = []struct {
11433	name string
11434	id   CurveID
11435}{
11436	{"P-224", CurveP224},
11437	{"P-256", CurveP256},
11438	{"P-384", CurveP384},
11439	{"P-521", CurveP521},
11440	{"X25519", CurveX25519},
11441	{"CECPQ2", CurveCECPQ2},
11442}
11443
11444const bogusCurve = 0x1234
11445
11446func isPqGroup(r CurveID) bool {
11447	return r == CurveCECPQ2
11448}
11449
11450func addCurveTests() {
11451	for _, curve := range testCurves {
11452		for _, ver := range tlsVersions {
11453			if isPqGroup(curve.id) && ver.version < VersionTLS13 {
11454				continue
11455			}
11456
11457			suffix := curve.name + "-" + ver.name
11458
11459			testCases = append(testCases, testCase{
11460				name: "CurveTest-Client-" + suffix,
11461				config: Config{
11462					MaxVersion: ver.version,
11463					CipherSuites: []uint16{
11464						TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
11465						TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
11466						TLS_AES_256_GCM_SHA384,
11467					},
11468					CurvePreferences: []CurveID{curve.id},
11469				},
11470				flags: []string{
11471					"-enable-all-curves",
11472					"-expect-curve-id", strconv.Itoa(int(curve.id)),
11473				},
11474				expectations: connectionExpectations{
11475					curveID: curve.id,
11476				},
11477			})
11478			testCases = append(testCases, testCase{
11479				testType: serverTest,
11480				name:     "CurveTest-Server-" + suffix,
11481				config: Config{
11482					MaxVersion: ver.version,
11483					CipherSuites: []uint16{
11484						TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
11485						TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
11486						TLS_AES_256_GCM_SHA384,
11487					},
11488					CurvePreferences: []CurveID{curve.id},
11489				},
11490				flags: []string{
11491					"-enable-all-curves",
11492					"-expect-curve-id", strconv.Itoa(int(curve.id)),
11493				},
11494				expectations: connectionExpectations{
11495					curveID: curve.id,
11496				},
11497			})
11498
11499			if curve.id != CurveX25519 && !isPqGroup(curve.id) {
11500				testCases = append(testCases, testCase{
11501					name: "CurveTest-Client-Compressed-" + suffix,
11502					config: Config{
11503						MaxVersion: ver.version,
11504						CipherSuites: []uint16{
11505							TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
11506							TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
11507							TLS_AES_256_GCM_SHA384,
11508						},
11509						CurvePreferences: []CurveID{curve.id},
11510						Bugs: ProtocolBugs{
11511							SendCompressedCoordinates: true,
11512						},
11513					},
11514					flags:         []string{"-enable-all-curves"},
11515					shouldFail:    true,
11516					expectedError: ":BAD_ECPOINT:",
11517				})
11518				testCases = append(testCases, testCase{
11519					testType: serverTest,
11520					name:     "CurveTest-Server-Compressed-" + suffix,
11521					config: Config{
11522						MaxVersion: ver.version,
11523						CipherSuites: []uint16{
11524							TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
11525							TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
11526							TLS_AES_256_GCM_SHA384,
11527						},
11528						CurvePreferences: []CurveID{curve.id},
11529						Bugs: ProtocolBugs{
11530							SendCompressedCoordinates: true,
11531						},
11532					},
11533					flags:         []string{"-enable-all-curves"},
11534					shouldFail:    true,
11535					expectedError: ":BAD_ECPOINT:",
11536				})
11537			}
11538		}
11539	}
11540
11541	// The server must be tolerant to bogus curves.
11542	testCases = append(testCases, testCase{
11543		testType: serverTest,
11544		name:     "UnknownCurve",
11545		config: Config{
11546			MaxVersion:       VersionTLS12,
11547			CipherSuites:     []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
11548			CurvePreferences: []CurveID{bogusCurve, CurveP256},
11549		},
11550	})
11551
11552	// The server must be tolerant to bogus curves.
11553	testCases = append(testCases, testCase{
11554		testType: serverTest,
11555		name:     "UnknownCurve-TLS13",
11556		config: Config{
11557			MaxVersion:       VersionTLS13,
11558			CurvePreferences: []CurveID{bogusCurve, CurveP256},
11559		},
11560	})
11561
11562	// The server must not consider ECDHE ciphers when there are no
11563	// supported curves.
11564	testCases = append(testCases, testCase{
11565		testType: serverTest,
11566		name:     "NoSupportedCurves",
11567		config: Config{
11568			MaxVersion:   VersionTLS12,
11569			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
11570			Bugs: ProtocolBugs{
11571				NoSupportedCurves: true,
11572			},
11573		},
11574		shouldFail:    true,
11575		expectedError: ":NO_SHARED_CIPHER:",
11576	})
11577	testCases = append(testCases, testCase{
11578		testType: serverTest,
11579		name:     "NoSupportedCurves-TLS13",
11580		config: Config{
11581			MaxVersion: VersionTLS13,
11582			Bugs: ProtocolBugs{
11583				NoSupportedCurves: true,
11584			},
11585		},
11586		shouldFail:    true,
11587		expectedError: ":NO_SHARED_GROUP:",
11588	})
11589
11590	// The server must fall back to another cipher when there are no
11591	// supported curves.
11592	testCases = append(testCases, testCase{
11593		testType: serverTest,
11594		name:     "NoCommonCurves",
11595		config: Config{
11596			MaxVersion: VersionTLS12,
11597			CipherSuites: []uint16{
11598				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
11599				TLS_RSA_WITH_AES_128_GCM_SHA256,
11600			},
11601			CurvePreferences: []CurveID{CurveP224},
11602		},
11603		expectations: connectionExpectations{
11604			cipher: TLS_RSA_WITH_AES_128_GCM_SHA256,
11605		},
11606	})
11607
11608	// The client must reject bogus curves and disabled curves.
11609	testCases = append(testCases, testCase{
11610		name: "BadECDHECurve",
11611		config: Config{
11612			MaxVersion:   VersionTLS12,
11613			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
11614			Bugs: ProtocolBugs{
11615				SendCurve: bogusCurve,
11616			},
11617		},
11618		shouldFail:    true,
11619		expectedError: ":WRONG_CURVE:",
11620	})
11621	testCases = append(testCases, testCase{
11622		name: "BadECDHECurve-TLS13",
11623		config: Config{
11624			MaxVersion: VersionTLS13,
11625			Bugs: ProtocolBugs{
11626				SendCurve: bogusCurve,
11627			},
11628		},
11629		shouldFail:    true,
11630		expectedError: ":WRONG_CURVE:",
11631	})
11632
11633	testCases = append(testCases, testCase{
11634		name: "UnsupportedCurve",
11635		config: Config{
11636			MaxVersion:       VersionTLS12,
11637			CipherSuites:     []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
11638			CurvePreferences: []CurveID{CurveP256},
11639			Bugs: ProtocolBugs{
11640				IgnorePeerCurvePreferences: true,
11641			},
11642		},
11643		flags:         []string{"-curves", strconv.Itoa(int(CurveP384))},
11644		shouldFail:    true,
11645		expectedError: ":WRONG_CURVE:",
11646	})
11647
11648	testCases = append(testCases, testCase{
11649		// TODO(davidben): Add a TLS 1.3 version where
11650		// HelloRetryRequest requests an unsupported curve.
11651		name: "UnsupportedCurve-ServerHello-TLS13",
11652		config: Config{
11653			MaxVersion:       VersionTLS13,
11654			CurvePreferences: []CurveID{CurveP384},
11655			Bugs: ProtocolBugs{
11656				SendCurve: CurveP256,
11657			},
11658		},
11659		flags:         []string{"-curves", strconv.Itoa(int(CurveP384))},
11660		shouldFail:    true,
11661		expectedError: ":WRONG_CURVE:",
11662	})
11663
11664	// Test invalid curve points.
11665	testCases = append(testCases, testCase{
11666		name: "InvalidECDHPoint-Client",
11667		config: Config{
11668			MaxVersion:       VersionTLS12,
11669			CipherSuites:     []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
11670			CurvePreferences: []CurveID{CurveP256},
11671			Bugs: ProtocolBugs{
11672				InvalidECDHPoint: true,
11673			},
11674		},
11675		shouldFail:    true,
11676		expectedError: ":BAD_ECPOINT:",
11677	})
11678	testCases = append(testCases, testCase{
11679		name: "InvalidECDHPoint-Client-TLS13",
11680		config: Config{
11681			MaxVersion:       VersionTLS13,
11682			CurvePreferences: []CurveID{CurveP256},
11683			Bugs: ProtocolBugs{
11684				InvalidECDHPoint: true,
11685			},
11686		},
11687		shouldFail:    true,
11688		expectedError: ":BAD_ECPOINT:",
11689	})
11690	testCases = append(testCases, testCase{
11691		testType: serverTest,
11692		name:     "InvalidECDHPoint-Server",
11693		config: Config{
11694			MaxVersion:       VersionTLS12,
11695			CipherSuites:     []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
11696			CurvePreferences: []CurveID{CurveP256},
11697			Bugs: ProtocolBugs{
11698				InvalidECDHPoint: true,
11699			},
11700		},
11701		shouldFail:    true,
11702		expectedError: ":BAD_ECPOINT:",
11703	})
11704	testCases = append(testCases, testCase{
11705		testType: serverTest,
11706		name:     "InvalidECDHPoint-Server-TLS13",
11707		config: Config{
11708			MaxVersion:       VersionTLS13,
11709			CurvePreferences: []CurveID{CurveP256},
11710			Bugs: ProtocolBugs{
11711				InvalidECDHPoint: true,
11712			},
11713		},
11714		shouldFail:    true,
11715		expectedError: ":BAD_ECPOINT:",
11716	})
11717
11718	// The previous curve ID should be reported on TLS 1.2 resumption.
11719	testCases = append(testCases, testCase{
11720		name: "CurveID-Resume-Client",
11721		config: Config{
11722			MaxVersion:       VersionTLS12,
11723			CipherSuites:     []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
11724			CurvePreferences: []CurveID{CurveX25519},
11725		},
11726		flags:         []string{"-expect-curve-id", strconv.Itoa(int(CurveX25519))},
11727		resumeSession: true,
11728	})
11729	testCases = append(testCases, testCase{
11730		testType: serverTest,
11731		name:     "CurveID-Resume-Server",
11732		config: Config{
11733			MaxVersion:       VersionTLS12,
11734			CipherSuites:     []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
11735			CurvePreferences: []CurveID{CurveX25519},
11736		},
11737		flags:         []string{"-expect-curve-id", strconv.Itoa(int(CurveX25519))},
11738		resumeSession: true,
11739	})
11740
11741	// TLS 1.3 allows resuming at a differet curve. If this happens, the new
11742	// one should be reported.
11743	testCases = append(testCases, testCase{
11744		name: "CurveID-Resume-Client-TLS13",
11745		config: Config{
11746			MaxVersion:       VersionTLS13,
11747			CurvePreferences: []CurveID{CurveX25519},
11748		},
11749		resumeConfig: &Config{
11750			MaxVersion:       VersionTLS13,
11751			CurvePreferences: []CurveID{CurveP256},
11752		},
11753		flags: []string{
11754			"-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)),
11755			"-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)),
11756		},
11757		resumeSession: true,
11758	})
11759	testCases = append(testCases, testCase{
11760		testType: serverTest,
11761		name:     "CurveID-Resume-Server-TLS13",
11762		config: Config{
11763			MaxVersion:       VersionTLS13,
11764			CurvePreferences: []CurveID{CurveX25519},
11765		},
11766		resumeConfig: &Config{
11767			MaxVersion:       VersionTLS13,
11768			CurvePreferences: []CurveID{CurveP256},
11769		},
11770		flags: []string{
11771			"-on-initial-expect-curve-id", strconv.Itoa(int(CurveX25519)),
11772			"-on-resume-expect-curve-id", strconv.Itoa(int(CurveP256)),
11773		},
11774		resumeSession: true,
11775	})
11776
11777	// Server-sent point formats are legal in TLS 1.2, but not in TLS 1.3.
11778	testCases = append(testCases, testCase{
11779		name: "PointFormat-ServerHello-TLS12",
11780		config: Config{
11781			MaxVersion: VersionTLS12,
11782			Bugs: ProtocolBugs{
11783				SendSupportedPointFormats: []byte{pointFormatUncompressed},
11784			},
11785		},
11786	})
11787	testCases = append(testCases, testCase{
11788		name: "PointFormat-EncryptedExtensions-TLS13",
11789		config: Config{
11790			MaxVersion: VersionTLS13,
11791			Bugs: ProtocolBugs{
11792				SendSupportedPointFormats: []byte{pointFormatUncompressed},
11793			},
11794		},
11795		shouldFail:    true,
11796		expectedError: ":ERROR_PARSING_EXTENSION:",
11797	})
11798
11799	// Server-sent supported groups/curves are legal in TLS 1.3. They are
11800	// illegal in TLS 1.2, but some servers send them anyway, so we must
11801	// tolerate them.
11802	testCases = append(testCases, testCase{
11803		name: "SupportedCurves-ServerHello-TLS12",
11804		config: Config{
11805			MaxVersion: VersionTLS12,
11806			Bugs: ProtocolBugs{
11807				SendServerSupportedCurves: true,
11808			},
11809		},
11810	})
11811	testCases = append(testCases, testCase{
11812		name: "SupportedCurves-EncryptedExtensions-TLS13",
11813		config: Config{
11814			MaxVersion: VersionTLS13,
11815			Bugs: ProtocolBugs{
11816				SendServerSupportedCurves: true,
11817			},
11818		},
11819	})
11820
11821	// Test that we tolerate unknown point formats, as long as
11822	// pointFormatUncompressed is present. Limit ciphers to ECDHE ciphers to
11823	// check they are still functional.
11824	testCases = append(testCases, testCase{
11825		name: "PointFormat-Client-Tolerance",
11826		config: Config{
11827			MaxVersion: VersionTLS12,
11828			Bugs: ProtocolBugs{
11829				SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime},
11830			},
11831		},
11832	})
11833	testCases = append(testCases, testCase{
11834		testType: serverTest,
11835		name:     "PointFormat-Server-Tolerance",
11836		config: Config{
11837			MaxVersion:   VersionTLS12,
11838			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
11839			Bugs: ProtocolBugs{
11840				SendSupportedPointFormats: []byte{42, pointFormatUncompressed, 99, pointFormatCompressedPrime},
11841			},
11842		},
11843	})
11844
11845	// Test TLS 1.2 does not require the point format extension to be
11846	// present.
11847	testCases = append(testCases, testCase{
11848		name: "PointFormat-Client-Missing",
11849		config: Config{
11850			MaxVersion:   VersionTLS12,
11851			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
11852			Bugs: ProtocolBugs{
11853				SendSupportedPointFormats: []byte{},
11854			},
11855		},
11856	})
11857	testCases = append(testCases, testCase{
11858		testType: serverTest,
11859		name:     "PointFormat-Server-Missing",
11860		config: Config{
11861			MaxVersion:   VersionTLS12,
11862			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
11863			Bugs: ProtocolBugs{
11864				SendSupportedPointFormats: []byte{},
11865			},
11866		},
11867	})
11868
11869	// If the point format extension is present, uncompressed points must be
11870	// offered. BoringSSL requires this whether or not ECDHE is used.
11871	testCases = append(testCases, testCase{
11872		name: "PointFormat-Client-MissingUncompressed",
11873		config: Config{
11874			MaxVersion: VersionTLS12,
11875			Bugs: ProtocolBugs{
11876				SendSupportedPointFormats: []byte{pointFormatCompressedPrime},
11877			},
11878		},
11879		shouldFail:    true,
11880		expectedError: ":ERROR_PARSING_EXTENSION:",
11881	})
11882	testCases = append(testCases, testCase{
11883		testType: serverTest,
11884		name:     "PointFormat-Server-MissingUncompressed",
11885		config: Config{
11886			MaxVersion: VersionTLS12,
11887			Bugs: ProtocolBugs{
11888				SendSupportedPointFormats: []byte{pointFormatCompressedPrime},
11889			},
11890		},
11891		shouldFail:    true,
11892		expectedError: ":ERROR_PARSING_EXTENSION:",
11893	})
11894
11895	// Implementations should mask off the high order bit in X25519.
11896	testCases = append(testCases, testCase{
11897		name: "SetX25519HighBit",
11898		config: Config{
11899			CipherSuites: []uint16{
11900				TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
11901				TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
11902				TLS_AES_128_GCM_SHA256,
11903			},
11904			CurvePreferences: []CurveID{CurveX25519},
11905			Bugs: ProtocolBugs{
11906				SetX25519HighBit: true,
11907			},
11908		},
11909	})
11910
11911	// CECPQ2 should not be offered by a TLS < 1.3 client.
11912	testCases = append(testCases, testCase{
11913		name: "CECPQ2NotInTLS12",
11914		config: Config{
11915			Bugs: ProtocolBugs{
11916				FailIfCECPQ2Offered: true,
11917			},
11918		},
11919		flags: []string{
11920			"-max-version", strconv.Itoa(VersionTLS12),
11921			"-curves", strconv.Itoa(int(CurveCECPQ2)),
11922			"-curves", strconv.Itoa(int(CurveX25519)),
11923		},
11924	})
11925
11926	// CECPQ2 should not crash a TLS < 1.3 client if the server mistakenly
11927	// selects it.
11928	testCases = append(testCases, testCase{
11929		name: "CECPQ2NotAcceptedByTLS12Client",
11930		config: Config{
11931			Bugs: ProtocolBugs{
11932				SendCurve: CurveCECPQ2,
11933			},
11934		},
11935		flags: []string{
11936			"-max-version", strconv.Itoa(VersionTLS12),
11937			"-curves", strconv.Itoa(int(CurveCECPQ2)),
11938			"-curves", strconv.Itoa(int(CurveX25519)),
11939		},
11940		shouldFail:    true,
11941		expectedError: ":WRONG_CURVE:",
11942	})
11943
11944	// CECPQ2 should not be offered by default as a client.
11945	testCases = append(testCases, testCase{
11946		name: "CECPQ2NotEnabledByDefaultInClients",
11947		config: Config{
11948			MinVersion: VersionTLS13,
11949			Bugs: ProtocolBugs{
11950				FailIfCECPQ2Offered: true,
11951			},
11952		},
11953	})
11954
11955	// If CECPQ2 is offered, both X25519 and CECPQ2 should have a key-share.
11956	testCases = append(testCases, testCase{
11957		name: "NotJustCECPQ2KeyShare",
11958		config: Config{
11959			MinVersion: VersionTLS13,
11960			Bugs: ProtocolBugs{
11961				ExpectedKeyShares: []CurveID{CurveCECPQ2, CurveX25519},
11962			},
11963		},
11964		flags: []string{
11965			"-curves", strconv.Itoa(int(CurveCECPQ2)),
11966			"-curves", strconv.Itoa(int(CurveX25519)),
11967			"-expect-curve-id", strconv.Itoa(int(CurveCECPQ2)),
11968		},
11969	})
11970
11971	// ... but only if CECPQ2 is listed first.
11972	testCases = append(testCases, testCase{
11973		name: "CECPQ2KeyShareNotIncludedSecond",
11974		config: Config{
11975			MinVersion: VersionTLS13,
11976			Bugs: ProtocolBugs{
11977				ExpectedKeyShares: []CurveID{CurveX25519},
11978			},
11979		},
11980		flags: []string{
11981			"-curves", strconv.Itoa(int(CurveX25519)),
11982			"-curves", strconv.Itoa(int(CurveCECPQ2)),
11983			"-expect-curve-id", strconv.Itoa(int(CurveX25519)),
11984		},
11985	})
11986
11987	// If CECPQ2 is the only configured curve, the key share is sent.
11988	testCases = append(testCases, testCase{
11989		name: "JustConfiguringCECPQ2Works",
11990		config: Config{
11991			MinVersion: VersionTLS13,
11992			Bugs: ProtocolBugs{
11993				ExpectedKeyShares: []CurveID{CurveCECPQ2},
11994			},
11995		},
11996		flags: []string{
11997			"-curves", strconv.Itoa(int(CurveCECPQ2)),
11998			"-expect-curve-id", strconv.Itoa(int(CurveCECPQ2)),
11999		},
12000	})
12001
12002	// As a server, CECPQ2 is not yet supported by default.
12003	testCases = append(testCases, testCase{
12004		testType: serverTest,
12005		name:     "CECPQ2NotEnabledByDefaultForAServer",
12006		config: Config{
12007			MinVersion:       VersionTLS13,
12008			CurvePreferences: []CurveID{CurveCECPQ2, CurveX25519},
12009			DefaultCurves:    []CurveID{CurveCECPQ2},
12010		},
12011		flags: []string{
12012			"-server-preference",
12013			"-expect-curve-id", strconv.Itoa(int(CurveX25519)),
12014		},
12015	})
12016}
12017
12018func addTLS13RecordTests() {
12019	testCases = append(testCases, testCase{
12020		name: "TLS13-RecordPadding",
12021		config: Config{
12022			MaxVersion: VersionTLS13,
12023			MinVersion: VersionTLS13,
12024			Bugs: ProtocolBugs{
12025				RecordPadding: 10,
12026			},
12027		},
12028	})
12029
12030	testCases = append(testCases, testCase{
12031		name: "TLS13-EmptyRecords",
12032		config: Config{
12033			MaxVersion: VersionTLS13,
12034			MinVersion: VersionTLS13,
12035			Bugs: ProtocolBugs{
12036				OmitRecordContents: true,
12037			},
12038		},
12039		shouldFail:    true,
12040		expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
12041	})
12042
12043	testCases = append(testCases, testCase{
12044		name: "TLS13-OnlyPadding",
12045		config: Config{
12046			MaxVersion: VersionTLS13,
12047			MinVersion: VersionTLS13,
12048			Bugs: ProtocolBugs{
12049				OmitRecordContents: true,
12050				RecordPadding:      10,
12051			},
12052		},
12053		shouldFail:    true,
12054		expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
12055	})
12056
12057	testCases = append(testCases, testCase{
12058		name: "TLS13-WrongOuterRecord",
12059		config: Config{
12060			MaxVersion: VersionTLS13,
12061			MinVersion: VersionTLS13,
12062			Bugs: ProtocolBugs{
12063				OuterRecordType: recordTypeHandshake,
12064			},
12065		},
12066		shouldFail:    true,
12067		expectedError: ":INVALID_OUTER_RECORD_TYPE:",
12068	})
12069}
12070
12071func addSessionTicketTests() {
12072	testCases = append(testCases, testCase{
12073		// In TLS 1.2 and below, empty NewSessionTicket messages
12074		// mean the server changed its mind on sending a ticket.
12075		name: "SendEmptySessionTicket",
12076		config: Config{
12077			MaxVersion: VersionTLS12,
12078			Bugs: ProtocolBugs{
12079				SendEmptySessionTicket: true,
12080			},
12081		},
12082		flags: []string{"-expect-no-session"},
12083	})
12084
12085	// Test that the server ignores unknown PSK modes.
12086	testCases = append(testCases, testCase{
12087		testType: serverTest,
12088		name:     "TLS13-SendUnknownModeSessionTicket-Server",
12089		config: Config{
12090			MaxVersion: VersionTLS13,
12091			Bugs: ProtocolBugs{
12092				SendPSKKeyExchangeModes: []byte{0x1a, pskDHEKEMode, 0x2a},
12093			},
12094		},
12095		resumeSession: true,
12096		expectations: connectionExpectations{
12097			version: VersionTLS13,
12098		},
12099	})
12100
12101	// Test that the server does not send session tickets with no matching key exchange mode.
12102	testCases = append(testCases, testCase{
12103		testType: serverTest,
12104		name:     "TLS13-ExpectNoSessionTicketOnBadKEMode-Server",
12105		config: Config{
12106			MaxVersion: VersionTLS13,
12107			Bugs: ProtocolBugs{
12108				SendPSKKeyExchangeModes:  []byte{0x1a},
12109				ExpectNoNewSessionTicket: true,
12110			},
12111		},
12112	})
12113
12114	// Test that the server does not accept a session with no matching key exchange mode.
12115	testCases = append(testCases, testCase{
12116		testType: serverTest,
12117		name:     "TLS13-SendBadKEModeSessionTicket-Server",
12118		config: Config{
12119			MaxVersion: VersionTLS13,
12120		},
12121		resumeConfig: &Config{
12122			MaxVersion: VersionTLS13,
12123			Bugs: ProtocolBugs{
12124				SendPSKKeyExchangeModes: []byte{0x1a},
12125			},
12126		},
12127		resumeSession:        true,
12128		expectResumeRejected: true,
12129	})
12130
12131	// Test that the client ticket age is sent correctly.
12132	testCases = append(testCases, testCase{
12133		testType: clientTest,
12134		name:     "TLS13-TestValidTicketAge-Client",
12135		config: Config{
12136			MaxVersion: VersionTLS13,
12137			Bugs: ProtocolBugs{
12138				ExpectTicketAge: 10 * time.Second,
12139			},
12140		},
12141		resumeSession: true,
12142		flags: []string{
12143			"-resumption-delay", "10",
12144		},
12145	})
12146
12147	// Test that the client ticket age is enforced.
12148	testCases = append(testCases, testCase{
12149		testType: clientTest,
12150		name:     "TLS13-TestBadTicketAge-Client",
12151		config: Config{
12152			MaxVersion: VersionTLS13,
12153			Bugs: ProtocolBugs{
12154				ExpectTicketAge: 1000 * time.Second,
12155			},
12156		},
12157		resumeSession:      true,
12158		shouldFail:         true,
12159		expectedLocalError: "tls: invalid ticket age",
12160	})
12161
12162	// Test that the server's ticket age skew reporting works.
12163	testCases = append(testCases, testCase{
12164		testType: serverTest,
12165		name:     "TLS13-TicketAgeSkew-Forward",
12166		config: Config{
12167			MaxVersion: VersionTLS13,
12168			Bugs: ProtocolBugs{
12169				SendTicketAge: 15 * time.Second,
12170			},
12171		},
12172		resumeSession:        true,
12173		resumeRenewedSession: true,
12174		flags: []string{
12175			"-resumption-delay", "10",
12176			"-expect-ticket-age-skew", "5",
12177		},
12178	})
12179	testCases = append(testCases, testCase{
12180		testType: serverTest,
12181		name:     "TLS13-TicketAgeSkew-Backward",
12182		config: Config{
12183			MaxVersion: VersionTLS13,
12184			Bugs: ProtocolBugs{
12185				SendTicketAge: 5 * time.Second,
12186			},
12187		},
12188		resumeSession:        true,
12189		resumeRenewedSession: true,
12190		flags: []string{
12191			"-resumption-delay", "10",
12192			"-expect-ticket-age-skew", "-5",
12193		},
12194	})
12195
12196	// Test that ticket age skew up to 60 seconds in either direction is accepted.
12197	testCases = append(testCases, testCase{
12198		testType: serverTest,
12199		name:     "TLS13-TicketAgeSkew-Forward-60-Accept",
12200		config: Config{
12201			MaxVersion: VersionTLS13,
12202			Bugs: ProtocolBugs{
12203				SendTicketAge: 70 * time.Second,
12204			},
12205		},
12206		resumeSession: true,
12207		earlyData:     true,
12208		flags: []string{
12209			"-resumption-delay", "10",
12210			"-expect-ticket-age-skew", "60",
12211		},
12212	})
12213	testCases = append(testCases, testCase{
12214		testType: serverTest,
12215		name:     "TLS13-TicketAgeSkew-Backward-60-Accept",
12216		config: Config{
12217			MaxVersion: VersionTLS13,
12218			Bugs: ProtocolBugs{
12219				SendTicketAge: 10 * time.Second,
12220			},
12221		},
12222		resumeSession: true,
12223		earlyData:     true,
12224		flags: []string{
12225			"-resumption-delay", "70",
12226			"-expect-ticket-age-skew", "-60",
12227		},
12228	})
12229
12230	// Test that ticket age skew beyond 60 seconds in either direction is rejected.
12231	testCases = append(testCases, testCase{
12232		testType: serverTest,
12233		name:     "TLS13-TicketAgeSkew-Forward-61-Reject",
12234		config: Config{
12235			MaxVersion: VersionTLS13,
12236			Bugs: ProtocolBugs{
12237				SendTicketAge: 71 * time.Second,
12238			},
12239		},
12240		resumeSession:           true,
12241		earlyData:               true,
12242		expectEarlyDataRejected: true,
12243		flags: []string{
12244			"-resumption-delay", "10",
12245			"-expect-ticket-age-skew", "61",
12246			"-on-resume-expect-early-data-reason", "ticket_age_skew",
12247		},
12248	})
12249	testCases = append(testCases, testCase{
12250		testType: serverTest,
12251		name:     "TLS13-TicketAgeSkew-Backward-61-Reject",
12252		config: Config{
12253			MaxVersion: VersionTLS13,
12254			Bugs: ProtocolBugs{
12255				SendTicketAge: 10 * time.Second,
12256			},
12257		},
12258		resumeSession:           true,
12259		earlyData:               true,
12260		expectEarlyDataRejected: true,
12261		flags: []string{
12262			"-resumption-delay", "71",
12263			"-expect-ticket-age-skew", "-61",
12264			"-on-resume-expect-early-data-reason", "ticket_age_skew",
12265		},
12266	})
12267
12268	testCases = append(testCases, testCase{
12269		testType: clientTest,
12270		name:     "TLS13-SendTicketEarlyDataSupport",
12271		config: Config{
12272			MaxVersion:       VersionTLS13,
12273			MaxEarlyDataSize: 16384,
12274		},
12275		flags: []string{
12276			"-enable-early-data",
12277			"-expect-ticket-supports-early-data",
12278		},
12279	})
12280
12281	// Test that 0-RTT tickets are still recorded as such when early data is disabled overall.
12282	testCases = append(testCases, testCase{
12283		testType: clientTest,
12284		name:     "TLS13-SendTicketEarlyDataSupport-Disabled",
12285		config: Config{
12286			MaxVersion:       VersionTLS13,
12287			MaxEarlyDataSize: 16384,
12288		},
12289		flags: []string{
12290			"-expect-ticket-supports-early-data",
12291		},
12292	})
12293
12294	testCases = append(testCases, testCase{
12295		testType: clientTest,
12296		name:     "TLS13-DuplicateTicketEarlyDataSupport",
12297		config: Config{
12298			MaxVersion:       VersionTLS13,
12299			MaxEarlyDataSize: 16384,
12300			Bugs: ProtocolBugs{
12301				DuplicateTicketEarlyData: true,
12302			},
12303		},
12304		shouldFail:         true,
12305		expectedError:      ":DUPLICATE_EXTENSION:",
12306		expectedLocalError: "remote error: illegal parameter",
12307	})
12308
12309	testCases = append(testCases, testCase{
12310		testType: serverTest,
12311		name:     "TLS13-ExpectTicketEarlyDataSupport",
12312		config: Config{
12313			MaxVersion: VersionTLS13,
12314			Bugs: ProtocolBugs{
12315				ExpectTicketEarlyData: true,
12316			},
12317		},
12318		flags: []string{
12319			"-enable-early-data",
12320		},
12321	})
12322
12323	// Test that, in TLS 1.3, the server-offered NewSessionTicket lifetime
12324	// is honored.
12325	testCases = append(testCases, testCase{
12326		testType: clientTest,
12327		name:     "TLS13-HonorServerSessionTicketLifetime",
12328		config: Config{
12329			MaxVersion: VersionTLS13,
12330			Bugs: ProtocolBugs{
12331				SendTicketLifetime: 20 * time.Second,
12332			},
12333		},
12334		flags: []string{
12335			"-resumption-delay", "19",
12336		},
12337		resumeSession: true,
12338	})
12339	testCases = append(testCases, testCase{
12340		testType: clientTest,
12341		name:     "TLS13-HonorServerSessionTicketLifetime-2",
12342		config: Config{
12343			MaxVersion: VersionTLS13,
12344			Bugs: ProtocolBugs{
12345				SendTicketLifetime: 20 * time.Second,
12346				// The client should not offer the expired session.
12347				ExpectNoTLS13PSK: true,
12348			},
12349		},
12350		flags: []string{
12351			"-resumption-delay", "21",
12352		},
12353		resumeSession:        true,
12354		expectResumeRejected: true,
12355	})
12356
12357	for _, ver := range tlsVersions {
12358		// Prior to TLS 1.3, disabling session tickets enables session IDs.
12359		useStatefulResumption := ver.version < VersionTLS13
12360
12361		// SSL_OP_NO_TICKET implies the server must not mint any tickets.
12362		testCases = append(testCases, testCase{
12363			testType: serverTest,
12364			name:     ver.name + "-NoTicket-NoMint",
12365			config: Config{
12366				MinVersion: ver.version,
12367				MaxVersion: ver.version,
12368				Bugs: ProtocolBugs{
12369					ExpectNoNewSessionTicket: true,
12370					RequireSessionIDs:        useStatefulResumption,
12371				},
12372			},
12373			resumeSession: useStatefulResumption,
12374			flags:         []string{"-no-ticket"},
12375		})
12376
12377		// SSL_OP_NO_TICKET implies the server must not accept any tickets.
12378		testCases = append(testCases, testCase{
12379			testType: serverTest,
12380			name:     ver.name + "-NoTicket-NoAccept",
12381			config: Config{
12382				MinVersion: ver.version,
12383				MaxVersion: ver.version,
12384			},
12385			resumeSession:        true,
12386			expectResumeRejected: true,
12387			// Set SSL_OP_NO_TICKET on the second connection, after the first
12388			// has established tickets.
12389			flags: []string{"-on-resume-no-ticket"},
12390		})
12391	}
12392}
12393
12394func addChangeCipherSpecTests() {
12395	// Test missing ChangeCipherSpecs.
12396	testCases = append(testCases, testCase{
12397		name: "SkipChangeCipherSpec-Client",
12398		config: Config{
12399			MaxVersion: VersionTLS12,
12400			Bugs: ProtocolBugs{
12401				SkipChangeCipherSpec: true,
12402			},
12403		},
12404		shouldFail:    true,
12405		expectedError: ":UNEXPECTED_RECORD:",
12406	})
12407	testCases = append(testCases, testCase{
12408		testType: serverTest,
12409		name:     "SkipChangeCipherSpec-Server",
12410		config: Config{
12411			MaxVersion: VersionTLS12,
12412			Bugs: ProtocolBugs{
12413				SkipChangeCipherSpec: true,
12414			},
12415		},
12416		shouldFail:    true,
12417		expectedError: ":UNEXPECTED_RECORD:",
12418	})
12419	testCases = append(testCases, testCase{
12420		testType: serverTest,
12421		name:     "SkipChangeCipherSpec-Server-NPN",
12422		config: Config{
12423			MaxVersion: VersionTLS12,
12424			NextProtos: []string{"bar"},
12425			Bugs: ProtocolBugs{
12426				SkipChangeCipherSpec: true,
12427			},
12428		},
12429		flags: []string{
12430			"-advertise-npn", "\x03foo\x03bar\x03baz",
12431		},
12432		shouldFail:    true,
12433		expectedError: ":UNEXPECTED_RECORD:",
12434	})
12435
12436	// Test synchronization between the handshake and ChangeCipherSpec.
12437	// Partial post-CCS handshake messages before ChangeCipherSpec should be
12438	// rejected. Test both with and without handshake packing to handle both
12439	// when the partial post-CCS message is in its own record and when it is
12440	// attached to the pre-CCS message.
12441	for _, packed := range []bool{false, true} {
12442		var suffix string
12443		if packed {
12444			suffix = "-Packed"
12445		}
12446
12447		testCases = append(testCases, testCase{
12448			name: "FragmentAcrossChangeCipherSpec-Client" + suffix,
12449			config: Config{
12450				MaxVersion: VersionTLS12,
12451				Bugs: ProtocolBugs{
12452					FragmentAcrossChangeCipherSpec: true,
12453					PackHandshakeFlight:            packed,
12454				},
12455			},
12456			shouldFail:    true,
12457			expectedError: ":UNEXPECTED_RECORD:",
12458		})
12459		testCases = append(testCases, testCase{
12460			name: "FragmentAcrossChangeCipherSpec-Client-Resume" + suffix,
12461			config: Config{
12462				MaxVersion: VersionTLS12,
12463			},
12464			resumeSession: true,
12465			resumeConfig: &Config{
12466				MaxVersion: VersionTLS12,
12467				Bugs: ProtocolBugs{
12468					FragmentAcrossChangeCipherSpec: true,
12469					PackHandshakeFlight:            packed,
12470				},
12471			},
12472			shouldFail:    true,
12473			expectedError: ":UNEXPECTED_RECORD:",
12474		})
12475		testCases = append(testCases, testCase{
12476			testType: serverTest,
12477			name:     "FragmentAcrossChangeCipherSpec-Server" + suffix,
12478			config: Config{
12479				MaxVersion: VersionTLS12,
12480				Bugs: ProtocolBugs{
12481					FragmentAcrossChangeCipherSpec: true,
12482					PackHandshakeFlight:            packed,
12483				},
12484			},
12485			shouldFail:    true,
12486			expectedError: ":UNEXPECTED_RECORD:",
12487		})
12488		testCases = append(testCases, testCase{
12489			testType: serverTest,
12490			name:     "FragmentAcrossChangeCipherSpec-Server-Resume" + suffix,
12491			config: Config{
12492				MaxVersion: VersionTLS12,
12493			},
12494			resumeSession: true,
12495			resumeConfig: &Config{
12496				MaxVersion: VersionTLS12,
12497				Bugs: ProtocolBugs{
12498					FragmentAcrossChangeCipherSpec: true,
12499					PackHandshakeFlight:            packed,
12500				},
12501			},
12502			shouldFail:    true,
12503			expectedError: ":UNEXPECTED_RECORD:",
12504		})
12505		testCases = append(testCases, testCase{
12506			testType: serverTest,
12507			name:     "FragmentAcrossChangeCipherSpec-Server-NPN" + suffix,
12508			config: Config{
12509				MaxVersion: VersionTLS12,
12510				NextProtos: []string{"bar"},
12511				Bugs: ProtocolBugs{
12512					FragmentAcrossChangeCipherSpec: true,
12513					PackHandshakeFlight:            packed,
12514				},
12515			},
12516			flags: []string{
12517				"-advertise-npn", "\x03foo\x03bar\x03baz",
12518			},
12519			shouldFail:    true,
12520			expectedError: ":UNEXPECTED_RECORD:",
12521		})
12522	}
12523
12524	// In TLS 1.2 resumptions, the client sends ClientHello in the first flight
12525	// and ChangeCipherSpec + Finished in the second flight. Test the server's
12526	// behavior when the Finished message is fragmented across not only
12527	// ChangeCipherSpec but also the flight boundary.
12528	testCases = append(testCases, testCase{
12529		testType: serverTest,
12530		name:     "PartialClientFinishedWithClientHello-TLS12-Resume",
12531		config: Config{
12532			MaxVersion: VersionTLS12,
12533		},
12534		resumeConfig: &Config{
12535			MaxVersion: VersionTLS12,
12536			Bugs: ProtocolBugs{
12537				PartialClientFinishedWithClientHello: true,
12538			},
12539		},
12540		resumeSession:      true,
12541		shouldFail:         true,
12542		expectedError:      ":EXCESS_HANDSHAKE_DATA:",
12543		expectedLocalError: "remote error: unexpected message",
12544	})
12545
12546	// In TLS 1.2 full handshakes without tickets, the server's first flight ends
12547	// with ServerHelloDone and the second flight is ChangeCipherSpec + Finished.
12548	// Test the client's behavior when the Finished message is fragmented across
12549	// not only ChangeCipherSpec but also the flight boundary.
12550	testCases = append(testCases, testCase{
12551		testType: clientTest,
12552		name:     "PartialFinishedWithServerHelloDone",
12553		config: Config{
12554			MaxVersion:             VersionTLS12,
12555			SessionTicketsDisabled: true,
12556			Bugs: ProtocolBugs{
12557				PartialFinishedWithServerHelloDone: true,
12558			},
12559		},
12560		shouldFail:         true,
12561		expectedError:      ":EXCESS_HANDSHAKE_DATA:",
12562		expectedLocalError: "remote error: unexpected message",
12563	})
12564
12565	// Test that, in DTLS, ChangeCipherSpec is not allowed when there are
12566	// messages in the handshake queue. Do this by testing the server
12567	// reading the client Finished, reversing the flight so Finished comes
12568	// first.
12569	testCases = append(testCases, testCase{
12570		protocol: dtls,
12571		testType: serverTest,
12572		name:     "SendUnencryptedFinished-DTLS",
12573		config: Config{
12574			MaxVersion: VersionTLS12,
12575			Bugs: ProtocolBugs{
12576				SendUnencryptedFinished:   true,
12577				ReverseHandshakeFragments: true,
12578			},
12579		},
12580		shouldFail:    true,
12581		expectedError: ":EXCESS_HANDSHAKE_DATA:",
12582	})
12583
12584	// Test synchronization between encryption changes and the handshake in
12585	// TLS 1.3, where ChangeCipherSpec is implicit.
12586	testCases = append(testCases, testCase{
12587		name: "PartialEncryptedExtensionsWithServerHello",
12588		config: Config{
12589			MaxVersion: VersionTLS13,
12590			Bugs: ProtocolBugs{
12591				PartialEncryptedExtensionsWithServerHello: true,
12592			},
12593		},
12594		shouldFail:    true,
12595		expectedError: ":EXCESS_HANDSHAKE_DATA:",
12596	})
12597	testCases = append(testCases, testCase{
12598		testType: serverTest,
12599		name:     "PartialClientFinishedWithClientHello",
12600		config: Config{
12601			MaxVersion: VersionTLS13,
12602			Bugs: ProtocolBugs{
12603				PartialClientFinishedWithClientHello: true,
12604			},
12605		},
12606		shouldFail:    true,
12607		expectedError: ":EXCESS_HANDSHAKE_DATA:",
12608	})
12609	testCases = append(testCases, testCase{
12610		testType: serverTest,
12611		name:     "PartialClientFinishedWithSecondClientHello",
12612		config: Config{
12613			MaxVersion: VersionTLS13,
12614			// Trigger a curve-based HelloRetryRequest.
12615			DefaultCurves: []CurveID{},
12616			Bugs: ProtocolBugs{
12617				PartialClientFinishedWithSecondClientHello: true,
12618			},
12619		},
12620		shouldFail:    true,
12621		expectedError: ":EXCESS_HANDSHAKE_DATA:",
12622	})
12623	testCases = append(testCases, testCase{
12624		testType: serverTest,
12625		name:     "PartialEndOfEarlyDataWithClientHello",
12626		config: Config{
12627			MaxVersion: VersionTLS13,
12628		},
12629		resumeConfig: &Config{
12630			MaxVersion: VersionTLS13,
12631			Bugs: ProtocolBugs{
12632				PartialEndOfEarlyDataWithClientHello: true,
12633			},
12634		},
12635		resumeSession: true,
12636		earlyData:     true,
12637		shouldFail:    true,
12638		expectedError: ":EXCESS_HANDSHAKE_DATA:",
12639	})
12640
12641	// Test that early ChangeCipherSpecs are handled correctly.
12642	testCases = append(testCases, testCase{
12643		testType: serverTest,
12644		name:     "EarlyChangeCipherSpec-server-1",
12645		config: Config{
12646			MaxVersion: VersionTLS12,
12647			Bugs: ProtocolBugs{
12648				EarlyChangeCipherSpec: 1,
12649			},
12650		},
12651		shouldFail:    true,
12652		expectedError: ":UNEXPECTED_RECORD:",
12653	})
12654	testCases = append(testCases, testCase{
12655		testType: serverTest,
12656		name:     "EarlyChangeCipherSpec-server-2",
12657		config: Config{
12658			MaxVersion: VersionTLS12,
12659			Bugs: ProtocolBugs{
12660				EarlyChangeCipherSpec: 2,
12661			},
12662		},
12663		shouldFail:    true,
12664		expectedError: ":UNEXPECTED_RECORD:",
12665	})
12666	testCases = append(testCases, testCase{
12667		protocol: dtls,
12668		name:     "StrayChangeCipherSpec",
12669		config: Config{
12670			// TODO(davidben): Once DTLS 1.3 exists, test
12671			// that stray ChangeCipherSpec messages are
12672			// rejected.
12673			MaxVersion: VersionTLS12,
12674			Bugs: ProtocolBugs{
12675				StrayChangeCipherSpec: true,
12676			},
12677		},
12678	})
12679
12680	// Test that reordered ChangeCipherSpecs are tolerated.
12681	testCases = append(testCases, testCase{
12682		protocol: dtls,
12683		name:     "ReorderChangeCipherSpec-DTLS-Client",
12684		config: Config{
12685			MaxVersion: VersionTLS12,
12686			Bugs: ProtocolBugs{
12687				ReorderChangeCipherSpec: true,
12688			},
12689		},
12690		resumeSession: true,
12691	})
12692	testCases = append(testCases, testCase{
12693		testType: serverTest,
12694		protocol: dtls,
12695		name:     "ReorderChangeCipherSpec-DTLS-Server",
12696		config: Config{
12697			MaxVersion: VersionTLS12,
12698			Bugs: ProtocolBugs{
12699				ReorderChangeCipherSpec: true,
12700			},
12701		},
12702		resumeSession: true,
12703	})
12704
12705	// Test that the contents of ChangeCipherSpec are checked.
12706	testCases = append(testCases, testCase{
12707		name: "BadChangeCipherSpec-1",
12708		config: Config{
12709			MaxVersion: VersionTLS12,
12710			Bugs: ProtocolBugs{
12711				BadChangeCipherSpec: []byte{2},
12712			},
12713		},
12714		shouldFail:    true,
12715		expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
12716	})
12717	testCases = append(testCases, testCase{
12718		name: "BadChangeCipherSpec-2",
12719		config: Config{
12720			MaxVersion: VersionTLS12,
12721			Bugs: ProtocolBugs{
12722				BadChangeCipherSpec: []byte{1, 1},
12723			},
12724		},
12725		shouldFail:    true,
12726		expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
12727	})
12728	testCases = append(testCases, testCase{
12729		protocol: dtls,
12730		name:     "BadChangeCipherSpec-DTLS-1",
12731		config: Config{
12732			MaxVersion: VersionTLS12,
12733			Bugs: ProtocolBugs{
12734				BadChangeCipherSpec: []byte{2},
12735			},
12736		},
12737		shouldFail:    true,
12738		expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
12739	})
12740	testCases = append(testCases, testCase{
12741		protocol: dtls,
12742		name:     "BadChangeCipherSpec-DTLS-2",
12743		config: Config{
12744			MaxVersion: VersionTLS12,
12745			Bugs: ProtocolBugs{
12746				BadChangeCipherSpec: []byte{1, 1},
12747			},
12748		},
12749		shouldFail:    true,
12750		expectedError: ":BAD_CHANGE_CIPHER_SPEC:",
12751	})
12752}
12753
12754// addEndOfFlightTests adds tests where the runner adds extra data in the final
12755// record of each handshake flight. Depending on the implementation strategy,
12756// this data may be carried over to the next flight (assuming no key change) or
12757// may be rejected. To avoid differences with split handshakes and generally
12758// reject misbehavior, BoringSSL treats this as an error. When possible, these
12759// tests pull the extra data from the subsequent flight to distinguish the data
12760// being carried over from a general syntax error.
12761//
12762// These tests are similar to tests in |addChangeCipherSpecTests| that send
12763// extra data at key changes. Not all key changes are at the end of a flight and
12764// not all flights end at a key change.
12765func addEndOfFlightTests() {
12766	// TLS 1.3 client handshakes.
12767	//
12768	// Data following the second TLS 1.3 ClientHello is covered by
12769	// PartialClientFinishedWithClientHello,
12770	// PartialClientFinishedWithSecondClientHello, and
12771	// PartialEndOfEarlyDataWithClientHello in |addChangeCipherSpecTests|.
12772	testCases = append(testCases, testCase{
12773		testType: serverTest,
12774		name:     "PartialSecondClientHelloAfterFirst",
12775		config: Config{
12776			MaxVersion: VersionTLS13,
12777			// Trigger a curve-based HelloRetryRequest.
12778			DefaultCurves: []CurveID{},
12779			Bugs: ProtocolBugs{
12780				PartialSecondClientHelloAfterFirst: true,
12781			},
12782		},
12783		shouldFail:         true,
12784		expectedError:      ":EXCESS_HANDSHAKE_DATA:",
12785		expectedLocalError: "remote error: unexpected message",
12786	})
12787
12788	// TLS 1.3 server handshakes.
12789	testCases = append(testCases, testCase{
12790		testType: clientTest,
12791		name:     "PartialServerHelloWithHelloRetryRequest",
12792		config: Config{
12793			MaxVersion: VersionTLS13,
12794			// P-384 requires HelloRetryRequest in BoringSSL.
12795			CurvePreferences: []CurveID{CurveP384},
12796			Bugs: ProtocolBugs{
12797				PartialServerHelloWithHelloRetryRequest: true,
12798			},
12799		},
12800		shouldFail:         true,
12801		expectedError:      ":EXCESS_HANDSHAKE_DATA:",
12802		expectedLocalError: "remote error: unexpected message",
12803	})
12804
12805	// TLS 1.2 client handshakes.
12806	testCases = append(testCases, testCase{
12807		testType: serverTest,
12808		name:     "PartialClientKeyExchangeWithClientHello",
12809		config: Config{
12810			MaxVersion: VersionTLS12,
12811			Bugs: ProtocolBugs{
12812				PartialClientKeyExchangeWithClientHello: true,
12813			},
12814		},
12815		shouldFail:         true,
12816		expectedError:      ":EXCESS_HANDSHAKE_DATA:",
12817		expectedLocalError: "remote error: unexpected message",
12818	})
12819
12820	// TLS 1.2 server handshakes.
12821	testCases = append(testCases, testCase{
12822		testType: clientTest,
12823		name:     "PartialNewSessionTicketWithServerHelloDone",
12824		config: Config{
12825			MaxVersion: VersionTLS12,
12826			Bugs: ProtocolBugs{
12827				PartialNewSessionTicketWithServerHelloDone: true,
12828			},
12829		},
12830		shouldFail:         true,
12831		expectedError:      ":EXCESS_HANDSHAKE_DATA:",
12832		expectedLocalError: "remote error: unexpected message",
12833	})
12834
12835	for _, vers := range tlsVersions {
12836		for _, testType := range []testType{clientTest, serverTest} {
12837			suffix := "-Client"
12838			if testType == serverTest {
12839				suffix = "-Server"
12840			}
12841			suffix += "-" + vers.name
12842
12843			testCases = append(testCases, testCase{
12844				testType: testType,
12845				name:     "TrailingDataWithFinished" + suffix,
12846				config: Config{
12847					MaxVersion: vers.version,
12848					Bugs: ProtocolBugs{
12849						TrailingDataWithFinished: true,
12850					},
12851				},
12852				shouldFail:         true,
12853				expectedError:      ":EXCESS_HANDSHAKE_DATA:",
12854				expectedLocalError: "remote error: unexpected message",
12855			})
12856			testCases = append(testCases, testCase{
12857				testType: testType,
12858				name:     "TrailingDataWithFinished-Resume" + suffix,
12859				config: Config{
12860					MaxVersion: vers.version,
12861				},
12862				resumeConfig: &Config{
12863					MaxVersion: vers.version,
12864					Bugs: ProtocolBugs{
12865						TrailingDataWithFinished: true,
12866					},
12867				},
12868				resumeSession:      true,
12869				shouldFail:         true,
12870				expectedError:      ":EXCESS_HANDSHAKE_DATA:",
12871				expectedLocalError: "remote error: unexpected message",
12872			})
12873		}
12874	}
12875}
12876
12877type perMessageTest struct {
12878	messageType uint8
12879	test        testCase
12880}
12881
12882// makePerMessageTests returns a series of test templates which cover each
12883// message in the TLS handshake. These may be used with bugs like
12884// WrongMessageType to fully test a per-message bug.
12885func makePerMessageTests() []perMessageTest {
12886	var ret []perMessageTest
12887	// The following tests are limited to TLS 1.2, so QUIC is not tested.
12888	for _, protocol := range []protocol{tls, dtls} {
12889		suffix := "-" + protocol.String()
12890
12891		ret = append(ret, perMessageTest{
12892			messageType: typeClientHello,
12893			test: testCase{
12894				protocol: protocol,
12895				testType: serverTest,
12896				name:     "ClientHello" + suffix,
12897				config: Config{
12898					MaxVersion: VersionTLS12,
12899				},
12900			},
12901		})
12902
12903		if protocol == dtls {
12904			ret = append(ret, perMessageTest{
12905				messageType: typeHelloVerifyRequest,
12906				test: testCase{
12907					protocol: protocol,
12908					name:     "HelloVerifyRequest" + suffix,
12909					config: Config{
12910						MaxVersion: VersionTLS12,
12911					},
12912				},
12913			})
12914		}
12915
12916		ret = append(ret, perMessageTest{
12917			messageType: typeServerHello,
12918			test: testCase{
12919				protocol: protocol,
12920				name:     "ServerHello" + suffix,
12921				config: Config{
12922					MaxVersion: VersionTLS12,
12923				},
12924			},
12925		})
12926
12927		ret = append(ret, perMessageTest{
12928			messageType: typeCertificate,
12929			test: testCase{
12930				protocol: protocol,
12931				name:     "ServerCertificate" + suffix,
12932				config: Config{
12933					MaxVersion: VersionTLS12,
12934				},
12935			},
12936		})
12937
12938		ret = append(ret, perMessageTest{
12939			messageType: typeCertificateStatus,
12940			test: testCase{
12941				protocol: protocol,
12942				name:     "CertificateStatus" + suffix,
12943				config: Config{
12944					MaxVersion: VersionTLS12,
12945				},
12946				flags: []string{"-enable-ocsp-stapling"},
12947			},
12948		})
12949
12950		ret = append(ret, perMessageTest{
12951			messageType: typeServerKeyExchange,
12952			test: testCase{
12953				protocol: protocol,
12954				name:     "ServerKeyExchange" + suffix,
12955				config: Config{
12956					MaxVersion:   VersionTLS12,
12957					CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
12958				},
12959			},
12960		})
12961
12962		ret = append(ret, perMessageTest{
12963			messageType: typeCertificateRequest,
12964			test: testCase{
12965				protocol: protocol,
12966				name:     "CertificateRequest" + suffix,
12967				config: Config{
12968					MaxVersion: VersionTLS12,
12969					ClientAuth: RequireAnyClientCert,
12970				},
12971			},
12972		})
12973
12974		ret = append(ret, perMessageTest{
12975			messageType: typeServerHelloDone,
12976			test: testCase{
12977				protocol: protocol,
12978				name:     "ServerHelloDone" + suffix,
12979				config: Config{
12980					MaxVersion: VersionTLS12,
12981				},
12982			},
12983		})
12984
12985		ret = append(ret, perMessageTest{
12986			messageType: typeCertificate,
12987			test: testCase{
12988				testType: serverTest,
12989				protocol: protocol,
12990				name:     "ClientCertificate" + suffix,
12991				config: Config{
12992					Certificates: []Certificate{rsaCertificate},
12993					MaxVersion:   VersionTLS12,
12994				},
12995				flags: []string{"-require-any-client-certificate"},
12996			},
12997		})
12998
12999		ret = append(ret, perMessageTest{
13000			messageType: typeCertificateVerify,
13001			test: testCase{
13002				testType: serverTest,
13003				protocol: protocol,
13004				name:     "CertificateVerify" + suffix,
13005				config: Config{
13006					Certificates: []Certificate{rsaCertificate},
13007					MaxVersion:   VersionTLS12,
13008				},
13009				flags: []string{"-require-any-client-certificate"},
13010			},
13011		})
13012
13013		ret = append(ret, perMessageTest{
13014			messageType: typeClientKeyExchange,
13015			test: testCase{
13016				testType: serverTest,
13017				protocol: protocol,
13018				name:     "ClientKeyExchange" + suffix,
13019				config: Config{
13020					MaxVersion: VersionTLS12,
13021				},
13022			},
13023		})
13024
13025		if protocol != dtls {
13026			ret = append(ret, perMessageTest{
13027				messageType: typeNextProtocol,
13028				test: testCase{
13029					testType: serverTest,
13030					protocol: protocol,
13031					name:     "NextProtocol" + suffix,
13032					config: Config{
13033						MaxVersion: VersionTLS12,
13034						NextProtos: []string{"bar"},
13035					},
13036					flags: []string{"-advertise-npn", "\x03foo\x03bar\x03baz"},
13037				},
13038			})
13039
13040			ret = append(ret, perMessageTest{
13041				messageType: typeChannelID,
13042				test: testCase{
13043					testType: serverTest,
13044					protocol: protocol,
13045					name:     "ChannelID" + suffix,
13046					config: Config{
13047						MaxVersion: VersionTLS12,
13048						ChannelID:  channelIDKey,
13049					},
13050					flags: []string{
13051						"-expect-channel-id",
13052						base64.StdEncoding.EncodeToString(channelIDBytes),
13053					},
13054				},
13055			})
13056		}
13057
13058		ret = append(ret, perMessageTest{
13059			messageType: typeFinished,
13060			test: testCase{
13061				testType: serverTest,
13062				protocol: protocol,
13063				name:     "ClientFinished" + suffix,
13064				config: Config{
13065					MaxVersion: VersionTLS12,
13066				},
13067			},
13068		})
13069
13070		ret = append(ret, perMessageTest{
13071			messageType: typeNewSessionTicket,
13072			test: testCase{
13073				protocol: protocol,
13074				name:     "NewSessionTicket" + suffix,
13075				config: Config{
13076					MaxVersion: VersionTLS12,
13077				},
13078			},
13079		})
13080
13081		ret = append(ret, perMessageTest{
13082			messageType: typeFinished,
13083			test: testCase{
13084				protocol: protocol,
13085				name:     "ServerFinished" + suffix,
13086				config: Config{
13087					MaxVersion: VersionTLS12,
13088				},
13089			},
13090		})
13091
13092	}
13093
13094	for _, protocol := range []protocol{tls, quic} {
13095		suffix := "-" + protocol.String()
13096		ret = append(ret, perMessageTest{
13097			messageType: typeClientHello,
13098			test: testCase{
13099				testType: serverTest,
13100				name:     "TLS13-ClientHello" + suffix,
13101				config: Config{
13102					MaxVersion: VersionTLS13,
13103				},
13104			},
13105		})
13106
13107		ret = append(ret, perMessageTest{
13108			messageType: typeServerHello,
13109			test: testCase{
13110				name: "TLS13-ServerHello" + suffix,
13111				config: Config{
13112					MaxVersion: VersionTLS13,
13113				},
13114			},
13115		})
13116
13117		ret = append(ret, perMessageTest{
13118			messageType: typeEncryptedExtensions,
13119			test: testCase{
13120				name: "TLS13-EncryptedExtensions" + suffix,
13121				config: Config{
13122					MaxVersion: VersionTLS13,
13123				},
13124			},
13125		})
13126
13127		ret = append(ret, perMessageTest{
13128			messageType: typeCertificateRequest,
13129			test: testCase{
13130				name: "TLS13-CertificateRequest" + suffix,
13131				config: Config{
13132					MaxVersion: VersionTLS13,
13133					ClientAuth: RequireAnyClientCert,
13134				},
13135			},
13136		})
13137
13138		ret = append(ret, perMessageTest{
13139			messageType: typeCertificate,
13140			test: testCase{
13141				name: "TLS13-ServerCertificate" + suffix,
13142				config: Config{
13143					MaxVersion: VersionTLS13,
13144				},
13145			},
13146		})
13147
13148		ret = append(ret, perMessageTest{
13149			messageType: typeCertificateVerify,
13150			test: testCase{
13151				name: "TLS13-ServerCertificateVerify" + suffix,
13152				config: Config{
13153					MaxVersion: VersionTLS13,
13154				},
13155			},
13156		})
13157
13158		ret = append(ret, perMessageTest{
13159			messageType: typeFinished,
13160			test: testCase{
13161				name: "TLS13-ServerFinished" + suffix,
13162				config: Config{
13163					MaxVersion: VersionTLS13,
13164				},
13165			},
13166		})
13167
13168		ret = append(ret, perMessageTest{
13169			messageType: typeCertificate,
13170			test: testCase{
13171				testType: serverTest,
13172				name:     "TLS13-ClientCertificate" + suffix,
13173				config: Config{
13174					Certificates: []Certificate{rsaCertificate},
13175					MaxVersion:   VersionTLS13,
13176				},
13177				flags: []string{"-require-any-client-certificate"},
13178			},
13179		})
13180
13181		ret = append(ret, perMessageTest{
13182			messageType: typeCertificateVerify,
13183			test: testCase{
13184				testType: serverTest,
13185				name:     "TLS13-ClientCertificateVerify" + suffix,
13186				config: Config{
13187					Certificates: []Certificate{rsaCertificate},
13188					MaxVersion:   VersionTLS13,
13189				},
13190				flags: []string{"-require-any-client-certificate"},
13191			},
13192		})
13193
13194		ret = append(ret, perMessageTest{
13195			messageType: typeFinished,
13196			test: testCase{
13197				testType: serverTest,
13198				name:     "TLS13-ClientFinished" + suffix,
13199				config: Config{
13200					MaxVersion: VersionTLS13,
13201				},
13202			},
13203		})
13204
13205		ret = append(ret, perMessageTest{
13206			messageType: typeEndOfEarlyData,
13207			test: testCase{
13208				testType: serverTest,
13209				name:     "TLS13-EndOfEarlyData" + suffix,
13210				config: Config{
13211					MaxVersion: VersionTLS13,
13212				},
13213				resumeSession: true,
13214				earlyData:     true,
13215			},
13216		})
13217	}
13218
13219	return ret
13220}
13221
13222func addWrongMessageTypeTests() {
13223	for _, t := range makePerMessageTests() {
13224		t.test.name = "WrongMessageType-" + t.test.name
13225		if t.test.resumeConfig != nil {
13226			t.test.resumeConfig.Bugs.SendWrongMessageType = t.messageType
13227		} else {
13228			t.test.config.Bugs.SendWrongMessageType = t.messageType
13229		}
13230		t.test.shouldFail = true
13231		t.test.expectedError = ":UNEXPECTED_MESSAGE:"
13232		t.test.expectedLocalError = "remote error: unexpected message"
13233
13234		if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello {
13235			// In TLS 1.3, a bad ServerHello means the client sends
13236			// an unencrypted alert while the server expects
13237			// encryption, so the alert is not readable by runner.
13238			t.test.expectedLocalError = "local error: bad record MAC"
13239		}
13240
13241		testCases = append(testCases, t.test)
13242	}
13243
13244	// The processing order for TLS 1.3 version negotiation is such that one
13245	// may accidentally accept a HelloRetryRequest in lieu of ServerHello in
13246	// TLS 1.2. Test that we do not do this.
13247	testCases = append(testCases, testCase{
13248		name: "SendServerHelloAsHelloRetryRequest",
13249		config: Config{
13250			MaxVersion: VersionTLS12,
13251			Bugs: ProtocolBugs{
13252				SendServerHelloAsHelloRetryRequest: true,
13253			},
13254		},
13255		shouldFail:         true,
13256		expectedError:      ":UNEXPECTED_MESSAGE:",
13257		expectedLocalError: "remote error: unexpected message",
13258	})
13259}
13260
13261func addTrailingMessageDataTests() {
13262	for _, t := range makePerMessageTests() {
13263		t.test.name = "TrailingMessageData-" + t.test.name
13264		if t.test.resumeConfig != nil {
13265			t.test.resumeConfig.Bugs.SendTrailingMessageData = t.messageType
13266		} else {
13267			t.test.config.Bugs.SendTrailingMessageData = t.messageType
13268		}
13269		t.test.shouldFail = true
13270		t.test.expectedError = ":DECODE_ERROR:"
13271		t.test.expectedLocalError = "remote error: error decoding message"
13272
13273		if t.test.config.MaxVersion >= VersionTLS13 && t.messageType == typeServerHello {
13274			// In TLS 1.3, a bad ServerHello means the client sends
13275			// an unencrypted alert while the server expects
13276			// encryption, so the alert is not readable by runner.
13277			t.test.expectedLocalError = "local error: bad record MAC"
13278		}
13279
13280		if t.messageType == typeFinished {
13281			// Bad Finished messages read as the verify data having
13282			// the wrong length.
13283			t.test.expectedError = ":DIGEST_CHECK_FAILED:"
13284			t.test.expectedLocalError = "remote error: error decrypting message"
13285		}
13286
13287		testCases = append(testCases, t.test)
13288	}
13289}
13290
13291func addTLS13HandshakeTests() {
13292	testCases = append(testCases, testCase{
13293		testType: clientTest,
13294		name:     "NegotiatePSKResumption-TLS13",
13295		config: Config{
13296			MaxVersion: VersionTLS13,
13297			Bugs: ProtocolBugs{
13298				NegotiatePSKResumption: true,
13299			},
13300		},
13301		resumeSession: true,
13302		shouldFail:    true,
13303		expectedError: ":MISSING_KEY_SHARE:",
13304	})
13305
13306	testCases = append(testCases, testCase{
13307		testType: clientTest,
13308		name:     "MissingKeyShare-Client-TLS13",
13309		config: Config{
13310			MaxVersion: VersionTLS13,
13311			Bugs: ProtocolBugs{
13312				MissingKeyShare: true,
13313			},
13314		},
13315		shouldFail:    true,
13316		expectedError: ":MISSING_KEY_SHARE:",
13317	})
13318
13319	testCases = append(testCases, testCase{
13320		testType: serverTest,
13321		name:     "MissingKeyShare-Server-TLS13",
13322		config: Config{
13323			MaxVersion: VersionTLS13,
13324			Bugs: ProtocolBugs{
13325				MissingKeyShare: true,
13326			},
13327		},
13328		shouldFail:    true,
13329		expectedError: ":MISSING_KEY_SHARE:",
13330	})
13331
13332	testCases = append(testCases, testCase{
13333		testType: serverTest,
13334		name:     "DuplicateKeyShares-TLS13",
13335		config: Config{
13336			MaxVersion: VersionTLS13,
13337			Bugs: ProtocolBugs{
13338				DuplicateKeyShares: true,
13339			},
13340		},
13341		shouldFail:    true,
13342		expectedError: ":DUPLICATE_KEY_SHARE:",
13343	})
13344
13345	testCases = append(testCases, testCase{
13346		testType: serverTest,
13347		name:     "SkipEarlyData-TLS13",
13348		config: Config{
13349			MaxVersion: VersionTLS13,
13350			Bugs: ProtocolBugs{
13351				SendFakeEarlyDataLength: 4,
13352			},
13353		},
13354	})
13355
13356	// Test that enabling TLS 1.3 does not interfere with TLS 1.2 session ID
13357	// resumption.
13358	testCases = append(testCases, testCase{
13359		testType: clientTest,
13360		name:     "ResumeTLS12SessionID-TLS13",
13361		config: Config{
13362			MaxVersion:             VersionTLS12,
13363			SessionTicketsDisabled: true,
13364		},
13365		resumeSession: true,
13366	})
13367
13368	// Test that the client correctly handles a TLS 1.3 ServerHello which echoes
13369	// a TLS 1.2 session ID.
13370	testCases = append(testCases, testCase{
13371		testType: clientTest,
13372		name:     "TLS12SessionID-TLS13",
13373		config: Config{
13374			MaxVersion:             VersionTLS12,
13375			SessionTicketsDisabled: true,
13376		},
13377		resumeConfig: &Config{
13378			MaxVersion: VersionTLS13,
13379		},
13380		resumeSession:        true,
13381		expectResumeRejected: true,
13382	})
13383
13384	// Test that the server correctly echoes back session IDs of
13385	// various lengths. The first test additionally asserts that
13386	// BoringSSL always sends the ChangeCipherSpec messages for
13387	// compatibility mode, rather than negotiating it based on the
13388	// ClientHello.
13389	testCases = append(testCases, testCase{
13390		testType: serverTest,
13391		name:     "EmptySessionID-TLS13",
13392		config: Config{
13393			MaxVersion: VersionTLS13,
13394			Bugs: ProtocolBugs{
13395				SendClientHelloSessionID: []byte{},
13396			},
13397		},
13398	})
13399
13400	testCases = append(testCases, testCase{
13401		testType: serverTest,
13402		name:     "ShortSessionID-TLS13",
13403		config: Config{
13404			MaxVersion: VersionTLS13,
13405			Bugs: ProtocolBugs{
13406				SendClientHelloSessionID: make([]byte, 16),
13407			},
13408		},
13409	})
13410
13411	testCases = append(testCases, testCase{
13412		testType: serverTest,
13413		name:     "FullSessionID-TLS13",
13414		config: Config{
13415			MaxVersion: VersionTLS13,
13416			Bugs: ProtocolBugs{
13417				SendClientHelloSessionID: make([]byte, 32),
13418			},
13419		},
13420	})
13421
13422	// Test that the client sends a fake session ID in TLS 1.3.
13423	testCases = append(testCases, testCase{
13424		testType: clientTest,
13425		name:     "TLS13SessionID-TLS13",
13426		config: Config{
13427			MaxVersion: VersionTLS13,
13428			Bugs: ProtocolBugs{
13429				ExpectClientHelloSessionID: true,
13430			},
13431		},
13432	})
13433
13434	// Test that the client omits the fake session ID when the max version is TLS 1.2 and below.
13435	testCases = append(testCases, testCase{
13436		testType: clientTest,
13437		name:     "TLS12NoSessionID-TLS13",
13438		config: Config{
13439			MaxVersion: VersionTLS13,
13440			Bugs: ProtocolBugs{
13441				ExpectNoTLS12Session: true,
13442			},
13443		},
13444		flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
13445	})
13446
13447	testCases = append(testCases, testCase{
13448		testType: clientTest,
13449		name:     "EarlyData-Client-TLS13",
13450		config: Config{
13451			MaxVersion: VersionTLS13,
13452			MinVersion: VersionTLS13,
13453		},
13454		resumeSession: true,
13455		earlyData:     true,
13456		flags: []string{
13457			"-on-initial-expect-early-data-reason", "no_session_offered",
13458			"-on-resume-expect-early-data-reason", "accept",
13459		},
13460	})
13461
13462	testCases = append(testCases, testCase{
13463		testType: clientTest,
13464		name:     "EarlyData-Reject-Client-TLS13",
13465		config: Config{
13466			MaxVersion: VersionTLS13,
13467		},
13468		resumeConfig: &Config{
13469			MaxVersion: VersionTLS13,
13470			Bugs: ProtocolBugs{
13471				AlwaysRejectEarlyData: true,
13472			},
13473		},
13474		resumeSession:           true,
13475		earlyData:               true,
13476		expectEarlyDataRejected: true,
13477		flags: []string{
13478			"-on-retry-expect-early-data-reason", "peer_declined",
13479		},
13480	})
13481
13482	testCases = append(testCases, testCase{
13483		testType: serverTest,
13484		name:     "EarlyData-Server-TLS13",
13485		config: Config{
13486			MaxVersion: VersionTLS13,
13487			MinVersion: VersionTLS13,
13488		},
13489		messageCount:  2,
13490		resumeSession: true,
13491		earlyData:     true,
13492		flags: []string{
13493			"-on-initial-expect-early-data-reason", "no_session_offered",
13494			"-on-resume-expect-early-data-reason", "accept",
13495		},
13496	})
13497
13498	// The above tests the most recent ticket. Additionally test that 0-RTT
13499	// works on the first ticket issued by the server.
13500	testCases = append(testCases, testCase{
13501		testType: serverTest,
13502		name:     "EarlyData-FirstTicket-Server-TLS13",
13503		config: Config{
13504			MaxVersion: VersionTLS13,
13505			MinVersion: VersionTLS13,
13506			Bugs: ProtocolBugs{
13507				UseFirstSessionTicket: true,
13508			},
13509		},
13510		messageCount:  2,
13511		resumeSession: true,
13512		earlyData:     true,
13513		flags: []string{
13514			"-on-resume-expect-early-data-reason", "accept",
13515		},
13516	})
13517
13518	testCases = append(testCases, testCase{
13519		testType: serverTest,
13520		name:     "SkipEarlyData-OmitEarlyDataExtension-TLS13",
13521		config: Config{
13522			MaxVersion: VersionTLS13,
13523			Bugs: ProtocolBugs{
13524				SendFakeEarlyDataLength: 4,
13525				OmitEarlyDataExtension:  true,
13526			},
13527		},
13528		shouldFail:    true,
13529		expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
13530	})
13531
13532	testCases = append(testCases, testCase{
13533		testType: serverTest,
13534		name:     "SkipEarlyData-TooMuchData-TLS13",
13535		config: Config{
13536			MaxVersion: VersionTLS13,
13537			Bugs: ProtocolBugs{
13538				SendFakeEarlyDataLength: 16384 + 1,
13539			},
13540		},
13541		shouldFail:    true,
13542		expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:",
13543	})
13544
13545	testCases = append(testCases, testCase{
13546		testType: serverTest,
13547		name:     "SkipEarlyData-Interleaved-TLS13",
13548		config: Config{
13549			MaxVersion: VersionTLS13,
13550			Bugs: ProtocolBugs{
13551				SendFakeEarlyDataLength: 4,
13552				InterleaveEarlyData:     true,
13553			},
13554		},
13555		shouldFail:    true,
13556		expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
13557	})
13558
13559	testCases = append(testCases, testCase{
13560		testType: serverTest,
13561		name:     "SkipEarlyData-EarlyDataInTLS12-TLS13",
13562		config: Config{
13563			MaxVersion: VersionTLS13,
13564			Bugs: ProtocolBugs{
13565				SendFakeEarlyDataLength: 4,
13566			},
13567		},
13568		shouldFail:    true,
13569		expectedError: ":UNEXPECTED_RECORD:",
13570		flags:         []string{"-max-version", strconv.Itoa(VersionTLS12)},
13571	})
13572
13573	testCases = append(testCases, testCase{
13574		testType: serverTest,
13575		name:     "SkipEarlyData-HRR-TLS13",
13576		config: Config{
13577			MaxVersion: VersionTLS13,
13578			Bugs: ProtocolBugs{
13579				SendFakeEarlyDataLength: 4,
13580			},
13581			DefaultCurves: []CurveID{},
13582		},
13583		// Though the session is not resumed and we send HelloRetryRequest,
13584		// early data being disabled takes priority as the reject reason.
13585		flags: []string{"-expect-early-data-reason", "disabled"},
13586	})
13587
13588	testCases = append(testCases, testCase{
13589		testType: serverTest,
13590		name:     "SkipEarlyData-HRR-Interleaved-TLS13",
13591		config: Config{
13592			MaxVersion: VersionTLS13,
13593			Bugs: ProtocolBugs{
13594				SendFakeEarlyDataLength: 4,
13595				InterleaveEarlyData:     true,
13596			},
13597			DefaultCurves: []CurveID{},
13598		},
13599		shouldFail:    true,
13600		expectedError: ":UNEXPECTED_RECORD:",
13601	})
13602
13603	testCases = append(testCases, testCase{
13604		testType: serverTest,
13605		name:     "SkipEarlyData-HRR-TooMuchData-TLS13",
13606		config: Config{
13607			MaxVersion: VersionTLS13,
13608			Bugs: ProtocolBugs{
13609				SendFakeEarlyDataLength: 16384 + 1,
13610			},
13611			DefaultCurves: []CurveID{},
13612		},
13613		shouldFail:    true,
13614		expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:",
13615	})
13616
13617	// Test that skipping early data looking for cleartext correctly
13618	// processes an alert record.
13619	testCases = append(testCases, testCase{
13620		testType: serverTest,
13621		name:     "SkipEarlyData-HRR-FatalAlert-TLS13",
13622		config: Config{
13623			MaxVersion: VersionTLS13,
13624			Bugs: ProtocolBugs{
13625				SendEarlyAlert:          true,
13626				SendFakeEarlyDataLength: 4,
13627			},
13628			DefaultCurves: []CurveID{},
13629		},
13630		shouldFail:    true,
13631		expectedError: ":SSLV3_ALERT_HANDSHAKE_FAILURE:",
13632	})
13633
13634	testCases = append(testCases, testCase{
13635		testType: serverTest,
13636		name:     "SkipEarlyData-SecondClientHelloEarlyData-TLS13",
13637		config: Config{
13638			MaxVersion: VersionTLS13,
13639			Bugs: ProtocolBugs{
13640				SendEarlyDataOnSecondClientHello: true,
13641			},
13642			DefaultCurves: []CurveID{},
13643		},
13644		shouldFail:         true,
13645		expectedLocalError: "remote error: bad record MAC",
13646	})
13647
13648	testCases = append(testCases, testCase{
13649		testType: clientTest,
13650		name:     "EmptyEncryptedExtensions-TLS13",
13651		config: Config{
13652			MaxVersion: VersionTLS13,
13653			Bugs: ProtocolBugs{
13654				EmptyEncryptedExtensions: true,
13655			},
13656		},
13657		shouldFail:         true,
13658		expectedLocalError: "remote error: error decoding message",
13659	})
13660
13661	testCases = append(testCases, testCase{
13662		testType: clientTest,
13663		name:     "EncryptedExtensionsWithKeyShare-TLS13",
13664		config: Config{
13665			MaxVersion: VersionTLS13,
13666			Bugs: ProtocolBugs{
13667				EncryptedExtensionsWithKeyShare: true,
13668			},
13669		},
13670		shouldFail:         true,
13671		expectedLocalError: "remote error: unsupported extension",
13672	})
13673
13674	testCases = append(testCases, testCase{
13675		testType: serverTest,
13676		name:     "SendHelloRetryRequest-TLS13",
13677		config: Config{
13678			MaxVersion: VersionTLS13,
13679			// Require a HelloRetryRequest for every curve.
13680			DefaultCurves:    []CurveID{},
13681			CurvePreferences: []CurveID{CurveX25519},
13682		},
13683		expectations: connectionExpectations{
13684			curveID: CurveX25519,
13685		},
13686		flags: []string{"-expect-hrr"},
13687	})
13688
13689	testCases = append(testCases, testCase{
13690		testType: serverTest,
13691		name:     "SendHelloRetryRequest-2-TLS13",
13692		config: Config{
13693			MaxVersion:       VersionTLS13,
13694			DefaultCurves:    []CurveID{CurveP384},
13695			CurvePreferences: []CurveID{CurveX25519, CurveP384},
13696		},
13697		// Although the ClientHello did not predict our preferred curve,
13698		// we always select it whether it is predicted or not.
13699		expectations: connectionExpectations{
13700			curveID: CurveX25519,
13701		},
13702		flags: []string{"-expect-hrr"},
13703	})
13704
13705	testCases = append(testCases, testCase{
13706		name: "UnknownCurve-HelloRetryRequest-TLS13",
13707		config: Config{
13708			MaxVersion: VersionTLS13,
13709			// P-384 requires HelloRetryRequest in BoringSSL.
13710			CurvePreferences: []CurveID{CurveP384},
13711			Bugs: ProtocolBugs{
13712				SendHelloRetryRequestCurve: bogusCurve,
13713			},
13714		},
13715		shouldFail:    true,
13716		expectedError: ":WRONG_CURVE:",
13717	})
13718
13719	testCases = append(testCases, testCase{
13720		name: "HelloRetryRequest-CipherChange-TLS13",
13721		config: Config{
13722			MaxVersion: VersionTLS13,
13723			// P-384 requires HelloRetryRequest in BoringSSL.
13724			CurvePreferences: []CurveID{CurveP384},
13725			Bugs: ProtocolBugs{
13726				SendCipherSuite:                  TLS_AES_128_GCM_SHA256,
13727				SendHelloRetryRequestCipherSuite: TLS_CHACHA20_POLY1305_SHA256,
13728			},
13729		},
13730		shouldFail:    true,
13731		expectedError: ":WRONG_CIPHER_RETURNED:",
13732	})
13733
13734	// Test that the client does not offer a PSK in the second ClientHello if the
13735	// HelloRetryRequest is incompatible with it.
13736	testCases = append(testCases, testCase{
13737		testType: clientTest,
13738		name:     "HelloRetryRequest-NonResumableCipher-TLS13",
13739		config: Config{
13740			MaxVersion: VersionTLS13,
13741			CipherSuites: []uint16{
13742				TLS_AES_128_GCM_SHA256,
13743			},
13744		},
13745		resumeConfig: &Config{
13746			MaxVersion: VersionTLS13,
13747			// P-384 requires HelloRetryRequest in BoringSSL.
13748			CurvePreferences: []CurveID{CurveP384},
13749			Bugs: ProtocolBugs{
13750				ExpectNoTLS13PSKAfterHRR: true,
13751			},
13752			CipherSuites: []uint16{
13753				TLS_AES_256_GCM_SHA384,
13754			},
13755		},
13756		resumeSession:        true,
13757		expectResumeRejected: true,
13758	})
13759
13760	testCases = append(testCases, testCase{
13761		name: "DisabledCurve-HelloRetryRequest-TLS13",
13762		config: Config{
13763			MaxVersion:       VersionTLS13,
13764			CurvePreferences: []CurveID{CurveP256},
13765			Bugs: ProtocolBugs{
13766				IgnorePeerCurvePreferences: true,
13767			},
13768		},
13769		flags:         []string{"-curves", strconv.Itoa(int(CurveP384))},
13770		shouldFail:    true,
13771		expectedError: ":WRONG_CURVE:",
13772	})
13773
13774	testCases = append(testCases, testCase{
13775		name: "UnnecessaryHelloRetryRequest-TLS13",
13776		config: Config{
13777			MaxVersion:       VersionTLS13,
13778			CurvePreferences: []CurveID{CurveX25519},
13779			Bugs: ProtocolBugs{
13780				SendHelloRetryRequestCurve: CurveX25519,
13781			},
13782		},
13783		shouldFail:    true,
13784		expectedError: ":WRONG_CURVE:",
13785	})
13786
13787	testCases = append(testCases, testCase{
13788		name: "SecondHelloRetryRequest-TLS13",
13789		config: Config{
13790			MaxVersion: VersionTLS13,
13791			// P-384 requires HelloRetryRequest in BoringSSL.
13792			CurvePreferences: []CurveID{CurveP384},
13793			Bugs: ProtocolBugs{
13794				SecondHelloRetryRequest: true,
13795			},
13796		},
13797		shouldFail:    true,
13798		expectedError: ":UNEXPECTED_MESSAGE:",
13799	})
13800
13801	testCases = append(testCases, testCase{
13802		name: "HelloRetryRequest-Empty-TLS13",
13803		config: Config{
13804			MaxVersion: VersionTLS13,
13805			Bugs: ProtocolBugs{
13806				AlwaysSendHelloRetryRequest: true,
13807			},
13808		},
13809		shouldFail:         true,
13810		expectedError:      ":EMPTY_HELLO_RETRY_REQUEST:",
13811		expectedLocalError: "remote error: illegal parameter",
13812	})
13813
13814	testCases = append(testCases, testCase{
13815		name: "HelloRetryRequest-DuplicateCurve-TLS13",
13816		config: Config{
13817			MaxVersion: VersionTLS13,
13818			// P-384 requires a HelloRetryRequest against BoringSSL's default
13819			// configuration. Assert this ExpectMissingKeyShare.
13820			CurvePreferences: []CurveID{CurveP384},
13821			Bugs: ProtocolBugs{
13822				ExpectMissingKeyShare:                true,
13823				DuplicateHelloRetryRequestExtensions: true,
13824			},
13825		},
13826		shouldFail:         true,
13827		expectedError:      ":DUPLICATE_EXTENSION:",
13828		expectedLocalError: "remote error: illegal parameter",
13829	})
13830
13831	testCases = append(testCases, testCase{
13832		name: "HelloRetryRequest-Cookie-TLS13",
13833		config: Config{
13834			MaxVersion: VersionTLS13,
13835			Bugs: ProtocolBugs{
13836				SendHelloRetryRequestCookie: []byte("cookie"),
13837			},
13838		},
13839	})
13840
13841	testCases = append(testCases, testCase{
13842		name: "HelloRetryRequest-DuplicateCookie-TLS13",
13843		config: Config{
13844			MaxVersion: VersionTLS13,
13845			Bugs: ProtocolBugs{
13846				SendHelloRetryRequestCookie:          []byte("cookie"),
13847				DuplicateHelloRetryRequestExtensions: true,
13848			},
13849		},
13850		shouldFail:         true,
13851		expectedError:      ":DUPLICATE_EXTENSION:",
13852		expectedLocalError: "remote error: illegal parameter",
13853	})
13854
13855	testCases = append(testCases, testCase{
13856		name: "HelloRetryRequest-EmptyCookie-TLS13",
13857		config: Config{
13858			MaxVersion: VersionTLS13,
13859			Bugs: ProtocolBugs{
13860				SendHelloRetryRequestCookie: []byte{},
13861			},
13862		},
13863		shouldFail:    true,
13864		expectedError: ":DECODE_ERROR:",
13865	})
13866
13867	testCases = append(testCases, testCase{
13868		name: "HelloRetryRequest-Cookie-Curve-TLS13",
13869		config: Config{
13870			MaxVersion: VersionTLS13,
13871			// P-384 requires HelloRetryRequest in BoringSSL.
13872			CurvePreferences: []CurveID{CurveP384},
13873			Bugs: ProtocolBugs{
13874				SendHelloRetryRequestCookie: []byte("cookie"),
13875				ExpectMissingKeyShare:       true,
13876			},
13877		},
13878	})
13879
13880	testCases = append(testCases, testCase{
13881		name: "HelloRetryRequest-Unknown-TLS13",
13882		config: Config{
13883			MaxVersion: VersionTLS13,
13884			Bugs: ProtocolBugs{
13885				CustomHelloRetryRequestExtension: "extension",
13886			},
13887		},
13888		shouldFail:         true,
13889		expectedError:      ":UNEXPECTED_EXTENSION:",
13890		expectedLocalError: "remote error: unsupported extension",
13891	})
13892
13893	testCases = append(testCases, testCase{
13894		testType: serverTest,
13895		name:     "SecondClientHelloMissingKeyShare-TLS13",
13896		config: Config{
13897			MaxVersion:    VersionTLS13,
13898			DefaultCurves: []CurveID{},
13899			Bugs: ProtocolBugs{
13900				SecondClientHelloMissingKeyShare: true,
13901			},
13902		},
13903		shouldFail:    true,
13904		expectedError: ":MISSING_KEY_SHARE:",
13905	})
13906
13907	testCases = append(testCases, testCase{
13908		testType: serverTest,
13909		name:     "SecondClientHelloWrongCurve-TLS13",
13910		config: Config{
13911			MaxVersion:    VersionTLS13,
13912			DefaultCurves: []CurveID{},
13913			Bugs: ProtocolBugs{
13914				MisinterpretHelloRetryRequestCurve: CurveP521,
13915			},
13916		},
13917		shouldFail:    true,
13918		expectedError: ":WRONG_CURVE:",
13919	})
13920
13921	testCases = append(testCases, testCase{
13922		name: "HelloRetryRequestVersionMismatch-TLS13",
13923		config: Config{
13924			MaxVersion: VersionTLS13,
13925			// P-384 requires HelloRetryRequest in BoringSSL.
13926			CurvePreferences: []CurveID{CurveP384},
13927			Bugs: ProtocolBugs{
13928				SendServerHelloVersion: 0x0305,
13929			},
13930		},
13931		shouldFail:    true,
13932		expectedError: ":WRONG_VERSION_NUMBER:",
13933	})
13934
13935	testCases = append(testCases, testCase{
13936		name: "HelloRetryRequestCurveMismatch-TLS13",
13937		config: Config{
13938			MaxVersion: VersionTLS13,
13939			// P-384 requires HelloRetryRequest in BoringSSL.
13940			CurvePreferences: []CurveID{CurveP384},
13941			Bugs: ProtocolBugs{
13942				// Send P-384 (correct) in the HelloRetryRequest.
13943				SendHelloRetryRequestCurve: CurveP384,
13944				// But send P-256 in the ServerHello.
13945				SendCurve: CurveP256,
13946			},
13947		},
13948		shouldFail:    true,
13949		expectedError: ":WRONG_CURVE:",
13950	})
13951
13952	// Test the server selecting a curve that requires a HelloRetryRequest
13953	// without sending it.
13954	testCases = append(testCases, testCase{
13955		name: "SkipHelloRetryRequest-TLS13",
13956		config: Config{
13957			MaxVersion: VersionTLS13,
13958			// P-384 requires HelloRetryRequest in BoringSSL.
13959			CurvePreferences: []CurveID{CurveP384},
13960			Bugs: ProtocolBugs{
13961				SkipHelloRetryRequest: true,
13962			},
13963		},
13964		shouldFail:    true,
13965		expectedError: ":WRONG_CURVE:",
13966	})
13967
13968	testCases = append(testCases, testCase{
13969		name: "SecondServerHelloNoVersion-TLS13",
13970		config: Config{
13971			MaxVersion: VersionTLS13,
13972			// P-384 requires HelloRetryRequest in BoringSSL.
13973			CurvePreferences: []CurveID{CurveP384},
13974			Bugs: ProtocolBugs{
13975				OmitServerSupportedVersionExtension: true,
13976			},
13977		},
13978		shouldFail:    true,
13979		expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:",
13980	})
13981	testCases = append(testCases, testCase{
13982		name: "SecondServerHelloWrongVersion-TLS13",
13983		config: Config{
13984			MaxVersion: VersionTLS13,
13985			// P-384 requires HelloRetryRequest in BoringSSL.
13986			CurvePreferences: []CurveID{CurveP384},
13987			Bugs: ProtocolBugs{
13988				SendServerSupportedVersionExtension: 0x1234,
13989			},
13990		},
13991		shouldFail:    true,
13992		expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:",
13993	})
13994
13995	testCases = append(testCases, testCase{
13996		name: "RequestContextInHandshake-TLS13",
13997		config: Config{
13998			MaxVersion: VersionTLS13,
13999			MinVersion: VersionTLS13,
14000			ClientAuth: RequireAnyClientCert,
14001			Bugs: ProtocolBugs{
14002				SendRequestContext: []byte("request context"),
14003			},
14004		},
14005		flags: []string{
14006			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14007			"-key-file", path.Join(*resourceDir, rsaKeyFile),
14008		},
14009		shouldFail:    true,
14010		expectedError: ":DECODE_ERROR:",
14011	})
14012
14013	testCases = append(testCases, testCase{
14014		name: "UnknownExtensionInCertificateRequest-TLS13",
14015		config: Config{
14016			MaxVersion: VersionTLS13,
14017			MinVersion: VersionTLS13,
14018			ClientAuth: RequireAnyClientCert,
14019			Bugs: ProtocolBugs{
14020				SendCustomCertificateRequest: 0x1212,
14021			},
14022		},
14023		flags: []string{
14024			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14025			"-key-file", path.Join(*resourceDir, rsaKeyFile),
14026		},
14027	})
14028
14029	testCases = append(testCases, testCase{
14030		name: "MissingSignatureAlgorithmsInCertificateRequest-TLS13",
14031		config: Config{
14032			MaxVersion: VersionTLS13,
14033			MinVersion: VersionTLS13,
14034			ClientAuth: RequireAnyClientCert,
14035			Bugs: ProtocolBugs{
14036				OmitCertificateRequestAlgorithms: true,
14037			},
14038		},
14039		flags: []string{
14040			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14041			"-key-file", path.Join(*resourceDir, rsaKeyFile),
14042		},
14043		shouldFail:    true,
14044		expectedError: ":DECODE_ERROR:",
14045	})
14046
14047	testCases = append(testCases, testCase{
14048		testType: serverTest,
14049		name:     "TrailingKeyShareData-TLS13",
14050		config: Config{
14051			MaxVersion: VersionTLS13,
14052			Bugs: ProtocolBugs{
14053				TrailingKeyShareData: true,
14054			},
14055		},
14056		shouldFail:    true,
14057		expectedError: ":DECODE_ERROR:",
14058	})
14059
14060	testCases = append(testCases, testCase{
14061		name: "AlwaysSelectPSKIdentity-TLS13",
14062		config: Config{
14063			MaxVersion: VersionTLS13,
14064			Bugs: ProtocolBugs{
14065				AlwaysSelectPSKIdentity: true,
14066			},
14067		},
14068		shouldFail:    true,
14069		expectedError: ":UNEXPECTED_EXTENSION:",
14070	})
14071
14072	testCases = append(testCases, testCase{
14073		name: "InvalidPSKIdentity-TLS13",
14074		config: Config{
14075			MaxVersion: VersionTLS13,
14076			Bugs: ProtocolBugs{
14077				SelectPSKIdentityOnResume: 1,
14078			},
14079		},
14080		resumeSession: true,
14081		shouldFail:    true,
14082		expectedError: ":PSK_IDENTITY_NOT_FOUND:",
14083	})
14084
14085	testCases = append(testCases, testCase{
14086		testType: serverTest,
14087		name:     "ExtraPSKIdentity-TLS13",
14088		config: Config{
14089			MaxVersion: VersionTLS13,
14090			Bugs: ProtocolBugs{
14091				ExtraPSKIdentity:   true,
14092				SendExtraPSKBinder: true,
14093			},
14094		},
14095		resumeSession: true,
14096	})
14097
14098	// Test that unknown NewSessionTicket extensions are tolerated.
14099	testCases = append(testCases, testCase{
14100		name: "CustomTicketExtension-TLS13",
14101		config: Config{
14102			MaxVersion: VersionTLS13,
14103			Bugs: ProtocolBugs{
14104				CustomTicketExtension: "1234",
14105			},
14106		},
14107	})
14108
14109	// Test the client handles 0-RTT being rejected by a full handshake
14110	// and correctly reports a certificate change.
14111	testCases = append(testCases, testCase{
14112		testType: clientTest,
14113		name:     "EarlyData-RejectTicket-Client-TLS13",
14114		config: Config{
14115			MaxVersion:   VersionTLS13,
14116			Certificates: []Certificate{rsaCertificate},
14117		},
14118		resumeConfig: &Config{
14119			MaxVersion:             VersionTLS13,
14120			Certificates:           []Certificate{ecdsaP256Certificate},
14121			SessionTicketsDisabled: true,
14122		},
14123		resumeSession:           true,
14124		expectResumeRejected:    true,
14125		earlyData:               true,
14126		expectEarlyDataRejected: true,
14127		flags: []string{
14128			"-on-retry-expect-early-data-reason", "session_not_resumed",
14129			// Test the peer certificate is reported correctly in each of the
14130			// three logical connections.
14131			"-on-initial-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14132			"-on-resume-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14133			"-on-retry-expect-peer-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
14134			// Session tickets are disabled, so the runner will not send a ticket.
14135			"-on-retry-expect-no-session",
14136		},
14137	})
14138
14139	// Test the server rejects 0-RTT if it does not recognize the ticket.
14140	testCases = append(testCases, testCase{
14141		testType: serverTest,
14142		name:     "EarlyData-RejectTicket-Server-TLS13",
14143		config: Config{
14144			MaxVersion: VersionTLS13,
14145			MinVersion: VersionTLS13,
14146			Bugs: ProtocolBugs{
14147				// Corrupt the ticket.
14148				FilterTicket: func(in []byte) ([]byte, error) {
14149					in[len(in)-1] ^= 1
14150					return in, nil
14151				},
14152			},
14153		},
14154		messageCount:            2,
14155		resumeSession:           true,
14156		expectResumeRejected:    true,
14157		earlyData:               true,
14158		expectEarlyDataRejected: true,
14159		flags: []string{
14160			"-on-resume-expect-early-data-reason", "session_not_resumed",
14161		},
14162	})
14163
14164	// Test the client handles 0-RTT being rejected via a HelloRetryRequest.
14165	testCases = append(testCases, testCase{
14166		testType: clientTest,
14167		name:     "EarlyData-HRR-Client-TLS13",
14168		config: Config{
14169			MaxVersion: VersionTLS13,
14170		},
14171		resumeConfig: &Config{
14172			MaxVersion: VersionTLS13,
14173			Bugs: ProtocolBugs{
14174				SendHelloRetryRequestCookie: []byte{1, 2, 3, 4},
14175			},
14176		},
14177		resumeSession:           true,
14178		earlyData:               true,
14179		expectEarlyDataRejected: true,
14180		flags: []string{
14181			"-on-retry-expect-early-data-reason", "hello_retry_request",
14182		},
14183	})
14184
14185	// Test the server rejects 0-RTT if it needs to send a HelloRetryRequest.
14186	testCases = append(testCases, testCase{
14187		testType: serverTest,
14188		name:     "EarlyData-HRR-Server-TLS13",
14189		config: Config{
14190			MaxVersion: VersionTLS13,
14191			MinVersion: VersionTLS13,
14192			// Require a HelloRetryRequest for every curve.
14193			DefaultCurves: []CurveID{},
14194		},
14195		messageCount:            2,
14196		resumeSession:           true,
14197		earlyData:               true,
14198		expectEarlyDataRejected: true,
14199		flags: []string{
14200			"-on-resume-expect-early-data-reason", "hello_retry_request",
14201		},
14202	})
14203
14204	// Test the client handles a 0-RTT reject from both ticket rejection and
14205	// HelloRetryRequest.
14206	testCases = append(testCases, testCase{
14207		testType: clientTest,
14208		name:     "EarlyData-HRR-RejectTicket-Client-TLS13",
14209		config: Config{
14210			MaxVersion:   VersionTLS13,
14211			Certificates: []Certificate{rsaCertificate},
14212		},
14213		resumeConfig: &Config{
14214			MaxVersion:             VersionTLS13,
14215			Certificates:           []Certificate{ecdsaP256Certificate},
14216			SessionTicketsDisabled: true,
14217			Bugs: ProtocolBugs{
14218				SendHelloRetryRequestCookie: []byte{1, 2, 3, 4},
14219			},
14220		},
14221		resumeSession:           true,
14222		expectResumeRejected:    true,
14223		earlyData:               true,
14224		expectEarlyDataRejected: true,
14225		flags: []string{
14226			// The client sees HelloRetryRequest before the resumption result,
14227			// though neither value is inherently preferable.
14228			"-on-retry-expect-early-data-reason", "hello_retry_request",
14229			// Test the peer certificate is reported correctly in each of the
14230			// three logical connections.
14231			"-on-initial-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14232			"-on-resume-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14233			"-on-retry-expect-peer-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
14234			// Session tickets are disabled, so the runner will not send a ticket.
14235			"-on-retry-expect-no-session",
14236		},
14237	})
14238
14239	// Test the server rejects 0-RTT if it needs to send a HelloRetryRequest.
14240	testCases = append(testCases, testCase{
14241		testType: serverTest,
14242		name:     "EarlyData-HRR-RejectTicket-Server-TLS13",
14243		config: Config{
14244			MaxVersion: VersionTLS13,
14245			MinVersion: VersionTLS13,
14246			// Require a HelloRetryRequest for every curve.
14247			DefaultCurves: []CurveID{},
14248			Bugs: ProtocolBugs{
14249				// Corrupt the ticket.
14250				FilterTicket: func(in []byte) ([]byte, error) {
14251					in[len(in)-1] ^= 1
14252					return in, nil
14253				},
14254			},
14255		},
14256		messageCount:            2,
14257		resumeSession:           true,
14258		expectResumeRejected:    true,
14259		earlyData:               true,
14260		expectEarlyDataRejected: true,
14261		flags: []string{
14262			// The server sees the missed resumption before HelloRetryRequest,
14263			// though neither value is inherently preferable.
14264			"-on-resume-expect-early-data-reason", "session_not_resumed",
14265		},
14266	})
14267
14268	// The client must check the server does not send the early_data
14269	// extension while rejecting the session.
14270	testCases = append(testCases, testCase{
14271		testType: clientTest,
14272		name:     "EarlyDataWithoutResume-Client-TLS13",
14273		config: Config{
14274			MaxVersion:       VersionTLS13,
14275			MaxEarlyDataSize: 16384,
14276		},
14277		resumeConfig: &Config{
14278			MaxVersion:             VersionTLS13,
14279			SessionTicketsDisabled: true,
14280			Bugs: ProtocolBugs{
14281				SendEarlyDataExtension: true,
14282			},
14283		},
14284		resumeSession: true,
14285		earlyData:     true,
14286		shouldFail:    true,
14287		expectedError: ":UNEXPECTED_EXTENSION:",
14288	})
14289
14290	// The client must fail with a dedicated error code if the server
14291	// responds with TLS 1.2 when offering 0-RTT.
14292	testCases = append(testCases, testCase{
14293		testType: clientTest,
14294		name:     "EarlyDataVersionDowngrade-Client-TLS13",
14295		config: Config{
14296			MaxVersion: VersionTLS13,
14297		},
14298		resumeConfig: &Config{
14299			MaxVersion: VersionTLS12,
14300		},
14301		resumeSession: true,
14302		earlyData:     true,
14303		shouldFail:    true,
14304		expectedError: ":WRONG_VERSION_ON_EARLY_DATA:",
14305	})
14306
14307	// Test that the client rejects an (unsolicited) early_data extension if
14308	// the server sent an HRR.
14309	testCases = append(testCases, testCase{
14310		testType: clientTest,
14311		name:     "ServerAcceptsEarlyDataOnHRR-Client-TLS13",
14312		config: Config{
14313			MaxVersion: VersionTLS13,
14314		},
14315		resumeConfig: &Config{
14316			MaxVersion: VersionTLS13,
14317			Bugs: ProtocolBugs{
14318				SendHelloRetryRequestCookie: []byte{1, 2, 3, 4},
14319				SendEarlyDataExtension:      true,
14320			},
14321		},
14322		resumeSession: true,
14323		earlyData:     true,
14324		// The client will first process an early data reject from the HRR.
14325		expectEarlyDataRejected: true,
14326		shouldFail:              true,
14327		expectedError:           ":UNEXPECTED_EXTENSION:",
14328	})
14329
14330	testCases = append(testCases, testCase{
14331		testType: clientTest,
14332		name:     "SkipChangeCipherSpec-Client-TLS13",
14333		config: Config{
14334			MaxVersion: VersionTLS13,
14335			Bugs: ProtocolBugs{
14336				SkipChangeCipherSpec: true,
14337			},
14338		},
14339	})
14340
14341	testCases = append(testCases, testCase{
14342		testType: serverTest,
14343		name:     "SkipChangeCipherSpec-Server-TLS13",
14344		config: Config{
14345			MaxVersion: VersionTLS13,
14346			Bugs: ProtocolBugs{
14347				SkipChangeCipherSpec: true,
14348			},
14349		},
14350	})
14351
14352	testCases = append(testCases, testCase{
14353		testType: clientTest,
14354		name:     "TooManyChangeCipherSpec-Client-TLS13",
14355		config: Config{
14356			MaxVersion: VersionTLS13,
14357			Bugs: ProtocolBugs{
14358				SendExtraChangeCipherSpec: 33,
14359			},
14360		},
14361		shouldFail:    true,
14362		expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
14363	})
14364
14365	testCases = append(testCases, testCase{
14366		testType: serverTest,
14367		name:     "TooManyChangeCipherSpec-Server-TLS13",
14368		config: Config{
14369			MaxVersion: VersionTLS13,
14370			Bugs: ProtocolBugs{
14371				SendExtraChangeCipherSpec: 33,
14372			},
14373		},
14374		shouldFail:    true,
14375		expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
14376	})
14377
14378	testCases = append(testCases, testCase{
14379		name: "SendPostHandshakeChangeCipherSpec-TLS13",
14380		config: Config{
14381			MaxVersion: VersionTLS13,
14382			Bugs: ProtocolBugs{
14383				SendPostHandshakeChangeCipherSpec: true,
14384			},
14385		},
14386		shouldFail:         true,
14387		expectedError:      ":UNEXPECTED_RECORD:",
14388		expectedLocalError: "remote error: unexpected message",
14389	})
14390
14391	fooString := "foo"
14392	barString := "bar"
14393
14394	// Test that the client reports the correct ALPN after a 0-RTT reject
14395	// that changed it.
14396	testCases = append(testCases, testCase{
14397		testType: clientTest,
14398		name:     "EarlyData-ALPNMismatch-Client-TLS13",
14399		config: Config{
14400			MaxVersion: VersionTLS13,
14401			Bugs: ProtocolBugs{
14402				ALPNProtocol: &fooString,
14403			},
14404		},
14405		resumeConfig: &Config{
14406			MaxVersion: VersionTLS13,
14407			Bugs: ProtocolBugs{
14408				ALPNProtocol: &barString,
14409			},
14410		},
14411		resumeSession:           true,
14412		earlyData:               true,
14413		expectEarlyDataRejected: true,
14414		flags: []string{
14415			"-advertise-alpn", "\x03foo\x03bar",
14416			// The client does not learn ALPN was the cause.
14417			"-on-retry-expect-early-data-reason", "peer_declined",
14418			// In the 0-RTT state, we surface the predicted ALPN. After
14419			// processing the reject, we surface the real one.
14420			"-on-initial-expect-alpn", "foo",
14421			"-on-resume-expect-alpn", "foo",
14422			"-on-retry-expect-alpn", "bar",
14423		},
14424	})
14425
14426	// Test that the client reports the correct ALPN after a 0-RTT reject if
14427	// ALPN was omitted from the first connection.
14428	testCases = append(testCases, testCase{
14429		testType: clientTest,
14430		name:     "EarlyData-ALPNOmitted1-Client-TLS13",
14431		config: Config{
14432			MaxVersion: VersionTLS13,
14433		},
14434		resumeConfig: &Config{
14435			MaxVersion: VersionTLS13,
14436			NextProtos: []string{"foo"},
14437		},
14438		resumeSession:           true,
14439		earlyData:               true,
14440		expectEarlyDataRejected: true,
14441		flags: []string{
14442			"-advertise-alpn", "\x03foo\x03bar",
14443			// The client does not learn ALPN was the cause.
14444			"-on-retry-expect-early-data-reason", "peer_declined",
14445			// In the 0-RTT state, we surface the predicted ALPN. After
14446			// processing the reject, we surface the real one.
14447			"-on-initial-expect-alpn", "",
14448			"-on-resume-expect-alpn", "",
14449			"-on-retry-expect-alpn", "foo",
14450		},
14451	})
14452
14453	// Test that the client reports the correct ALPN after a 0-RTT reject if
14454	// ALPN was omitted from the second connection.
14455	testCases = append(testCases, testCase{
14456		testType: clientTest,
14457		name:     "EarlyData-ALPNOmitted2-Client-TLS13",
14458		config: Config{
14459			MaxVersion: VersionTLS13,
14460			NextProtos: []string{"foo"},
14461		},
14462		resumeConfig: &Config{
14463			MaxVersion: VersionTLS13,
14464		},
14465		resumeSession:           true,
14466		earlyData:               true,
14467		expectEarlyDataRejected: true,
14468		flags: []string{
14469			"-advertise-alpn", "\x03foo\x03bar",
14470			// The client does not learn ALPN was the cause.
14471			"-on-retry-expect-early-data-reason", "peer_declined",
14472			// In the 0-RTT state, we surface the predicted ALPN. After
14473			// processing the reject, we surface the real one.
14474			"-on-initial-expect-alpn", "foo",
14475			"-on-resume-expect-alpn", "foo",
14476			"-on-retry-expect-alpn", "",
14477		},
14478	})
14479
14480	// Test that the client enforces ALPN match on 0-RTT accept.
14481	testCases = append(testCases, testCase{
14482		testType: clientTest,
14483		name:     "EarlyData-BadALPNMismatch-Client-TLS13",
14484		config: Config{
14485			MaxVersion: VersionTLS13,
14486			Bugs: ProtocolBugs{
14487				ALPNProtocol: &fooString,
14488			},
14489		},
14490		resumeConfig: &Config{
14491			MaxVersion: VersionTLS13,
14492			Bugs: ProtocolBugs{
14493				AlwaysAcceptEarlyData: true,
14494				ALPNProtocol:          &barString,
14495			},
14496		},
14497		resumeSession: true,
14498		earlyData:     true,
14499		flags: []string{
14500			"-advertise-alpn", "\x03foo\x03bar",
14501			"-on-initial-expect-alpn", "foo",
14502			"-on-resume-expect-alpn", "foo",
14503			"-on-retry-expect-alpn", "bar",
14504		},
14505		shouldFail:         true,
14506		expectedError:      ":ALPN_MISMATCH_ON_EARLY_DATA:",
14507		expectedLocalError: "remote error: illegal parameter",
14508	})
14509
14510	// Test that the client does not offer early data if it is incompatible
14511	// with ALPN preferences.
14512	testCases = append(testCases, testCase{
14513		testType: clientTest,
14514		name:     "EarlyData-ALPNPreferenceChanged-TLS13",
14515		config: Config{
14516			MaxVersion:       VersionTLS13,
14517			MaxEarlyDataSize: 16384,
14518			NextProtos:       []string{"foo", "bar"},
14519		},
14520		resumeSession: true,
14521		flags: []string{
14522			"-enable-early-data",
14523			"-expect-ticket-supports-early-data",
14524			"-expect-no-offer-early-data",
14525			// Offer different ALPN values in the initial and resumption.
14526			"-on-initial-advertise-alpn", "\x03foo",
14527			"-on-initial-expect-alpn", "foo",
14528			"-on-resume-advertise-alpn", "\x03bar",
14529			"-on-resume-expect-alpn", "bar",
14530			// The ALPN mismatch comes from the client, so it reports it as the
14531			// reason.
14532			"-on-resume-expect-early-data-reason", "alpn_mismatch",
14533		},
14534	})
14535
14536	// Test that the client does not offer 0-RTT to servers which never
14537	// advertise it.
14538	testCases = append(testCases, testCase{
14539		testType: clientTest,
14540		name:     "EarlyData-NonZeroRTTSession-Client-TLS13",
14541		config: Config{
14542			MaxVersion: VersionTLS13,
14543		},
14544		resumeSession: true,
14545		flags: []string{
14546			"-enable-early-data",
14547			"-on-resume-expect-no-offer-early-data",
14548			// The client declines to offer 0-RTT because of the session.
14549			"-on-resume-expect-early-data-reason", "unsupported_for_session",
14550		},
14551	})
14552
14553	// Test that the server correctly rejects 0-RTT when the previous
14554	// session did not allow early data on resumption.
14555	testCases = append(testCases, testCase{
14556		testType: serverTest,
14557		name:     "EarlyData-NonZeroRTTSession-Server-TLS13",
14558		config: Config{
14559			MaxVersion: VersionTLS13,
14560		},
14561		resumeConfig: &Config{
14562			MaxVersion: VersionTLS13,
14563			Bugs: ProtocolBugs{
14564				SendEarlyData:           [][]byte{{1, 2, 3, 4}},
14565				ExpectEarlyDataAccepted: false,
14566			},
14567		},
14568		resumeSession: true,
14569		// This test configures early data manually instead of the earlyData
14570		// option, to customize the -enable-early-data flag.
14571		flags: []string{
14572			"-on-resume-enable-early-data",
14573			"-expect-reject-early-data",
14574			// The server rejects 0-RTT because of the session.
14575			"-on-resume-expect-early-data-reason", "unsupported_for_session",
14576		},
14577	})
14578
14579	// Test that we reject early data where ALPN is omitted from the first
14580	// connection, but negotiated in the second.
14581	testCases = append(testCases, testCase{
14582		testType: serverTest,
14583		name:     "EarlyData-ALPNOmitted1-Server-TLS13",
14584		config: Config{
14585			MaxVersion: VersionTLS13,
14586			NextProtos: []string{},
14587		},
14588		resumeConfig: &Config{
14589			MaxVersion: VersionTLS13,
14590			NextProtos: []string{"foo"},
14591		},
14592		resumeSession:           true,
14593		earlyData:               true,
14594		expectEarlyDataRejected: true,
14595		flags: []string{
14596			"-on-initial-select-alpn", "",
14597			"-on-resume-select-alpn", "foo",
14598			"-on-resume-expect-early-data-reason", "alpn_mismatch",
14599		},
14600	})
14601
14602	// Test that we reject early data where ALPN is omitted from the second
14603	// connection, but negotiated in the first.
14604	testCases = append(testCases, testCase{
14605		testType: serverTest,
14606		name:     "EarlyData-ALPNOmitted2-Server-TLS13",
14607		config: Config{
14608			MaxVersion: VersionTLS13,
14609			NextProtos: []string{"foo"},
14610		},
14611		resumeConfig: &Config{
14612			MaxVersion: VersionTLS13,
14613			NextProtos: []string{},
14614		},
14615		resumeSession:           true,
14616		earlyData:               true,
14617		expectEarlyDataRejected: true,
14618		flags: []string{
14619			"-on-initial-select-alpn", "foo",
14620			"-on-resume-select-alpn", "",
14621			"-on-resume-expect-early-data-reason", "alpn_mismatch",
14622		},
14623	})
14624
14625	// Test that we reject early data with mismatched ALPN.
14626	testCases = append(testCases, testCase{
14627		testType: serverTest,
14628		name:     "EarlyData-ALPNMismatch-Server-TLS13",
14629		config: Config{
14630			MaxVersion: VersionTLS13,
14631			NextProtos: []string{"foo"},
14632		},
14633		resumeConfig: &Config{
14634			MaxVersion: VersionTLS13,
14635			NextProtos: []string{"bar"},
14636		},
14637		resumeSession:           true,
14638		earlyData:               true,
14639		expectEarlyDataRejected: true,
14640		flags: []string{
14641			"-on-initial-select-alpn", "foo",
14642			"-on-resume-select-alpn", "bar",
14643			"-on-resume-expect-early-data-reason", "alpn_mismatch",
14644		},
14645	})
14646
14647	// Test that the client offering 0-RTT and Channel ID forbids the server
14648	// from accepting both.
14649	testCases = append(testCases, testCase{
14650		testType: clientTest,
14651		name:     "EarlyDataChannelID-AcceptBoth-Client-TLS13",
14652		config: Config{
14653			MaxVersion:       VersionTLS13,
14654			RequestChannelID: true,
14655		},
14656		resumeSession: true,
14657		earlyData:     true,
14658		expectations: connectionExpectations{
14659			channelID: true,
14660		},
14661		shouldFail:         true,
14662		expectedError:      ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:",
14663		expectedLocalError: "remote error: illegal parameter",
14664		flags: []string{
14665			"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile),
14666		},
14667	})
14668
14669	// Test that the client offering Channel ID and 0-RTT allows the server
14670	// to decline 0-RTT.
14671	testCases = append(testCases, testCase{
14672		testType: clientTest,
14673		name:     "EarlyDataChannelID-AcceptChannelID-Client-TLS13",
14674		config: Config{
14675			MaxVersion:       VersionTLS13,
14676			RequestChannelID: true,
14677			Bugs: ProtocolBugs{
14678				AlwaysRejectEarlyData: true,
14679			},
14680		},
14681		resumeSession:           true,
14682		earlyData:               true,
14683		expectEarlyDataRejected: true,
14684		expectations: connectionExpectations{
14685			channelID: true,
14686		},
14687		flags: []string{
14688			"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile),
14689			// The client never learns the reason was Channel ID.
14690			"-on-retry-expect-early-data-reason", "peer_declined",
14691		},
14692	})
14693
14694	// Test that the client offering Channel ID and 0-RTT allows the server
14695	// to decline Channel ID.
14696	testCases = append(testCases, testCase{
14697		testType: clientTest,
14698		name:     "EarlyDataChannelID-AcceptEarlyData-Client-TLS13",
14699		config: Config{
14700			MaxVersion: VersionTLS13,
14701		},
14702		resumeSession: true,
14703		earlyData:     true,
14704		flags: []string{
14705			"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile),
14706		},
14707	})
14708
14709	// Test that the server supporting Channel ID and 0-RTT declines 0-RTT
14710	// if it would negotiate Channel ID.
14711	testCases = append(testCases, testCase{
14712		testType: serverTest,
14713		name:     "EarlyDataChannelID-OfferBoth-Server-TLS13",
14714		config: Config{
14715			MaxVersion: VersionTLS13,
14716			ChannelID:  channelIDKey,
14717		},
14718		resumeSession:           true,
14719		earlyData:               true,
14720		expectEarlyDataRejected: true,
14721		expectations: connectionExpectations{
14722			channelID: true,
14723		},
14724		flags: []string{
14725			"-expect-channel-id",
14726			base64.StdEncoding.EncodeToString(channelIDBytes),
14727			"-on-resume-expect-early-data-reason", "channel_id",
14728		},
14729	})
14730
14731	// Test that the server supporting Channel ID and 0-RTT accepts 0-RTT
14732	// if not offered Channel ID.
14733	testCases = append(testCases, testCase{
14734		testType: serverTest,
14735		name:     "EarlyDataChannelID-OfferEarlyData-Server-TLS13",
14736		config: Config{
14737			MaxVersion: VersionTLS13,
14738		},
14739		resumeSession: true,
14740		earlyData:     true,
14741		expectations: connectionExpectations{
14742			channelID: false,
14743		},
14744		flags: []string{
14745			"-enable-channel-id",
14746			"-on-resume-expect-early-data-reason", "accept",
14747		},
14748	})
14749
14750	// Test that the server errors on 0-RTT streams without end_of_early_data.
14751	// The subsequent records should fail to decrypt.
14752	testCases = append(testCases, testCase{
14753		testType: serverTest,
14754		name:     "EarlyData-SkipEndOfEarlyData-TLS13",
14755		config: Config{
14756			MaxVersion: VersionTLS13,
14757			Bugs: ProtocolBugs{
14758				SkipEndOfEarlyData: true,
14759			},
14760		},
14761		resumeSession:      true,
14762		earlyData:          true,
14763		shouldFail:         true,
14764		expectedLocalError: "remote error: bad record MAC",
14765		expectedError:      ":BAD_DECRYPT:",
14766	})
14767
14768	// Test that the server errors on 0-RTT streams with a stray handshake
14769	// message in them.
14770	testCases = append(testCases, testCase{
14771		testType: serverTest,
14772		name:     "EarlyData-UnexpectedHandshake-Server-TLS13",
14773		config: Config{
14774			MaxVersion: VersionTLS13,
14775		},
14776		resumeConfig: &Config{
14777			MaxVersion: VersionTLS13,
14778			Bugs: ProtocolBugs{
14779				SendStrayEarlyHandshake: true,
14780			},
14781		},
14782		resumeSession:      true,
14783		earlyData:          true,
14784		shouldFail:         true,
14785		expectedError:      ":UNEXPECTED_MESSAGE:",
14786		expectedLocalError: "remote error: unexpected message",
14787	})
14788
14789	// Test that the client reports TLS 1.3 as the version while sending
14790	// early data.
14791	testCases = append(testCases, testCase{
14792		testType: clientTest,
14793		name:     "EarlyData-Client-VersionAPI-TLS13",
14794		config: Config{
14795			MaxVersion: VersionTLS13,
14796		},
14797		resumeSession: true,
14798		earlyData:     true,
14799		flags: []string{
14800			"-expect-version", strconv.Itoa(VersionTLS13),
14801		},
14802	})
14803
14804	// Test that client and server both notice handshake errors after data
14805	// has started flowing.
14806	testCases = append(testCases, testCase{
14807		testType: clientTest,
14808		name:     "EarlyData-Client-BadFinished-TLS13",
14809		config: Config{
14810			MaxVersion: VersionTLS13,
14811		},
14812		resumeConfig: &Config{
14813			MaxVersion: VersionTLS13,
14814			Bugs: ProtocolBugs{
14815				BadFinished: true,
14816			},
14817		},
14818		resumeSession:      true,
14819		earlyData:          true,
14820		shouldFail:         true,
14821		expectedError:      ":DIGEST_CHECK_FAILED:",
14822		expectedLocalError: "remote error: error decrypting message",
14823	})
14824	testCases = append(testCases, testCase{
14825		testType: serverTest,
14826		name:     "EarlyData-Server-BadFinished-TLS13",
14827		config: Config{
14828			MaxVersion: VersionTLS13,
14829		},
14830		resumeConfig: &Config{
14831			MaxVersion: VersionTLS13,
14832			Bugs: ProtocolBugs{
14833				BadFinished: true,
14834			},
14835		},
14836		resumeSession:      true,
14837		earlyData:          true,
14838		shouldFail:         true,
14839		expectedError:      ":DIGEST_CHECK_FAILED:",
14840		expectedLocalError: "remote error: error decrypting message",
14841	})
14842
14843	testCases = append(testCases, testCase{
14844		testType: serverTest,
14845		name:     "Server-NonEmptyEndOfEarlyData-TLS13",
14846		config: Config{
14847			MaxVersion: VersionTLS13,
14848		},
14849		resumeConfig: &Config{
14850			MaxVersion: VersionTLS13,
14851			Bugs: ProtocolBugs{
14852				NonEmptyEndOfEarlyData: true,
14853			},
14854		},
14855		resumeSession: true,
14856		earlyData:     true,
14857		shouldFail:    true,
14858		expectedError: ":DECODE_ERROR:",
14859	})
14860
14861	testCases = append(testCases, testCase{
14862		testType: serverTest,
14863		name:     "ServerSkipCertificateVerify-TLS13",
14864		config: Config{
14865			MinVersion:   VersionTLS13,
14866			MaxVersion:   VersionTLS13,
14867			Certificates: []Certificate{rsaChainCertificate},
14868			Bugs: ProtocolBugs{
14869				SkipCertificateVerify: true,
14870			},
14871		},
14872		expectations: connectionExpectations{
14873			peerCertificate: &rsaChainCertificate,
14874		},
14875		flags: []string{
14876			"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
14877			"-key-file", path.Join(*resourceDir, rsaChainKeyFile),
14878			"-require-any-client-certificate",
14879		},
14880		shouldFail:         true,
14881		expectedError:      ":UNEXPECTED_MESSAGE:",
14882		expectedLocalError: "remote error: unexpected message",
14883	})
14884	testCases = append(testCases, testCase{
14885		testType: clientTest,
14886		name:     "ClientSkipCertificateVerify-TLS13",
14887		config: Config{
14888			MinVersion:   VersionTLS13,
14889			MaxVersion:   VersionTLS13,
14890			Certificates: []Certificate{rsaChainCertificate},
14891			Bugs: ProtocolBugs{
14892				SkipCertificateVerify: true,
14893			},
14894		},
14895		expectations: connectionExpectations{
14896			peerCertificate: &rsaChainCertificate,
14897		},
14898		flags: []string{
14899			"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
14900			"-key-file", path.Join(*resourceDir, rsaChainKeyFile),
14901		},
14902		shouldFail:         true,
14903		expectedError:      ":UNEXPECTED_MESSAGE:",
14904		expectedLocalError: "remote error: unexpected message",
14905	})
14906
14907	// If the client or server has 0-RTT enabled but disabled TLS 1.3, it should
14908	// report a reason of protocol_version.
14909	testCases = append(testCases, testCase{
14910		testType: clientTest,
14911		name:     "EarlyDataEnabled-Client-MaxTLS12",
14912		expectations: connectionExpectations{
14913			version: VersionTLS12,
14914		},
14915		flags: []string{
14916			"-enable-early-data",
14917			"-max-version", strconv.Itoa(VersionTLS12),
14918			"-expect-early-data-reason", "protocol_version",
14919		},
14920	})
14921	testCases = append(testCases, testCase{
14922		testType: serverTest,
14923		name:     "EarlyDataEnabled-Server-MaxTLS12",
14924		expectations: connectionExpectations{
14925			version: VersionTLS12,
14926		},
14927		flags: []string{
14928			"-enable-early-data",
14929			"-max-version", strconv.Itoa(VersionTLS12),
14930			"-expect-early-data-reason", "protocol_version",
14931		},
14932	})
14933
14934	// The server additionally reports protocol_version if it enabled TLS 1.3,
14935	// but the peer negotiated TLS 1.2. (The corresponding situation does not
14936	// exist on the client because negotiating TLS 1.2 with a 0-RTT ClientHello
14937	// is a fatal error.)
14938	testCases = append(testCases, testCase{
14939		testType: serverTest,
14940		name:     "EarlyDataEnabled-Server-NegotiateTLS12",
14941		config: Config{
14942			MaxVersion: VersionTLS12,
14943		},
14944		expectations: connectionExpectations{
14945			version: VersionTLS12,
14946		},
14947		flags: []string{
14948			"-enable-early-data",
14949			"-expect-early-data-reason", "protocol_version",
14950		},
14951	})
14952
14953	// On 0-RTT reject, the server may end up negotiating a cipher suite with a
14954	// different PRF hash. Test that the client handles this correctly.
14955	testCases = append(testCases, testCase{
14956		testType: clientTest,
14957		name:     "EarlyData-Reject0RTT-DifferentPRF-Client",
14958		config: Config{
14959			MaxVersion:   VersionTLS13,
14960			CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
14961		},
14962		resumeConfig: &Config{
14963			MaxVersion:   VersionTLS13,
14964			CipherSuites: []uint16{TLS_AES_256_GCM_SHA384},
14965		},
14966		resumeSession:           true,
14967		expectResumeRejected:    true,
14968		earlyData:               true,
14969		expectEarlyDataRejected: true,
14970		flags: []string{
14971			"-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
14972			// The client initially reports the old cipher suite while sending
14973			// early data. After processing the 0-RTT reject, it reports the
14974			// true cipher suite.
14975			"-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
14976			"-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)),
14977		},
14978	})
14979	testCases = append(testCases, testCase{
14980		testType: clientTest,
14981		name:     "EarlyData-Reject0RTT-DifferentPRF-HRR-Client",
14982		config: Config{
14983			MaxVersion:   VersionTLS13,
14984			CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
14985		},
14986		resumeConfig: &Config{
14987			MaxVersion:   VersionTLS13,
14988			CipherSuites: []uint16{TLS_AES_256_GCM_SHA384},
14989			// P-384 requires a HelloRetryRequest against BoringSSL's default
14990			// configuration. Assert this with ExpectMissingKeyShare.
14991			CurvePreferences: []CurveID{CurveP384},
14992			Bugs: ProtocolBugs{
14993				ExpectMissingKeyShare: true,
14994			},
14995		},
14996		resumeSession:           true,
14997		expectResumeRejected:    true,
14998		earlyData:               true,
14999		expectEarlyDataRejected: true,
15000		flags: []string{
15001			"-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
15002			// The client initially reports the old cipher suite while sending
15003			// early data. After processing the 0-RTT reject, it reports the
15004			// true cipher suite.
15005			"-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
15006			"-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)),
15007		},
15008	})
15009
15010	// Test that the client enforces cipher suite match on 0-RTT accept.
15011	testCases = append(testCases, testCase{
15012		testType: clientTest,
15013		name:     "EarlyData-CipherMismatch-Client-TLS13",
15014		config: Config{
15015			MaxVersion:   VersionTLS13,
15016			CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
15017		},
15018		resumeConfig: &Config{
15019			MaxVersion:   VersionTLS13,
15020			CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256},
15021			Bugs: ProtocolBugs{
15022				AlwaysAcceptEarlyData: true,
15023			},
15024		},
15025		resumeSession:      true,
15026		earlyData:          true,
15027		shouldFail:         true,
15028		expectedError:      ":CIPHER_MISMATCH_ON_EARLY_DATA:",
15029		expectedLocalError: "remote error: illegal parameter",
15030	})
15031}
15032
15033func addTLS13CipherPreferenceTests() {
15034	// Test that client preference is honored if the shim has AES hardware
15035	// and ChaCha20-Poly1305 is preferred otherwise.
15036	testCases = append(testCases, testCase{
15037		testType: serverTest,
15038		name:     "TLS13-CipherPreference-Server-ChaCha20-AES",
15039		config: Config{
15040			MaxVersion: VersionTLS13,
15041			CipherSuites: []uint16{
15042				TLS_CHACHA20_POLY1305_SHA256,
15043				TLS_AES_128_GCM_SHA256,
15044			},
15045			CurvePreferences: []CurveID{CurveX25519},
15046		},
15047		flags: []string{
15048			"-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15049			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15050		},
15051	})
15052
15053	testCases = append(testCases, testCase{
15054		testType: serverTest,
15055		name:     "TLS13-CipherPreference-Server-AES-ChaCha20",
15056		config: Config{
15057			MaxVersion: VersionTLS13,
15058			CipherSuites: []uint16{
15059				TLS_AES_128_GCM_SHA256,
15060				TLS_CHACHA20_POLY1305_SHA256,
15061			},
15062			CurvePreferences: []CurveID{CurveX25519},
15063		},
15064		flags: []string{
15065			"-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
15066			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15067		},
15068	})
15069
15070	// Test that the client orders ChaCha20-Poly1305 and AES-GCM based on
15071	// whether it has AES hardware.
15072	testCases = append(testCases, testCase{
15073		name: "TLS13-CipherPreference-Client",
15074		config: Config{
15075			MaxVersion: VersionTLS13,
15076			// Use the client cipher order. (This is the default but
15077			// is listed to be explicit.)
15078			PreferServerCipherSuites: false,
15079		},
15080		flags: []string{
15081			"-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
15082			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15083		},
15084	})
15085
15086	// CECPQ2 prefers 256-bit ciphers but will use AES-128 if there's nothing else.
15087	testCases = append(testCases, testCase{
15088		testType: serverTest,
15089		name:     "TLS13-CipherPreference-CECPQ2-AES128Only",
15090		config: Config{
15091			MaxVersion: VersionTLS13,
15092			CipherSuites: []uint16{
15093				TLS_AES_128_GCM_SHA256,
15094			},
15095		},
15096		flags: []string{
15097			"-curves", strconv.Itoa(int(CurveCECPQ2)),
15098		},
15099	})
15100
15101	// When a 256-bit cipher is offered, even if not in first place, it should be
15102	// picked.
15103	testCases = append(testCases, testCase{
15104		testType: serverTest,
15105		name:     "TLS13-CipherPreference-CECPQ2-AES256Preferred",
15106		config: Config{
15107			MaxVersion: VersionTLS13,
15108			CipherSuites: []uint16{
15109				TLS_AES_128_GCM_SHA256,
15110				TLS_AES_256_GCM_SHA384,
15111			},
15112		},
15113		flags: []string{
15114			"-curves", strconv.Itoa(int(CurveCECPQ2)),
15115		},
15116		expectations: connectionExpectations{
15117			cipher: TLS_AES_256_GCM_SHA384,
15118		},
15119	})
15120	// ... but when CECPQ2 isn't being used, the client's preference controls.
15121	testCases = append(testCases, testCase{
15122		testType: serverTest,
15123		name:     "TLS13-CipherPreference-CECPQ2-AES128PreferredOtherwise",
15124		config: Config{
15125			MaxVersion: VersionTLS13,
15126			CipherSuites: []uint16{
15127				TLS_AES_128_GCM_SHA256,
15128				TLS_AES_256_GCM_SHA384,
15129			},
15130		},
15131		flags: []string{
15132			"-curves", strconv.Itoa(int(CurveX25519)),
15133		},
15134		expectations: connectionExpectations{
15135			cipher: TLS_AES_128_GCM_SHA256,
15136		},
15137	})
15138
15139	// Test that CECPQ2 continues to honor AES vs ChaCha20 logic.
15140	testCases = append(testCases, testCase{
15141		testType: serverTest,
15142		name:     "TLS13-CipherPreference-CECPQ2-AES128-ChaCha20-AES256",
15143		config: Config{
15144			MaxVersion: VersionTLS13,
15145			CipherSuites: []uint16{
15146				TLS_AES_128_GCM_SHA256,
15147				TLS_CHACHA20_POLY1305_SHA256,
15148				TLS_AES_256_GCM_SHA384,
15149			},
15150		},
15151		flags: []string{
15152			"-curves", strconv.Itoa(int(CurveCECPQ2)),
15153			"-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15154			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15155		},
15156	})
15157	testCases = append(testCases, testCase{
15158		testType: serverTest,
15159		name:     "TLS13-CipherPreference-CECPQ2-AES128-AES256-ChaCha20",
15160		config: Config{
15161			MaxVersion: VersionTLS13,
15162			CipherSuites: []uint16{
15163				TLS_AES_128_GCM_SHA256,
15164				TLS_AES_256_GCM_SHA384,
15165				TLS_CHACHA20_POLY1305_SHA256,
15166			},
15167		},
15168		flags: []string{
15169			"-curves", strconv.Itoa(int(CurveCECPQ2)),
15170			"-expect-cipher-aes", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)),
15171			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15172		},
15173	})
15174}
15175
15176func addPeekTests() {
15177	// Test SSL_peek works, including on empty records.
15178	testCases = append(testCases, testCase{
15179		name:             "Peek-Basic",
15180		sendEmptyRecords: 1,
15181		flags:            []string{"-peek-then-read"},
15182	})
15183
15184	// Test SSL_peek can drive the initial handshake.
15185	testCases = append(testCases, testCase{
15186		name: "Peek-ImplicitHandshake",
15187		flags: []string{
15188			"-peek-then-read",
15189			"-implicit-handshake",
15190		},
15191	})
15192
15193	// Test SSL_peek can discover and drive a renegotiation.
15194	testCases = append(testCases, testCase{
15195		name: "Peek-Renegotiate",
15196		config: Config{
15197			MaxVersion: VersionTLS12,
15198		},
15199		renegotiate: 1,
15200		flags: []string{
15201			"-peek-then-read",
15202			"-renegotiate-freely",
15203			"-expect-total-renegotiations", "1",
15204		},
15205	})
15206
15207	// Test SSL_peek can discover a close_notify.
15208	testCases = append(testCases, testCase{
15209		name: "Peek-Shutdown",
15210		config: Config{
15211			Bugs: ProtocolBugs{
15212				ExpectCloseNotify: true,
15213			},
15214		},
15215		flags: []string{
15216			"-peek-then-read",
15217			"-check-close-notify",
15218		},
15219	})
15220
15221	// Test SSL_peek can discover an alert.
15222	testCases = append(testCases, testCase{
15223		name: "Peek-Alert",
15224		config: Config{
15225			Bugs: ProtocolBugs{
15226				SendSpuriousAlert: alertRecordOverflow,
15227			},
15228		},
15229		flags:         []string{"-peek-then-read"},
15230		shouldFail:    true,
15231		expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
15232	})
15233
15234	// Test SSL_peek can handle KeyUpdate.
15235	testCases = append(testCases, testCase{
15236		name: "Peek-KeyUpdate",
15237		config: Config{
15238			MaxVersion: VersionTLS13,
15239		},
15240		sendKeyUpdates:   1,
15241		keyUpdateRequest: keyUpdateNotRequested,
15242		flags:            []string{"-peek-then-read"},
15243	})
15244}
15245
15246func addRecordVersionTests() {
15247	for _, ver := range tlsVersions {
15248		// Test that the record version is enforced.
15249		testCases = append(testCases, testCase{
15250			name: "CheckRecordVersion-" + ver.name,
15251			config: Config{
15252				MinVersion: ver.version,
15253				MaxVersion: ver.version,
15254				Bugs: ProtocolBugs{
15255					SendRecordVersion: 0x03ff,
15256				},
15257			},
15258			shouldFail:    true,
15259			expectedError: ":WRONG_VERSION_NUMBER:",
15260		})
15261
15262		// Test that the ClientHello may use any record version, for
15263		// compatibility reasons.
15264		testCases = append(testCases, testCase{
15265			testType: serverTest,
15266			name:     "LooseInitialRecordVersion-" + ver.name,
15267			config: Config{
15268				MinVersion: ver.version,
15269				MaxVersion: ver.version,
15270				Bugs: ProtocolBugs{
15271					SendInitialRecordVersion: 0x03ff,
15272				},
15273			},
15274		})
15275
15276		// Test that garbage ClientHello record versions are rejected.
15277		testCases = append(testCases, testCase{
15278			testType: serverTest,
15279			name:     "GarbageInitialRecordVersion-" + ver.name,
15280			config: Config{
15281				MinVersion: ver.version,
15282				MaxVersion: ver.version,
15283				Bugs: ProtocolBugs{
15284					SendInitialRecordVersion: 0xffff,
15285				},
15286			},
15287			shouldFail:    true,
15288			expectedError: ":WRONG_VERSION_NUMBER:",
15289		})
15290	}
15291}
15292
15293func addCertificateTests() {
15294	for _, ver := range tlsVersions {
15295		// Test that a certificate chain with intermediate may be sent
15296		// and received as both client and server.
15297		testCases = append(testCases, testCase{
15298			testType: clientTest,
15299			name:     "SendReceiveIntermediate-Client-" + ver.name,
15300			config: Config{
15301				MinVersion:   ver.version,
15302				MaxVersion:   ver.version,
15303				Certificates: []Certificate{rsaChainCertificate},
15304				ClientAuth:   RequireAnyClientCert,
15305			},
15306			expectations: connectionExpectations{
15307				peerCertificate: &rsaChainCertificate,
15308			},
15309			flags: []string{
15310				"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
15311				"-key-file", path.Join(*resourceDir, rsaChainKeyFile),
15312				"-expect-peer-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
15313			},
15314		})
15315
15316		testCases = append(testCases, testCase{
15317			testType: serverTest,
15318			name:     "SendReceiveIntermediate-Server-" + ver.name,
15319			config: Config{
15320				MinVersion:   ver.version,
15321				MaxVersion:   ver.version,
15322				Certificates: []Certificate{rsaChainCertificate},
15323			},
15324			expectations: connectionExpectations{
15325				peerCertificate: &rsaChainCertificate,
15326			},
15327			flags: []string{
15328				"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
15329				"-key-file", path.Join(*resourceDir, rsaChainKeyFile),
15330				"-require-any-client-certificate",
15331				"-expect-peer-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
15332			},
15333		})
15334
15335		// Test that garbage leaf certificates are properly rejected.
15336		testCases = append(testCases, testCase{
15337			testType: clientTest,
15338			name:     "GarbageCertificate-Client-" + ver.name,
15339			config: Config{
15340				MinVersion:   ver.version,
15341				MaxVersion:   ver.version,
15342				Certificates: []Certificate{garbageCertificate},
15343			},
15344			shouldFail:         true,
15345			expectedError:      ":CANNOT_PARSE_LEAF_CERT:",
15346			expectedLocalError: "remote error: error decoding message",
15347		})
15348
15349		testCases = append(testCases, testCase{
15350			testType: serverTest,
15351			name:     "GarbageCertificate-Server-" + ver.name,
15352			config: Config{
15353				MinVersion:   ver.version,
15354				MaxVersion:   ver.version,
15355				Certificates: []Certificate{garbageCertificate},
15356			},
15357			flags:              []string{"-require-any-client-certificate"},
15358			shouldFail:         true,
15359			expectedError:      ":CANNOT_PARSE_LEAF_CERT:",
15360			expectedLocalError: "remote error: error decoding message",
15361		})
15362	}
15363}
15364
15365func addRetainOnlySHA256ClientCertTests() {
15366	for _, ver := range tlsVersions {
15367		// Test that enabling
15368		// SSL_CTX_set_retain_only_sha256_of_client_certs without
15369		// actually requesting a client certificate is a no-op.
15370		testCases = append(testCases, testCase{
15371			testType: serverTest,
15372			name:     "RetainOnlySHA256-NoCert-" + ver.name,
15373			config: Config{
15374				MinVersion: ver.version,
15375				MaxVersion: ver.version,
15376			},
15377			flags: []string{
15378				"-on-initial-retain-only-sha256-client-cert",
15379				"-on-resume-retain-only-sha256-client-cert",
15380			},
15381			resumeSession: true,
15382		})
15383
15384		// Test that when retaining only a SHA-256 certificate is
15385		// enabled, the hash appears as expected.
15386		testCases = append(testCases, testCase{
15387			testType: serverTest,
15388			name:     "RetainOnlySHA256-Cert-" + ver.name,
15389			config: Config{
15390				MinVersion:   ver.version,
15391				MaxVersion:   ver.version,
15392				Certificates: []Certificate{rsaCertificate},
15393			},
15394			flags: []string{
15395				"-verify-peer",
15396				"-on-initial-retain-only-sha256-client-cert",
15397				"-on-resume-retain-only-sha256-client-cert",
15398				"-on-initial-expect-sha256-client-cert",
15399				"-on-resume-expect-sha256-client-cert",
15400			},
15401			resumeSession: true,
15402		})
15403
15404		// Test that when the config changes from on to off, a
15405		// resumption is rejected because the server now wants the full
15406		// certificate chain.
15407		testCases = append(testCases, testCase{
15408			testType: serverTest,
15409			name:     "RetainOnlySHA256-OnOff-" + ver.name,
15410			config: Config{
15411				MinVersion:   ver.version,
15412				MaxVersion:   ver.version,
15413				Certificates: []Certificate{rsaCertificate},
15414			},
15415			flags: []string{
15416				"-verify-peer",
15417				"-on-initial-retain-only-sha256-client-cert",
15418				"-on-initial-expect-sha256-client-cert",
15419			},
15420			resumeSession:        true,
15421			expectResumeRejected: true,
15422		})
15423
15424		// Test that when the config changes from off to on, a
15425		// resumption is rejected because the server now wants just the
15426		// hash.
15427		testCases = append(testCases, testCase{
15428			testType: serverTest,
15429			name:     "RetainOnlySHA256-OffOn-" + ver.name,
15430			config: Config{
15431				MinVersion:   ver.version,
15432				MaxVersion:   ver.version,
15433				Certificates: []Certificate{rsaCertificate},
15434			},
15435			flags: []string{
15436				"-verify-peer",
15437				"-on-resume-retain-only-sha256-client-cert",
15438				"-on-resume-expect-sha256-client-cert",
15439			},
15440			resumeSession:        true,
15441			expectResumeRejected: true,
15442		})
15443	}
15444}
15445
15446func addECDSAKeyUsageTests() {
15447	p256 := elliptic.P256()
15448	priv, err := ecdsa.GenerateKey(p256, rand.Reader)
15449	if err != nil {
15450		panic(err)
15451	}
15452
15453	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
15454	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
15455	if err != nil {
15456		panic(err)
15457	}
15458
15459	template := x509.Certificate{
15460		SerialNumber: serialNumber,
15461		Subject: pkix.Name{
15462			Organization: []string{"Acme Co"},
15463		},
15464		NotBefore: time.Now(),
15465		NotAfter:  time.Now(),
15466
15467		// An ECC certificate with only the keyAgreement key usgae may
15468		// be used with ECDH, but not ECDSA.
15469		KeyUsage:              x509.KeyUsageKeyAgreement,
15470		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
15471		BasicConstraintsValid: true,
15472	}
15473
15474	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
15475	if err != nil {
15476		panic(err)
15477	}
15478
15479	cert := Certificate{
15480		Certificate: [][]byte{derBytes},
15481		PrivateKey:  priv,
15482	}
15483
15484	for _, ver := range tlsVersions {
15485		if ver.version < VersionTLS12 {
15486			continue
15487		}
15488
15489		testCases = append(testCases, testCase{
15490			testType: clientTest,
15491			name:     "ECDSAKeyUsage-Client-" + ver.name,
15492			config: Config{
15493				MinVersion:   ver.version,
15494				MaxVersion:   ver.version,
15495				Certificates: []Certificate{cert},
15496			},
15497			shouldFail:    true,
15498			expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15499		})
15500
15501		testCases = append(testCases, testCase{
15502			testType: serverTest,
15503			name:     "ECDSAKeyUsage-Server-" + ver.name,
15504			config: Config{
15505				MinVersion:   ver.version,
15506				MaxVersion:   ver.version,
15507				Certificates: []Certificate{cert},
15508			},
15509			flags:         []string{"-require-any-client-certificate"},
15510			shouldFail:    true,
15511			expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15512		})
15513	}
15514}
15515
15516func addRSAKeyUsageTests() {
15517	priv := rsaCertificate.PrivateKey.(*rsa.PrivateKey)
15518
15519	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
15520	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
15521	if err != nil {
15522		panic(err)
15523	}
15524
15525	dsTemplate := x509.Certificate{
15526		SerialNumber: serialNumber,
15527		Subject: pkix.Name{
15528			Organization: []string{"Acme Co"},
15529		},
15530		NotBefore: time.Now(),
15531		NotAfter:  time.Now(),
15532
15533		KeyUsage:              x509.KeyUsageDigitalSignature,
15534		BasicConstraintsValid: true,
15535	}
15536
15537	encTemplate := x509.Certificate{
15538		SerialNumber: serialNumber,
15539		Subject: pkix.Name{
15540			Organization: []string{"Acme Co"},
15541		},
15542		NotBefore: time.Now(),
15543		NotAfter:  time.Now(),
15544
15545		KeyUsage:              x509.KeyUsageKeyEncipherment,
15546		BasicConstraintsValid: true,
15547	}
15548
15549	dsDerBytes, err := x509.CreateCertificate(rand.Reader, &dsTemplate, &dsTemplate, &priv.PublicKey, priv)
15550	if err != nil {
15551		panic(err)
15552	}
15553
15554	encDerBytes, err := x509.CreateCertificate(rand.Reader, &encTemplate, &encTemplate, &priv.PublicKey, priv)
15555	if err != nil {
15556		panic(err)
15557	}
15558
15559	dsCert := Certificate{
15560		Certificate: [][]byte{dsDerBytes},
15561		PrivateKey:  priv,
15562	}
15563
15564	encCert := Certificate{
15565		Certificate: [][]byte{encDerBytes},
15566		PrivateKey:  priv,
15567	}
15568
15569	dsSuites := []uint16{
15570		TLS_AES_128_GCM_SHA256,
15571		TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
15572		TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
15573	}
15574	encSuites := []uint16{
15575		TLS_RSA_WITH_AES_128_GCM_SHA256,
15576		TLS_RSA_WITH_AES_128_CBC_SHA,
15577	}
15578
15579	for _, ver := range tlsVersions {
15580		testCases = append(testCases, testCase{
15581			testType: clientTest,
15582			name:     "RSAKeyUsage-Client-WantSignature-GotEncipherment-" + ver.name,
15583			config: Config{
15584				MinVersion:   ver.version,
15585				MaxVersion:   ver.version,
15586				Certificates: []Certificate{encCert},
15587				CipherSuites: dsSuites,
15588			},
15589			shouldFail:    true,
15590			expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15591			flags: []string{
15592				"-enforce-rsa-key-usage",
15593			},
15594		})
15595
15596		testCases = append(testCases, testCase{
15597			testType: clientTest,
15598			name:     "RSAKeyUsage-Client-WantSignature-GotSignature-" + ver.name,
15599			config: Config{
15600				MinVersion:   ver.version,
15601				MaxVersion:   ver.version,
15602				Certificates: []Certificate{dsCert},
15603				CipherSuites: dsSuites,
15604			},
15605			flags: []string{
15606				"-enforce-rsa-key-usage",
15607			},
15608		})
15609
15610		// TLS 1.3 removes the encipherment suites.
15611		if ver.version < VersionTLS13 {
15612			testCases = append(testCases, testCase{
15613				testType: clientTest,
15614				name:     "RSAKeyUsage-Client-WantEncipherment-GotEncipherment" + ver.name,
15615				config: Config{
15616					MinVersion:   ver.version,
15617					MaxVersion:   ver.version,
15618					Certificates: []Certificate{encCert},
15619					CipherSuites: encSuites,
15620				},
15621				flags: []string{
15622					"-enforce-rsa-key-usage",
15623				},
15624			})
15625
15626			testCases = append(testCases, testCase{
15627				testType: clientTest,
15628				name:     "RSAKeyUsage-Client-WantEncipherment-GotSignature-" + ver.name,
15629				config: Config{
15630					MinVersion:   ver.version,
15631					MaxVersion:   ver.version,
15632					Certificates: []Certificate{dsCert},
15633					CipherSuites: encSuites,
15634				},
15635				shouldFail:    true,
15636				expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15637				flags: []string{
15638					"-enforce-rsa-key-usage",
15639				},
15640			})
15641
15642			// In 1.2 and below, we should not enforce without the enforce-rsa-key-usage flag.
15643			testCases = append(testCases, testCase{
15644				testType: clientTest,
15645				name:     "RSAKeyUsage-Client-WantSignature-GotEncipherment-Unenforced" + ver.name,
15646				config: Config{
15647					MinVersion:   ver.version,
15648					MaxVersion:   ver.version,
15649					Certificates: []Certificate{dsCert},
15650					CipherSuites: encSuites,
15651				},
15652			})
15653
15654			testCases = append(testCases, testCase{
15655				testType: clientTest,
15656				name:     "RSAKeyUsage-Client-WantEncipherment-GotSignature-Unenforced" + ver.name,
15657				config: Config{
15658					MinVersion:   ver.version,
15659					MaxVersion:   ver.version,
15660					Certificates: []Certificate{encCert},
15661					CipherSuites: dsSuites,
15662				},
15663			})
15664		}
15665
15666		if ver.version >= VersionTLS13 {
15667			// In 1.3 and above, we enforce keyUsage even without the flag.
15668			testCases = append(testCases, testCase{
15669				testType: clientTest,
15670				name:     "RSAKeyUsage-Client-WantSignature-GotEncipherment-Enforced" + ver.name,
15671				config: Config{
15672					MinVersion:   ver.version,
15673					MaxVersion:   ver.version,
15674					Certificates: []Certificate{encCert},
15675					CipherSuites: dsSuites,
15676				},
15677				shouldFail:    true,
15678				expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15679			})
15680		}
15681
15682		// The server only uses signatures and always enforces it.
15683		testCases = append(testCases, testCase{
15684			testType: serverTest,
15685			name:     "RSAKeyUsage-Server-WantSignature-GotEncipherment-" + ver.name,
15686			config: Config{
15687				MinVersion:   ver.version,
15688				MaxVersion:   ver.version,
15689				Certificates: []Certificate{encCert},
15690			},
15691			shouldFail:    true,
15692			expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15693			flags:         []string{"-require-any-client-certificate"},
15694		})
15695
15696		testCases = append(testCases, testCase{
15697			testType: serverTest,
15698			name:     "RSAKeyUsage-Server-WantSignature-GotSignature-" + ver.name,
15699			config: Config{
15700				MinVersion:   ver.version,
15701				MaxVersion:   ver.version,
15702				Certificates: []Certificate{dsCert},
15703			},
15704			flags: []string{"-require-any-client-certificate"},
15705		})
15706
15707	}
15708}
15709
15710func addExtraHandshakeTests() {
15711	// An extra SSL_do_handshake is normally a no-op. These tests use -async
15712	// to ensure there is no transport I/O.
15713	testCases = append(testCases, testCase{
15714		testType: clientTest,
15715		name:     "ExtraHandshake-Client-TLS12",
15716		config: Config{
15717			MinVersion: VersionTLS12,
15718			MaxVersion: VersionTLS12,
15719		},
15720		flags: []string{
15721			"-async",
15722			"-no-op-extra-handshake",
15723		},
15724	})
15725	testCases = append(testCases, testCase{
15726		testType: serverTest,
15727		name:     "ExtraHandshake-Server-TLS12",
15728		config: Config{
15729			MinVersion: VersionTLS12,
15730			MaxVersion: VersionTLS12,
15731		},
15732		flags: []string{
15733			"-async",
15734			"-no-op-extra-handshake",
15735		},
15736	})
15737	testCases = append(testCases, testCase{
15738		testType: clientTest,
15739		name:     "ExtraHandshake-Client-TLS13",
15740		config: Config{
15741			MinVersion: VersionTLS13,
15742			MaxVersion: VersionTLS13,
15743		},
15744		flags: []string{
15745			"-async",
15746			"-no-op-extra-handshake",
15747		},
15748	})
15749	testCases = append(testCases, testCase{
15750		testType: serverTest,
15751		name:     "ExtraHandshake-Server-TLS13",
15752		config: Config{
15753			MinVersion: VersionTLS13,
15754			MaxVersion: VersionTLS13,
15755		},
15756		flags: []string{
15757			"-async",
15758			"-no-op-extra-handshake",
15759		},
15760	})
15761
15762	// An extra SSL_do_handshake is a no-op in server 0-RTT.
15763	testCases = append(testCases, testCase{
15764		testType: serverTest,
15765		name:     "ExtraHandshake-Server-EarlyData-TLS13",
15766		config: Config{
15767			MaxVersion: VersionTLS13,
15768			MinVersion: VersionTLS13,
15769		},
15770		messageCount:  2,
15771		resumeSession: true,
15772		earlyData:     true,
15773		flags: []string{
15774			"-async",
15775			"-no-op-extra-handshake",
15776		},
15777	})
15778
15779	// An extra SSL_do_handshake drives the handshake to completion in False
15780	// Start. We test this by handshaking twice and asserting the False
15781	// Start does not appear to happen. See AlertBeforeFalseStartTest for
15782	// how the test works.
15783	testCases = append(testCases, testCase{
15784		testType: clientTest,
15785		name:     "ExtraHandshake-FalseStart",
15786		config: Config{
15787			MaxVersion:   VersionTLS12,
15788			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
15789			NextProtos:   []string{"foo"},
15790			Bugs: ProtocolBugs{
15791				ExpectFalseStart:          true,
15792				AlertBeforeFalseStartTest: alertAccessDenied,
15793			},
15794		},
15795		flags: []string{
15796			"-handshake-twice",
15797			"-false-start",
15798			"-advertise-alpn", "\x03foo",
15799			"-expect-alpn", "foo",
15800		},
15801		shimWritesFirst:    true,
15802		shouldFail:         true,
15803		expectedError:      ":TLSV1_ALERT_ACCESS_DENIED:",
15804		expectedLocalError: "tls: peer did not false start: EOF",
15805	})
15806}
15807
15808// Test that omitted and empty extensions blocks are tolerated.
15809func addOmitExtensionsTests() {
15810	// Check the ExpectOmitExtensions setting works.
15811	testCases = append(testCases, testCase{
15812		testType: serverTest,
15813		name:     "ExpectOmitExtensions",
15814		config: Config{
15815			MinVersion: VersionTLS12,
15816			MaxVersion: VersionTLS12,
15817			Bugs: ProtocolBugs{
15818				ExpectOmitExtensions: true,
15819			},
15820		},
15821		shouldFail:         true,
15822		expectedLocalError: "tls: ServerHello did not omit extensions",
15823	})
15824
15825	for _, ver := range tlsVersions {
15826		if ver.version > VersionTLS12 {
15827			continue
15828		}
15829
15830		testCases = append(testCases, testCase{
15831			testType: serverTest,
15832			name:     "OmitExtensions-ClientHello-" + ver.name,
15833			config: Config{
15834				MinVersion:             ver.version,
15835				MaxVersion:             ver.version,
15836				SessionTicketsDisabled: true,
15837				Bugs: ProtocolBugs{
15838					OmitExtensions: true,
15839					// With no client extensions, the ServerHello must not have
15840					// extensions. It should then omit the extensions field.
15841					ExpectOmitExtensions: true,
15842				},
15843			},
15844		})
15845
15846		testCases = append(testCases, testCase{
15847			testType: serverTest,
15848			name:     "EmptyExtensions-ClientHello-" + ver.name,
15849			config: Config{
15850				MinVersion:             ver.version,
15851				MaxVersion:             ver.version,
15852				SessionTicketsDisabled: true,
15853				Bugs: ProtocolBugs{
15854					EmptyExtensions: true,
15855					// With no client extensions, the ServerHello must not have
15856					// extensions. It should then omit the extensions field.
15857					ExpectOmitExtensions: true,
15858				},
15859			},
15860		})
15861
15862		testCases = append(testCases, testCase{
15863			testType: clientTest,
15864			name:     "OmitExtensions-ServerHello-" + ver.name,
15865			config: Config{
15866				MinVersion:             ver.version,
15867				MaxVersion:             ver.version,
15868				SessionTicketsDisabled: true,
15869				Bugs: ProtocolBugs{
15870					OmitExtensions: true,
15871					// Disable all ServerHello extensions so
15872					// OmitExtensions works.
15873					NoExtendedMasterSecret:        true,
15874					NoRenegotiationInfo:           true,
15875					NoOCSPStapling:                true,
15876					NoSignedCertificateTimestamps: true,
15877				},
15878			},
15879		})
15880
15881		testCases = append(testCases, testCase{
15882			testType: clientTest,
15883			name:     "EmptyExtensions-ServerHello-" + ver.name,
15884			config: Config{
15885				MinVersion:             ver.version,
15886				MaxVersion:             ver.version,
15887				SessionTicketsDisabled: true,
15888				Bugs: ProtocolBugs{
15889					EmptyExtensions: true,
15890					// Disable all ServerHello extensions so
15891					// EmptyExtensions works.
15892					NoExtendedMasterSecret:        true,
15893					NoRenegotiationInfo:           true,
15894					NoOCSPStapling:                true,
15895					NoSignedCertificateTimestamps: true,
15896				},
15897			},
15898		})
15899	}
15900}
15901
15902func addCertCompressionTests() {
15903	// shrinkingPrefix is the first two bytes of a Certificate message.
15904	shrinkingPrefix := []byte{0, 0}
15905	// expandingPrefix is just some arbitrary byte string. This has to match the
15906	// value in the shim.
15907	expandingPrefix := []byte{1, 2, 3, 4}
15908
15909	shrinking := CertCompressionAlg{
15910		Compress: func(uncompressed []byte) []byte {
15911			if !bytes.HasPrefix(uncompressed, shrinkingPrefix) {
15912				panic(fmt.Sprintf("cannot compress certificate message %x", uncompressed))
15913			}
15914			return uncompressed[len(shrinkingPrefix):]
15915		},
15916		Decompress: func(out []byte, compressed []byte) bool {
15917			if len(out) != len(shrinkingPrefix)+len(compressed) {
15918				return false
15919			}
15920
15921			copy(out, shrinkingPrefix)
15922			copy(out[len(shrinkingPrefix):], compressed)
15923			return true
15924		},
15925	}
15926
15927	expanding := CertCompressionAlg{
15928		Compress: func(uncompressed []byte) []byte {
15929			ret := make([]byte, 0, len(expandingPrefix)+len(uncompressed))
15930			ret = append(ret, expandingPrefix...)
15931			return append(ret, uncompressed...)
15932		},
15933		Decompress: func(out []byte, compressed []byte) bool {
15934			if !bytes.HasPrefix(compressed, expandingPrefix) {
15935				return false
15936			}
15937			copy(out, compressed[len(expandingPrefix):])
15938			return true
15939		},
15940	}
15941
15942	const (
15943		shrinkingAlgID = 0xff01
15944		expandingAlgID = 0xff02
15945	)
15946
15947	for _, ver := range tlsVersions {
15948		if ver.version < VersionTLS12 {
15949			continue
15950		}
15951
15952		// Duplicate compression algorithms is an error, even if nothing is
15953		// configured.
15954		testCases = append(testCases, testCase{
15955			testType: serverTest,
15956			name:     "DuplicateCertCompressionExt-" + ver.name,
15957			config: Config{
15958				MinVersion: ver.version,
15959				MaxVersion: ver.version,
15960				Bugs: ProtocolBugs{
15961					DuplicateCompressedCertAlgs: true,
15962				},
15963			},
15964			shouldFail:    true,
15965			expectedError: ":ERROR_PARSING_EXTENSION:",
15966		})
15967
15968		// With compression algorithms configured, an duplicate values should still
15969		// be an error.
15970		testCases = append(testCases, testCase{
15971			testType: serverTest,
15972			name:     "DuplicateCertCompressionExt2-" + ver.name,
15973			flags:    []string{"-install-cert-compression-algs"},
15974			config: Config{
15975				MinVersion: ver.version,
15976				MaxVersion: ver.version,
15977				Bugs: ProtocolBugs{
15978					DuplicateCompressedCertAlgs: true,
15979				},
15980			},
15981			shouldFail:    true,
15982			expectedError: ":ERROR_PARSING_EXTENSION:",
15983		})
15984
15985		if ver.version < VersionTLS13 {
15986			testCases = append(testCases, testCase{
15987				testType: serverTest,
15988				name:     "CertCompressionIgnoredBefore13-" + ver.name,
15989				flags:    []string{"-install-cert-compression-algs"},
15990				config: Config{
15991					MinVersion:          ver.version,
15992					MaxVersion:          ver.version,
15993					CertCompressionAlgs: map[uint16]CertCompressionAlg{expandingAlgID: expanding},
15994				},
15995			})
15996
15997			continue
15998		}
15999
16000		testCases = append(testCases, testCase{
16001			testType: serverTest,
16002			name:     "CertCompressionExpands-" + ver.name,
16003			flags:    []string{"-install-cert-compression-algs"},
16004			config: Config{
16005				MinVersion:          ver.version,
16006				MaxVersion:          ver.version,
16007				CertCompressionAlgs: map[uint16]CertCompressionAlg{expandingAlgID: expanding},
16008				Bugs: ProtocolBugs{
16009					ExpectedCompressedCert: expandingAlgID,
16010				},
16011			},
16012		})
16013
16014		testCases = append(testCases, testCase{
16015			testType: serverTest,
16016			name:     "CertCompressionShrinks-" + ver.name,
16017			flags:    []string{"-install-cert-compression-algs"},
16018			config: Config{
16019				MinVersion:          ver.version,
16020				MaxVersion:          ver.version,
16021				CertCompressionAlgs: map[uint16]CertCompressionAlg{shrinkingAlgID: shrinking},
16022				Bugs: ProtocolBugs{
16023					ExpectedCompressedCert: shrinkingAlgID,
16024				},
16025			},
16026		})
16027
16028		// With both algorithms configured, the server should pick its most
16029		// preferable. (Which is expandingAlgID.)
16030		testCases = append(testCases, testCase{
16031			testType: serverTest,
16032			name:     "CertCompressionPriority-" + ver.name,
16033			flags:    []string{"-install-cert-compression-algs"},
16034			config: Config{
16035				MinVersion: ver.version,
16036				MaxVersion: ver.version,
16037				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16038					shrinkingAlgID: shrinking,
16039					expandingAlgID: expanding,
16040				},
16041				Bugs: ProtocolBugs{
16042					ExpectedCompressedCert: expandingAlgID,
16043				},
16044			},
16045		})
16046
16047		testCases = append(testCases, testCase{
16048			testType: clientTest,
16049			name:     "CertCompressionExpandsClient-" + ver.name,
16050			flags:    []string{"-install-cert-compression-algs"},
16051			config: Config{
16052				MinVersion: ver.version,
16053				MaxVersion: ver.version,
16054				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16055					expandingAlgID: expanding,
16056				},
16057				Bugs: ProtocolBugs{
16058					ExpectedCompressedCert: expandingAlgID,
16059				},
16060			},
16061		})
16062
16063		testCases = append(testCases, testCase{
16064			testType: clientTest,
16065			name:     "CertCompressionShrinksClient-" + ver.name,
16066			flags:    []string{"-install-cert-compression-algs"},
16067			config: Config{
16068				MinVersion: ver.version,
16069				MaxVersion: ver.version,
16070				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16071					shrinkingAlgID: shrinking,
16072				},
16073				Bugs: ProtocolBugs{
16074					ExpectedCompressedCert: shrinkingAlgID,
16075				},
16076			},
16077		})
16078
16079		testCases = append(testCases, testCase{
16080			testType: clientTest,
16081			name:     "CertCompressionBadAlgIDClient-" + ver.name,
16082			flags:    []string{"-install-cert-compression-algs"},
16083			config: Config{
16084				MinVersion: ver.version,
16085				MaxVersion: ver.version,
16086				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16087					shrinkingAlgID: shrinking,
16088				},
16089				Bugs: ProtocolBugs{
16090					ExpectedCompressedCert:   shrinkingAlgID,
16091					SendCertCompressionAlgID: 1234,
16092				},
16093			},
16094			shouldFail:    true,
16095			expectedError: ":UNKNOWN_CERT_COMPRESSION_ALG:",
16096		})
16097
16098		testCases = append(testCases, testCase{
16099			testType: clientTest,
16100			name:     "CertCompressionTooSmallClient-" + ver.name,
16101			flags:    []string{"-install-cert-compression-algs"},
16102			config: Config{
16103				MinVersion: ver.version,
16104				MaxVersion: ver.version,
16105				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16106					shrinkingAlgID: shrinking,
16107				},
16108				Bugs: ProtocolBugs{
16109					ExpectedCompressedCert:     shrinkingAlgID,
16110					SendCertUncompressedLength: 12,
16111				},
16112			},
16113			shouldFail:    true,
16114			expectedError: ":CERT_DECOMPRESSION_FAILED:",
16115		})
16116
16117		testCases = append(testCases, testCase{
16118			testType: clientTest,
16119			name:     "CertCompressionTooLargeClient-" + ver.name,
16120			flags:    []string{"-install-cert-compression-algs"},
16121			config: Config{
16122				MinVersion: ver.version,
16123				MaxVersion: ver.version,
16124				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16125					shrinkingAlgID: shrinking,
16126				},
16127				Bugs: ProtocolBugs{
16128					ExpectedCompressedCert:     shrinkingAlgID,
16129					SendCertUncompressedLength: 1 << 20,
16130				},
16131			},
16132			shouldFail:    true,
16133			expectedError: ":UNCOMPRESSED_CERT_TOO_LARGE:",
16134		})
16135	}
16136}
16137
16138func addJDK11WorkaroundTests() {
16139	// Test the client treats the JDK 11 downgrade random like the usual one.
16140	testCases = append(testCases, testCase{
16141		testType: clientTest,
16142		name:     "Client-RejectJDK11DowngradeRandom",
16143		config: Config{
16144			MaxVersion: VersionTLS12,
16145			Bugs: ProtocolBugs{
16146				SendJDK11DowngradeRandom: true,
16147			},
16148		},
16149		shouldFail:         true,
16150		expectedError:      ":TLS13_DOWNGRADE:",
16151		expectedLocalError: "remote error: illegal parameter",
16152	})
16153	testCases = append(testCases, testCase{
16154		testType: clientTest,
16155		name:     "Client-AcceptJDK11DowngradeRandom",
16156		config: Config{
16157			MaxVersion: VersionTLS12,
16158			Bugs: ProtocolBugs{
16159				SendJDK11DowngradeRandom: true,
16160			},
16161		},
16162		flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
16163	})
16164
16165	var clientHelloTests = []struct {
16166		clientHello []byte
16167		isJDK11     bool
16168	}{
16169		{
16170			// A default JDK 11 ClientHello.
16171			decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"),
16172			true,
16173		},
16174		{
16175			// The above with supported_versions and
16176			// psk_key_exchange_modes in the wrong order.
16177			decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002d00020101002b00090803040303030203010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"),
16178			false,
16179		},
16180		{
16181			// The above with a padding extension added at the end.
16182			decodeHexOrPanic("010001b4030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000111000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b50015000700000000000000"),
16183			false,
16184		},
16185		{
16186			// A JDK 11 ClientHello offering a TLS 1.3 PSK.
16187			decodeHexOrPanic("0100024c0303a8d71b20f060545a398226e807d21371a7a02b7ca2f96f476c2dea7e5860c5a400005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010001c9000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104aaec585ea9e121b24710a23560571322b2cf8ab8cd14e5762ef0486d8a6d0ecd721d8f2abda2eb8ed5ab7195505660450f49bba94bbf0c3f0070a531d9a1be4f002900cb00a600a0e6f7586d9a2bf64a54c1adf55a2f76657047e8e88e26629e2e7b9d630941e06fd87792770f6834e159a70b252157a9b4b082183f24629c8ff5049088b07ce37c49de8cf752a2ed7a545aff63bdc7a1b18e1bc201f23f159ee75d4987a04e00f840824f764691ab83a20e3032646e793065874cdb46138a52f50ed71406f399f96f9309eba4e5b1966148c22a63dc4aa1364269dd41dd5cc0e848d07af0095622c52cfcfc00212009cc315259e2328d65ad17a3de7c182c7874140a9356fecdd4614657806cd659"),
16188			true,
16189		},
16190		{
16191			// A JDK 11 ClientHello offering a TLS 1.2 session.
16192			decodeHexOrPanic("010001a903038cdec49f4836d064a75046c93f22d0b9c2cf4900917332e6f0e1f41d692d3146201a3e99047492285ec65ab4e0eeee59f8f9d1eb7687398887bcd7b81353e93923005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d0002010100330047004500170041041c83c42fcd8fc06265b9f6e4f076f7e7ee17ace915c587845c0e1bc8cd177f904befeb611b682cae4702509a5f5d0c7162a282b8152d843169b91136e7c6f3e7"),
16193			true,
16194		},
16195		{
16196			// A JDK 11 ClientHello with EMS disabled.
16197			decodeHexOrPanic("010001a50303323a857c324a9ef57d6e2544d129073830385cb1dc75ea79f6a2ec8ae09d2e7320f85fdd081678874c67ebab235e6d6a81d947f690bc0af9be4d39854ed67d9ef9005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000102000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200110009000702000400000000002b0009080304030303020301002d0002010100330047004500170041049c904c4850b495d75522f955d79e9cabea065c90279d6037a101a4c4ee712afc93ad0df5d12d287d53e458c7075d9a3ce3969c939bb62222bda779cecf54a603"),
16198			true,
16199		},
16200		{
16201			// A JDK 11 ClientHello with OCSP stapling disabled.
16202			decodeHexOrPanic("0100019303038a50481dc85ee4f6581670821c50f2b3d34ac3251dc6e9b751bfd2521ab47ab02069a963c5486034c37ae0577ddb4c2db28cab592380ef8e4599d1305148712112005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010000f0000000080006000003736e69000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200170000002b0009080304030303020301002d00020101003300470045001700410438a97824f842c549e3c339322d8b2dbaa85d10bd7bca9c969376cb0c60b1e929eb4d13db38dcb0082ad8c637b24f55466a9acbb0b63634c1f431ec8342cf720d"),
16203			true,
16204		},
16205		{
16206			// A JDK 11 ClientHello configured with a smaller set of
16207			// ciphers.
16208			decodeHexOrPanic("0100015603036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"),
16209			true,
16210		},
16211		{
16212			// The above with TLS_CHACHA20_POLY1305_SHA256 added,
16213			// which JDK 11 does not support.
16214			decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f48118000813011303c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"),
16215			false,
16216		},
16217		{
16218			// The above with X25519 added, which JDK 11 does not
16219			// support.
16220			decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000109000000080006000003736e69000500050100000000000a00220020001d0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"),
16221			false,
16222		},
16223		{
16224			// A JDK 11 ClientHello with ALPN protocols configured.
16225			decodeHexOrPanic("010001bb0303c0e0ea707b00c5311eb09cabd58626692cebfaefaef7265637e4550811dae16220da86d6eea04e214e873675223f08a6926bcf79f16d866280bdbab85e9e09c3ff005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000118000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020010000e000c02683208687474702f312e310011000900070200040000000000170000002b0009080304030303020301002d00020101003300470045001700410416def07c1d66ddde5fc9dcc328c8e77022d321c590c0d30cb41d515b38dca34540819a216c6c053bd47b9068f4f6b960f03647de4e36e8b7ffeea78f7252e3d9"),
16226			true,
16227		},
16228	}
16229	for i, t := range clientHelloTests {
16230		expectedVersion := uint16(VersionTLS13)
16231		if t.isJDK11 {
16232			expectedVersion = VersionTLS12
16233		}
16234
16235		// In each of these tests, we set DefaultCurves to P-256 to
16236		// match the test inputs. SendClientHelloWithFixes requires the
16237		// key_shares extension to match in type.
16238
16239		// With the workaround enabled, we should negotiate TLS 1.2 on
16240		// JDK 11 ClientHellos.
16241		testCases = append(testCases, testCase{
16242			testType: serverTest,
16243			name:     fmt.Sprintf("Server-JDK11-%d", i),
16244			config: Config{
16245				MaxVersion:    VersionTLS13,
16246				DefaultCurves: []CurveID{CurveP256},
16247				Bugs: ProtocolBugs{
16248					SendClientHelloWithFixes:   t.clientHello,
16249					ExpectJDK11DowngradeRandom: t.isJDK11,
16250				},
16251			},
16252			expectations: connectionExpectations{
16253				version: expectedVersion,
16254			},
16255			flags: []string{"-jdk11-workaround"},
16256		})
16257
16258		// With the workaround disabled, we always negotiate TLS 1.3.
16259		testCases = append(testCases, testCase{
16260			testType: serverTest,
16261			name:     fmt.Sprintf("Server-JDK11-NoWorkaround-%d", i),
16262			config: Config{
16263				MaxVersion:    VersionTLS13,
16264				DefaultCurves: []CurveID{CurveP256},
16265				Bugs: ProtocolBugs{
16266					SendClientHelloWithFixes:   t.clientHello,
16267					ExpectJDK11DowngradeRandom: false,
16268				},
16269			},
16270			expectations: connectionExpectations{
16271				version: VersionTLS13,
16272			},
16273		})
16274
16275		// If the server does not support TLS 1.3, the workaround should
16276		// be a no-op. In particular, it should not send the downgrade
16277		// signal.
16278		testCases = append(testCases, testCase{
16279			testType: serverTest,
16280			name:     fmt.Sprintf("Server-JDK11-TLS12-%d", i),
16281			config: Config{
16282				MaxVersion:    VersionTLS13,
16283				DefaultCurves: []CurveID{CurveP256},
16284				Bugs: ProtocolBugs{
16285					SendClientHelloWithFixes:   t.clientHello,
16286					ExpectJDK11DowngradeRandom: false,
16287				},
16288			},
16289			expectations: connectionExpectations{
16290				version: VersionTLS12,
16291			},
16292			flags: []string{
16293				"-jdk11-workaround",
16294				"-max-version", strconv.Itoa(VersionTLS12),
16295			},
16296		})
16297	}
16298}
16299
16300func addDelegatedCredentialTests() {
16301	certPath := path.Join(*resourceDir, rsaCertificateFile)
16302	pemBytes, err := ioutil.ReadFile(certPath)
16303	if err != nil {
16304		panic(err)
16305	}
16306
16307	block, _ := pem.Decode(pemBytes)
16308	if block == nil {
16309		panic(fmt.Sprintf("no PEM block found in %q", certPath))
16310	}
16311	parentDER := block.Bytes
16312
16313	rsaPriv, _, err := loadRSAPrivateKey(rsaKeyFile)
16314	if err != nil {
16315		panic(err)
16316	}
16317
16318	ecdsaDC, ecdsaPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{
16319		algo: signatureRSAPSSWithSHA256,
16320	}, parentDER, rsaPriv)
16321	if err != nil {
16322		panic(err)
16323	}
16324	ecdsaFlagValue := fmt.Sprintf("%x,%x", ecdsaDC, ecdsaPKCS8)
16325
16326	testCases = append(testCases, testCase{
16327		testType: serverTest,
16328		name:     "DelegatedCredentials-NoClientSupport",
16329		config: Config{
16330			MinVersion: VersionTLS13,
16331			MaxVersion: VersionTLS13,
16332			Bugs: ProtocolBugs{
16333				DisableDelegatedCredentials: true,
16334			},
16335		},
16336		flags: []string{
16337			"-delegated-credential", ecdsaFlagValue,
16338		},
16339	})
16340
16341	testCases = append(testCases, testCase{
16342		testType: serverTest,
16343		name:     "DelegatedCredentials-Basic",
16344		config: Config{
16345			MinVersion: VersionTLS13,
16346			MaxVersion: VersionTLS13,
16347			Bugs: ProtocolBugs{
16348				ExpectDelegatedCredentials: true,
16349			},
16350		},
16351		flags: []string{
16352			"-delegated-credential", ecdsaFlagValue,
16353			"-expect-delegated-credential-used",
16354		},
16355	})
16356
16357	testCases = append(testCases, testCase{
16358		testType: serverTest,
16359		name:     "DelegatedCredentials-SigAlgoMissing",
16360		config: Config{
16361			MinVersion: VersionTLS13,
16362			MaxVersion: VersionTLS13,
16363			Bugs: ProtocolBugs{
16364				FailIfDelegatedCredentials: true,
16365			},
16366			// If the client doesn't support the delegated credential signature
16367			// algorithm then the handshake should complete without using delegated
16368			// credentials.
16369			VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256},
16370		},
16371		flags: []string{
16372			"-delegated-credential", ecdsaFlagValue,
16373		},
16374	})
16375
16376	// This flag value has mismatched public and private keys which should cause a
16377	// configuration error in the shim.
16378	_, badTLSVersionPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{
16379		algo:       signatureRSAPSSWithSHA256,
16380		tlsVersion: 0x1234,
16381	}, parentDER, rsaPriv)
16382	if err != nil {
16383		panic(err)
16384	}
16385	mismatchFlagValue := fmt.Sprintf("%x,%x", ecdsaDC, badTLSVersionPKCS8)
16386	testCases = append(testCases, testCase{
16387		testType: serverTest,
16388		name:     "DelegatedCredentials-KeyMismatch",
16389		config: Config{
16390			MinVersion: VersionTLS13,
16391			MaxVersion: VersionTLS13,
16392			Bugs: ProtocolBugs{
16393				FailIfDelegatedCredentials: true,
16394			},
16395		},
16396		flags: []string{
16397			"-delegated-credential", mismatchFlagValue,
16398		},
16399		shouldFail:    true,
16400		expectedError: ":KEY_VALUES_MISMATCH:",
16401	})
16402}
16403
16404func addEncryptedClientHelloTests() {
16405	// Test ECH GREASE.
16406
16407	// Test the client's behavior when the server ignores ECH GREASE.
16408	testCases = append(testCases, testCase{
16409		testType: clientTest,
16410		name:     "ECH-GREASE-Client-TLS13",
16411		config: Config{
16412			MinVersion: VersionTLS13,
16413			MaxVersion: VersionTLS13,
16414			Bugs: ProtocolBugs{
16415				ExpectClientECH: true,
16416			},
16417		},
16418		flags: []string{"-enable-ech-grease"},
16419	})
16420
16421	// Test the client's ECH GREASE behavior when responding to server's
16422	// HelloRetryRequest. This test implicitly checks that the first and second
16423	// ClientHello messages have identical ECH extensions.
16424	testCases = append(testCases, testCase{
16425		testType: clientTest,
16426		name:     "ECH-GREASE-Client-TLS13-HelloRetryRequest",
16427		config: Config{
16428			MaxVersion: VersionTLS13,
16429			MinVersion: VersionTLS13,
16430			// P-384 requires a HelloRetryRequest against BoringSSL's default
16431			// configuration. Assert this with ExpectMissingKeyShare.
16432			CurvePreferences: []CurveID{CurveP384},
16433			Bugs: ProtocolBugs{
16434				ExpectMissingKeyShare: true,
16435				ExpectClientECH:       true,
16436			},
16437		},
16438		flags: []string{"-enable-ech-grease", "-expect-hrr"},
16439	})
16440
16441	retryConfigValid := ECHConfig{
16442		PublicName: "example.com",
16443		// A real X25519 public key obtained from hpke.GenerateKeyPair().
16444		PublicKey: []byte{
16445			0x23, 0x1a, 0x96, 0x53, 0x52, 0x81, 0x1d, 0x7a,
16446			0x36, 0x76, 0xaa, 0x5e, 0xad, 0xdb, 0x66, 0x1c,
16447			0x92, 0x45, 0x8a, 0x60, 0xc7, 0x81, 0x93, 0xb0,
16448			0x47, 0x7b, 0x54, 0x18, 0x6b, 0x9a, 0x1d, 0x6d},
16449		KEM: hpke.X25519WithHKDFSHA256,
16450		CipherSuites: []HPKECipherSuite{
16451			{
16452				KDF:  hpke.HKDFSHA256,
16453				AEAD: hpke.AES256GCM,
16454			},
16455		},
16456		MaxNameLen: 42,
16457	}
16458
16459	retryConfigUnsupportedVersion := []byte{
16460		// version
16461		0xba, 0xdd,
16462		// length
16463		0x00, 0x05,
16464		// contents
16465		0x05, 0x04, 0x03, 0x02, 0x01,
16466	}
16467
16468	var validAndInvalidConfigs []byte
16469	validAndInvalidConfigs = append(validAndInvalidConfigs, MarshalECHConfig(&retryConfigValid)...)
16470	validAndInvalidConfigs = append(validAndInvalidConfigs, retryConfigUnsupportedVersion...)
16471
16472	// Test that the client accepts a well-formed encrypted_client_hello
16473	// extension in response to ECH GREASE. The response includes one ECHConfig
16474	// with a supported version and one with an unsupported version.
16475	testCases = append(testCases, testCase{
16476		testType: clientTest,
16477		name:     "ECH-GREASE-Client-TLS13-Retry-Configs",
16478		config: Config{
16479			MinVersion: VersionTLS13,
16480			MaxVersion: VersionTLS13,
16481			Bugs: ProtocolBugs{
16482				ExpectClientECH: true,
16483				// Include an additional well-formed ECHConfig with an invalid
16484				// version. This ensures the client can iterate over the retry
16485				// configs.
16486				SendECHRetryConfigs: validAndInvalidConfigs,
16487			},
16488		},
16489		flags: []string{"-enable-ech-grease"},
16490	})
16491
16492	// Test that the client aborts with a decode_error alert when it receives a
16493	// syntactically-invalid encrypted_client_hello extension from the server.
16494	testCases = append(testCases, testCase{
16495		testType: clientTest,
16496		name:     "ECH-GREASE-Client-TLS13-Invalid-Retry-Configs",
16497		config: Config{
16498			MinVersion: VersionTLS13,
16499			MaxVersion: VersionTLS13,
16500			Bugs: ProtocolBugs{
16501				ExpectClientECH:     true,
16502				SendECHRetryConfigs: []byte{0xba, 0xdd, 0xec, 0xcc},
16503			},
16504		},
16505		flags:              []string{"-enable-ech-grease"},
16506		shouldFail:         true,
16507		expectedLocalError: "remote error: error decoding message",
16508		expectedError:      ":ERROR_PARSING_EXTENSION:",
16509	})
16510
16511	// Test that the server responds to an empty ECH extension with the acceptance
16512	// confirmation.
16513	testCases = append(testCases, testCase{
16514		testType: serverTest,
16515		name:     "ECH-Server-ECHIsInner",
16516		config: Config{
16517			MinVersion: VersionTLS13,
16518			MaxVersion: VersionTLS13,
16519			Bugs: ProtocolBugs{
16520				SendECHIsInner:        []byte{},
16521				ExpectServerAcceptECH: true,
16522			},
16523		},
16524	})
16525
16526	// Test that server fails the handshake when it sees a nonempty ech_is_inner
16527	// extension.
16528	testCases = append(testCases, testCase{
16529		testType: serverTest,
16530		name:     "ECH-Server-ECHIsInner-NotEmpty",
16531		config: Config{
16532			MinVersion: VersionTLS13,
16533			MaxVersion: VersionTLS13,
16534			Bugs: ProtocolBugs{
16535				SendECHIsInner: []byte{42, 42, 42},
16536			},
16537		},
16538		shouldFail:         true,
16539		expectedLocalError: "remote error: illegal parameter",
16540		expectedError:      ":ERROR_PARSING_EXTENSION:",
16541	})
16542
16543	// When ech_is_inner extension is absent, the server should not accept ECH.
16544	testCases = append(testCases, testCase{
16545		testType: serverTest,
16546		name:     "ECH-Server-ECHIsInner-Absent",
16547		config: Config{
16548			MinVersion: VersionTLS13,
16549			MaxVersion: VersionTLS13,
16550			Bugs: ProtocolBugs{
16551				ExpectServerAcceptECH: false,
16552			},
16553		},
16554	})
16555
16556	// Test that a TLS 1.3 server that receives an ech_is_inner extension can
16557	// negotiate TLS 1.2 without clobbering the downgrade signal.
16558	testCases = append(testCases, testCase{
16559		testType: serverTest,
16560		name:     "ECH-Server-ECHIsInner-Absent-TLS12",
16561		config: Config{
16562			MinVersion: VersionTLS12,
16563			MaxVersion: VersionTLS13,
16564			Bugs: ProtocolBugs{
16565				// Omit supported_versions extension so the server negotiates
16566				// TLS 1.2.
16567				OmitSupportedVersions: true,
16568				SendECHIsInner:        []byte{},
16569			},
16570		},
16571		// Check that the client sees the TLS 1.3 downgrade signal in
16572		// ServerHello.random.
16573		shouldFail:         true,
16574		expectedLocalError: "tls: downgrade from TLS 1.3 detected",
16575	})
16576
16577	// Test that the handshake fails when the client sends both
16578	// encrypted_client_hello and ech_is_inner extensions.
16579	//
16580	// TODO(dmcardle) Replace this test once runner is capable of sending real
16581	// ECH extensions. The equivalent test will send ech_is_inner and a real
16582	// encrypted_client_hello extension derived from a key unknown to the
16583	// server.
16584	testCases = append(testCases, testCase{
16585		testType: serverTest,
16586		name:     "ECH-Server-EncryptedClientHello-ECHIsInner",
16587		config: Config{
16588			MinVersion: VersionTLS13,
16589			MaxVersion: VersionTLS13,
16590			Bugs: ProtocolBugs{
16591				SendECHIsInner:                      []byte{},
16592				SendPlaceholderEncryptedClientHello: true,
16593			},
16594		},
16595		shouldFail:         true,
16596		expectedLocalError: "remote error: illegal parameter",
16597		expectedError:      ":UNEXPECTED_EXTENSION:",
16598	})
16599}
16600
16601func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
16602	defer wg.Done()
16603
16604	for test := range c {
16605		var err error
16606
16607		if *mallocTest >= 0 {
16608			for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
16609				statusChan <- statusMsg{test: test, statusType: statusStarted}
16610				if err = runTest(statusChan, test, shimPath, mallocNumToFail); err != errMoreMallocs {
16611					if err != nil {
16612						fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err)
16613					}
16614					break
16615				}
16616			}
16617		} else if *repeatUntilFailure {
16618			for err == nil {
16619				statusChan <- statusMsg{test: test, statusType: statusStarted}
16620				err = runTest(statusChan, test, shimPath, -1)
16621			}
16622		} else {
16623			statusChan <- statusMsg{test: test, statusType: statusStarted}
16624			err = runTest(statusChan, test, shimPath, -1)
16625		}
16626		statusChan <- statusMsg{test: test, statusType: statusDone, err: err}
16627	}
16628}
16629
16630type statusType int
16631
16632const (
16633	statusStarted statusType = iota
16634	statusShimStarted
16635	statusDone
16636)
16637
16638type statusMsg struct {
16639	test       *testCase
16640	statusType statusType
16641	pid        int
16642	err        error
16643}
16644
16645func statusPrinter(doneChan chan *testresult.Results, statusChan chan statusMsg, total int) {
16646	var started, done, failed, unimplemented, lineLen int
16647
16648	testOutput := testresult.NewResults()
16649	for msg := range statusChan {
16650		if !*pipe {
16651			// Erase the previous status line.
16652			var erase string
16653			for i := 0; i < lineLen; i++ {
16654				erase += "\b \b"
16655			}
16656			fmt.Print(erase)
16657		}
16658
16659		if msg.statusType == statusStarted {
16660			started++
16661		} else if msg.statusType == statusDone {
16662			done++
16663
16664			if msg.err != nil {
16665				if msg.err == errUnimplemented {
16666					if *pipe {
16667						// Print each test instead of a status line.
16668						fmt.Printf("UNIMPLEMENTED (%s)\n", msg.test.name)
16669					}
16670					unimplemented++
16671					if *allowUnimplemented {
16672						testOutput.AddSkip(msg.test.name)
16673					} else {
16674						testOutput.AddResult(msg.test.name, "SKIP")
16675					}
16676				} else {
16677					fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err)
16678					failed++
16679					testOutput.AddResult(msg.test.name, "FAIL")
16680				}
16681			} else {
16682				if *pipe {
16683					// Print each test instead of a status line.
16684					fmt.Printf("PASSED (%s)\n", msg.test.name)
16685				}
16686				testOutput.AddResult(msg.test.name, "PASS")
16687			}
16688		}
16689
16690		if !*pipe {
16691			// Print a new status line.
16692			line := fmt.Sprintf("%d/%d/%d/%d/%d", failed, unimplemented, done, started, total)
16693			if msg.statusType == statusShimStarted && *waitForDebugger {
16694				// Note -wait-for-debugger limits the test to one worker,
16695				// otherwise some output would be skipped.
16696				line += fmt.Sprintf(" (%s: attach to process %d to continue)", msg.test.name, msg.pid)
16697			}
16698			lineLen = len(line)
16699			os.Stdout.WriteString(line)
16700		}
16701	}
16702
16703	doneChan <- testOutput
16704}
16705
16706func match(oneOfPatternIfAny []string, noneOfPattern []string, candidate string) (matched bool, err error) {
16707	matched = len(oneOfPatternIfAny) == 0
16708
16709	var didMatch bool
16710	for _, pattern := range oneOfPatternIfAny {
16711		didMatch, err = filepath.Match(pattern, candidate)
16712		if err != nil {
16713			return false, err
16714		}
16715
16716		matched = didMatch || matched
16717	}
16718
16719	for _, pattern := range noneOfPattern {
16720		didMatch, err = filepath.Match(pattern, candidate)
16721		if err != nil {
16722			return false, err
16723		}
16724
16725		matched = !didMatch && matched
16726	}
16727
16728	return matched, nil
16729}
16730
16731func main() {
16732	flag.Parse()
16733	*resourceDir = path.Clean(*resourceDir)
16734	initCertificates()
16735
16736	addBasicTests()
16737	addCipherSuiteTests()
16738	addBadECDSASignatureTests()
16739	addCBCPaddingTests()
16740	addCBCSplittingTests()
16741	addClientAuthTests()
16742	addDDoSCallbackTests()
16743	addVersionNegotiationTests()
16744	addMinimumVersionTests()
16745	addExtensionTests()
16746	addResumptionVersionTests()
16747	addExtendedMasterSecretTests()
16748	addRenegotiationTests()
16749	addDTLSReplayTests()
16750	addSignatureAlgorithmTests()
16751	addDTLSRetransmitTests()
16752	addExportKeyingMaterialTests()
16753	addExportTrafficSecretsTests()
16754	addTLSUniqueTests()
16755	addCustomExtensionTests()
16756	addRSAClientKeyExchangeTests()
16757	addCurveTests()
16758	addSessionTicketTests()
16759	addTLS13RecordTests()
16760	addAllStateMachineCoverageTests()
16761	addChangeCipherSpecTests()
16762	addEndOfFlightTests()
16763	addWrongMessageTypeTests()
16764	addTrailingMessageDataTests()
16765	addTLS13HandshakeTests()
16766	addTLS13CipherPreferenceTests()
16767	addPeekTests()
16768	addRecordVersionTests()
16769	addCertificateTests()
16770	addRetainOnlySHA256ClientCertTests()
16771	addECDSAKeyUsageTests()
16772	addRSAKeyUsageTests()
16773	addExtraHandshakeTests()
16774	addOmitExtensionsTests()
16775	addCertCompressionTests()
16776	addJDK11WorkaroundTests()
16777	addDelegatedCredentialTests()
16778	addEncryptedClientHelloTests()
16779
16780	testCases = append(testCases, convertToSplitHandshakeTests(testCases)...)
16781
16782	var wg sync.WaitGroup
16783
16784	numWorkers := *numWorkersFlag
16785	if useDebugger() {
16786		numWorkers = 1
16787	}
16788
16789	statusChan := make(chan statusMsg, numWorkers)
16790	testChan := make(chan *testCase, numWorkers)
16791	doneChan := make(chan *testresult.Results)
16792
16793	if len(*shimConfigFile) != 0 {
16794		encoded, err := ioutil.ReadFile(*shimConfigFile)
16795		if err != nil {
16796			fmt.Fprintf(os.Stderr, "Couldn't read config file %q: %s\n", *shimConfigFile, err)
16797			os.Exit(1)
16798		}
16799
16800		if err := json.Unmarshal(encoded, &shimConfig); err != nil {
16801			fmt.Fprintf(os.Stderr, "Couldn't decode config file %q: %s\n", *shimConfigFile, err)
16802			os.Exit(1)
16803		}
16804	}
16805
16806	go statusPrinter(doneChan, statusChan, len(testCases))
16807
16808	for i := 0; i < numWorkers; i++ {
16809		wg.Add(1)
16810		go worker(statusChan, testChan, *shimPath, &wg)
16811	}
16812
16813	var oneOfPatternIfAny, noneOfPattern []string
16814	if len(*testToRun) > 0 {
16815		oneOfPatternIfAny = strings.Split(*testToRun, ";")
16816	}
16817	if len(*skipTest) > 0 {
16818		noneOfPattern = strings.Split(*skipTest, ";")
16819	}
16820
16821	var foundTest bool
16822	for i := range testCases {
16823		matched, err := match(oneOfPatternIfAny, noneOfPattern, testCases[i].name)
16824		if err != nil {
16825			fmt.Fprintf(os.Stderr, "Error matching pattern: %s\n", err)
16826			os.Exit(1)
16827		}
16828
16829		if !*includeDisabled {
16830			for pattern := range shimConfig.DisabledTests {
16831				isDisabled, err := filepath.Match(pattern, testCases[i].name)
16832				if err != nil {
16833					fmt.Fprintf(os.Stderr, "Error matching pattern %q from config file: %s\n", pattern, err)
16834					os.Exit(1)
16835				}
16836
16837				if isDisabled {
16838					matched = false
16839					break
16840				}
16841			}
16842		}
16843
16844		if matched {
16845			foundTest = true
16846			testChan <- &testCases[i]
16847
16848			// Only run one test if repeating until failure.
16849			if *repeatUntilFailure {
16850				break
16851			}
16852		}
16853	}
16854
16855	if !foundTest {
16856		fmt.Fprintf(os.Stderr, "No tests run\n")
16857		os.Exit(1)
16858	}
16859
16860	close(testChan)
16861	wg.Wait()
16862	close(statusChan)
16863	testOutput := <-doneChan
16864
16865	fmt.Printf("\n")
16866
16867	if *jsonOutput != "" {
16868		if err := testOutput.WriteToFile(*jsonOutput); err != nil {
16869			fmt.Fprintf(os.Stderr, "Error: %s\n", err)
16870		}
16871	}
16872
16873	if !testOutput.HasUnexpectedResults() {
16874		os.Exit(1)
16875	}
16876}
16877