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