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. We cover both
13423	// normal and resumption handshakes to capture interactions with the
13424	// session resumption path.
13425	testCases = append(testCases, testCase{
13426		testType: clientTest,
13427		name:     "TLS13SessionID-TLS13",
13428		config: Config{
13429			MaxVersion: VersionTLS13,
13430			Bugs: ProtocolBugs{
13431				ExpectClientHelloSessionID: true,
13432			},
13433		},
13434		resumeSession: true,
13435	})
13436
13437	// Test that the client omits the fake session ID when the max version is TLS 1.2 and below.
13438	testCases = append(testCases, testCase{
13439		testType: clientTest,
13440		name:     "TLS12NoSessionID-TLS13",
13441		config: Config{
13442			MaxVersion: VersionTLS13,
13443			Bugs: ProtocolBugs{
13444				ExpectNoTLS12Session: true,
13445			},
13446		},
13447		flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
13448	})
13449
13450	testCases = append(testCases, testCase{
13451		testType: clientTest,
13452		name:     "EarlyData-Client-TLS13",
13453		config: Config{
13454			MaxVersion: VersionTLS13,
13455			MinVersion: VersionTLS13,
13456		},
13457		resumeSession: true,
13458		earlyData:     true,
13459		flags: []string{
13460			"-on-initial-expect-early-data-reason", "no_session_offered",
13461			"-on-resume-expect-early-data-reason", "accept",
13462		},
13463	})
13464
13465	testCases = append(testCases, testCase{
13466		testType: clientTest,
13467		name:     "EarlyData-Reject-Client-TLS13",
13468		config: Config{
13469			MaxVersion: VersionTLS13,
13470		},
13471		resumeConfig: &Config{
13472			MaxVersion: VersionTLS13,
13473			Bugs: ProtocolBugs{
13474				AlwaysRejectEarlyData: true,
13475			},
13476		},
13477		resumeSession:           true,
13478		earlyData:               true,
13479		expectEarlyDataRejected: true,
13480		flags: []string{
13481			"-on-retry-expect-early-data-reason", "peer_declined",
13482		},
13483	})
13484
13485	testCases = append(testCases, testCase{
13486		testType: serverTest,
13487		name:     "EarlyData-Server-TLS13",
13488		config: Config{
13489			MaxVersion: VersionTLS13,
13490			MinVersion: VersionTLS13,
13491		},
13492		messageCount:  2,
13493		resumeSession: true,
13494		earlyData:     true,
13495		flags: []string{
13496			"-on-initial-expect-early-data-reason", "no_session_offered",
13497			"-on-resume-expect-early-data-reason", "accept",
13498		},
13499	})
13500
13501	// The above tests the most recent ticket. Additionally test that 0-RTT
13502	// works on the first ticket issued by the server.
13503	testCases = append(testCases, testCase{
13504		testType: serverTest,
13505		name:     "EarlyData-FirstTicket-Server-TLS13",
13506		config: Config{
13507			MaxVersion: VersionTLS13,
13508			MinVersion: VersionTLS13,
13509			Bugs: ProtocolBugs{
13510				UseFirstSessionTicket: true,
13511			},
13512		},
13513		messageCount:  2,
13514		resumeSession: true,
13515		earlyData:     true,
13516		flags: []string{
13517			"-on-resume-expect-early-data-reason", "accept",
13518		},
13519	})
13520
13521	testCases = append(testCases, testCase{
13522		testType: serverTest,
13523		name:     "SkipEarlyData-OmitEarlyDataExtension-TLS13",
13524		config: Config{
13525			MaxVersion: VersionTLS13,
13526			Bugs: ProtocolBugs{
13527				SendFakeEarlyDataLength: 4,
13528				OmitEarlyDataExtension:  true,
13529			},
13530		},
13531		shouldFail:    true,
13532		expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
13533	})
13534
13535	testCases = append(testCases, testCase{
13536		testType: serverTest,
13537		name:     "SkipEarlyData-TooMuchData-TLS13",
13538		config: Config{
13539			MaxVersion: VersionTLS13,
13540			Bugs: ProtocolBugs{
13541				SendFakeEarlyDataLength: 16384 + 1,
13542			},
13543		},
13544		shouldFail:    true,
13545		expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:",
13546	})
13547
13548	testCases = append(testCases, testCase{
13549		testType: serverTest,
13550		name:     "SkipEarlyData-Interleaved-TLS13",
13551		config: Config{
13552			MaxVersion: VersionTLS13,
13553			Bugs: ProtocolBugs{
13554				SendFakeEarlyDataLength: 4,
13555				InterleaveEarlyData:     true,
13556			},
13557		},
13558		shouldFail:    true,
13559		expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
13560	})
13561
13562	testCases = append(testCases, testCase{
13563		testType: serverTest,
13564		name:     "SkipEarlyData-EarlyDataInTLS12-TLS13",
13565		config: Config{
13566			MaxVersion: VersionTLS13,
13567			Bugs: ProtocolBugs{
13568				SendFakeEarlyDataLength: 4,
13569			},
13570		},
13571		shouldFail:    true,
13572		expectedError: ":UNEXPECTED_RECORD:",
13573		flags:         []string{"-max-version", strconv.Itoa(VersionTLS12)},
13574	})
13575
13576	testCases = append(testCases, testCase{
13577		testType: serverTest,
13578		name:     "SkipEarlyData-HRR-TLS13",
13579		config: Config{
13580			MaxVersion: VersionTLS13,
13581			Bugs: ProtocolBugs{
13582				SendFakeEarlyDataLength: 4,
13583			},
13584			DefaultCurves: []CurveID{},
13585		},
13586		// Though the session is not resumed and we send HelloRetryRequest,
13587		// early data being disabled takes priority as the reject reason.
13588		flags: []string{"-expect-early-data-reason", "disabled"},
13589	})
13590
13591	testCases = append(testCases, testCase{
13592		testType: serverTest,
13593		name:     "SkipEarlyData-HRR-Interleaved-TLS13",
13594		config: Config{
13595			MaxVersion: VersionTLS13,
13596			Bugs: ProtocolBugs{
13597				SendFakeEarlyDataLength: 4,
13598				InterleaveEarlyData:     true,
13599			},
13600			DefaultCurves: []CurveID{},
13601		},
13602		shouldFail:    true,
13603		expectedError: ":UNEXPECTED_RECORD:",
13604	})
13605
13606	testCases = append(testCases, testCase{
13607		testType: serverTest,
13608		name:     "SkipEarlyData-HRR-TooMuchData-TLS13",
13609		config: Config{
13610			MaxVersion: VersionTLS13,
13611			Bugs: ProtocolBugs{
13612				SendFakeEarlyDataLength: 16384 + 1,
13613			},
13614			DefaultCurves: []CurveID{},
13615		},
13616		shouldFail:    true,
13617		expectedError: ":TOO_MUCH_SKIPPED_EARLY_DATA:",
13618	})
13619
13620	// Test that skipping early data looking for cleartext correctly
13621	// processes an alert record.
13622	testCases = append(testCases, testCase{
13623		testType: serverTest,
13624		name:     "SkipEarlyData-HRR-FatalAlert-TLS13",
13625		config: Config{
13626			MaxVersion: VersionTLS13,
13627			Bugs: ProtocolBugs{
13628				SendEarlyAlert:          true,
13629				SendFakeEarlyDataLength: 4,
13630			},
13631			DefaultCurves: []CurveID{},
13632		},
13633		shouldFail:    true,
13634		expectedError: ":SSLV3_ALERT_HANDSHAKE_FAILURE:",
13635	})
13636
13637	testCases = append(testCases, testCase{
13638		testType: serverTest,
13639		name:     "SkipEarlyData-SecondClientHelloEarlyData-TLS13",
13640		config: Config{
13641			MaxVersion: VersionTLS13,
13642			Bugs: ProtocolBugs{
13643				SendEarlyDataOnSecondClientHello: true,
13644			},
13645			DefaultCurves: []CurveID{},
13646		},
13647		shouldFail:         true,
13648		expectedLocalError: "remote error: bad record MAC",
13649	})
13650
13651	testCases = append(testCases, testCase{
13652		testType: clientTest,
13653		name:     "EmptyEncryptedExtensions-TLS13",
13654		config: Config{
13655			MaxVersion: VersionTLS13,
13656			Bugs: ProtocolBugs{
13657				EmptyEncryptedExtensions: true,
13658			},
13659		},
13660		shouldFail:         true,
13661		expectedLocalError: "remote error: error decoding message",
13662	})
13663
13664	testCases = append(testCases, testCase{
13665		testType: clientTest,
13666		name:     "EncryptedExtensionsWithKeyShare-TLS13",
13667		config: Config{
13668			MaxVersion: VersionTLS13,
13669			Bugs: ProtocolBugs{
13670				EncryptedExtensionsWithKeyShare: true,
13671			},
13672		},
13673		shouldFail:         true,
13674		expectedLocalError: "remote error: unsupported extension",
13675	})
13676
13677	testCases = append(testCases, testCase{
13678		testType: serverTest,
13679		name:     "SendHelloRetryRequest-TLS13",
13680		config: Config{
13681			MaxVersion: VersionTLS13,
13682			// Require a HelloRetryRequest for every curve.
13683			DefaultCurves:    []CurveID{},
13684			CurvePreferences: []CurveID{CurveX25519},
13685		},
13686		expectations: connectionExpectations{
13687			curveID: CurveX25519,
13688		},
13689		flags: []string{"-expect-hrr"},
13690	})
13691
13692	testCases = append(testCases, testCase{
13693		testType: serverTest,
13694		name:     "SendHelloRetryRequest-2-TLS13",
13695		config: Config{
13696			MaxVersion:       VersionTLS13,
13697			DefaultCurves:    []CurveID{CurveP384},
13698			CurvePreferences: []CurveID{CurveX25519, CurveP384},
13699		},
13700		// Although the ClientHello did not predict our preferred curve,
13701		// we always select it whether it is predicted or not.
13702		expectations: connectionExpectations{
13703			curveID: CurveX25519,
13704		},
13705		flags: []string{"-expect-hrr"},
13706	})
13707
13708	testCases = append(testCases, testCase{
13709		name: "UnknownCurve-HelloRetryRequest-TLS13",
13710		config: Config{
13711			MaxVersion: VersionTLS13,
13712			// P-384 requires HelloRetryRequest in BoringSSL.
13713			CurvePreferences: []CurveID{CurveP384},
13714			Bugs: ProtocolBugs{
13715				SendHelloRetryRequestCurve: bogusCurve,
13716			},
13717		},
13718		shouldFail:    true,
13719		expectedError: ":WRONG_CURVE:",
13720	})
13721
13722	testCases = append(testCases, testCase{
13723		name: "HelloRetryRequest-CipherChange-TLS13",
13724		config: Config{
13725			MaxVersion: VersionTLS13,
13726			// P-384 requires HelloRetryRequest in BoringSSL.
13727			CurvePreferences: []CurveID{CurveP384},
13728			Bugs: ProtocolBugs{
13729				SendCipherSuite:                  TLS_AES_128_GCM_SHA256,
13730				SendHelloRetryRequestCipherSuite: TLS_CHACHA20_POLY1305_SHA256,
13731			},
13732		},
13733		shouldFail:    true,
13734		expectedError: ":WRONG_CIPHER_RETURNED:",
13735	})
13736
13737	// Test that the client does not offer a PSK in the second ClientHello if the
13738	// HelloRetryRequest is incompatible with it.
13739	testCases = append(testCases, testCase{
13740		testType: clientTest,
13741		name:     "HelloRetryRequest-NonResumableCipher-TLS13",
13742		config: Config{
13743			MaxVersion: VersionTLS13,
13744			CipherSuites: []uint16{
13745				TLS_AES_128_GCM_SHA256,
13746			},
13747		},
13748		resumeConfig: &Config{
13749			MaxVersion: VersionTLS13,
13750			// P-384 requires HelloRetryRequest in BoringSSL.
13751			CurvePreferences: []CurveID{CurveP384},
13752			Bugs: ProtocolBugs{
13753				ExpectNoTLS13PSKAfterHRR: true,
13754			},
13755			CipherSuites: []uint16{
13756				TLS_AES_256_GCM_SHA384,
13757			},
13758		},
13759		resumeSession:        true,
13760		expectResumeRejected: true,
13761	})
13762
13763	testCases = append(testCases, testCase{
13764		name: "DisabledCurve-HelloRetryRequest-TLS13",
13765		config: Config{
13766			MaxVersion:       VersionTLS13,
13767			CurvePreferences: []CurveID{CurveP256},
13768			Bugs: ProtocolBugs{
13769				IgnorePeerCurvePreferences: true,
13770			},
13771		},
13772		flags:         []string{"-curves", strconv.Itoa(int(CurveP384))},
13773		shouldFail:    true,
13774		expectedError: ":WRONG_CURVE:",
13775	})
13776
13777	testCases = append(testCases, testCase{
13778		name: "UnnecessaryHelloRetryRequest-TLS13",
13779		config: Config{
13780			MaxVersion:       VersionTLS13,
13781			CurvePreferences: []CurveID{CurveX25519},
13782			Bugs: ProtocolBugs{
13783				SendHelloRetryRequestCurve: CurveX25519,
13784			},
13785		},
13786		shouldFail:    true,
13787		expectedError: ":WRONG_CURVE:",
13788	})
13789
13790	testCases = append(testCases, testCase{
13791		name: "SecondHelloRetryRequest-TLS13",
13792		config: Config{
13793			MaxVersion: VersionTLS13,
13794			// P-384 requires HelloRetryRequest in BoringSSL.
13795			CurvePreferences: []CurveID{CurveP384},
13796			Bugs: ProtocolBugs{
13797				SecondHelloRetryRequest: true,
13798			},
13799		},
13800		shouldFail:    true,
13801		expectedError: ":UNEXPECTED_MESSAGE:",
13802	})
13803
13804	testCases = append(testCases, testCase{
13805		name: "HelloRetryRequest-Empty-TLS13",
13806		config: Config{
13807			MaxVersion: VersionTLS13,
13808			Bugs: ProtocolBugs{
13809				AlwaysSendHelloRetryRequest: true,
13810			},
13811		},
13812		shouldFail:         true,
13813		expectedError:      ":EMPTY_HELLO_RETRY_REQUEST:",
13814		expectedLocalError: "remote error: illegal parameter",
13815	})
13816
13817	testCases = append(testCases, testCase{
13818		name: "HelloRetryRequest-DuplicateCurve-TLS13",
13819		config: Config{
13820			MaxVersion: VersionTLS13,
13821			// P-384 requires a HelloRetryRequest against BoringSSL's default
13822			// configuration. Assert this ExpectMissingKeyShare.
13823			CurvePreferences: []CurveID{CurveP384},
13824			Bugs: ProtocolBugs{
13825				ExpectMissingKeyShare:                true,
13826				DuplicateHelloRetryRequestExtensions: true,
13827			},
13828		},
13829		shouldFail:         true,
13830		expectedError:      ":DUPLICATE_EXTENSION:",
13831		expectedLocalError: "remote error: illegal parameter",
13832	})
13833
13834	testCases = append(testCases, testCase{
13835		name: "HelloRetryRequest-Cookie-TLS13",
13836		config: Config{
13837			MaxVersion: VersionTLS13,
13838			Bugs: ProtocolBugs{
13839				SendHelloRetryRequestCookie: []byte("cookie"),
13840			},
13841		},
13842	})
13843
13844	testCases = append(testCases, testCase{
13845		name: "HelloRetryRequest-DuplicateCookie-TLS13",
13846		config: Config{
13847			MaxVersion: VersionTLS13,
13848			Bugs: ProtocolBugs{
13849				SendHelloRetryRequestCookie:          []byte("cookie"),
13850				DuplicateHelloRetryRequestExtensions: true,
13851			},
13852		},
13853		shouldFail:         true,
13854		expectedError:      ":DUPLICATE_EXTENSION:",
13855		expectedLocalError: "remote error: illegal parameter",
13856	})
13857
13858	testCases = append(testCases, testCase{
13859		name: "HelloRetryRequest-EmptyCookie-TLS13",
13860		config: Config{
13861			MaxVersion: VersionTLS13,
13862			Bugs: ProtocolBugs{
13863				SendHelloRetryRequestCookie: []byte{},
13864			},
13865		},
13866		shouldFail:    true,
13867		expectedError: ":DECODE_ERROR:",
13868	})
13869
13870	testCases = append(testCases, testCase{
13871		name: "HelloRetryRequest-Cookie-Curve-TLS13",
13872		config: Config{
13873			MaxVersion: VersionTLS13,
13874			// P-384 requires HelloRetryRequest in BoringSSL.
13875			CurvePreferences: []CurveID{CurveP384},
13876			Bugs: ProtocolBugs{
13877				SendHelloRetryRequestCookie: []byte("cookie"),
13878				ExpectMissingKeyShare:       true,
13879			},
13880		},
13881	})
13882
13883	testCases = append(testCases, testCase{
13884		name: "HelloRetryRequest-Unknown-TLS13",
13885		config: Config{
13886			MaxVersion: VersionTLS13,
13887			Bugs: ProtocolBugs{
13888				CustomHelloRetryRequestExtension: "extension",
13889			},
13890		},
13891		shouldFail:         true,
13892		expectedError:      ":UNEXPECTED_EXTENSION:",
13893		expectedLocalError: "remote error: unsupported extension",
13894	})
13895
13896	testCases = append(testCases, testCase{
13897		testType: serverTest,
13898		name:     "SecondClientHelloMissingKeyShare-TLS13",
13899		config: Config{
13900			MaxVersion:    VersionTLS13,
13901			DefaultCurves: []CurveID{},
13902			Bugs: ProtocolBugs{
13903				SecondClientHelloMissingKeyShare: true,
13904			},
13905		},
13906		shouldFail:    true,
13907		expectedError: ":MISSING_KEY_SHARE:",
13908	})
13909
13910	testCases = append(testCases, testCase{
13911		testType: serverTest,
13912		name:     "SecondClientHelloWrongCurve-TLS13",
13913		config: Config{
13914			MaxVersion:    VersionTLS13,
13915			DefaultCurves: []CurveID{},
13916			Bugs: ProtocolBugs{
13917				MisinterpretHelloRetryRequestCurve: CurveP521,
13918			},
13919		},
13920		shouldFail:    true,
13921		expectedError: ":WRONG_CURVE:",
13922	})
13923
13924	testCases = append(testCases, testCase{
13925		name: "HelloRetryRequestVersionMismatch-TLS13",
13926		config: Config{
13927			MaxVersion: VersionTLS13,
13928			// P-384 requires HelloRetryRequest in BoringSSL.
13929			CurvePreferences: []CurveID{CurveP384},
13930			Bugs: ProtocolBugs{
13931				SendServerHelloVersion: 0x0305,
13932			},
13933		},
13934		shouldFail:    true,
13935		expectedError: ":WRONG_VERSION_NUMBER:",
13936	})
13937
13938	testCases = append(testCases, testCase{
13939		name: "HelloRetryRequestCurveMismatch-TLS13",
13940		config: Config{
13941			MaxVersion: VersionTLS13,
13942			// P-384 requires HelloRetryRequest in BoringSSL.
13943			CurvePreferences: []CurveID{CurveP384},
13944			Bugs: ProtocolBugs{
13945				// Send P-384 (correct) in the HelloRetryRequest.
13946				SendHelloRetryRequestCurve: CurveP384,
13947				// But send P-256 in the ServerHello.
13948				SendCurve: CurveP256,
13949			},
13950		},
13951		shouldFail:    true,
13952		expectedError: ":WRONG_CURVE:",
13953	})
13954
13955	// Test the server selecting a curve that requires a HelloRetryRequest
13956	// without sending it.
13957	testCases = append(testCases, testCase{
13958		name: "SkipHelloRetryRequest-TLS13",
13959		config: Config{
13960			MaxVersion: VersionTLS13,
13961			// P-384 requires HelloRetryRequest in BoringSSL.
13962			CurvePreferences: []CurveID{CurveP384},
13963			Bugs: ProtocolBugs{
13964				SkipHelloRetryRequest: true,
13965			},
13966		},
13967		shouldFail:    true,
13968		expectedError: ":WRONG_CURVE:",
13969	})
13970
13971	testCases = append(testCases, testCase{
13972		name: "SecondServerHelloNoVersion-TLS13",
13973		config: Config{
13974			MaxVersion: VersionTLS13,
13975			// P-384 requires HelloRetryRequest in BoringSSL.
13976			CurvePreferences: []CurveID{CurveP384},
13977			Bugs: ProtocolBugs{
13978				OmitServerSupportedVersionExtension: true,
13979			},
13980		},
13981		shouldFail:    true,
13982		expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:",
13983	})
13984	testCases = append(testCases, testCase{
13985		name: "SecondServerHelloWrongVersion-TLS13",
13986		config: Config{
13987			MaxVersion: VersionTLS13,
13988			// P-384 requires HelloRetryRequest in BoringSSL.
13989			CurvePreferences: []CurveID{CurveP384},
13990			Bugs: ProtocolBugs{
13991				SendServerSupportedVersionExtension: 0x1234,
13992			},
13993		},
13994		shouldFail:    true,
13995		expectedError: ":SECOND_SERVERHELLO_VERSION_MISMATCH:",
13996	})
13997
13998	testCases = append(testCases, testCase{
13999		name: "RequestContextInHandshake-TLS13",
14000		config: Config{
14001			MaxVersion: VersionTLS13,
14002			MinVersion: VersionTLS13,
14003			ClientAuth: RequireAnyClientCert,
14004			Bugs: ProtocolBugs{
14005				SendRequestContext: []byte("request context"),
14006			},
14007		},
14008		flags: []string{
14009			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14010			"-key-file", path.Join(*resourceDir, rsaKeyFile),
14011		},
14012		shouldFail:    true,
14013		expectedError: ":DECODE_ERROR:",
14014	})
14015
14016	testCases = append(testCases, testCase{
14017		name: "UnknownExtensionInCertificateRequest-TLS13",
14018		config: Config{
14019			MaxVersion: VersionTLS13,
14020			MinVersion: VersionTLS13,
14021			ClientAuth: RequireAnyClientCert,
14022			Bugs: ProtocolBugs{
14023				SendCustomCertificateRequest: 0x1212,
14024			},
14025		},
14026		flags: []string{
14027			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14028			"-key-file", path.Join(*resourceDir, rsaKeyFile),
14029		},
14030	})
14031
14032	testCases = append(testCases, testCase{
14033		name: "MissingSignatureAlgorithmsInCertificateRequest-TLS13",
14034		config: Config{
14035			MaxVersion: VersionTLS13,
14036			MinVersion: VersionTLS13,
14037			ClientAuth: RequireAnyClientCert,
14038			Bugs: ProtocolBugs{
14039				OmitCertificateRequestAlgorithms: true,
14040			},
14041		},
14042		flags: []string{
14043			"-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14044			"-key-file", path.Join(*resourceDir, rsaKeyFile),
14045		},
14046		shouldFail:    true,
14047		expectedError: ":DECODE_ERROR:",
14048	})
14049
14050	testCases = append(testCases, testCase{
14051		testType: serverTest,
14052		name:     "TrailingKeyShareData-TLS13",
14053		config: Config{
14054			MaxVersion: VersionTLS13,
14055			Bugs: ProtocolBugs{
14056				TrailingKeyShareData: true,
14057			},
14058		},
14059		shouldFail:    true,
14060		expectedError: ":DECODE_ERROR:",
14061	})
14062
14063	testCases = append(testCases, testCase{
14064		name: "AlwaysSelectPSKIdentity-TLS13",
14065		config: Config{
14066			MaxVersion: VersionTLS13,
14067			Bugs: ProtocolBugs{
14068				AlwaysSelectPSKIdentity: true,
14069			},
14070		},
14071		shouldFail:    true,
14072		expectedError: ":UNEXPECTED_EXTENSION:",
14073	})
14074
14075	testCases = append(testCases, testCase{
14076		name: "InvalidPSKIdentity-TLS13",
14077		config: Config{
14078			MaxVersion: VersionTLS13,
14079			Bugs: ProtocolBugs{
14080				SelectPSKIdentityOnResume: 1,
14081			},
14082		},
14083		resumeSession: true,
14084		shouldFail:    true,
14085		expectedError: ":PSK_IDENTITY_NOT_FOUND:",
14086	})
14087
14088	testCases = append(testCases, testCase{
14089		testType: serverTest,
14090		name:     "ExtraPSKIdentity-TLS13",
14091		config: Config{
14092			MaxVersion: VersionTLS13,
14093			Bugs: ProtocolBugs{
14094				ExtraPSKIdentity:   true,
14095				SendExtraPSKBinder: true,
14096			},
14097		},
14098		resumeSession: true,
14099	})
14100
14101	// Test that unknown NewSessionTicket extensions are tolerated.
14102	testCases = append(testCases, testCase{
14103		name: "CustomTicketExtension-TLS13",
14104		config: Config{
14105			MaxVersion: VersionTLS13,
14106			Bugs: ProtocolBugs{
14107				CustomTicketExtension: "1234",
14108			},
14109		},
14110	})
14111
14112	// Test the client handles 0-RTT being rejected by a full handshake
14113	// and correctly reports a certificate change.
14114	testCases = append(testCases, testCase{
14115		testType: clientTest,
14116		name:     "EarlyData-RejectTicket-Client-TLS13",
14117		config: Config{
14118			MaxVersion:   VersionTLS13,
14119			Certificates: []Certificate{rsaCertificate},
14120		},
14121		resumeConfig: &Config{
14122			MaxVersion:             VersionTLS13,
14123			Certificates:           []Certificate{ecdsaP256Certificate},
14124			SessionTicketsDisabled: true,
14125		},
14126		resumeSession:           true,
14127		expectResumeRejected:    true,
14128		earlyData:               true,
14129		expectEarlyDataRejected: true,
14130		flags: []string{
14131			"-on-retry-expect-early-data-reason", "session_not_resumed",
14132			// Test the peer certificate is reported correctly in each of the
14133			// three logical connections.
14134			"-on-initial-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14135			"-on-resume-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14136			"-on-retry-expect-peer-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
14137			// Session tickets are disabled, so the runner will not send a ticket.
14138			"-on-retry-expect-no-session",
14139		},
14140	})
14141
14142	// Test the server rejects 0-RTT if it does not recognize the ticket.
14143	testCases = append(testCases, testCase{
14144		testType: serverTest,
14145		name:     "EarlyData-RejectTicket-Server-TLS13",
14146		config: Config{
14147			MaxVersion: VersionTLS13,
14148			MinVersion: VersionTLS13,
14149			Bugs: ProtocolBugs{
14150				// Corrupt the ticket.
14151				FilterTicket: func(in []byte) ([]byte, error) {
14152					in[len(in)-1] ^= 1
14153					return in, nil
14154				},
14155			},
14156		},
14157		messageCount:            2,
14158		resumeSession:           true,
14159		expectResumeRejected:    true,
14160		earlyData:               true,
14161		expectEarlyDataRejected: true,
14162		flags: []string{
14163			"-on-resume-expect-early-data-reason", "session_not_resumed",
14164		},
14165	})
14166
14167	// Test the client handles 0-RTT being rejected via a HelloRetryRequest.
14168	testCases = append(testCases, testCase{
14169		testType: clientTest,
14170		name:     "EarlyData-HRR-Client-TLS13",
14171		config: Config{
14172			MaxVersion: VersionTLS13,
14173		},
14174		resumeConfig: &Config{
14175			MaxVersion: VersionTLS13,
14176			Bugs: ProtocolBugs{
14177				SendHelloRetryRequestCookie: []byte{1, 2, 3, 4},
14178			},
14179		},
14180		resumeSession:           true,
14181		earlyData:               true,
14182		expectEarlyDataRejected: true,
14183		flags: []string{
14184			"-on-retry-expect-early-data-reason", "hello_retry_request",
14185		},
14186	})
14187
14188	// Test the server rejects 0-RTT if it needs to send a HelloRetryRequest.
14189	testCases = append(testCases, testCase{
14190		testType: serverTest,
14191		name:     "EarlyData-HRR-Server-TLS13",
14192		config: Config{
14193			MaxVersion: VersionTLS13,
14194			MinVersion: VersionTLS13,
14195			// Require a HelloRetryRequest for every curve.
14196			DefaultCurves: []CurveID{},
14197		},
14198		messageCount:            2,
14199		resumeSession:           true,
14200		earlyData:               true,
14201		expectEarlyDataRejected: true,
14202		flags: []string{
14203			"-on-resume-expect-early-data-reason", "hello_retry_request",
14204		},
14205	})
14206
14207	// Test the client handles a 0-RTT reject from both ticket rejection and
14208	// HelloRetryRequest.
14209	testCases = append(testCases, testCase{
14210		testType: clientTest,
14211		name:     "EarlyData-HRR-RejectTicket-Client-TLS13",
14212		config: Config{
14213			MaxVersion:   VersionTLS13,
14214			Certificates: []Certificate{rsaCertificate},
14215		},
14216		resumeConfig: &Config{
14217			MaxVersion:             VersionTLS13,
14218			Certificates:           []Certificate{ecdsaP256Certificate},
14219			SessionTicketsDisabled: true,
14220			Bugs: ProtocolBugs{
14221				SendHelloRetryRequestCookie: []byte{1, 2, 3, 4},
14222			},
14223		},
14224		resumeSession:           true,
14225		expectResumeRejected:    true,
14226		earlyData:               true,
14227		expectEarlyDataRejected: true,
14228		flags: []string{
14229			// The client sees HelloRetryRequest before the resumption result,
14230			// though neither value is inherently preferable.
14231			"-on-retry-expect-early-data-reason", "hello_retry_request",
14232			// Test the peer certificate is reported correctly in each of the
14233			// three logical connections.
14234			"-on-initial-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14235			"-on-resume-expect-peer-cert-file", path.Join(*resourceDir, rsaCertificateFile),
14236			"-on-retry-expect-peer-cert-file", path.Join(*resourceDir, ecdsaP256CertificateFile),
14237			// Session tickets are disabled, so the runner will not send a ticket.
14238			"-on-retry-expect-no-session",
14239		},
14240	})
14241
14242	// Test the server rejects 0-RTT if it needs to send a HelloRetryRequest.
14243	testCases = append(testCases, testCase{
14244		testType: serverTest,
14245		name:     "EarlyData-HRR-RejectTicket-Server-TLS13",
14246		config: Config{
14247			MaxVersion: VersionTLS13,
14248			MinVersion: VersionTLS13,
14249			// Require a HelloRetryRequest for every curve.
14250			DefaultCurves: []CurveID{},
14251			Bugs: ProtocolBugs{
14252				// Corrupt the ticket.
14253				FilterTicket: func(in []byte) ([]byte, error) {
14254					in[len(in)-1] ^= 1
14255					return in, nil
14256				},
14257			},
14258		},
14259		messageCount:            2,
14260		resumeSession:           true,
14261		expectResumeRejected:    true,
14262		earlyData:               true,
14263		expectEarlyDataRejected: true,
14264		flags: []string{
14265			// The server sees the missed resumption before HelloRetryRequest,
14266			// though neither value is inherently preferable.
14267			"-on-resume-expect-early-data-reason", "session_not_resumed",
14268		},
14269	})
14270
14271	// The client must check the server does not send the early_data
14272	// extension while rejecting the session.
14273	testCases = append(testCases, testCase{
14274		testType: clientTest,
14275		name:     "EarlyDataWithoutResume-Client-TLS13",
14276		config: Config{
14277			MaxVersion:       VersionTLS13,
14278			MaxEarlyDataSize: 16384,
14279		},
14280		resumeConfig: &Config{
14281			MaxVersion:             VersionTLS13,
14282			SessionTicketsDisabled: true,
14283			Bugs: ProtocolBugs{
14284				SendEarlyDataExtension: true,
14285			},
14286		},
14287		resumeSession: true,
14288		earlyData:     true,
14289		shouldFail:    true,
14290		expectedError: ":UNEXPECTED_EXTENSION:",
14291	})
14292
14293	// The client must fail with a dedicated error code if the server
14294	// responds with TLS 1.2 when offering 0-RTT.
14295	testCases = append(testCases, testCase{
14296		testType: clientTest,
14297		name:     "EarlyDataVersionDowngrade-Client-TLS13",
14298		config: Config{
14299			MaxVersion: VersionTLS13,
14300		},
14301		resumeConfig: &Config{
14302			MaxVersion: VersionTLS12,
14303		},
14304		resumeSession: true,
14305		earlyData:     true,
14306		shouldFail:    true,
14307		expectedError: ":WRONG_VERSION_ON_EARLY_DATA:",
14308	})
14309
14310	// Test that the client rejects an (unsolicited) early_data extension if
14311	// the server sent an HRR.
14312	testCases = append(testCases, testCase{
14313		testType: clientTest,
14314		name:     "ServerAcceptsEarlyDataOnHRR-Client-TLS13",
14315		config: Config{
14316			MaxVersion: VersionTLS13,
14317		},
14318		resumeConfig: &Config{
14319			MaxVersion: VersionTLS13,
14320			Bugs: ProtocolBugs{
14321				SendHelloRetryRequestCookie: []byte{1, 2, 3, 4},
14322				SendEarlyDataExtension:      true,
14323			},
14324		},
14325		resumeSession: true,
14326		earlyData:     true,
14327		// The client will first process an early data reject from the HRR.
14328		expectEarlyDataRejected: true,
14329		shouldFail:              true,
14330		expectedError:           ":UNEXPECTED_EXTENSION:",
14331	})
14332
14333	testCases = append(testCases, testCase{
14334		testType: clientTest,
14335		name:     "SkipChangeCipherSpec-Client-TLS13",
14336		config: Config{
14337			MaxVersion: VersionTLS13,
14338			Bugs: ProtocolBugs{
14339				SkipChangeCipherSpec: true,
14340			},
14341		},
14342	})
14343
14344	testCases = append(testCases, testCase{
14345		testType: serverTest,
14346		name:     "SkipChangeCipherSpec-Server-TLS13",
14347		config: Config{
14348			MaxVersion: VersionTLS13,
14349			Bugs: ProtocolBugs{
14350				SkipChangeCipherSpec: true,
14351			},
14352		},
14353	})
14354
14355	testCases = append(testCases, testCase{
14356		testType: clientTest,
14357		name:     "TooManyChangeCipherSpec-Client-TLS13",
14358		config: Config{
14359			MaxVersion: VersionTLS13,
14360			Bugs: ProtocolBugs{
14361				SendExtraChangeCipherSpec: 33,
14362			},
14363		},
14364		shouldFail:    true,
14365		expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
14366	})
14367
14368	testCases = append(testCases, testCase{
14369		testType: serverTest,
14370		name:     "TooManyChangeCipherSpec-Server-TLS13",
14371		config: Config{
14372			MaxVersion: VersionTLS13,
14373			Bugs: ProtocolBugs{
14374				SendExtraChangeCipherSpec: 33,
14375			},
14376		},
14377		shouldFail:    true,
14378		expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
14379	})
14380
14381	testCases = append(testCases, testCase{
14382		name: "SendPostHandshakeChangeCipherSpec-TLS13",
14383		config: Config{
14384			MaxVersion: VersionTLS13,
14385			Bugs: ProtocolBugs{
14386				SendPostHandshakeChangeCipherSpec: true,
14387			},
14388		},
14389		shouldFail:         true,
14390		expectedError:      ":UNEXPECTED_RECORD:",
14391		expectedLocalError: "remote error: unexpected message",
14392	})
14393
14394	fooString := "foo"
14395	barString := "bar"
14396
14397	// Test that the client reports the correct ALPN after a 0-RTT reject
14398	// that changed it.
14399	testCases = append(testCases, testCase{
14400		testType: clientTest,
14401		name:     "EarlyData-ALPNMismatch-Client-TLS13",
14402		config: Config{
14403			MaxVersion: VersionTLS13,
14404			Bugs: ProtocolBugs{
14405				ALPNProtocol: &fooString,
14406			},
14407		},
14408		resumeConfig: &Config{
14409			MaxVersion: VersionTLS13,
14410			Bugs: ProtocolBugs{
14411				ALPNProtocol: &barString,
14412			},
14413		},
14414		resumeSession:           true,
14415		earlyData:               true,
14416		expectEarlyDataRejected: true,
14417		flags: []string{
14418			"-advertise-alpn", "\x03foo\x03bar",
14419			// The client does not learn ALPN was the cause.
14420			"-on-retry-expect-early-data-reason", "peer_declined",
14421			// In the 0-RTT state, we surface the predicted ALPN. After
14422			// processing the reject, we surface the real one.
14423			"-on-initial-expect-alpn", "foo",
14424			"-on-resume-expect-alpn", "foo",
14425			"-on-retry-expect-alpn", "bar",
14426		},
14427	})
14428
14429	// Test that the client reports the correct ALPN after a 0-RTT reject if
14430	// ALPN was omitted from the first connection.
14431	testCases = append(testCases, testCase{
14432		testType: clientTest,
14433		name:     "EarlyData-ALPNOmitted1-Client-TLS13",
14434		config: Config{
14435			MaxVersion: VersionTLS13,
14436		},
14437		resumeConfig: &Config{
14438			MaxVersion: VersionTLS13,
14439			NextProtos: []string{"foo"},
14440		},
14441		resumeSession:           true,
14442		earlyData:               true,
14443		expectEarlyDataRejected: true,
14444		flags: []string{
14445			"-advertise-alpn", "\x03foo\x03bar",
14446			// The client does not learn ALPN was the cause.
14447			"-on-retry-expect-early-data-reason", "peer_declined",
14448			// In the 0-RTT state, we surface the predicted ALPN. After
14449			// processing the reject, we surface the real one.
14450			"-on-initial-expect-alpn", "",
14451			"-on-resume-expect-alpn", "",
14452			"-on-retry-expect-alpn", "foo",
14453		},
14454	})
14455
14456	// Test that the client reports the correct ALPN after a 0-RTT reject if
14457	// ALPN was omitted from the second connection.
14458	testCases = append(testCases, testCase{
14459		testType: clientTest,
14460		name:     "EarlyData-ALPNOmitted2-Client-TLS13",
14461		config: Config{
14462			MaxVersion: VersionTLS13,
14463			NextProtos: []string{"foo"},
14464		},
14465		resumeConfig: &Config{
14466			MaxVersion: VersionTLS13,
14467		},
14468		resumeSession:           true,
14469		earlyData:               true,
14470		expectEarlyDataRejected: true,
14471		flags: []string{
14472			"-advertise-alpn", "\x03foo\x03bar",
14473			// The client does not learn ALPN was the cause.
14474			"-on-retry-expect-early-data-reason", "peer_declined",
14475			// In the 0-RTT state, we surface the predicted ALPN. After
14476			// processing the reject, we surface the real one.
14477			"-on-initial-expect-alpn", "foo",
14478			"-on-resume-expect-alpn", "foo",
14479			"-on-retry-expect-alpn", "",
14480		},
14481	})
14482
14483	// Test that the client enforces ALPN match on 0-RTT accept.
14484	testCases = append(testCases, testCase{
14485		testType: clientTest,
14486		name:     "EarlyData-BadALPNMismatch-Client-TLS13",
14487		config: Config{
14488			MaxVersion: VersionTLS13,
14489			Bugs: ProtocolBugs{
14490				ALPNProtocol: &fooString,
14491			},
14492		},
14493		resumeConfig: &Config{
14494			MaxVersion: VersionTLS13,
14495			Bugs: ProtocolBugs{
14496				AlwaysAcceptEarlyData: true,
14497				ALPNProtocol:          &barString,
14498			},
14499		},
14500		resumeSession: true,
14501		earlyData:     true,
14502		flags: []string{
14503			"-advertise-alpn", "\x03foo\x03bar",
14504			"-on-initial-expect-alpn", "foo",
14505			"-on-resume-expect-alpn", "foo",
14506			"-on-retry-expect-alpn", "bar",
14507		},
14508		shouldFail:         true,
14509		expectedError:      ":ALPN_MISMATCH_ON_EARLY_DATA:",
14510		expectedLocalError: "remote error: illegal parameter",
14511	})
14512
14513	// Test that the client does not offer early data if it is incompatible
14514	// with ALPN preferences.
14515	testCases = append(testCases, testCase{
14516		testType: clientTest,
14517		name:     "EarlyData-ALPNPreferenceChanged-TLS13",
14518		config: Config{
14519			MaxVersion:       VersionTLS13,
14520			MaxEarlyDataSize: 16384,
14521			NextProtos:       []string{"foo", "bar"},
14522		},
14523		resumeSession: true,
14524		flags: []string{
14525			"-enable-early-data",
14526			"-expect-ticket-supports-early-data",
14527			"-expect-no-offer-early-data",
14528			// Offer different ALPN values in the initial and resumption.
14529			"-on-initial-advertise-alpn", "\x03foo",
14530			"-on-initial-expect-alpn", "foo",
14531			"-on-resume-advertise-alpn", "\x03bar",
14532			"-on-resume-expect-alpn", "bar",
14533			// The ALPN mismatch comes from the client, so it reports it as the
14534			// reason.
14535			"-on-resume-expect-early-data-reason", "alpn_mismatch",
14536		},
14537	})
14538
14539	// Test that the client does not offer 0-RTT to servers which never
14540	// advertise it.
14541	testCases = append(testCases, testCase{
14542		testType: clientTest,
14543		name:     "EarlyData-NonZeroRTTSession-Client-TLS13",
14544		config: Config{
14545			MaxVersion: VersionTLS13,
14546		},
14547		resumeSession: true,
14548		flags: []string{
14549			"-enable-early-data",
14550			"-on-resume-expect-no-offer-early-data",
14551			// The client declines to offer 0-RTT because of the session.
14552			"-on-resume-expect-early-data-reason", "unsupported_for_session",
14553		},
14554	})
14555
14556	// Test that the server correctly rejects 0-RTT when the previous
14557	// session did not allow early data on resumption.
14558	testCases = append(testCases, testCase{
14559		testType: serverTest,
14560		name:     "EarlyData-NonZeroRTTSession-Server-TLS13",
14561		config: Config{
14562			MaxVersion: VersionTLS13,
14563		},
14564		resumeConfig: &Config{
14565			MaxVersion: VersionTLS13,
14566			Bugs: ProtocolBugs{
14567				SendEarlyData:           [][]byte{{1, 2, 3, 4}},
14568				ExpectEarlyDataAccepted: false,
14569			},
14570		},
14571		resumeSession: true,
14572		// This test configures early data manually instead of the earlyData
14573		// option, to customize the -enable-early-data flag.
14574		flags: []string{
14575			"-on-resume-enable-early-data",
14576			"-expect-reject-early-data",
14577			// The server rejects 0-RTT because of the session.
14578			"-on-resume-expect-early-data-reason", "unsupported_for_session",
14579		},
14580	})
14581
14582	// Test that we reject early data where ALPN is omitted from the first
14583	// connection, but negotiated in the second.
14584	testCases = append(testCases, testCase{
14585		testType: serverTest,
14586		name:     "EarlyData-ALPNOmitted1-Server-TLS13",
14587		config: Config{
14588			MaxVersion: VersionTLS13,
14589			NextProtos: []string{},
14590		},
14591		resumeConfig: &Config{
14592			MaxVersion: VersionTLS13,
14593			NextProtos: []string{"foo"},
14594		},
14595		resumeSession:           true,
14596		earlyData:               true,
14597		expectEarlyDataRejected: true,
14598		flags: []string{
14599			"-on-initial-select-alpn", "",
14600			"-on-resume-select-alpn", "foo",
14601			"-on-resume-expect-early-data-reason", "alpn_mismatch",
14602		},
14603	})
14604
14605	// Test that we reject early data where ALPN is omitted from the second
14606	// connection, but negotiated in the first.
14607	testCases = append(testCases, testCase{
14608		testType: serverTest,
14609		name:     "EarlyData-ALPNOmitted2-Server-TLS13",
14610		config: Config{
14611			MaxVersion: VersionTLS13,
14612			NextProtos: []string{"foo"},
14613		},
14614		resumeConfig: &Config{
14615			MaxVersion: VersionTLS13,
14616			NextProtos: []string{},
14617		},
14618		resumeSession:           true,
14619		earlyData:               true,
14620		expectEarlyDataRejected: true,
14621		flags: []string{
14622			"-on-initial-select-alpn", "foo",
14623			"-on-resume-select-alpn", "",
14624			"-on-resume-expect-early-data-reason", "alpn_mismatch",
14625		},
14626	})
14627
14628	// Test that we reject early data with mismatched ALPN.
14629	testCases = append(testCases, testCase{
14630		testType: serverTest,
14631		name:     "EarlyData-ALPNMismatch-Server-TLS13",
14632		config: Config{
14633			MaxVersion: VersionTLS13,
14634			NextProtos: []string{"foo"},
14635		},
14636		resumeConfig: &Config{
14637			MaxVersion: VersionTLS13,
14638			NextProtos: []string{"bar"},
14639		},
14640		resumeSession:           true,
14641		earlyData:               true,
14642		expectEarlyDataRejected: true,
14643		flags: []string{
14644			"-on-initial-select-alpn", "foo",
14645			"-on-resume-select-alpn", "bar",
14646			"-on-resume-expect-early-data-reason", "alpn_mismatch",
14647		},
14648	})
14649
14650	// Test that the client offering 0-RTT and Channel ID forbids the server
14651	// from accepting both.
14652	testCases = append(testCases, testCase{
14653		testType: clientTest,
14654		name:     "EarlyDataChannelID-AcceptBoth-Client-TLS13",
14655		config: Config{
14656			MaxVersion:       VersionTLS13,
14657			RequestChannelID: true,
14658		},
14659		resumeSession: true,
14660		earlyData:     true,
14661		expectations: connectionExpectations{
14662			channelID: true,
14663		},
14664		shouldFail:         true,
14665		expectedError:      ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:",
14666		expectedLocalError: "remote error: illegal parameter",
14667		flags: []string{
14668			"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile),
14669		},
14670	})
14671
14672	// Test that the client offering Channel ID and 0-RTT allows the server
14673	// to decline 0-RTT.
14674	testCases = append(testCases, testCase{
14675		testType: clientTest,
14676		name:     "EarlyDataChannelID-AcceptChannelID-Client-TLS13",
14677		config: Config{
14678			MaxVersion:       VersionTLS13,
14679			RequestChannelID: true,
14680			Bugs: ProtocolBugs{
14681				AlwaysRejectEarlyData: true,
14682			},
14683		},
14684		resumeSession:           true,
14685		earlyData:               true,
14686		expectEarlyDataRejected: true,
14687		expectations: connectionExpectations{
14688			channelID: true,
14689		},
14690		flags: []string{
14691			"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile),
14692			// The client never learns the reason was Channel ID.
14693			"-on-retry-expect-early-data-reason", "peer_declined",
14694		},
14695	})
14696
14697	// Test that the client offering Channel ID and 0-RTT allows the server
14698	// to decline Channel ID.
14699	testCases = append(testCases, testCase{
14700		testType: clientTest,
14701		name:     "EarlyDataChannelID-AcceptEarlyData-Client-TLS13",
14702		config: Config{
14703			MaxVersion: VersionTLS13,
14704		},
14705		resumeSession: true,
14706		earlyData:     true,
14707		flags: []string{
14708			"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile),
14709		},
14710	})
14711
14712	// Test that the server supporting Channel ID and 0-RTT declines 0-RTT
14713	// if it would negotiate Channel ID.
14714	testCases = append(testCases, testCase{
14715		testType: serverTest,
14716		name:     "EarlyDataChannelID-OfferBoth-Server-TLS13",
14717		config: Config{
14718			MaxVersion: VersionTLS13,
14719			ChannelID:  channelIDKey,
14720		},
14721		resumeSession:           true,
14722		earlyData:               true,
14723		expectEarlyDataRejected: true,
14724		expectations: connectionExpectations{
14725			channelID: true,
14726		},
14727		flags: []string{
14728			"-expect-channel-id",
14729			base64.StdEncoding.EncodeToString(channelIDBytes),
14730			"-on-resume-expect-early-data-reason", "channel_id",
14731		},
14732	})
14733
14734	// Test that the server supporting Channel ID and 0-RTT accepts 0-RTT
14735	// if not offered Channel ID.
14736	testCases = append(testCases, testCase{
14737		testType: serverTest,
14738		name:     "EarlyDataChannelID-OfferEarlyData-Server-TLS13",
14739		config: Config{
14740			MaxVersion: VersionTLS13,
14741		},
14742		resumeSession: true,
14743		earlyData:     true,
14744		expectations: connectionExpectations{
14745			channelID: false,
14746		},
14747		flags: []string{
14748			"-enable-channel-id",
14749			"-on-resume-expect-early-data-reason", "accept",
14750		},
14751	})
14752
14753	// Test that the server errors on 0-RTT streams without end_of_early_data.
14754	// The subsequent records should fail to decrypt.
14755	testCases = append(testCases, testCase{
14756		testType: serverTest,
14757		name:     "EarlyData-SkipEndOfEarlyData-TLS13",
14758		config: Config{
14759			MaxVersion: VersionTLS13,
14760			Bugs: ProtocolBugs{
14761				SkipEndOfEarlyData: true,
14762			},
14763		},
14764		resumeSession:      true,
14765		earlyData:          true,
14766		shouldFail:         true,
14767		expectedLocalError: "remote error: bad record MAC",
14768		expectedError:      ":BAD_DECRYPT:",
14769	})
14770
14771	// Test that the server errors on 0-RTT streams with a stray handshake
14772	// message in them.
14773	testCases = append(testCases, testCase{
14774		testType: serverTest,
14775		name:     "EarlyData-UnexpectedHandshake-Server-TLS13",
14776		config: Config{
14777			MaxVersion: VersionTLS13,
14778		},
14779		resumeConfig: &Config{
14780			MaxVersion: VersionTLS13,
14781			Bugs: ProtocolBugs{
14782				SendStrayEarlyHandshake: true,
14783			},
14784		},
14785		resumeSession:      true,
14786		earlyData:          true,
14787		shouldFail:         true,
14788		expectedError:      ":UNEXPECTED_MESSAGE:",
14789		expectedLocalError: "remote error: unexpected message",
14790	})
14791
14792	// Test that the client reports TLS 1.3 as the version while sending
14793	// early data.
14794	testCases = append(testCases, testCase{
14795		testType: clientTest,
14796		name:     "EarlyData-Client-VersionAPI-TLS13",
14797		config: Config{
14798			MaxVersion: VersionTLS13,
14799		},
14800		resumeSession: true,
14801		earlyData:     true,
14802		flags: []string{
14803			"-expect-version", strconv.Itoa(VersionTLS13),
14804		},
14805	})
14806
14807	// Test that client and server both notice handshake errors after data
14808	// has started flowing.
14809	testCases = append(testCases, testCase{
14810		testType: clientTest,
14811		name:     "EarlyData-Client-BadFinished-TLS13",
14812		config: Config{
14813			MaxVersion: VersionTLS13,
14814		},
14815		resumeConfig: &Config{
14816			MaxVersion: VersionTLS13,
14817			Bugs: ProtocolBugs{
14818				BadFinished: true,
14819			},
14820		},
14821		resumeSession:      true,
14822		earlyData:          true,
14823		shouldFail:         true,
14824		expectedError:      ":DIGEST_CHECK_FAILED:",
14825		expectedLocalError: "remote error: error decrypting message",
14826	})
14827	testCases = append(testCases, testCase{
14828		testType: serverTest,
14829		name:     "EarlyData-Server-BadFinished-TLS13",
14830		config: Config{
14831			MaxVersion: VersionTLS13,
14832		},
14833		resumeConfig: &Config{
14834			MaxVersion: VersionTLS13,
14835			Bugs: ProtocolBugs{
14836				BadFinished: true,
14837			},
14838		},
14839		resumeSession:      true,
14840		earlyData:          true,
14841		shouldFail:         true,
14842		expectedError:      ":DIGEST_CHECK_FAILED:",
14843		expectedLocalError: "remote error: error decrypting message",
14844	})
14845
14846	testCases = append(testCases, testCase{
14847		testType: serverTest,
14848		name:     "Server-NonEmptyEndOfEarlyData-TLS13",
14849		config: Config{
14850			MaxVersion: VersionTLS13,
14851		},
14852		resumeConfig: &Config{
14853			MaxVersion: VersionTLS13,
14854			Bugs: ProtocolBugs{
14855				NonEmptyEndOfEarlyData: true,
14856			},
14857		},
14858		resumeSession: true,
14859		earlyData:     true,
14860		shouldFail:    true,
14861		expectedError: ":DECODE_ERROR:",
14862	})
14863
14864	testCases = append(testCases, testCase{
14865		testType: serverTest,
14866		name:     "ServerSkipCertificateVerify-TLS13",
14867		config: Config{
14868			MinVersion:   VersionTLS13,
14869			MaxVersion:   VersionTLS13,
14870			Certificates: []Certificate{rsaChainCertificate},
14871			Bugs: ProtocolBugs{
14872				SkipCertificateVerify: true,
14873			},
14874		},
14875		expectations: connectionExpectations{
14876			peerCertificate: &rsaChainCertificate,
14877		},
14878		flags: []string{
14879			"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
14880			"-key-file", path.Join(*resourceDir, rsaChainKeyFile),
14881			"-require-any-client-certificate",
14882		},
14883		shouldFail:         true,
14884		expectedError:      ":UNEXPECTED_MESSAGE:",
14885		expectedLocalError: "remote error: unexpected message",
14886	})
14887	testCases = append(testCases, testCase{
14888		testType: clientTest,
14889		name:     "ClientSkipCertificateVerify-TLS13",
14890		config: Config{
14891			MinVersion:   VersionTLS13,
14892			MaxVersion:   VersionTLS13,
14893			Certificates: []Certificate{rsaChainCertificate},
14894			Bugs: ProtocolBugs{
14895				SkipCertificateVerify: true,
14896			},
14897		},
14898		expectations: connectionExpectations{
14899			peerCertificate: &rsaChainCertificate,
14900		},
14901		flags: []string{
14902			"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
14903			"-key-file", path.Join(*resourceDir, rsaChainKeyFile),
14904		},
14905		shouldFail:         true,
14906		expectedError:      ":UNEXPECTED_MESSAGE:",
14907		expectedLocalError: "remote error: unexpected message",
14908	})
14909
14910	// If the client or server has 0-RTT enabled but disabled TLS 1.3, it should
14911	// report a reason of protocol_version.
14912	testCases = append(testCases, testCase{
14913		testType: clientTest,
14914		name:     "EarlyDataEnabled-Client-MaxTLS12",
14915		expectations: connectionExpectations{
14916			version: VersionTLS12,
14917		},
14918		flags: []string{
14919			"-enable-early-data",
14920			"-max-version", strconv.Itoa(VersionTLS12),
14921			"-expect-early-data-reason", "protocol_version",
14922		},
14923	})
14924	testCases = append(testCases, testCase{
14925		testType: serverTest,
14926		name:     "EarlyDataEnabled-Server-MaxTLS12",
14927		expectations: connectionExpectations{
14928			version: VersionTLS12,
14929		},
14930		flags: []string{
14931			"-enable-early-data",
14932			"-max-version", strconv.Itoa(VersionTLS12),
14933			"-expect-early-data-reason", "protocol_version",
14934		},
14935	})
14936
14937	// The server additionally reports protocol_version if it enabled TLS 1.3,
14938	// but the peer negotiated TLS 1.2. (The corresponding situation does not
14939	// exist on the client because negotiating TLS 1.2 with a 0-RTT ClientHello
14940	// is a fatal error.)
14941	testCases = append(testCases, testCase{
14942		testType: serverTest,
14943		name:     "EarlyDataEnabled-Server-NegotiateTLS12",
14944		config: Config{
14945			MaxVersion: VersionTLS12,
14946		},
14947		expectations: connectionExpectations{
14948			version: VersionTLS12,
14949		},
14950		flags: []string{
14951			"-enable-early-data",
14952			"-expect-early-data-reason", "protocol_version",
14953		},
14954	})
14955
14956	// On 0-RTT reject, the server may end up negotiating a cipher suite with a
14957	// different PRF hash. Test that the client handles this correctly.
14958	testCases = append(testCases, testCase{
14959		testType: clientTest,
14960		name:     "EarlyData-Reject0RTT-DifferentPRF-Client",
14961		config: Config{
14962			MaxVersion:   VersionTLS13,
14963			CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
14964		},
14965		resumeConfig: &Config{
14966			MaxVersion:   VersionTLS13,
14967			CipherSuites: []uint16{TLS_AES_256_GCM_SHA384},
14968		},
14969		resumeSession:           true,
14970		expectResumeRejected:    true,
14971		earlyData:               true,
14972		expectEarlyDataRejected: true,
14973		flags: []string{
14974			"-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
14975			// The client initially reports the old cipher suite while sending
14976			// early data. After processing the 0-RTT reject, it reports the
14977			// true cipher suite.
14978			"-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
14979			"-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)),
14980		},
14981	})
14982	testCases = append(testCases, testCase{
14983		testType: clientTest,
14984		name:     "EarlyData-Reject0RTT-DifferentPRF-HRR-Client",
14985		config: Config{
14986			MaxVersion:   VersionTLS13,
14987			CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
14988		},
14989		resumeConfig: &Config{
14990			MaxVersion:   VersionTLS13,
14991			CipherSuites: []uint16{TLS_AES_256_GCM_SHA384},
14992			// P-384 requires a HelloRetryRequest against BoringSSL's default
14993			// configuration. Assert this with ExpectMissingKeyShare.
14994			CurvePreferences: []CurveID{CurveP384},
14995			Bugs: ProtocolBugs{
14996				ExpectMissingKeyShare: true,
14997			},
14998		},
14999		resumeSession:           true,
15000		expectResumeRejected:    true,
15001		earlyData:               true,
15002		expectEarlyDataRejected: true,
15003		flags: []string{
15004			"-on-initial-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
15005			// The client initially reports the old cipher suite while sending
15006			// early data. After processing the 0-RTT reject, it reports the
15007			// true cipher suite.
15008			"-on-resume-expect-cipher", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
15009			"-on-retry-expect-cipher", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)),
15010		},
15011	})
15012
15013	// Test that the client enforces cipher suite match on 0-RTT accept.
15014	testCases = append(testCases, testCase{
15015		testType: clientTest,
15016		name:     "EarlyData-CipherMismatch-Client-TLS13",
15017		config: Config{
15018			MaxVersion:   VersionTLS13,
15019			CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
15020		},
15021		resumeConfig: &Config{
15022			MaxVersion:   VersionTLS13,
15023			CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256},
15024			Bugs: ProtocolBugs{
15025				AlwaysAcceptEarlyData: true,
15026			},
15027		},
15028		resumeSession:      true,
15029		earlyData:          true,
15030		shouldFail:         true,
15031		expectedError:      ":CIPHER_MISMATCH_ON_EARLY_DATA:",
15032		expectedLocalError: "remote error: illegal parameter",
15033	})
15034}
15035
15036func addTLS13CipherPreferenceTests() {
15037	// Test that client preference is honored if the shim has AES hardware
15038	// and ChaCha20-Poly1305 is preferred otherwise.
15039	testCases = append(testCases, testCase{
15040		testType: serverTest,
15041		name:     "TLS13-CipherPreference-Server-ChaCha20-AES",
15042		config: Config{
15043			MaxVersion: VersionTLS13,
15044			CipherSuites: []uint16{
15045				TLS_CHACHA20_POLY1305_SHA256,
15046				TLS_AES_128_GCM_SHA256,
15047			},
15048			CurvePreferences: []CurveID{CurveX25519},
15049		},
15050		flags: []string{
15051			"-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15052			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15053		},
15054	})
15055
15056	testCases = append(testCases, testCase{
15057		testType: serverTest,
15058		name:     "TLS13-CipherPreference-Server-AES-ChaCha20",
15059		config: Config{
15060			MaxVersion: VersionTLS13,
15061			CipherSuites: []uint16{
15062				TLS_AES_128_GCM_SHA256,
15063				TLS_CHACHA20_POLY1305_SHA256,
15064			},
15065			CurvePreferences: []CurveID{CurveX25519},
15066		},
15067		flags: []string{
15068			"-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
15069			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15070		},
15071	})
15072
15073	// Test that the client orders ChaCha20-Poly1305 and AES-GCM based on
15074	// whether it has AES hardware.
15075	testCases = append(testCases, testCase{
15076		name: "TLS13-CipherPreference-Client",
15077		config: Config{
15078			MaxVersion: VersionTLS13,
15079			// Use the client cipher order. (This is the default but
15080			// is listed to be explicit.)
15081			PreferServerCipherSuites: false,
15082		},
15083		flags: []string{
15084			"-expect-cipher-aes", strconv.Itoa(int(TLS_AES_128_GCM_SHA256)),
15085			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15086		},
15087	})
15088
15089	// CECPQ2 prefers 256-bit ciphers but will use AES-128 if there's nothing else.
15090	testCases = append(testCases, testCase{
15091		testType: serverTest,
15092		name:     "TLS13-CipherPreference-CECPQ2-AES128Only",
15093		config: Config{
15094			MaxVersion: VersionTLS13,
15095			CipherSuites: []uint16{
15096				TLS_AES_128_GCM_SHA256,
15097			},
15098		},
15099		flags: []string{
15100			"-curves", strconv.Itoa(int(CurveCECPQ2)),
15101		},
15102	})
15103
15104	// When a 256-bit cipher is offered, even if not in first place, it should be
15105	// picked.
15106	testCases = append(testCases, testCase{
15107		testType: serverTest,
15108		name:     "TLS13-CipherPreference-CECPQ2-AES256Preferred",
15109		config: Config{
15110			MaxVersion: VersionTLS13,
15111			CipherSuites: []uint16{
15112				TLS_AES_128_GCM_SHA256,
15113				TLS_AES_256_GCM_SHA384,
15114			},
15115		},
15116		flags: []string{
15117			"-curves", strconv.Itoa(int(CurveCECPQ2)),
15118		},
15119		expectations: connectionExpectations{
15120			cipher: TLS_AES_256_GCM_SHA384,
15121		},
15122	})
15123	// ... but when CECPQ2 isn't being used, the client's preference controls.
15124	testCases = append(testCases, testCase{
15125		testType: serverTest,
15126		name:     "TLS13-CipherPreference-CECPQ2-AES128PreferredOtherwise",
15127		config: Config{
15128			MaxVersion: VersionTLS13,
15129			CipherSuites: []uint16{
15130				TLS_AES_128_GCM_SHA256,
15131				TLS_AES_256_GCM_SHA384,
15132			},
15133		},
15134		flags: []string{
15135			"-curves", strconv.Itoa(int(CurveX25519)),
15136		},
15137		expectations: connectionExpectations{
15138			cipher: TLS_AES_128_GCM_SHA256,
15139		},
15140	})
15141
15142	// Test that CECPQ2 continues to honor AES vs ChaCha20 logic.
15143	testCases = append(testCases, testCase{
15144		testType: serverTest,
15145		name:     "TLS13-CipherPreference-CECPQ2-AES128-ChaCha20-AES256",
15146		config: Config{
15147			MaxVersion: VersionTLS13,
15148			CipherSuites: []uint16{
15149				TLS_AES_128_GCM_SHA256,
15150				TLS_CHACHA20_POLY1305_SHA256,
15151				TLS_AES_256_GCM_SHA384,
15152			},
15153		},
15154		flags: []string{
15155			"-curves", strconv.Itoa(int(CurveCECPQ2)),
15156			"-expect-cipher-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15157			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15158		},
15159	})
15160	testCases = append(testCases, testCase{
15161		testType: serverTest,
15162		name:     "TLS13-CipherPreference-CECPQ2-AES128-AES256-ChaCha20",
15163		config: Config{
15164			MaxVersion: VersionTLS13,
15165			CipherSuites: []uint16{
15166				TLS_AES_128_GCM_SHA256,
15167				TLS_AES_256_GCM_SHA384,
15168				TLS_CHACHA20_POLY1305_SHA256,
15169			},
15170		},
15171		flags: []string{
15172			"-curves", strconv.Itoa(int(CurveCECPQ2)),
15173			"-expect-cipher-aes", strconv.Itoa(int(TLS_AES_256_GCM_SHA384)),
15174			"-expect-cipher-no-aes", strconv.Itoa(int(TLS_CHACHA20_POLY1305_SHA256)),
15175		},
15176	})
15177}
15178
15179func addPeekTests() {
15180	// Test SSL_peek works, including on empty records.
15181	testCases = append(testCases, testCase{
15182		name:             "Peek-Basic",
15183		sendEmptyRecords: 1,
15184		flags:            []string{"-peek-then-read"},
15185	})
15186
15187	// Test SSL_peek can drive the initial handshake.
15188	testCases = append(testCases, testCase{
15189		name: "Peek-ImplicitHandshake",
15190		flags: []string{
15191			"-peek-then-read",
15192			"-implicit-handshake",
15193		},
15194	})
15195
15196	// Test SSL_peek can discover and drive a renegotiation.
15197	testCases = append(testCases, testCase{
15198		name: "Peek-Renegotiate",
15199		config: Config{
15200			MaxVersion: VersionTLS12,
15201		},
15202		renegotiate: 1,
15203		flags: []string{
15204			"-peek-then-read",
15205			"-renegotiate-freely",
15206			"-expect-total-renegotiations", "1",
15207		},
15208	})
15209
15210	// Test SSL_peek can discover a close_notify.
15211	testCases = append(testCases, testCase{
15212		name: "Peek-Shutdown",
15213		config: Config{
15214			Bugs: ProtocolBugs{
15215				ExpectCloseNotify: true,
15216			},
15217		},
15218		flags: []string{
15219			"-peek-then-read",
15220			"-check-close-notify",
15221		},
15222	})
15223
15224	// Test SSL_peek can discover an alert.
15225	testCases = append(testCases, testCase{
15226		name: "Peek-Alert",
15227		config: Config{
15228			Bugs: ProtocolBugs{
15229				SendSpuriousAlert: alertRecordOverflow,
15230			},
15231		},
15232		flags:         []string{"-peek-then-read"},
15233		shouldFail:    true,
15234		expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
15235	})
15236
15237	// Test SSL_peek can handle KeyUpdate.
15238	testCases = append(testCases, testCase{
15239		name: "Peek-KeyUpdate",
15240		config: Config{
15241			MaxVersion: VersionTLS13,
15242		},
15243		sendKeyUpdates:   1,
15244		keyUpdateRequest: keyUpdateNotRequested,
15245		flags:            []string{"-peek-then-read"},
15246	})
15247}
15248
15249func addRecordVersionTests() {
15250	for _, ver := range tlsVersions {
15251		// Test that the record version is enforced.
15252		testCases = append(testCases, testCase{
15253			name: "CheckRecordVersion-" + ver.name,
15254			config: Config{
15255				MinVersion: ver.version,
15256				MaxVersion: ver.version,
15257				Bugs: ProtocolBugs{
15258					SendRecordVersion: 0x03ff,
15259				},
15260			},
15261			shouldFail:    true,
15262			expectedError: ":WRONG_VERSION_NUMBER:",
15263		})
15264
15265		// Test that the ClientHello may use any record version, for
15266		// compatibility reasons.
15267		testCases = append(testCases, testCase{
15268			testType: serverTest,
15269			name:     "LooseInitialRecordVersion-" + ver.name,
15270			config: Config{
15271				MinVersion: ver.version,
15272				MaxVersion: ver.version,
15273				Bugs: ProtocolBugs{
15274					SendInitialRecordVersion: 0x03ff,
15275				},
15276			},
15277		})
15278
15279		// Test that garbage ClientHello record versions are rejected.
15280		testCases = append(testCases, testCase{
15281			testType: serverTest,
15282			name:     "GarbageInitialRecordVersion-" + ver.name,
15283			config: Config{
15284				MinVersion: ver.version,
15285				MaxVersion: ver.version,
15286				Bugs: ProtocolBugs{
15287					SendInitialRecordVersion: 0xffff,
15288				},
15289			},
15290			shouldFail:    true,
15291			expectedError: ":WRONG_VERSION_NUMBER:",
15292		})
15293	}
15294}
15295
15296func addCertificateTests() {
15297	for _, ver := range tlsVersions {
15298		// Test that a certificate chain with intermediate may be sent
15299		// and received as both client and server.
15300		testCases = append(testCases, testCase{
15301			testType: clientTest,
15302			name:     "SendReceiveIntermediate-Client-" + ver.name,
15303			config: Config{
15304				MinVersion:   ver.version,
15305				MaxVersion:   ver.version,
15306				Certificates: []Certificate{rsaChainCertificate},
15307				ClientAuth:   RequireAnyClientCert,
15308			},
15309			expectations: connectionExpectations{
15310				peerCertificate: &rsaChainCertificate,
15311			},
15312			flags: []string{
15313				"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
15314				"-key-file", path.Join(*resourceDir, rsaChainKeyFile),
15315				"-expect-peer-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
15316			},
15317		})
15318
15319		testCases = append(testCases, testCase{
15320			testType: serverTest,
15321			name:     "SendReceiveIntermediate-Server-" + ver.name,
15322			config: Config{
15323				MinVersion:   ver.version,
15324				MaxVersion:   ver.version,
15325				Certificates: []Certificate{rsaChainCertificate},
15326			},
15327			expectations: connectionExpectations{
15328				peerCertificate: &rsaChainCertificate,
15329			},
15330			flags: []string{
15331				"-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
15332				"-key-file", path.Join(*resourceDir, rsaChainKeyFile),
15333				"-require-any-client-certificate",
15334				"-expect-peer-cert-file", path.Join(*resourceDir, rsaChainCertificateFile),
15335			},
15336		})
15337
15338		// Test that garbage leaf certificates are properly rejected.
15339		testCases = append(testCases, testCase{
15340			testType: clientTest,
15341			name:     "GarbageCertificate-Client-" + ver.name,
15342			config: Config{
15343				MinVersion:   ver.version,
15344				MaxVersion:   ver.version,
15345				Certificates: []Certificate{garbageCertificate},
15346			},
15347			shouldFail:         true,
15348			expectedError:      ":CANNOT_PARSE_LEAF_CERT:",
15349			expectedLocalError: "remote error: error decoding message",
15350		})
15351
15352		testCases = append(testCases, testCase{
15353			testType: serverTest,
15354			name:     "GarbageCertificate-Server-" + ver.name,
15355			config: Config{
15356				MinVersion:   ver.version,
15357				MaxVersion:   ver.version,
15358				Certificates: []Certificate{garbageCertificate},
15359			},
15360			flags:              []string{"-require-any-client-certificate"},
15361			shouldFail:         true,
15362			expectedError:      ":CANNOT_PARSE_LEAF_CERT:",
15363			expectedLocalError: "remote error: error decoding message",
15364		})
15365	}
15366}
15367
15368func addRetainOnlySHA256ClientCertTests() {
15369	for _, ver := range tlsVersions {
15370		// Test that enabling
15371		// SSL_CTX_set_retain_only_sha256_of_client_certs without
15372		// actually requesting a client certificate is a no-op.
15373		testCases = append(testCases, testCase{
15374			testType: serverTest,
15375			name:     "RetainOnlySHA256-NoCert-" + ver.name,
15376			config: Config{
15377				MinVersion: ver.version,
15378				MaxVersion: ver.version,
15379			},
15380			flags: []string{
15381				"-on-initial-retain-only-sha256-client-cert",
15382				"-on-resume-retain-only-sha256-client-cert",
15383			},
15384			resumeSession: true,
15385		})
15386
15387		// Test that when retaining only a SHA-256 certificate is
15388		// enabled, the hash appears as expected.
15389		testCases = append(testCases, testCase{
15390			testType: serverTest,
15391			name:     "RetainOnlySHA256-Cert-" + ver.name,
15392			config: Config{
15393				MinVersion:   ver.version,
15394				MaxVersion:   ver.version,
15395				Certificates: []Certificate{rsaCertificate},
15396			},
15397			flags: []string{
15398				"-verify-peer",
15399				"-on-initial-retain-only-sha256-client-cert",
15400				"-on-resume-retain-only-sha256-client-cert",
15401				"-on-initial-expect-sha256-client-cert",
15402				"-on-resume-expect-sha256-client-cert",
15403			},
15404			resumeSession: true,
15405		})
15406
15407		// Test that when the config changes from on to off, a
15408		// resumption is rejected because the server now wants the full
15409		// certificate chain.
15410		testCases = append(testCases, testCase{
15411			testType: serverTest,
15412			name:     "RetainOnlySHA256-OnOff-" + ver.name,
15413			config: Config{
15414				MinVersion:   ver.version,
15415				MaxVersion:   ver.version,
15416				Certificates: []Certificate{rsaCertificate},
15417			},
15418			flags: []string{
15419				"-verify-peer",
15420				"-on-initial-retain-only-sha256-client-cert",
15421				"-on-initial-expect-sha256-client-cert",
15422			},
15423			resumeSession:        true,
15424			expectResumeRejected: true,
15425		})
15426
15427		// Test that when the config changes from off to on, a
15428		// resumption is rejected because the server now wants just the
15429		// hash.
15430		testCases = append(testCases, testCase{
15431			testType: serverTest,
15432			name:     "RetainOnlySHA256-OffOn-" + ver.name,
15433			config: Config{
15434				MinVersion:   ver.version,
15435				MaxVersion:   ver.version,
15436				Certificates: []Certificate{rsaCertificate},
15437			},
15438			flags: []string{
15439				"-verify-peer",
15440				"-on-resume-retain-only-sha256-client-cert",
15441				"-on-resume-expect-sha256-client-cert",
15442			},
15443			resumeSession:        true,
15444			expectResumeRejected: true,
15445		})
15446	}
15447}
15448
15449func addECDSAKeyUsageTests() {
15450	p256 := elliptic.P256()
15451	priv, err := ecdsa.GenerateKey(p256, rand.Reader)
15452	if err != nil {
15453		panic(err)
15454	}
15455
15456	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
15457	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
15458	if err != nil {
15459		panic(err)
15460	}
15461
15462	template := x509.Certificate{
15463		SerialNumber: serialNumber,
15464		Subject: pkix.Name{
15465			Organization: []string{"Acme Co"},
15466		},
15467		NotBefore: time.Now(),
15468		NotAfter:  time.Now(),
15469
15470		// An ECC certificate with only the keyAgreement key usgae may
15471		// be used with ECDH, but not ECDSA.
15472		KeyUsage:              x509.KeyUsageKeyAgreement,
15473		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
15474		BasicConstraintsValid: true,
15475	}
15476
15477	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
15478	if err != nil {
15479		panic(err)
15480	}
15481
15482	cert := Certificate{
15483		Certificate: [][]byte{derBytes},
15484		PrivateKey:  priv,
15485	}
15486
15487	for _, ver := range tlsVersions {
15488		if ver.version < VersionTLS12 {
15489			continue
15490		}
15491
15492		testCases = append(testCases, testCase{
15493			testType: clientTest,
15494			name:     "ECDSAKeyUsage-Client-" + ver.name,
15495			config: Config{
15496				MinVersion:   ver.version,
15497				MaxVersion:   ver.version,
15498				Certificates: []Certificate{cert},
15499			},
15500			shouldFail:    true,
15501			expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15502		})
15503
15504		testCases = append(testCases, testCase{
15505			testType: serverTest,
15506			name:     "ECDSAKeyUsage-Server-" + ver.name,
15507			config: Config{
15508				MinVersion:   ver.version,
15509				MaxVersion:   ver.version,
15510				Certificates: []Certificate{cert},
15511			},
15512			flags:         []string{"-require-any-client-certificate"},
15513			shouldFail:    true,
15514			expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15515		})
15516	}
15517}
15518
15519func addRSAKeyUsageTests() {
15520	priv := rsaCertificate.PrivateKey.(*rsa.PrivateKey)
15521
15522	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
15523	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
15524	if err != nil {
15525		panic(err)
15526	}
15527
15528	dsTemplate := x509.Certificate{
15529		SerialNumber: serialNumber,
15530		Subject: pkix.Name{
15531			Organization: []string{"Acme Co"},
15532		},
15533		NotBefore: time.Now(),
15534		NotAfter:  time.Now(),
15535
15536		KeyUsage:              x509.KeyUsageDigitalSignature,
15537		BasicConstraintsValid: true,
15538	}
15539
15540	encTemplate := x509.Certificate{
15541		SerialNumber: serialNumber,
15542		Subject: pkix.Name{
15543			Organization: []string{"Acme Co"},
15544		},
15545		NotBefore: time.Now(),
15546		NotAfter:  time.Now(),
15547
15548		KeyUsage:              x509.KeyUsageKeyEncipherment,
15549		BasicConstraintsValid: true,
15550	}
15551
15552	dsDerBytes, err := x509.CreateCertificate(rand.Reader, &dsTemplate, &dsTemplate, &priv.PublicKey, priv)
15553	if err != nil {
15554		panic(err)
15555	}
15556
15557	encDerBytes, err := x509.CreateCertificate(rand.Reader, &encTemplate, &encTemplate, &priv.PublicKey, priv)
15558	if err != nil {
15559		panic(err)
15560	}
15561
15562	dsCert := Certificate{
15563		Certificate: [][]byte{dsDerBytes},
15564		PrivateKey:  priv,
15565	}
15566
15567	encCert := Certificate{
15568		Certificate: [][]byte{encDerBytes},
15569		PrivateKey:  priv,
15570	}
15571
15572	dsSuites := []uint16{
15573		TLS_AES_128_GCM_SHA256,
15574		TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
15575		TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
15576	}
15577	encSuites := []uint16{
15578		TLS_RSA_WITH_AES_128_GCM_SHA256,
15579		TLS_RSA_WITH_AES_128_CBC_SHA,
15580	}
15581
15582	for _, ver := range tlsVersions {
15583		testCases = append(testCases, testCase{
15584			testType: clientTest,
15585			name:     "RSAKeyUsage-Client-WantSignature-GotEncipherment-" + ver.name,
15586			config: Config{
15587				MinVersion:   ver.version,
15588				MaxVersion:   ver.version,
15589				Certificates: []Certificate{encCert},
15590				CipherSuites: dsSuites,
15591			},
15592			shouldFail:    true,
15593			expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15594			flags: []string{
15595				"-enforce-rsa-key-usage",
15596			},
15597		})
15598
15599		testCases = append(testCases, testCase{
15600			testType: clientTest,
15601			name:     "RSAKeyUsage-Client-WantSignature-GotSignature-" + ver.name,
15602			config: Config{
15603				MinVersion:   ver.version,
15604				MaxVersion:   ver.version,
15605				Certificates: []Certificate{dsCert},
15606				CipherSuites: dsSuites,
15607			},
15608			flags: []string{
15609				"-enforce-rsa-key-usage",
15610			},
15611		})
15612
15613		// TLS 1.3 removes the encipherment suites.
15614		if ver.version < VersionTLS13 {
15615			testCases = append(testCases, testCase{
15616				testType: clientTest,
15617				name:     "RSAKeyUsage-Client-WantEncipherment-GotEncipherment" + ver.name,
15618				config: Config{
15619					MinVersion:   ver.version,
15620					MaxVersion:   ver.version,
15621					Certificates: []Certificate{encCert},
15622					CipherSuites: encSuites,
15623				},
15624				flags: []string{
15625					"-enforce-rsa-key-usage",
15626				},
15627			})
15628
15629			testCases = append(testCases, testCase{
15630				testType: clientTest,
15631				name:     "RSAKeyUsage-Client-WantEncipherment-GotSignature-" + ver.name,
15632				config: Config{
15633					MinVersion:   ver.version,
15634					MaxVersion:   ver.version,
15635					Certificates: []Certificate{dsCert},
15636					CipherSuites: encSuites,
15637				},
15638				shouldFail:    true,
15639				expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15640				flags: []string{
15641					"-enforce-rsa-key-usage",
15642				},
15643			})
15644
15645			// In 1.2 and below, we should not enforce without the enforce-rsa-key-usage flag.
15646			testCases = append(testCases, testCase{
15647				testType: clientTest,
15648				name:     "RSAKeyUsage-Client-WantSignature-GotEncipherment-Unenforced" + ver.name,
15649				config: Config{
15650					MinVersion:   ver.version,
15651					MaxVersion:   ver.version,
15652					Certificates: []Certificate{dsCert},
15653					CipherSuites: encSuites,
15654				},
15655			})
15656
15657			testCases = append(testCases, testCase{
15658				testType: clientTest,
15659				name:     "RSAKeyUsage-Client-WantEncipherment-GotSignature-Unenforced" + ver.name,
15660				config: Config{
15661					MinVersion:   ver.version,
15662					MaxVersion:   ver.version,
15663					Certificates: []Certificate{encCert},
15664					CipherSuites: dsSuites,
15665				},
15666			})
15667		}
15668
15669		if ver.version >= VersionTLS13 {
15670			// In 1.3 and above, we enforce keyUsage even without the flag.
15671			testCases = append(testCases, testCase{
15672				testType: clientTest,
15673				name:     "RSAKeyUsage-Client-WantSignature-GotEncipherment-Enforced" + ver.name,
15674				config: Config{
15675					MinVersion:   ver.version,
15676					MaxVersion:   ver.version,
15677					Certificates: []Certificate{encCert},
15678					CipherSuites: dsSuites,
15679				},
15680				shouldFail:    true,
15681				expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15682			})
15683		}
15684
15685		// The server only uses signatures and always enforces it.
15686		testCases = append(testCases, testCase{
15687			testType: serverTest,
15688			name:     "RSAKeyUsage-Server-WantSignature-GotEncipherment-" + ver.name,
15689			config: Config{
15690				MinVersion:   ver.version,
15691				MaxVersion:   ver.version,
15692				Certificates: []Certificate{encCert},
15693			},
15694			shouldFail:    true,
15695			expectedError: ":KEY_USAGE_BIT_INCORRECT:",
15696			flags:         []string{"-require-any-client-certificate"},
15697		})
15698
15699		testCases = append(testCases, testCase{
15700			testType: serverTest,
15701			name:     "RSAKeyUsage-Server-WantSignature-GotSignature-" + ver.name,
15702			config: Config{
15703				MinVersion:   ver.version,
15704				MaxVersion:   ver.version,
15705				Certificates: []Certificate{dsCert},
15706			},
15707			flags: []string{"-require-any-client-certificate"},
15708		})
15709
15710	}
15711}
15712
15713func addExtraHandshakeTests() {
15714	// An extra SSL_do_handshake is normally a no-op. These tests use -async
15715	// to ensure there is no transport I/O.
15716	testCases = append(testCases, testCase{
15717		testType: clientTest,
15718		name:     "ExtraHandshake-Client-TLS12",
15719		config: Config{
15720			MinVersion: VersionTLS12,
15721			MaxVersion: VersionTLS12,
15722		},
15723		flags: []string{
15724			"-async",
15725			"-no-op-extra-handshake",
15726		},
15727	})
15728	testCases = append(testCases, testCase{
15729		testType: serverTest,
15730		name:     "ExtraHandshake-Server-TLS12",
15731		config: Config{
15732			MinVersion: VersionTLS12,
15733			MaxVersion: VersionTLS12,
15734		},
15735		flags: []string{
15736			"-async",
15737			"-no-op-extra-handshake",
15738		},
15739	})
15740	testCases = append(testCases, testCase{
15741		testType: clientTest,
15742		name:     "ExtraHandshake-Client-TLS13",
15743		config: Config{
15744			MinVersion: VersionTLS13,
15745			MaxVersion: VersionTLS13,
15746		},
15747		flags: []string{
15748			"-async",
15749			"-no-op-extra-handshake",
15750		},
15751	})
15752	testCases = append(testCases, testCase{
15753		testType: serverTest,
15754		name:     "ExtraHandshake-Server-TLS13",
15755		config: Config{
15756			MinVersion: VersionTLS13,
15757			MaxVersion: VersionTLS13,
15758		},
15759		flags: []string{
15760			"-async",
15761			"-no-op-extra-handshake",
15762		},
15763	})
15764
15765	// An extra SSL_do_handshake is a no-op in server 0-RTT.
15766	testCases = append(testCases, testCase{
15767		testType: serverTest,
15768		name:     "ExtraHandshake-Server-EarlyData-TLS13",
15769		config: Config{
15770			MaxVersion: VersionTLS13,
15771			MinVersion: VersionTLS13,
15772		},
15773		messageCount:  2,
15774		resumeSession: true,
15775		earlyData:     true,
15776		flags: []string{
15777			"-async",
15778			"-no-op-extra-handshake",
15779		},
15780	})
15781
15782	// An extra SSL_do_handshake drives the handshake to completion in False
15783	// Start. We test this by handshaking twice and asserting the False
15784	// Start does not appear to happen. See AlertBeforeFalseStartTest for
15785	// how the test works.
15786	testCases = append(testCases, testCase{
15787		testType: clientTest,
15788		name:     "ExtraHandshake-FalseStart",
15789		config: Config{
15790			MaxVersion:   VersionTLS12,
15791			CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
15792			NextProtos:   []string{"foo"},
15793			Bugs: ProtocolBugs{
15794				ExpectFalseStart:          true,
15795				AlertBeforeFalseStartTest: alertAccessDenied,
15796			},
15797		},
15798		flags: []string{
15799			"-handshake-twice",
15800			"-false-start",
15801			"-advertise-alpn", "\x03foo",
15802			"-expect-alpn", "foo",
15803		},
15804		shimWritesFirst:    true,
15805		shouldFail:         true,
15806		expectedError:      ":TLSV1_ALERT_ACCESS_DENIED:",
15807		expectedLocalError: "tls: peer did not false start: EOF",
15808	})
15809}
15810
15811// Test that omitted and empty extensions blocks are tolerated.
15812func addOmitExtensionsTests() {
15813	// Check the ExpectOmitExtensions setting works.
15814	testCases = append(testCases, testCase{
15815		testType: serverTest,
15816		name:     "ExpectOmitExtensions",
15817		config: Config{
15818			MinVersion: VersionTLS12,
15819			MaxVersion: VersionTLS12,
15820			Bugs: ProtocolBugs{
15821				ExpectOmitExtensions: true,
15822			},
15823		},
15824		shouldFail:         true,
15825		expectedLocalError: "tls: ServerHello did not omit extensions",
15826	})
15827
15828	for _, ver := range tlsVersions {
15829		if ver.version > VersionTLS12 {
15830			continue
15831		}
15832
15833		testCases = append(testCases, testCase{
15834			testType: serverTest,
15835			name:     "OmitExtensions-ClientHello-" + ver.name,
15836			config: Config{
15837				MinVersion:             ver.version,
15838				MaxVersion:             ver.version,
15839				SessionTicketsDisabled: true,
15840				Bugs: ProtocolBugs{
15841					OmitExtensions: true,
15842					// With no client extensions, the ServerHello must not have
15843					// extensions. It should then omit the extensions field.
15844					ExpectOmitExtensions: true,
15845				},
15846			},
15847		})
15848
15849		testCases = append(testCases, testCase{
15850			testType: serverTest,
15851			name:     "EmptyExtensions-ClientHello-" + ver.name,
15852			config: Config{
15853				MinVersion:             ver.version,
15854				MaxVersion:             ver.version,
15855				SessionTicketsDisabled: true,
15856				Bugs: ProtocolBugs{
15857					EmptyExtensions: true,
15858					// With no client extensions, the ServerHello must not have
15859					// extensions. It should then omit the extensions field.
15860					ExpectOmitExtensions: true,
15861				},
15862			},
15863		})
15864
15865		testCases = append(testCases, testCase{
15866			testType: clientTest,
15867			name:     "OmitExtensions-ServerHello-" + ver.name,
15868			config: Config{
15869				MinVersion:             ver.version,
15870				MaxVersion:             ver.version,
15871				SessionTicketsDisabled: true,
15872				Bugs: ProtocolBugs{
15873					OmitExtensions: true,
15874					// Disable all ServerHello extensions so
15875					// OmitExtensions works.
15876					NoExtendedMasterSecret:        true,
15877					NoRenegotiationInfo:           true,
15878					NoOCSPStapling:                true,
15879					NoSignedCertificateTimestamps: true,
15880				},
15881			},
15882		})
15883
15884		testCases = append(testCases, testCase{
15885			testType: clientTest,
15886			name:     "EmptyExtensions-ServerHello-" + ver.name,
15887			config: Config{
15888				MinVersion:             ver.version,
15889				MaxVersion:             ver.version,
15890				SessionTicketsDisabled: true,
15891				Bugs: ProtocolBugs{
15892					EmptyExtensions: true,
15893					// Disable all ServerHello extensions so
15894					// EmptyExtensions works.
15895					NoExtendedMasterSecret:        true,
15896					NoRenegotiationInfo:           true,
15897					NoOCSPStapling:                true,
15898					NoSignedCertificateTimestamps: true,
15899				},
15900			},
15901		})
15902	}
15903}
15904
15905func addCertCompressionTests() {
15906	// shrinkingPrefix is the first two bytes of a Certificate message.
15907	shrinkingPrefix := []byte{0, 0}
15908	// expandingPrefix is just some arbitrary byte string. This has to match the
15909	// value in the shim.
15910	expandingPrefix := []byte{1, 2, 3, 4}
15911
15912	shrinking := CertCompressionAlg{
15913		Compress: func(uncompressed []byte) []byte {
15914			if !bytes.HasPrefix(uncompressed, shrinkingPrefix) {
15915				panic(fmt.Sprintf("cannot compress certificate message %x", uncompressed))
15916			}
15917			return uncompressed[len(shrinkingPrefix):]
15918		},
15919		Decompress: func(out []byte, compressed []byte) bool {
15920			if len(out) != len(shrinkingPrefix)+len(compressed) {
15921				return false
15922			}
15923
15924			copy(out, shrinkingPrefix)
15925			copy(out[len(shrinkingPrefix):], compressed)
15926			return true
15927		},
15928	}
15929
15930	expanding := CertCompressionAlg{
15931		Compress: func(uncompressed []byte) []byte {
15932			ret := make([]byte, 0, len(expandingPrefix)+len(uncompressed))
15933			ret = append(ret, expandingPrefix...)
15934			return append(ret, uncompressed...)
15935		},
15936		Decompress: func(out []byte, compressed []byte) bool {
15937			if !bytes.HasPrefix(compressed, expandingPrefix) {
15938				return false
15939			}
15940			copy(out, compressed[len(expandingPrefix):])
15941			return true
15942		},
15943	}
15944
15945	const (
15946		shrinkingAlgID = 0xff01
15947		expandingAlgID = 0xff02
15948	)
15949
15950	for _, ver := range tlsVersions {
15951		if ver.version < VersionTLS12 {
15952			continue
15953		}
15954
15955		// Duplicate compression algorithms is an error, even if nothing is
15956		// configured.
15957		testCases = append(testCases, testCase{
15958			testType: serverTest,
15959			name:     "DuplicateCertCompressionExt-" + ver.name,
15960			config: Config{
15961				MinVersion: ver.version,
15962				MaxVersion: ver.version,
15963				Bugs: ProtocolBugs{
15964					DuplicateCompressedCertAlgs: true,
15965				},
15966			},
15967			shouldFail:    true,
15968			expectedError: ":ERROR_PARSING_EXTENSION:",
15969		})
15970
15971		// With compression algorithms configured, an duplicate values should still
15972		// be an error.
15973		testCases = append(testCases, testCase{
15974			testType: serverTest,
15975			name:     "DuplicateCertCompressionExt2-" + ver.name,
15976			flags:    []string{"-install-cert-compression-algs"},
15977			config: Config{
15978				MinVersion: ver.version,
15979				MaxVersion: ver.version,
15980				Bugs: ProtocolBugs{
15981					DuplicateCompressedCertAlgs: true,
15982				},
15983			},
15984			shouldFail:    true,
15985			expectedError: ":ERROR_PARSING_EXTENSION:",
15986		})
15987
15988		if ver.version < VersionTLS13 {
15989			testCases = append(testCases, testCase{
15990				testType: serverTest,
15991				name:     "CertCompressionIgnoredBefore13-" + ver.name,
15992				flags:    []string{"-install-cert-compression-algs"},
15993				config: Config{
15994					MinVersion:          ver.version,
15995					MaxVersion:          ver.version,
15996					CertCompressionAlgs: map[uint16]CertCompressionAlg{expandingAlgID: expanding},
15997				},
15998			})
15999
16000			continue
16001		}
16002
16003		testCases = append(testCases, testCase{
16004			testType: serverTest,
16005			name:     "CertCompressionExpands-" + ver.name,
16006			flags:    []string{"-install-cert-compression-algs"},
16007			config: Config{
16008				MinVersion:          ver.version,
16009				MaxVersion:          ver.version,
16010				CertCompressionAlgs: map[uint16]CertCompressionAlg{expandingAlgID: expanding},
16011				Bugs: ProtocolBugs{
16012					ExpectedCompressedCert: expandingAlgID,
16013				},
16014			},
16015		})
16016
16017		testCases = append(testCases, testCase{
16018			testType: serverTest,
16019			name:     "CertCompressionShrinks-" + ver.name,
16020			flags:    []string{"-install-cert-compression-algs"},
16021			config: Config{
16022				MinVersion:          ver.version,
16023				MaxVersion:          ver.version,
16024				CertCompressionAlgs: map[uint16]CertCompressionAlg{shrinkingAlgID: shrinking},
16025				Bugs: ProtocolBugs{
16026					ExpectedCompressedCert: shrinkingAlgID,
16027				},
16028			},
16029		})
16030
16031		// With both algorithms configured, the server should pick its most
16032		// preferable. (Which is expandingAlgID.)
16033		testCases = append(testCases, testCase{
16034			testType: serverTest,
16035			name:     "CertCompressionPriority-" + ver.name,
16036			flags:    []string{"-install-cert-compression-algs"},
16037			config: Config{
16038				MinVersion: ver.version,
16039				MaxVersion: ver.version,
16040				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16041					shrinkingAlgID: shrinking,
16042					expandingAlgID: expanding,
16043				},
16044				Bugs: ProtocolBugs{
16045					ExpectedCompressedCert: expandingAlgID,
16046				},
16047			},
16048		})
16049
16050		testCases = append(testCases, testCase{
16051			testType: clientTest,
16052			name:     "CertCompressionExpandsClient-" + ver.name,
16053			flags:    []string{"-install-cert-compression-algs"},
16054			config: Config{
16055				MinVersion: ver.version,
16056				MaxVersion: ver.version,
16057				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16058					expandingAlgID: expanding,
16059				},
16060				Bugs: ProtocolBugs{
16061					ExpectedCompressedCert: expandingAlgID,
16062				},
16063			},
16064		})
16065
16066		testCases = append(testCases, testCase{
16067			testType: clientTest,
16068			name:     "CertCompressionShrinksClient-" + ver.name,
16069			flags:    []string{"-install-cert-compression-algs"},
16070			config: Config{
16071				MinVersion: ver.version,
16072				MaxVersion: ver.version,
16073				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16074					shrinkingAlgID: shrinking,
16075				},
16076				Bugs: ProtocolBugs{
16077					ExpectedCompressedCert: shrinkingAlgID,
16078				},
16079			},
16080		})
16081
16082		testCases = append(testCases, testCase{
16083			testType: clientTest,
16084			name:     "CertCompressionBadAlgIDClient-" + ver.name,
16085			flags:    []string{"-install-cert-compression-algs"},
16086			config: Config{
16087				MinVersion: ver.version,
16088				MaxVersion: ver.version,
16089				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16090					shrinkingAlgID: shrinking,
16091				},
16092				Bugs: ProtocolBugs{
16093					ExpectedCompressedCert:   shrinkingAlgID,
16094					SendCertCompressionAlgID: 1234,
16095				},
16096			},
16097			shouldFail:    true,
16098			expectedError: ":UNKNOWN_CERT_COMPRESSION_ALG:",
16099		})
16100
16101		testCases = append(testCases, testCase{
16102			testType: clientTest,
16103			name:     "CertCompressionTooSmallClient-" + ver.name,
16104			flags:    []string{"-install-cert-compression-algs"},
16105			config: Config{
16106				MinVersion: ver.version,
16107				MaxVersion: ver.version,
16108				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16109					shrinkingAlgID: shrinking,
16110				},
16111				Bugs: ProtocolBugs{
16112					ExpectedCompressedCert:     shrinkingAlgID,
16113					SendCertUncompressedLength: 12,
16114				},
16115			},
16116			shouldFail:    true,
16117			expectedError: ":CERT_DECOMPRESSION_FAILED:",
16118		})
16119
16120		testCases = append(testCases, testCase{
16121			testType: clientTest,
16122			name:     "CertCompressionTooLargeClient-" + ver.name,
16123			flags:    []string{"-install-cert-compression-algs"},
16124			config: Config{
16125				MinVersion: ver.version,
16126				MaxVersion: ver.version,
16127				CertCompressionAlgs: map[uint16]CertCompressionAlg{
16128					shrinkingAlgID: shrinking,
16129				},
16130				Bugs: ProtocolBugs{
16131					ExpectedCompressedCert:     shrinkingAlgID,
16132					SendCertUncompressedLength: 1 << 20,
16133				},
16134			},
16135			shouldFail:    true,
16136			expectedError: ":UNCOMPRESSED_CERT_TOO_LARGE:",
16137		})
16138	}
16139}
16140
16141func addJDK11WorkaroundTests() {
16142	// Test the client treats the JDK 11 downgrade random like the usual one.
16143	testCases = append(testCases, testCase{
16144		testType: clientTest,
16145		name:     "Client-RejectJDK11DowngradeRandom",
16146		config: Config{
16147			MaxVersion: VersionTLS12,
16148			Bugs: ProtocolBugs{
16149				SendJDK11DowngradeRandom: true,
16150			},
16151		},
16152		shouldFail:         true,
16153		expectedError:      ":TLS13_DOWNGRADE:",
16154		expectedLocalError: "remote error: illegal parameter",
16155	})
16156	testCases = append(testCases, testCase{
16157		testType: clientTest,
16158		name:     "Client-AcceptJDK11DowngradeRandom",
16159		config: Config{
16160			MaxVersion: VersionTLS12,
16161			Bugs: ProtocolBugs{
16162				SendJDK11DowngradeRandom: true,
16163			},
16164		},
16165		flags: []string{"-max-version", strconv.Itoa(VersionTLS12)},
16166	})
16167
16168	var clientHelloTests = []struct {
16169		clientHello []byte
16170		isJDK11     bool
16171	}{
16172		{
16173			// A default JDK 11 ClientHello.
16174			decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"),
16175			true,
16176		},
16177		{
16178			// The above with supported_versions and
16179			// psk_key_exchange_modes in the wrong order.
16180			decodeHexOrPanic("010001a9030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002d00020101002b00090803040303030203010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b5"),
16181			false,
16182		},
16183		{
16184			// The above with a padding extension added at the end.
16185			decodeHexOrPanic("010001b4030336a379aa355a22a064b4402760efae1c73977b0b4c975efc7654c35677723dde201fe3f8a2bca60418a68f72463ea19f3c241e7cbfceb347e451a62bd2417d8981005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000111000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104721f007464cb08a0f36e093ad178eb78d6968df20077b2dd882694a85dc4c9884caf5092db41f16cc3f8d41f59426992fa5e32cfb9ad08deee752cdd95b1a6b50015000700000000000000"),
16186			false,
16187		},
16188		{
16189			// A JDK 11 ClientHello offering a TLS 1.3 PSK.
16190			decodeHexOrPanic("0100024c0303a8d71b20f060545a398226e807d21371a7a02b7ca2f96f476c2dea7e5860c5a400005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010001c9000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d000201010033004700450017004104aaec585ea9e121b24710a23560571322b2cf8ab8cd14e5762ef0486d8a6d0ecd721d8f2abda2eb8ed5ab7195505660450f49bba94bbf0c3f0070a531d9a1be4f002900cb00a600a0e6f7586d9a2bf64a54c1adf55a2f76657047e8e88e26629e2e7b9d630941e06fd87792770f6834e159a70b252157a9b4b082183f24629c8ff5049088b07ce37c49de8cf752a2ed7a545aff63bdc7a1b18e1bc201f23f159ee75d4987a04e00f840824f764691ab83a20e3032646e793065874cdb46138a52f50ed71406f399f96f9309eba4e5b1966148c22a63dc4aa1364269dd41dd5cc0e848d07af0095622c52cfcfc00212009cc315259e2328d65ad17a3de7c182c7874140a9356fecdd4614657806cd659"),
16191			true,
16192		},
16193		{
16194			// A JDK 11 ClientHello offering a TLS 1.2 session.
16195			decodeHexOrPanic("010001a903038cdec49f4836d064a75046c93f22d0b9c2cf4900917332e6f0e1f41d692d3146201a3e99047492285ec65ab4e0eeee59f8f9d1eb7687398887bcd7b81353e93923005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000106000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b0009080304030303020301002d0002010100330047004500170041041c83c42fcd8fc06265b9f6e4f076f7e7ee17ace915c587845c0e1bc8cd177f904befeb611b682cae4702509a5f5d0c7162a282b8152d843169b91136e7c6f3e7"),
16196			true,
16197		},
16198		{
16199			// A JDK 11 ClientHello with EMS disabled.
16200			decodeHexOrPanic("010001a50303323a857c324a9ef57d6e2544d129073830385cb1dc75ea79f6a2ec8ae09d2e7320f85fdd081678874c67ebab235e6d6a81d947f690bc0af9be4d39854ed67d9ef9005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000102000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200110009000702000400000000002b0009080304030303020301002d0002010100330047004500170041049c904c4850b495d75522f955d79e9cabea065c90279d6037a101a4c4ee712afc93ad0df5d12d287d53e458c7075d9a3ce3969c939bb62222bda779cecf54a603"),
16201			true,
16202		},
16203		{
16204			// A JDK 11 ClientHello with OCSP stapling disabled.
16205			decodeHexOrPanic("0100019303038a50481dc85ee4f6581670821c50f2b3d34ac3251dc6e9b751bfd2521ab47ab02069a963c5486034c37ae0577ddb4c2db28cab592380ef8e4599d1305148712112005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff010000f0000000080006000003736e69000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b040105010601040203030301030202030201020200170000002b0009080304030303020301002d00020101003300470045001700410438a97824f842c549e3c339322d8b2dbaa85d10bd7bca9c969376cb0c60b1e929eb4d13db38dcb0082ad8c637b24f55466a9acbb0b63634c1f431ec8342cf720d"),
16206			true,
16207		},
16208		{
16209			// A JDK 11 ClientHello configured with a smaller set of
16210			// ciphers.
16211			decodeHexOrPanic("0100015603036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"),
16212			true,
16213		},
16214		{
16215			// The above with TLS_CHACHA20_POLY1305_SHA256 added,
16216			// which JDK 11 does not support.
16217			decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f48118000813011303c02bc02f01000107000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"),
16218			false,
16219		},
16220		{
16221			// The above with X25519 added, which JDK 11 does not
16222			// support.
16223			decodeHexOrPanic("0100015803036f5706bbdf1dcae671cd9be043603f5ed20f8fc195b426504cafb4f353edb0012007aabd35e588bc2504a72eda42cbbf89d69cfc0a6a1d77db0d757606f1f4811800061301c02bc02f01000109000000080006000003736e69000500050100000000000a00220020001d0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020011000900070200040000000000170000002b00050403040303002d000201010033004700450017004104d283f3d5a90259b61d43ea1511211f568ce5d18457326b717e1f9d6b7d1476f2b51cdc3c798d3bdfba5095edff0ffd0540f6bc0c324bd9744f3b3f24317496e3ff01000100"),
16224			false,
16225		},
16226		{
16227			// A JDK 11 ClientHello with ALPN protocols configured.
16228			decodeHexOrPanic("010001bb0303c0e0ea707b00c5311eb09cabd58626692cebfaefaef7265637e4550811dae16220da86d6eea04e214e873675223f08a6926bcf79f16d866280bdbab85e9e09c3ff005a13011302c02cc02bc030009dc02ec032009f00a3c02f009cc02dc031009e00a2c024c028003dc026c02a006b006ac00ac0140035c005c00f00390038c023c027003cc025c02900670040c009c013002fc004c00e0033003200ff01000118000000080006000003736e69000500050100000000000a0020001e0017001800190009000a000b000c000d000e001601000101010201030104000b00020100000d002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020032002800260403050306030804080508060809080a080b04010501060104020303030103020203020102020010000e000c02683208687474702f312e310011000900070200040000000000170000002b0009080304030303020301002d00020101003300470045001700410416def07c1d66ddde5fc9dcc328c8e77022d321c590c0d30cb41d515b38dca34540819a216c6c053bd47b9068f4f6b960f03647de4e36e8b7ffeea78f7252e3d9"),
16229			true,
16230		},
16231	}
16232	for i, t := range clientHelloTests {
16233		expectedVersion := uint16(VersionTLS13)
16234		if t.isJDK11 {
16235			expectedVersion = VersionTLS12
16236		}
16237
16238		// In each of these tests, we set DefaultCurves to P-256 to
16239		// match the test inputs. SendClientHelloWithFixes requires the
16240		// key_shares extension to match in type.
16241
16242		// With the workaround enabled, we should negotiate TLS 1.2 on
16243		// JDK 11 ClientHellos.
16244		testCases = append(testCases, testCase{
16245			testType: serverTest,
16246			name:     fmt.Sprintf("Server-JDK11-%d", i),
16247			config: Config{
16248				MaxVersion:    VersionTLS13,
16249				DefaultCurves: []CurveID{CurveP256},
16250				Bugs: ProtocolBugs{
16251					SendClientHelloWithFixes:   t.clientHello,
16252					ExpectJDK11DowngradeRandom: t.isJDK11,
16253				},
16254			},
16255			expectations: connectionExpectations{
16256				version: expectedVersion,
16257			},
16258			flags: []string{"-jdk11-workaround"},
16259		})
16260
16261		// With the workaround disabled, we always negotiate TLS 1.3.
16262		testCases = append(testCases, testCase{
16263			testType: serverTest,
16264			name:     fmt.Sprintf("Server-JDK11-NoWorkaround-%d", i),
16265			config: Config{
16266				MaxVersion:    VersionTLS13,
16267				DefaultCurves: []CurveID{CurveP256},
16268				Bugs: ProtocolBugs{
16269					SendClientHelloWithFixes:   t.clientHello,
16270					ExpectJDK11DowngradeRandom: false,
16271				},
16272			},
16273			expectations: connectionExpectations{
16274				version: VersionTLS13,
16275			},
16276		})
16277
16278		// If the server does not support TLS 1.3, the workaround should
16279		// be a no-op. In particular, it should not send the downgrade
16280		// signal.
16281		testCases = append(testCases, testCase{
16282			testType: serverTest,
16283			name:     fmt.Sprintf("Server-JDK11-TLS12-%d", i),
16284			config: Config{
16285				MaxVersion:    VersionTLS13,
16286				DefaultCurves: []CurveID{CurveP256},
16287				Bugs: ProtocolBugs{
16288					SendClientHelloWithFixes:   t.clientHello,
16289					ExpectJDK11DowngradeRandom: false,
16290				},
16291			},
16292			expectations: connectionExpectations{
16293				version: VersionTLS12,
16294			},
16295			flags: []string{
16296				"-jdk11-workaround",
16297				"-max-version", strconv.Itoa(VersionTLS12),
16298			},
16299		})
16300	}
16301}
16302
16303func addDelegatedCredentialTests() {
16304	certPath := path.Join(*resourceDir, rsaCertificateFile)
16305	pemBytes, err := ioutil.ReadFile(certPath)
16306	if err != nil {
16307		panic(err)
16308	}
16309
16310	block, _ := pem.Decode(pemBytes)
16311	if block == nil {
16312		panic(fmt.Sprintf("no PEM block found in %q", certPath))
16313	}
16314	parentDER := block.Bytes
16315
16316	rsaPriv, _, err := loadRSAPrivateKey(rsaKeyFile)
16317	if err != nil {
16318		panic(err)
16319	}
16320
16321	ecdsaDC, ecdsaPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{
16322		algo: signatureRSAPSSWithSHA256,
16323	}, parentDER, rsaPriv)
16324	if err != nil {
16325		panic(err)
16326	}
16327	ecdsaFlagValue := fmt.Sprintf("%x,%x", ecdsaDC, ecdsaPKCS8)
16328
16329	testCases = append(testCases, testCase{
16330		testType: serverTest,
16331		name:     "DelegatedCredentials-NoClientSupport",
16332		config: Config{
16333			MinVersion: VersionTLS13,
16334			MaxVersion: VersionTLS13,
16335			Bugs: ProtocolBugs{
16336				DisableDelegatedCredentials: true,
16337			},
16338		},
16339		flags: []string{
16340			"-delegated-credential", ecdsaFlagValue,
16341		},
16342	})
16343
16344	testCases = append(testCases, testCase{
16345		testType: serverTest,
16346		name:     "DelegatedCredentials-Basic",
16347		config: Config{
16348			MinVersion: VersionTLS13,
16349			MaxVersion: VersionTLS13,
16350			Bugs: ProtocolBugs{
16351				ExpectDelegatedCredentials: true,
16352			},
16353		},
16354		flags: []string{
16355			"-delegated-credential", ecdsaFlagValue,
16356			"-expect-delegated-credential-used",
16357		},
16358	})
16359
16360	testCases = append(testCases, testCase{
16361		testType: serverTest,
16362		name:     "DelegatedCredentials-SigAlgoMissing",
16363		config: Config{
16364			MinVersion: VersionTLS13,
16365			MaxVersion: VersionTLS13,
16366			Bugs: ProtocolBugs{
16367				FailIfDelegatedCredentials: true,
16368			},
16369			// If the client doesn't support the delegated credential signature
16370			// algorithm then the handshake should complete without using delegated
16371			// credentials.
16372			VerifySignatureAlgorithms: []signatureAlgorithm{signatureRSAPSSWithSHA256},
16373		},
16374		flags: []string{
16375			"-delegated-credential", ecdsaFlagValue,
16376		},
16377	})
16378
16379	// This flag value has mismatched public and private keys which should cause a
16380	// configuration error in the shim.
16381	_, badTLSVersionPKCS8, err := createDelegatedCredential(delegatedCredentialConfig{
16382		algo:       signatureRSAPSSWithSHA256,
16383		tlsVersion: 0x1234,
16384	}, parentDER, rsaPriv)
16385	if err != nil {
16386		panic(err)
16387	}
16388	mismatchFlagValue := fmt.Sprintf("%x,%x", ecdsaDC, badTLSVersionPKCS8)
16389	testCases = append(testCases, testCase{
16390		testType: serverTest,
16391		name:     "DelegatedCredentials-KeyMismatch",
16392		config: Config{
16393			MinVersion: VersionTLS13,
16394			MaxVersion: VersionTLS13,
16395			Bugs: ProtocolBugs{
16396				FailIfDelegatedCredentials: true,
16397			},
16398		},
16399		flags: []string{
16400			"-delegated-credential", mismatchFlagValue,
16401		},
16402		shouldFail:    true,
16403		expectedError: ":KEY_VALUES_MISMATCH:",
16404	})
16405}
16406
16407func addEncryptedClientHelloTests() {
16408	// Test ECH GREASE.
16409
16410	// Test the client's behavior when the server ignores ECH GREASE.
16411	testCases = append(testCases, testCase{
16412		testType: clientTest,
16413		name:     "ECH-GREASE-Client-TLS13",
16414		config: Config{
16415			MinVersion: VersionTLS13,
16416			MaxVersion: VersionTLS13,
16417			Bugs: ProtocolBugs{
16418				ExpectClientECH: true,
16419			},
16420		},
16421		flags: []string{"-enable-ech-grease"},
16422	})
16423
16424	// Test the client's ECH GREASE behavior when responding to server's
16425	// HelloRetryRequest. This test implicitly checks that the first and second
16426	// ClientHello messages have identical ECH extensions.
16427	testCases = append(testCases, testCase{
16428		testType: clientTest,
16429		name:     "ECH-GREASE-Client-TLS13-HelloRetryRequest",
16430		config: Config{
16431			MaxVersion: VersionTLS13,
16432			MinVersion: VersionTLS13,
16433			// P-384 requires a HelloRetryRequest against BoringSSL's default
16434			// configuration. Assert this with ExpectMissingKeyShare.
16435			CurvePreferences: []CurveID{CurveP384},
16436			Bugs: ProtocolBugs{
16437				ExpectMissingKeyShare: true,
16438				ExpectClientECH:       true,
16439			},
16440		},
16441		flags: []string{"-enable-ech-grease", "-expect-hrr"},
16442	})
16443
16444	retryConfigValid := ECHConfig{
16445		PublicName: "example.com",
16446		// A real X25519 public key obtained from hpke.GenerateKeyPair().
16447		PublicKey: []byte{
16448			0x23, 0x1a, 0x96, 0x53, 0x52, 0x81, 0x1d, 0x7a,
16449			0x36, 0x76, 0xaa, 0x5e, 0xad, 0xdb, 0x66, 0x1c,
16450			0x92, 0x45, 0x8a, 0x60, 0xc7, 0x81, 0x93, 0xb0,
16451			0x47, 0x7b, 0x54, 0x18, 0x6b, 0x9a, 0x1d, 0x6d},
16452		KEM: hpke.X25519WithHKDFSHA256,
16453		CipherSuites: []HPKECipherSuite{
16454			{
16455				KDF:  hpke.HKDFSHA256,
16456				AEAD: hpke.AES256GCM,
16457			},
16458		},
16459		MaxNameLen: 42,
16460	}
16461
16462	retryConfigUnsupportedVersion := []byte{
16463		// version
16464		0xba, 0xdd,
16465		// length
16466		0x00, 0x05,
16467		// contents
16468		0x05, 0x04, 0x03, 0x02, 0x01,
16469	}
16470
16471	var validAndInvalidConfigs []byte
16472	validAndInvalidConfigs = append(validAndInvalidConfigs, MarshalECHConfig(&retryConfigValid)...)
16473	validAndInvalidConfigs = append(validAndInvalidConfigs, retryConfigUnsupportedVersion...)
16474
16475	// Test that the client accepts a well-formed encrypted_client_hello
16476	// extension in response to ECH GREASE. The response includes one ECHConfig
16477	// with a supported version and one with an unsupported version.
16478	testCases = append(testCases, testCase{
16479		testType: clientTest,
16480		name:     "ECH-GREASE-Client-TLS13-Retry-Configs",
16481		config: Config{
16482			MinVersion: VersionTLS13,
16483			MaxVersion: VersionTLS13,
16484			Bugs: ProtocolBugs{
16485				ExpectClientECH: true,
16486				// Include an additional well-formed ECHConfig with an invalid
16487				// version. This ensures the client can iterate over the retry
16488				// configs.
16489				SendECHRetryConfigs: validAndInvalidConfigs,
16490			},
16491		},
16492		flags: []string{"-enable-ech-grease"},
16493	})
16494
16495	// Test that the client aborts with a decode_error alert when it receives a
16496	// syntactically-invalid encrypted_client_hello extension from the server.
16497	testCases = append(testCases, testCase{
16498		testType: clientTest,
16499		name:     "ECH-GREASE-Client-TLS13-Invalid-Retry-Configs",
16500		config: Config{
16501			MinVersion: VersionTLS13,
16502			MaxVersion: VersionTLS13,
16503			Bugs: ProtocolBugs{
16504				ExpectClientECH:     true,
16505				SendECHRetryConfigs: []byte{0xba, 0xdd, 0xec, 0xcc},
16506			},
16507		},
16508		flags:              []string{"-enable-ech-grease"},
16509		shouldFail:         true,
16510		expectedLocalError: "remote error: error decoding message",
16511		expectedError:      ":ERROR_PARSING_EXTENSION:",
16512	})
16513
16514	// Test that the server responds to an empty ECH extension with the acceptance
16515	// confirmation.
16516	testCases = append(testCases, testCase{
16517		testType: serverTest,
16518		name:     "ECH-Server-ECHIsInner",
16519		config: Config{
16520			MinVersion: VersionTLS13,
16521			MaxVersion: VersionTLS13,
16522			Bugs: ProtocolBugs{
16523				SendECHIsInner:        []byte{},
16524				ExpectServerAcceptECH: true,
16525			},
16526		},
16527	})
16528
16529	// Test that server fails the handshake when it sees a nonempty ech_is_inner
16530	// extension.
16531	testCases = append(testCases, testCase{
16532		testType: serverTest,
16533		name:     "ECH-Server-ECHIsInner-NotEmpty",
16534		config: Config{
16535			MinVersion: VersionTLS13,
16536			MaxVersion: VersionTLS13,
16537			Bugs: ProtocolBugs{
16538				SendECHIsInner: []byte{42, 42, 42},
16539			},
16540		},
16541		shouldFail:         true,
16542		expectedLocalError: "remote error: illegal parameter",
16543		expectedError:      ":ERROR_PARSING_EXTENSION:",
16544	})
16545
16546	// When ech_is_inner extension is absent, the server should not accept ECH.
16547	testCases = append(testCases, testCase{
16548		testType: serverTest,
16549		name:     "ECH-Server-ECHIsInner-Absent",
16550		config: Config{
16551			MinVersion: VersionTLS13,
16552			MaxVersion: VersionTLS13,
16553			Bugs: ProtocolBugs{
16554				ExpectServerAcceptECH: false,
16555			},
16556		},
16557	})
16558
16559	// Test that a TLS 1.3 server that receives an ech_is_inner extension can
16560	// negotiate TLS 1.2 without clobbering the downgrade signal.
16561	testCases = append(testCases, testCase{
16562		testType: serverTest,
16563		name:     "ECH-Server-ECHIsInner-Absent-TLS12",
16564		config: Config{
16565			MinVersion: VersionTLS12,
16566			MaxVersion: VersionTLS13,
16567			Bugs: ProtocolBugs{
16568				// Omit supported_versions extension so the server negotiates
16569				// TLS 1.2.
16570				OmitSupportedVersions: true,
16571				SendECHIsInner:        []byte{},
16572			},
16573		},
16574		// Check that the client sees the TLS 1.3 downgrade signal in
16575		// ServerHello.random.
16576		shouldFail:         true,
16577		expectedLocalError: "tls: downgrade from TLS 1.3 detected",
16578	})
16579
16580	// Test that the handshake fails when the client sends both
16581	// encrypted_client_hello and ech_is_inner extensions.
16582	//
16583	// TODO(dmcardle) Replace this test once runner is capable of sending real
16584	// ECH extensions. The equivalent test will send ech_is_inner and a real
16585	// encrypted_client_hello extension derived from a key unknown to the
16586	// server.
16587	testCases = append(testCases, testCase{
16588		testType: serverTest,
16589		name:     "ECH-Server-EncryptedClientHello-ECHIsInner",
16590		config: Config{
16591			MinVersion: VersionTLS13,
16592			MaxVersion: VersionTLS13,
16593			Bugs: ProtocolBugs{
16594				SendECHIsInner:                      []byte{},
16595				SendPlaceholderEncryptedClientHello: true,
16596			},
16597		},
16598		shouldFail:         true,
16599		expectedLocalError: "remote error: illegal parameter",
16600		expectedError:      ":UNEXPECTED_EXTENSION:",
16601	})
16602}
16603
16604func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
16605	defer wg.Done()
16606
16607	for test := range c {
16608		var err error
16609
16610		if *mallocTest >= 0 {
16611			for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
16612				statusChan <- statusMsg{test: test, statusType: statusStarted}
16613				if err = runTest(statusChan, test, shimPath, mallocNumToFail); err != errMoreMallocs {
16614					if err != nil {
16615						fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err)
16616					}
16617					break
16618				}
16619			}
16620		} else if *repeatUntilFailure {
16621			for err == nil {
16622				statusChan <- statusMsg{test: test, statusType: statusStarted}
16623				err = runTest(statusChan, test, shimPath, -1)
16624			}
16625		} else {
16626			statusChan <- statusMsg{test: test, statusType: statusStarted}
16627			err = runTest(statusChan, test, shimPath, -1)
16628		}
16629		statusChan <- statusMsg{test: test, statusType: statusDone, err: err}
16630	}
16631}
16632
16633type statusType int
16634
16635const (
16636	statusStarted statusType = iota
16637	statusShimStarted
16638	statusDone
16639)
16640
16641type statusMsg struct {
16642	test       *testCase
16643	statusType statusType
16644	pid        int
16645	err        error
16646}
16647
16648func statusPrinter(doneChan chan *testresult.Results, statusChan chan statusMsg, total int) {
16649	var started, done, failed, unimplemented, lineLen int
16650
16651	testOutput := testresult.NewResults()
16652	for msg := range statusChan {
16653		if !*pipe {
16654			// Erase the previous status line.
16655			var erase string
16656			for i := 0; i < lineLen; i++ {
16657				erase += "\b \b"
16658			}
16659			fmt.Print(erase)
16660		}
16661
16662		if msg.statusType == statusStarted {
16663			started++
16664		} else if msg.statusType == statusDone {
16665			done++
16666
16667			if msg.err != nil {
16668				if msg.err == errUnimplemented {
16669					if *pipe {
16670						// Print each test instead of a status line.
16671						fmt.Printf("UNIMPLEMENTED (%s)\n", msg.test.name)
16672					}
16673					unimplemented++
16674					if *allowUnimplemented {
16675						testOutput.AddSkip(msg.test.name)
16676					} else {
16677						testOutput.AddResult(msg.test.name, "SKIP")
16678					}
16679				} else {
16680					fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err)
16681					failed++
16682					testOutput.AddResult(msg.test.name, "FAIL")
16683				}
16684			} else {
16685				if *pipe {
16686					// Print each test instead of a status line.
16687					fmt.Printf("PASSED (%s)\n", msg.test.name)
16688				}
16689				testOutput.AddResult(msg.test.name, "PASS")
16690			}
16691		}
16692
16693		if !*pipe {
16694			// Print a new status line.
16695			line := fmt.Sprintf("%d/%d/%d/%d/%d", failed, unimplemented, done, started, total)
16696			if msg.statusType == statusShimStarted && *waitForDebugger {
16697				// Note -wait-for-debugger limits the test to one worker,
16698				// otherwise some output would be skipped.
16699				line += fmt.Sprintf(" (%s: attach to process %d to continue)", msg.test.name, msg.pid)
16700			}
16701			lineLen = len(line)
16702			os.Stdout.WriteString(line)
16703		}
16704	}
16705
16706	doneChan <- testOutput
16707}
16708
16709func match(oneOfPatternIfAny []string, noneOfPattern []string, candidate string) (matched bool, err error) {
16710	matched = len(oneOfPatternIfAny) == 0
16711
16712	var didMatch bool
16713	for _, pattern := range oneOfPatternIfAny {
16714		didMatch, err = filepath.Match(pattern, candidate)
16715		if err != nil {
16716			return false, err
16717		}
16718
16719		matched = didMatch || matched
16720	}
16721
16722	for _, pattern := range noneOfPattern {
16723		didMatch, err = filepath.Match(pattern, candidate)
16724		if err != nil {
16725			return false, err
16726		}
16727
16728		matched = !didMatch && matched
16729	}
16730
16731	return matched, nil
16732}
16733
16734func main() {
16735	flag.Parse()
16736	*resourceDir = path.Clean(*resourceDir)
16737	initCertificates()
16738
16739	addBasicTests()
16740	addCipherSuiteTests()
16741	addBadECDSASignatureTests()
16742	addCBCPaddingTests()
16743	addCBCSplittingTests()
16744	addClientAuthTests()
16745	addDDoSCallbackTests()
16746	addVersionNegotiationTests()
16747	addMinimumVersionTests()
16748	addExtensionTests()
16749	addResumptionVersionTests()
16750	addExtendedMasterSecretTests()
16751	addRenegotiationTests()
16752	addDTLSReplayTests()
16753	addSignatureAlgorithmTests()
16754	addDTLSRetransmitTests()
16755	addExportKeyingMaterialTests()
16756	addExportTrafficSecretsTests()
16757	addTLSUniqueTests()
16758	addCustomExtensionTests()
16759	addRSAClientKeyExchangeTests()
16760	addCurveTests()
16761	addSessionTicketTests()
16762	addTLS13RecordTests()
16763	addAllStateMachineCoverageTests()
16764	addChangeCipherSpecTests()
16765	addEndOfFlightTests()
16766	addWrongMessageTypeTests()
16767	addTrailingMessageDataTests()
16768	addTLS13HandshakeTests()
16769	addTLS13CipherPreferenceTests()
16770	addPeekTests()
16771	addRecordVersionTests()
16772	addCertificateTests()
16773	addRetainOnlySHA256ClientCertTests()
16774	addECDSAKeyUsageTests()
16775	addRSAKeyUsageTests()
16776	addExtraHandshakeTests()
16777	addOmitExtensionsTests()
16778	addCertCompressionTests()
16779	addJDK11WorkaroundTests()
16780	addDelegatedCredentialTests()
16781	addEncryptedClientHelloTests()
16782
16783	testCases = append(testCases, convertToSplitHandshakeTests(testCases)...)
16784
16785	var wg sync.WaitGroup
16786
16787	numWorkers := *numWorkersFlag
16788	if useDebugger() {
16789		numWorkers = 1
16790	}
16791
16792	statusChan := make(chan statusMsg, numWorkers)
16793	testChan := make(chan *testCase, numWorkers)
16794	doneChan := make(chan *testresult.Results)
16795
16796	if len(*shimConfigFile) != 0 {
16797		encoded, err := ioutil.ReadFile(*shimConfigFile)
16798		if err != nil {
16799			fmt.Fprintf(os.Stderr, "Couldn't read config file %q: %s\n", *shimConfigFile, err)
16800			os.Exit(1)
16801		}
16802
16803		if err := json.Unmarshal(encoded, &shimConfig); err != nil {
16804			fmt.Fprintf(os.Stderr, "Couldn't decode config file %q: %s\n", *shimConfigFile, err)
16805			os.Exit(1)
16806		}
16807	}
16808
16809	go statusPrinter(doneChan, statusChan, len(testCases))
16810
16811	for i := 0; i < numWorkers; i++ {
16812		wg.Add(1)
16813		go worker(statusChan, testChan, *shimPath, &wg)
16814	}
16815
16816	var oneOfPatternIfAny, noneOfPattern []string
16817	if len(*testToRun) > 0 {
16818		oneOfPatternIfAny = strings.Split(*testToRun, ";")
16819	}
16820	if len(*skipTest) > 0 {
16821		noneOfPattern = strings.Split(*skipTest, ";")
16822	}
16823
16824	var foundTest bool
16825	for i := range testCases {
16826		matched, err := match(oneOfPatternIfAny, noneOfPattern, testCases[i].name)
16827		if err != nil {
16828			fmt.Fprintf(os.Stderr, "Error matching pattern: %s\n", err)
16829			os.Exit(1)
16830		}
16831
16832		if !*includeDisabled {
16833			for pattern := range shimConfig.DisabledTests {
16834				isDisabled, err := filepath.Match(pattern, testCases[i].name)
16835				if err != nil {
16836					fmt.Fprintf(os.Stderr, "Error matching pattern %q from config file: %s\n", pattern, err)
16837					os.Exit(1)
16838				}
16839
16840				if isDisabled {
16841					matched = false
16842					break
16843				}
16844			}
16845		}
16846
16847		if matched {
16848			foundTest = true
16849			testChan <- &testCases[i]
16850
16851			// Only run one test if repeating until failure.
16852			if *repeatUntilFailure {
16853				break
16854			}
16855		}
16856	}
16857
16858	if !foundTest {
16859		fmt.Fprintf(os.Stderr, "No tests run\n")
16860		os.Exit(1)
16861	}
16862
16863	close(testChan)
16864	wg.Wait()
16865	close(statusChan)
16866	testOutput := <-doneChan
16867
16868	fmt.Printf("\n")
16869
16870	if *jsonOutput != "" {
16871		if err := testOutput.WriteToFile(*jsonOutput); err != nil {
16872			fmt.Fprintf(os.Stderr, "Error: %s\n", err)
16873		}
16874	}
16875
16876	if !testOutput.HasUnexpectedResults() {
16877		os.Exit(1)
16878	}
16879}
16880