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