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