1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package tls
6
7import (
8	"bytes"
9	"context"
10	"errors"
11	"reflect"
12	"testing"
13)
14
15type testQUICConn struct {
16	t                 *testing.T
17	conn              *QUICConn
18	readSecret        map[QUICEncryptionLevel]suiteSecret
19	writeSecret       map[QUICEncryptionLevel]suiteSecret
20	ticketOpts        QUICSessionTicketOptions
21	onResumeSession   func(*SessionState)
22	gotParams         []byte
23	earlyDataRejected bool
24	complete          bool
25}
26
27func newTestQUICClient(t *testing.T, config *QUICConfig) *testQUICConn {
28	q := &testQUICConn{
29		t:    t,
30		conn: QUICClient(config),
31	}
32	t.Cleanup(func() {
33		q.conn.Close()
34	})
35	return q
36}
37
38func newTestQUICServer(t *testing.T, config *QUICConfig) *testQUICConn {
39	q := &testQUICConn{
40		t:    t,
41		conn: QUICServer(config),
42	}
43	t.Cleanup(func() {
44		q.conn.Close()
45	})
46	return q
47}
48
49type suiteSecret struct {
50	suite  uint16
51	secret []byte
52}
53
54func (q *testQUICConn) setReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
55	if _, ok := q.writeSecret[level]; !ok && level != QUICEncryptionLevelEarly {
56		q.t.Errorf("SetReadSecret for level %v called before SetWriteSecret", level)
57	}
58	if level == QUICEncryptionLevelApplication && !q.complete {
59		q.t.Errorf("SetReadSecret for level %v called before HandshakeComplete", level)
60	}
61	if _, ok := q.readSecret[level]; ok {
62		q.t.Errorf("SetReadSecret for level %v called twice", level)
63	}
64	if q.readSecret == nil {
65		q.readSecret = map[QUICEncryptionLevel]suiteSecret{}
66	}
67	switch level {
68	case QUICEncryptionLevelHandshake,
69		QUICEncryptionLevelEarly,
70		QUICEncryptionLevelApplication:
71		q.readSecret[level] = suiteSecret{suite, secret}
72	default:
73		q.t.Errorf("SetReadSecret for unexpected level %v", level)
74	}
75}
76
77func (q *testQUICConn) setWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
78	if _, ok := q.writeSecret[level]; ok {
79		q.t.Errorf("SetWriteSecret for level %v called twice", level)
80	}
81	if q.writeSecret == nil {
82		q.writeSecret = map[QUICEncryptionLevel]suiteSecret{}
83	}
84	switch level {
85	case QUICEncryptionLevelHandshake,
86		QUICEncryptionLevelEarly,
87		QUICEncryptionLevelApplication:
88		q.writeSecret[level] = suiteSecret{suite, secret}
89	default:
90		q.t.Errorf("SetWriteSecret for unexpected level %v", level)
91	}
92}
93
94var errTransportParametersRequired = errors.New("transport parameters required")
95
96func runTestQUICConnection(ctx context.Context, cli, srv *testQUICConn, onEvent func(e QUICEvent, src, dst *testQUICConn) bool) error {
97	a, b := cli, srv
98	for _, c := range []*testQUICConn{a, b} {
99		if !c.conn.conn.quic.started {
100			if err := c.conn.Start(ctx); err != nil {
101				return err
102			}
103		}
104	}
105	idleCount := 0
106	for {
107		e := a.conn.NextEvent()
108		if onEvent != nil && onEvent(e, a, b) {
109			continue
110		}
111		switch e.Kind {
112		case QUICNoEvent:
113			idleCount++
114			if idleCount == 2 {
115				if !a.complete || !b.complete {
116					return errors.New("handshake incomplete")
117				}
118				return nil
119			}
120			a, b = b, a
121		case QUICSetReadSecret:
122			a.setReadSecret(e.Level, e.Suite, e.Data)
123		case QUICSetWriteSecret:
124			a.setWriteSecret(e.Level, e.Suite, e.Data)
125		case QUICWriteData:
126			if err := b.conn.HandleData(e.Level, e.Data); err != nil {
127				return err
128			}
129		case QUICTransportParameters:
130			a.gotParams = e.Data
131			if a.gotParams == nil {
132				a.gotParams = []byte{}
133			}
134		case QUICTransportParametersRequired:
135			return errTransportParametersRequired
136		case QUICHandshakeDone:
137			a.complete = true
138			if a == srv {
139				if err := srv.conn.SendSessionTicket(srv.ticketOpts); err != nil {
140					return err
141				}
142			}
143		case QUICStoreSession:
144			if a != cli {
145				return errors.New("unexpected QUICStoreSession event received by server")
146			}
147			a.conn.StoreSession(e.SessionState)
148		case QUICResumeSession:
149			if a.onResumeSession != nil {
150				a.onResumeSession(e.SessionState)
151			}
152		case QUICRejectedEarlyData:
153			a.earlyDataRejected = true
154		}
155		if e.Kind != QUICNoEvent {
156			idleCount = 0
157		}
158	}
159}
160
161func TestQUICConnection(t *testing.T) {
162	config := &QUICConfig{TLSConfig: testConfig.Clone()}
163	config.TLSConfig.MinVersion = VersionTLS13
164
165	cli := newTestQUICClient(t, config)
166	cli.conn.SetTransportParameters(nil)
167
168	srv := newTestQUICServer(t, config)
169	srv.conn.SetTransportParameters(nil)
170
171	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
172		t.Fatalf("error during connection handshake: %v", err)
173	}
174
175	if _, ok := cli.readSecret[QUICEncryptionLevelHandshake]; !ok {
176		t.Errorf("client has no Handshake secret")
177	}
178	if _, ok := cli.readSecret[QUICEncryptionLevelApplication]; !ok {
179		t.Errorf("client has no Application secret")
180	}
181	if _, ok := srv.readSecret[QUICEncryptionLevelHandshake]; !ok {
182		t.Errorf("server has no Handshake secret")
183	}
184	if _, ok := srv.readSecret[QUICEncryptionLevelApplication]; !ok {
185		t.Errorf("server has no Application secret")
186	}
187	for _, level := range []QUICEncryptionLevel{QUICEncryptionLevelHandshake, QUICEncryptionLevelApplication} {
188		if _, ok := cli.readSecret[level]; !ok {
189			t.Errorf("client has no %v read secret", level)
190		}
191		if _, ok := srv.readSecret[level]; !ok {
192			t.Errorf("server has no %v read secret", level)
193		}
194		if !reflect.DeepEqual(cli.readSecret[level], srv.writeSecret[level]) {
195			t.Errorf("client read secret does not match server write secret for level %v", level)
196		}
197		if !reflect.DeepEqual(cli.writeSecret[level], srv.readSecret[level]) {
198			t.Errorf("client write secret does not match server read secret for level %v", level)
199		}
200	}
201}
202
203func TestQUICSessionResumption(t *testing.T) {
204	clientConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
205	clientConfig.TLSConfig.MinVersion = VersionTLS13
206	clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
207	clientConfig.TLSConfig.ServerName = "example.go.dev"
208
209	serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
210	serverConfig.TLSConfig.MinVersion = VersionTLS13
211
212	cli := newTestQUICClient(t, clientConfig)
213	cli.conn.SetTransportParameters(nil)
214	srv := newTestQUICServer(t, serverConfig)
215	srv.conn.SetTransportParameters(nil)
216	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
217		t.Fatalf("error during first connection handshake: %v", err)
218	}
219	if cli.conn.ConnectionState().DidResume {
220		t.Errorf("first connection unexpectedly used session resumption")
221	}
222
223	cli2 := newTestQUICClient(t, clientConfig)
224	cli2.conn.SetTransportParameters(nil)
225	srv2 := newTestQUICServer(t, serverConfig)
226	srv2.conn.SetTransportParameters(nil)
227	if err := runTestQUICConnection(context.Background(), cli2, srv2, nil); err != nil {
228		t.Fatalf("error during second connection handshake: %v", err)
229	}
230	if !cli2.conn.ConnectionState().DidResume {
231		t.Errorf("second connection did not use session resumption")
232	}
233}
234
235func TestQUICFragmentaryData(t *testing.T) {
236	clientConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
237	clientConfig.TLSConfig.MinVersion = VersionTLS13
238	clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
239	clientConfig.TLSConfig.ServerName = "example.go.dev"
240
241	serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
242	serverConfig.TLSConfig.MinVersion = VersionTLS13
243
244	cli := newTestQUICClient(t, clientConfig)
245	cli.conn.SetTransportParameters(nil)
246	srv := newTestQUICServer(t, serverConfig)
247	srv.conn.SetTransportParameters(nil)
248	onEvent := func(e QUICEvent, src, dst *testQUICConn) bool {
249		if e.Kind == QUICWriteData {
250			// Provide the data one byte at a time.
251			for i := range e.Data {
252				if err := dst.conn.HandleData(e.Level, e.Data[i:i+1]); err != nil {
253					t.Errorf("HandleData: %v", err)
254					break
255				}
256			}
257			return true
258		}
259		return false
260	}
261	if err := runTestQUICConnection(context.Background(), cli, srv, onEvent); err != nil {
262		t.Fatalf("error during first connection handshake: %v", err)
263	}
264}
265
266func TestQUICPostHandshakeClientAuthentication(t *testing.T) {
267	// RFC 9001, Section 4.4.
268	config := &QUICConfig{TLSConfig: testConfig.Clone()}
269	config.TLSConfig.MinVersion = VersionTLS13
270	cli := newTestQUICClient(t, config)
271	cli.conn.SetTransportParameters(nil)
272	srv := newTestQUICServer(t, config)
273	srv.conn.SetTransportParameters(nil)
274	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
275		t.Fatalf("error during connection handshake: %v", err)
276	}
277
278	certReq := new(certificateRequestMsgTLS13)
279	certReq.ocspStapling = true
280	certReq.scts = true
281	certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
282	certReqBytes, err := certReq.marshal()
283	if err != nil {
284		t.Fatal(err)
285	}
286	if err := cli.conn.HandleData(QUICEncryptionLevelApplication, append([]byte{
287		byte(typeCertificateRequest),
288		byte(0), byte(0), byte(len(certReqBytes)),
289	}, certReqBytes...)); err == nil {
290		t.Fatalf("post-handshake authentication request: got no error, want one")
291	}
292}
293
294func TestQUICPostHandshakeKeyUpdate(t *testing.T) {
295	// RFC 9001, Section 6.
296	config := &QUICConfig{TLSConfig: testConfig.Clone()}
297	config.TLSConfig.MinVersion = VersionTLS13
298	cli := newTestQUICClient(t, config)
299	cli.conn.SetTransportParameters(nil)
300	srv := newTestQUICServer(t, config)
301	srv.conn.SetTransportParameters(nil)
302	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
303		t.Fatalf("error during connection handshake: %v", err)
304	}
305
306	keyUpdate := new(keyUpdateMsg)
307	keyUpdateBytes, err := keyUpdate.marshal()
308	if err != nil {
309		t.Fatal(err)
310	}
311	if err := cli.conn.HandleData(QUICEncryptionLevelApplication, append([]byte{
312		byte(typeKeyUpdate),
313		byte(0), byte(0), byte(len(keyUpdateBytes)),
314	}, keyUpdateBytes...)); !errors.Is(err, alertUnexpectedMessage) {
315		t.Fatalf("key update request: got error %v, want alertUnexpectedMessage", err)
316	}
317}
318
319func TestQUICPostHandshakeMessageTooLarge(t *testing.T) {
320	config := &QUICConfig{TLSConfig: testConfig.Clone()}
321	config.TLSConfig.MinVersion = VersionTLS13
322	cli := newTestQUICClient(t, config)
323	cli.conn.SetTransportParameters(nil)
324	srv := newTestQUICServer(t, config)
325	srv.conn.SetTransportParameters(nil)
326	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
327		t.Fatalf("error during connection handshake: %v", err)
328	}
329
330	size := maxHandshake + 1
331	if err := cli.conn.HandleData(QUICEncryptionLevelApplication, []byte{
332		byte(typeNewSessionTicket),
333		byte(size >> 16),
334		byte(size >> 8),
335		byte(size),
336	}); err == nil {
337		t.Fatalf("%v-byte post-handshake message: got no error, want one", size)
338	}
339}
340
341func TestQUICHandshakeError(t *testing.T) {
342	clientConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
343	clientConfig.TLSConfig.MinVersion = VersionTLS13
344	clientConfig.TLSConfig.InsecureSkipVerify = false
345	clientConfig.TLSConfig.ServerName = "name"
346
347	serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
348	serverConfig.TLSConfig.MinVersion = VersionTLS13
349
350	cli := newTestQUICClient(t, clientConfig)
351	cli.conn.SetTransportParameters(nil)
352	srv := newTestQUICServer(t, serverConfig)
353	srv.conn.SetTransportParameters(nil)
354	err := runTestQUICConnection(context.Background(), cli, srv, nil)
355	if !errors.Is(err, AlertError(alertBadCertificate)) {
356		t.Errorf("connection handshake terminated with error %q, want alertBadCertificate", err)
357	}
358	var e *CertificateVerificationError
359	if !errors.As(err, &e) {
360		t.Errorf("connection handshake terminated with error %q, want CertificateVerificationError", err)
361	}
362}
363
364// Test that QUICConn.ConnectionState can be used during the handshake,
365// and that it reports the application protocol as soon as it has been
366// negotiated.
367func TestQUICConnectionState(t *testing.T) {
368	config := &QUICConfig{TLSConfig: testConfig.Clone()}
369	config.TLSConfig.MinVersion = VersionTLS13
370	config.TLSConfig.NextProtos = []string{"h3"}
371	cli := newTestQUICClient(t, config)
372	cli.conn.SetTransportParameters(nil)
373	srv := newTestQUICServer(t, config)
374	srv.conn.SetTransportParameters(nil)
375	onEvent := func(e QUICEvent, src, dst *testQUICConn) bool {
376		cliCS := cli.conn.ConnectionState()
377		if _, ok := cli.readSecret[QUICEncryptionLevelApplication]; ok {
378			if want, got := cliCS.NegotiatedProtocol, "h3"; want != got {
379				t.Errorf("cli.ConnectionState().NegotiatedProtocol = %q, want %q", want, got)
380			}
381		}
382		srvCS := srv.conn.ConnectionState()
383		if _, ok := srv.readSecret[QUICEncryptionLevelHandshake]; ok {
384			if want, got := srvCS.NegotiatedProtocol, "h3"; want != got {
385				t.Errorf("srv.ConnectionState().NegotiatedProtocol = %q, want %q", want, got)
386			}
387		}
388		return false
389	}
390	if err := runTestQUICConnection(context.Background(), cli, srv, onEvent); err != nil {
391		t.Fatalf("error during connection handshake: %v", err)
392	}
393}
394
395func TestQUICStartContextPropagation(t *testing.T) {
396	const key = "key"
397	const value = "value"
398	ctx := context.WithValue(context.Background(), key, value)
399	config := &QUICConfig{TLSConfig: testConfig.Clone()}
400	config.TLSConfig.MinVersion = VersionTLS13
401	calls := 0
402	config.TLSConfig.GetConfigForClient = func(info *ClientHelloInfo) (*Config, error) {
403		calls++
404		got, _ := info.Context().Value(key).(string)
405		if got != value {
406			t.Errorf("GetConfigForClient context key %q has value %q, want %q", key, got, value)
407		}
408		return nil, nil
409	}
410	cli := newTestQUICClient(t, config)
411	cli.conn.SetTransportParameters(nil)
412	srv := newTestQUICServer(t, config)
413	srv.conn.SetTransportParameters(nil)
414	if err := runTestQUICConnection(ctx, cli, srv, nil); err != nil {
415		t.Fatalf("error during connection handshake: %v", err)
416	}
417	if calls != 1 {
418		t.Errorf("GetConfigForClient called %v times, want 1", calls)
419	}
420}
421
422func TestQUICDelayedTransportParameters(t *testing.T) {
423	clientConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
424	clientConfig.TLSConfig.MinVersion = VersionTLS13
425	clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
426	clientConfig.TLSConfig.ServerName = "example.go.dev"
427
428	serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
429	serverConfig.TLSConfig.MinVersion = VersionTLS13
430
431	cliParams := "client params"
432	srvParams := "server params"
433
434	cli := newTestQUICClient(t, clientConfig)
435	srv := newTestQUICServer(t, serverConfig)
436	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != errTransportParametersRequired {
437		t.Fatalf("handshake with no client parameters: %v; want errTransportParametersRequired", err)
438	}
439	cli.conn.SetTransportParameters([]byte(cliParams))
440	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != errTransportParametersRequired {
441		t.Fatalf("handshake with no server parameters: %v; want errTransportParametersRequired", err)
442	}
443	srv.conn.SetTransportParameters([]byte(srvParams))
444	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
445		t.Fatalf("error during connection handshake: %v", err)
446	}
447
448	if got, want := string(cli.gotParams), srvParams; got != want {
449		t.Errorf("client got transport params: %q, want %q", got, want)
450	}
451	if got, want := string(srv.gotParams), cliParams; got != want {
452		t.Errorf("server got transport params: %q, want %q", got, want)
453	}
454}
455
456func TestQUICEmptyTransportParameters(t *testing.T) {
457	config := &QUICConfig{TLSConfig: testConfig.Clone()}
458	config.TLSConfig.MinVersion = VersionTLS13
459
460	cli := newTestQUICClient(t, config)
461	cli.conn.SetTransportParameters(nil)
462	srv := newTestQUICServer(t, config)
463	srv.conn.SetTransportParameters(nil)
464	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
465		t.Fatalf("error during connection handshake: %v", err)
466	}
467
468	if cli.gotParams == nil {
469		t.Errorf("client did not get transport params")
470	}
471	if srv.gotParams == nil {
472		t.Errorf("server did not get transport params")
473	}
474	if len(cli.gotParams) != 0 {
475		t.Errorf("client got transport params: %v, want empty", cli.gotParams)
476	}
477	if len(srv.gotParams) != 0 {
478		t.Errorf("server got transport params: %v, want empty", srv.gotParams)
479	}
480}
481
482func TestQUICCanceledWaitingForData(t *testing.T) {
483	config := &QUICConfig{TLSConfig: testConfig.Clone()}
484	config.TLSConfig.MinVersion = VersionTLS13
485	cli := newTestQUICClient(t, config)
486	cli.conn.SetTransportParameters(nil)
487	cli.conn.Start(context.Background())
488	for cli.conn.NextEvent().Kind != QUICNoEvent {
489	}
490	err := cli.conn.Close()
491	if !errors.Is(err, alertCloseNotify) {
492		t.Errorf("conn.Close() = %v, want alertCloseNotify", err)
493	}
494}
495
496func TestQUICCanceledWaitingForTransportParams(t *testing.T) {
497	config := &QUICConfig{TLSConfig: testConfig.Clone()}
498	config.TLSConfig.MinVersion = VersionTLS13
499	cli := newTestQUICClient(t, config)
500	cli.conn.Start(context.Background())
501	for cli.conn.NextEvent().Kind != QUICTransportParametersRequired {
502	}
503	err := cli.conn.Close()
504	if !errors.Is(err, alertCloseNotify) {
505		t.Errorf("conn.Close() = %v, want alertCloseNotify", err)
506	}
507}
508
509func TestQUICEarlyData(t *testing.T) {
510	clientConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
511	clientConfig.TLSConfig.MinVersion = VersionTLS13
512	clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
513	clientConfig.TLSConfig.ServerName = "example.go.dev"
514	clientConfig.TLSConfig.NextProtos = []string{"h3"}
515
516	serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
517	serverConfig.TLSConfig.MinVersion = VersionTLS13
518	serverConfig.TLSConfig.NextProtos = []string{"h3"}
519
520	cli := newTestQUICClient(t, clientConfig)
521	cli.conn.SetTransportParameters(nil)
522	srv := newTestQUICServer(t, serverConfig)
523	srv.conn.SetTransportParameters(nil)
524	srv.ticketOpts.EarlyData = true
525	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
526		t.Fatalf("error during first connection handshake: %v", err)
527	}
528	if cli.conn.ConnectionState().DidResume {
529		t.Errorf("first connection unexpectedly used session resumption")
530	}
531
532	cli2 := newTestQUICClient(t, clientConfig)
533	cli2.conn.SetTransportParameters(nil)
534	srv2 := newTestQUICServer(t, serverConfig)
535	srv2.conn.SetTransportParameters(nil)
536	onEvent := func(e QUICEvent, src, dst *testQUICConn) bool {
537		switch e.Kind {
538		case QUICStoreSession, QUICResumeSession:
539			t.Errorf("with EnableSessionEvents=false, got unexpected event %v", e.Kind)
540		}
541		return false
542	}
543	if err := runTestQUICConnection(context.Background(), cli2, srv2, onEvent); err != nil {
544		t.Fatalf("error during second connection handshake: %v", err)
545	}
546	if !cli2.conn.ConnectionState().DidResume {
547		t.Errorf("second connection did not use session resumption")
548	}
549	cliSecret := cli2.writeSecret[QUICEncryptionLevelEarly]
550	if cliSecret.secret == nil {
551		t.Errorf("client did not receive early data write secret")
552	}
553	srvSecret := srv2.readSecret[QUICEncryptionLevelEarly]
554	if srvSecret.secret == nil {
555		t.Errorf("server did not receive early data read secret")
556	}
557	if cliSecret.suite != srvSecret.suite || !bytes.Equal(cliSecret.secret, srvSecret.secret) {
558		t.Errorf("client early data secret does not match server")
559	}
560}
561
562func TestQUICEarlyDataDeclined(t *testing.T) {
563	t.Run("server", func(t *testing.T) {
564		testQUICEarlyDataDeclined(t, true)
565	})
566	t.Run("client", func(t *testing.T) {
567		testQUICEarlyDataDeclined(t, false)
568	})
569}
570
571func testQUICEarlyDataDeclined(t *testing.T, server bool) {
572	clientConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
573	clientConfig.EnableSessionEvents = true
574	clientConfig.TLSConfig.MinVersion = VersionTLS13
575	clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
576	clientConfig.TLSConfig.ServerName = "example.go.dev"
577	clientConfig.TLSConfig.NextProtos = []string{"h3"}
578
579	serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
580	serverConfig.EnableSessionEvents = true
581	serverConfig.TLSConfig.MinVersion = VersionTLS13
582	serverConfig.TLSConfig.NextProtos = []string{"h3"}
583
584	cli := newTestQUICClient(t, clientConfig)
585	cli.conn.SetTransportParameters(nil)
586	srv := newTestQUICServer(t, serverConfig)
587	srv.conn.SetTransportParameters(nil)
588	srv.ticketOpts.EarlyData = true
589	if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
590		t.Fatalf("error during first connection handshake: %v", err)
591	}
592	if cli.conn.ConnectionState().DidResume {
593		t.Errorf("first connection unexpectedly used session resumption")
594	}
595
596	cli2 := newTestQUICClient(t, clientConfig)
597	cli2.conn.SetTransportParameters(nil)
598	srv2 := newTestQUICServer(t, serverConfig)
599	srv2.conn.SetTransportParameters(nil)
600	declineEarlyData := func(state *SessionState) {
601		state.EarlyData = false
602	}
603	if server {
604		srv2.onResumeSession = declineEarlyData
605	} else {
606		cli2.onResumeSession = declineEarlyData
607	}
608	if err := runTestQUICConnection(context.Background(), cli2, srv2, nil); err != nil {
609		t.Fatalf("error during second connection handshake: %v", err)
610	}
611	if !cli2.conn.ConnectionState().DidResume {
612		t.Errorf("second connection did not use session resumption")
613	}
614	_, cliEarlyData := cli2.writeSecret[QUICEncryptionLevelEarly]
615	if server {
616		if !cliEarlyData {
617			t.Errorf("client did not receive early data write secret")
618		}
619		if !cli2.earlyDataRejected {
620			t.Errorf("client did not receive QUICEarlyDataRejected")
621		}
622	}
623	if _, srvEarlyData := srv2.readSecret[QUICEncryptionLevelEarly]; srvEarlyData {
624		t.Errorf("server received early data read secret")
625	}
626}
627