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 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
176 clientConfig.TLSConfig.MinVersion = VersionTLS13
177 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
178 serverConfig.TLSConfig.MinVersion = VersionTLS13
179
180 cli := newTestQUICClient(t, clientConfig)
181 cli.conn.SetTransportParameters(nil)
182
183 srv := newTestQUICServer(t, serverConfig)
184 srv.conn.SetTransportParameters(nil)
185
186 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
187 t.Fatalf("error during connection handshake: %v", err)
188 }
189
190 if _, ok := cli.readSecret[QUICEncryptionLevelHandshake]; !ok {
191 t.Errorf("client has no Handshake secret")
192 }
193 if _, ok := cli.readSecret[QUICEncryptionLevelApplication]; !ok {
194 t.Errorf("client has no Application secret")
195 }
196 if _, ok := srv.readSecret[QUICEncryptionLevelHandshake]; !ok {
197 t.Errorf("server has no Handshake secret")
198 }
199 if _, ok := srv.readSecret[QUICEncryptionLevelApplication]; !ok {
200 t.Errorf("server has no Application secret")
201 }
202 for _, level := range []QUICEncryptionLevel{QUICEncryptionLevelHandshake, QUICEncryptionLevelApplication} {
203 if _, ok := cli.readSecret[level]; !ok {
204 t.Errorf("client has no %v read secret", level)
205 }
206 if _, ok := srv.readSecret[level]; !ok {
207 t.Errorf("server has no %v read secret", level)
208 }
209 if !reflect.DeepEqual(cli.readSecret[level], srv.writeSecret[level]) {
210 t.Errorf("client read secret does not match server write secret for level %v", level)
211 }
212 if !reflect.DeepEqual(cli.writeSecret[level], srv.readSecret[level]) {
213 t.Errorf("client write secret does not match server read secret for level %v", level)
214 }
215 }
216 }
217
218 func TestQUICVersions(t *testing.T) {
219 for _, tc := range []struct {
220 name string
221 clientMin uint16
222 clientMax uint16
223 serverMin uint16
224 serverMax uint16
225 wantErr bool
226 }{
227 {
228 name: "defaults",
229 },
230 {
231 name: "MinVersion TLS 1.2",
232 clientMin: VersionTLS12,
233 serverMin: VersionTLS12,
234 },
235 {
236 name: "MinVersion TLS 1.3",
237 clientMin: VersionTLS13,
238 serverMin: VersionTLS13,
239 },
240 {
241 name: "client MaxVersion TLS 1.2",
242 clientMax: VersionTLS12,
243 wantErr: true,
244 },
245 {
246 name: "server MaxVersion TLS 1.2",
247 serverMax: VersionTLS12,
248 wantErr: true,
249 },
250 } {
251 t.Run(tc.name, func(t *testing.T) {
252 client := testConfigClient.Clone()
253 client.MinVersion = tc.clientMin
254 client.MaxVersion = tc.clientMax
255 server := testConfigServer.Clone()
256 server.MinVersion = tc.serverMin
257 server.MaxVersion = tc.serverMax
258
259 cli := newTestQUICClient(t, &QUICConfig{TLSConfig: client})
260 cli.conn.SetTransportParameters(nil)
261 srv := newTestQUICServer(t, &QUICConfig{TLSConfig: server})
262 srv.conn.SetTransportParameters(nil)
263 err := runTestQUICConnection(context.Background(), cli, srv, nil)
264 if tc.wantErr == (err == nil) {
265 t.Errorf("got err=%v, wantErr=%v", err, tc.wantErr)
266 }
267 })
268 }
269 }
270
271 func TestQUICSessionResumption(t *testing.T) {
272 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
273 clientConfig.TLSConfig.MinVersion = VersionTLS13
274 clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
275
276 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
277 serverConfig.TLSConfig.MinVersion = VersionTLS13
278
279 cli := newTestQUICClient(t, clientConfig)
280 cli.conn.SetTransportParameters(nil)
281 srv := newTestQUICServer(t, serverConfig)
282 srv.conn.SetTransportParameters(nil)
283 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
284 t.Fatalf("error during first connection handshake: %v", err)
285 }
286 if cli.conn.ConnectionState().DidResume {
287 t.Errorf("first connection unexpectedly used session resumption")
288 }
289
290 cli2 := newTestQUICClient(t, clientConfig)
291 cli2.conn.SetTransportParameters(nil)
292 srv2 := newTestQUICServer(t, serverConfig)
293 srv2.conn.SetTransportParameters(nil)
294 if err := runTestQUICConnection(context.Background(), cli2, srv2, nil); err != nil {
295 t.Fatalf("error during second connection handshake: %v", err)
296 }
297 if !cli2.conn.ConnectionState().DidResume {
298 t.Errorf("second connection did not use session resumption")
299 }
300
301 clientConfig.TLSConfig.SessionTicketsDisabled = true
302 cli3 := newTestQUICClient(t, clientConfig)
303 cli3.conn.SetTransportParameters(nil)
304 srv3 := newTestQUICServer(t, serverConfig)
305 srv3.conn.SetTransportParameters(nil)
306 if err := runTestQUICConnection(context.Background(), cli3, srv3, nil); err != nil {
307 t.Fatalf("error during third connection handshake: %v", err)
308 }
309 if cli3.conn.ConnectionState().DidResume {
310 t.Errorf("third connection unexpectedly used session resumption")
311 }
312 }
313
314 func TestQUICFragmentaryData(t *testing.T) {
315 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
316 clientConfig.TLSConfig.MinVersion = VersionTLS13
317 clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
318
319 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
320 serverConfig.TLSConfig.MinVersion = VersionTLS13
321
322 cli := newTestQUICClient(t, clientConfig)
323 cli.conn.SetTransportParameters(nil)
324 srv := newTestQUICServer(t, serverConfig)
325 srv.conn.SetTransportParameters(nil)
326 onEvent := func(e QUICEvent, src, dst *testQUICConn) bool {
327 if e.Kind == QUICWriteData {
328
329 for i := range e.Data {
330 if err := dst.conn.HandleData(e.Level, e.Data[i:i+1]); err != nil {
331 t.Errorf("HandleData: %v", err)
332 break
333 }
334 }
335 return true
336 }
337 return false
338 }
339 if err := runTestQUICConnection(context.Background(), cli, srv, onEvent); err != nil {
340 t.Fatalf("error during first connection handshake: %v", err)
341 }
342 }
343
344 func TestQUICPostHandshakeClientAuthentication(t *testing.T) {
345
346 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
347 clientConfig.TLSConfig.MinVersion = VersionTLS13
348 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
349 serverConfig.TLSConfig.MinVersion = VersionTLS13
350 cli := newTestQUICClient(t, clientConfig)
351 cli.conn.SetTransportParameters(nil)
352 srv := newTestQUICServer(t, serverConfig)
353 srv.conn.SetTransportParameters(nil)
354 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
355 t.Fatalf("error during connection handshake: %v", err)
356 }
357
358 certReq := new(certificateRequestMsgTLS13)
359 certReq.ocspStapling = true
360 certReq.scts = true
361 certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms(VersionTLS13, VersionTLS13)
362 certReqBytes, err := certReq.marshal()
363 if err != nil {
364 t.Fatal(err)
365 }
366 if err := cli.conn.HandleData(QUICEncryptionLevelApplication, append([]byte{
367 byte(typeCertificateRequest),
368 byte(0), byte(0), byte(len(certReqBytes)),
369 }, certReqBytes...)); err == nil {
370 t.Fatalf("post-handshake authentication request: got no error, want one")
371 }
372 }
373
374 func TestQUICPostHandshakeKeyUpdate(t *testing.T) {
375
376 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
377 clientConfig.TLSConfig.MinVersion = VersionTLS13
378 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
379 serverConfig.TLSConfig.MinVersion = VersionTLS13
380 cli := newTestQUICClient(t, clientConfig)
381 cli.conn.SetTransportParameters(nil)
382 srv := newTestQUICServer(t, serverConfig)
383 srv.conn.SetTransportParameters(nil)
384 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
385 t.Fatalf("error during connection handshake: %v", err)
386 }
387
388 keyUpdate := new(keyUpdateMsg)
389 keyUpdateBytes, err := keyUpdate.marshal()
390 if err != nil {
391 t.Fatal(err)
392 }
393 expectedErr := "unexpected key update message"
394 if err = cli.conn.HandleData(QUICEncryptionLevelApplication, keyUpdateBytes); err == nil {
395 t.Fatalf("key update request: expected error from post-handshake key update, got nil")
396 } else if !strings.Contains(err.Error(), expectedErr) {
397 t.Fatalf("key update request: got error %v, expected substring %q", err, expectedErr)
398 }
399 }
400
401 func TestQUICPostHandshakeMessageTooLarge(t *testing.T) {
402 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
403 clientConfig.TLSConfig.MinVersion = VersionTLS13
404 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
405 serverConfig.TLSConfig.MinVersion = VersionTLS13
406 cli := newTestQUICClient(t, clientConfig)
407 cli.conn.SetTransportParameters(nil)
408 srv := newTestQUICServer(t, serverConfig)
409 srv.conn.SetTransportParameters(nil)
410 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
411 t.Fatalf("error during connection handshake: %v", err)
412 }
413
414 size := maxHandshake + 1
415 if err := cli.conn.HandleData(QUICEncryptionLevelApplication, []byte{
416 byte(typeNewSessionTicket),
417 byte(size >> 16),
418 byte(size >> 8),
419 byte(size),
420 }); err == nil {
421 t.Fatalf("%v-byte post-handshake message: got no error, want one", size)
422 }
423 }
424
425 func TestQUICHandshakeError(t *testing.T) {
426 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
427 clientConfig.TLSConfig.MinVersion = VersionTLS13
428 clientConfig.TLSConfig.InsecureSkipVerify = false
429 clientConfig.TLSConfig.ServerName = "name"
430
431 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
432 serverConfig.TLSConfig.MinVersion = VersionTLS13
433
434 cli := newTestQUICClient(t, clientConfig)
435 cli.conn.SetTransportParameters(nil)
436 srv := newTestQUICServer(t, serverConfig)
437 srv.conn.SetTransportParameters(nil)
438 err := runTestQUICConnection(context.Background(), cli, srv, nil)
439 if !errors.Is(err, AlertError(alertBadCertificate)) {
440 t.Errorf("connection handshake terminated with error %q, want alertBadCertificate", err)
441 }
442 if _, ok := errors.AsType[*CertificateVerificationError](err); !ok {
443 t.Errorf("connection handshake terminated with error %q, want CertificateVerificationError", err)
444 }
445
446 ev := cli.conn.NextEvent()
447 if ev.Kind != QUICErrorEvent {
448 t.Errorf("client.NextEvent: no QUICErrorEvent, want one")
449 }
450 if ev.Err != err {
451 t.Errorf("client.NextEvent: want same error returned by Start, got %v", ev.Err)
452 }
453 }
454
455
456 func TestQUICECHKeyError(t *testing.T) {
457 getECHKeysError := errors.New("error returned by GetEncryptedClientHelloKeys")
458 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
459 clientConfig.TLSConfig.MinVersion = VersionTLS13
460 clientConfig.TLSConfig.NextProtos = []string{"h3"}
461 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
462 serverConfig.TLSConfig.MinVersion = VersionTLS13
463 serverConfig.TLSConfig.NextProtos = []string{"h3"}
464 serverConfig.TLSConfig.GetEncryptedClientHelloKeys = func(*ClientHelloInfo) ([]EncryptedClientHelloKey, error) {
465 return nil, getECHKeysError
466 }
467 cli := newTestQUICClient(t, clientConfig)
468 cli.conn.SetTransportParameters(nil)
469 srv := newTestQUICServer(t, serverConfig)
470
471 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != errTransportParametersRequired {
472 t.Fatalf("handshake with no client parameters: %v; want errTransportParametersRequired", err)
473 }
474 srv.conn.SetTransportParameters(nil)
475 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err == nil {
476 t.Fatalf("handshake with GetEncryptedClientHelloKeys errors: nil, want error")
477 }
478 if srv.gotError == nil {
479 t.Fatalf("after GetEncryptedClientHelloKeys error, server did not see QUICErrorEvent")
480 }
481 if _, ok := errors.AsType[AlertError](srv.gotError); !ok {
482 t.Errorf("connection handshake terminated with error %T, want AlertError", srv.gotError)
483 }
484 if !errors.Is(srv.gotError, getECHKeysError) {
485 t.Errorf("connection handshake terminated with error %v, want error returned by GetEncryptedClientHelloKeys", srv.gotError)
486 }
487 }
488
489
490
491
492 func TestQUICConnectionState(t *testing.T) {
493 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
494 clientConfig.TLSConfig.MinVersion = VersionTLS13
495 clientConfig.TLSConfig.NextProtos = []string{"h3"}
496 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
497 serverConfig.TLSConfig.MinVersion = VersionTLS13
498 serverConfig.TLSConfig.NextProtos = []string{"h3"}
499 cli := newTestQUICClient(t, clientConfig)
500 cli.conn.SetTransportParameters(nil)
501 srv := newTestQUICServer(t, serverConfig)
502 srv.conn.SetTransportParameters(nil)
503 onEvent := func(e QUICEvent, src, dst *testQUICConn) bool {
504 cliCS := cli.conn.ConnectionState()
505 if _, ok := cli.readSecret[QUICEncryptionLevelApplication]; ok {
506 if want, got := cliCS.NegotiatedProtocol, "h3"; want != got {
507 t.Errorf("cli.ConnectionState().NegotiatedProtocol = %q, want %q", want, got)
508 }
509 }
510 srvCS := srv.conn.ConnectionState()
511 if _, ok := srv.readSecret[QUICEncryptionLevelHandshake]; ok {
512 if want, got := srvCS.NegotiatedProtocol, "h3"; want != got {
513 t.Errorf("srv.ConnectionState().NegotiatedProtocol = %q, want %q", want, got)
514 }
515 }
516 return false
517 }
518 if err := runTestQUICConnection(context.Background(), cli, srv, onEvent); err != nil {
519 t.Fatalf("error during connection handshake: %v", err)
520 }
521 }
522
523 func TestQUICStartContextPropagation(t *testing.T) {
524 const key = "key"
525 const value = "value"
526 ctx := context.WithValue(context.Background(), key, value)
527 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
528 clientConfig.TLSConfig.MinVersion = VersionTLS13
529 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
530 serverConfig.TLSConfig.MinVersion = VersionTLS13
531 calls := 0
532 serverConfig.TLSConfig.GetConfigForClient = func(info *ClientHelloInfo) (*Config, error) {
533 calls++
534 got, _ := info.Context().Value(key).(string)
535 if got != value {
536 t.Errorf("GetConfigForClient context key %q has value %q, want %q", key, got, value)
537 }
538 return nil, nil
539 }
540 cli := newTestQUICClient(t, clientConfig)
541 cli.conn.SetTransportParameters(nil)
542 srv := newTestQUICServer(t, serverConfig)
543 srv.conn.SetTransportParameters(nil)
544 if err := runTestQUICConnection(ctx, cli, srv, nil); err != nil {
545 t.Fatalf("error during connection handshake: %v", err)
546 }
547 if calls != 1 {
548 t.Errorf("GetConfigForClient called %v times, want 1", calls)
549 }
550 }
551
552 func TestQUICClientHelloInfoConn(t *testing.T) {
553 clientHelloInfoConn, peerConn := net.Pipe()
554 t.Cleanup(func() {
555 clientHelloInfoConn.Close()
556 peerConn.Close()
557 })
558 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
559 clientConfig.TLSConfig.MinVersion = VersionTLS13
560 serverConfig := &QUICConfig{
561 TLSConfig: testConfigServer.Clone(),
562 ClientHelloInfoConn: clientHelloInfoConn,
563 }
564 serverConfig.TLSConfig.MinVersion = VersionTLS13
565 var called bool
566 serverConfig.TLSConfig.GetConfigForClient = func(info *ClientHelloInfo) (*Config, error) {
567 called = true
568 if info.Conn != clientHelloInfoConn {
569 t.Errorf("ClientHelloInfo.Conn = %v, want %v", info.Conn, clientHelloInfoConn)
570 }
571 return nil, nil
572 }
573 cli := newTestQUICClient(t, clientConfig)
574 cli.conn.SetTransportParameters(nil)
575 srv := newTestQUICServer(t, serverConfig)
576 srv.conn.SetTransportParameters(nil)
577 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
578 t.Fatalf("error during connection handshake: %v", err)
579 }
580 if !called {
581 t.Fatal("GetConfigForClient was not called")
582 }
583 }
584
585 func TestQUICContextCancelation(t *testing.T) {
586 ctx, cancel := context.WithCancel(context.Background())
587 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
588 clientConfig.TLSConfig.MinVersion = VersionTLS13
589 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
590 serverConfig.TLSConfig.MinVersion = VersionTLS13
591 cli := newTestQUICClient(t, clientConfig)
592 cli.conn.SetTransportParameters(nil)
593 srv := newTestQUICServer(t, serverConfig)
594 srv.conn.SetTransportParameters(nil)
595
596
597 var wg sync.WaitGroup
598 wg.Go(func() {
599 _ = runTestQUICConnection(ctx, cli, srv, nil)
600 })
601 wg.Go(cancel)
602 wg.Wait()
603 }
604
605 func TestQUICDelayedTransportParameters(t *testing.T) {
606 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
607 clientConfig.TLSConfig.MinVersion = VersionTLS13
608 clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
609
610 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
611 serverConfig.TLSConfig.MinVersion = VersionTLS13
612
613 cliParams := "client params"
614 srvParams := "server params"
615
616 cli := newTestQUICClient(t, clientConfig)
617 srv := newTestQUICServer(t, serverConfig)
618 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != errTransportParametersRequired {
619 t.Fatalf("handshake with no client parameters: %v; want errTransportParametersRequired", err)
620 }
621 cli.conn.SetTransportParameters([]byte(cliParams))
622 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != errTransportParametersRequired {
623 t.Fatalf("handshake with no server parameters: %v; want errTransportParametersRequired", err)
624 }
625 srv.conn.SetTransportParameters([]byte(srvParams))
626 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
627 t.Fatalf("error during connection handshake: %v", err)
628 }
629
630 if got, want := string(cli.gotParams), srvParams; got != want {
631 t.Errorf("client got transport params: %q, want %q", got, want)
632 }
633 if got, want := string(srv.gotParams), cliParams; got != want {
634 t.Errorf("server got transport params: %q, want %q", got, want)
635 }
636 }
637
638 func TestQUICEmptyTransportParameters(t *testing.T) {
639 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
640 clientConfig.TLSConfig.MinVersion = VersionTLS13
641 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
642 serverConfig.TLSConfig.MinVersion = VersionTLS13
643
644 cli := newTestQUICClient(t, clientConfig)
645 cli.conn.SetTransportParameters(nil)
646 srv := newTestQUICServer(t, serverConfig)
647 srv.conn.SetTransportParameters(nil)
648 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
649 t.Fatalf("error during connection handshake: %v", err)
650 }
651
652 if cli.gotParams == nil {
653 t.Errorf("client did not get transport params")
654 }
655 if srv.gotParams == nil {
656 t.Errorf("server did not get transport params")
657 }
658 if len(cli.gotParams) != 0 {
659 t.Errorf("client got transport params: %v, want empty", cli.gotParams)
660 }
661 if len(srv.gotParams) != 0 {
662 t.Errorf("server got transport params: %v, want empty", srv.gotParams)
663 }
664 }
665
666 func TestQUICCanceledWaitingForData(t *testing.T) {
667 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
668 clientConfig.TLSConfig.MinVersion = VersionTLS13
669 cli := newTestQUICClient(t, clientConfig)
670 cli.conn.SetTransportParameters(nil)
671 cli.conn.Start(context.Background())
672 for cli.conn.NextEvent().Kind != QUICNoEvent {
673 }
674 err := cli.conn.Close()
675 if !errors.Is(err, alertCloseNotify) {
676 t.Errorf("conn.Close() = %v, want alertCloseNotify", err)
677 }
678 }
679
680 func TestQUICCanceledWaitingForTransportParams(t *testing.T) {
681 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
682 clientConfig.TLSConfig.MinVersion = VersionTLS13
683 cli := newTestQUICClient(t, clientConfig)
684 cli.conn.Start(context.Background())
685 for cli.conn.NextEvent().Kind != QUICTransportParametersRequired {
686 }
687 err := cli.conn.Close()
688 if !errors.Is(err, alertCloseNotify) {
689 t.Errorf("conn.Close() = %v, want alertCloseNotify", err)
690 }
691 }
692
693 func TestQUICEarlyData(t *testing.T) {
694 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
695 clientConfig.TLSConfig.MinVersion = VersionTLS13
696 clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
697 clientConfig.TLSConfig.NextProtos = []string{"h3"}
698
699 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
700 serverConfig.TLSConfig.MinVersion = VersionTLS13
701 serverConfig.TLSConfig.NextProtos = []string{"h3"}
702
703 cli := newTestQUICClient(t, clientConfig)
704 cli.conn.SetTransportParameters(nil)
705 srv := newTestQUICServer(t, serverConfig)
706 srv.conn.SetTransportParameters(nil)
707 srv.ticketOpts.EarlyData = true
708 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
709 t.Fatalf("error during first connection handshake: %v", err)
710 }
711 if cli.conn.ConnectionState().DidResume {
712 t.Errorf("first connection unexpectedly used session resumption")
713 }
714
715 cli2 := newTestQUICClient(t, clientConfig)
716 cli2.conn.SetTransportParameters(nil)
717 srv2 := newTestQUICServer(t, serverConfig)
718 srv2.conn.SetTransportParameters(nil)
719 onEvent := func(e QUICEvent, src, dst *testQUICConn) bool {
720 switch e.Kind {
721 case QUICStoreSession, QUICResumeSession:
722 t.Errorf("with EnableSessionEvents=false, got unexpected event %v", e.Kind)
723 }
724 return false
725 }
726 if err := runTestQUICConnection(context.Background(), cli2, srv2, onEvent); err != nil {
727 t.Fatalf("error during second connection handshake: %v", err)
728 }
729 if !cli2.conn.ConnectionState().DidResume {
730 t.Errorf("second connection did not use session resumption")
731 }
732 cliSecret := cli2.writeSecret[QUICEncryptionLevelEarly]
733 if cliSecret.secret == nil {
734 t.Errorf("client did not receive early data write secret")
735 }
736 srvSecret := srv2.readSecret[QUICEncryptionLevelEarly]
737 if srvSecret.secret == nil {
738 t.Errorf("server did not receive early data read secret")
739 }
740 if cliSecret.suite != srvSecret.suite || !bytes.Equal(cliSecret.secret, srvSecret.secret) {
741 t.Errorf("client early data secret does not match server")
742 }
743 }
744
745 func TestQUICEarlyDataDeclined(t *testing.T) {
746 t.Run("server", func(t *testing.T) {
747 testQUICEarlyDataDeclined(t, true)
748 })
749 t.Run("client", func(t *testing.T) {
750 testQUICEarlyDataDeclined(t, false)
751 })
752 }
753
754 func testQUICEarlyDataDeclined(t *testing.T, server bool) {
755 clientConfig := &QUICConfig{TLSConfig: testConfigClient.Clone()}
756 clientConfig.EnableSessionEvents = true
757 clientConfig.TLSConfig.MinVersion = VersionTLS13
758 clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
759 clientConfig.TLSConfig.NextProtos = []string{"h3"}
760
761 serverConfig := &QUICConfig{TLSConfig: testConfigServer.Clone()}
762 serverConfig.EnableSessionEvents = true
763 serverConfig.TLSConfig.MinVersion = VersionTLS13
764 serverConfig.TLSConfig.NextProtos = []string{"h3"}
765
766 cli := newTestQUICClient(t, clientConfig)
767 cli.conn.SetTransportParameters(nil)
768 srv := newTestQUICServer(t, serverConfig)
769 srv.conn.SetTransportParameters(nil)
770 srv.ticketOpts.EarlyData = true
771 if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
772 t.Fatalf("error during first connection handshake: %v", err)
773 }
774 if cli.conn.ConnectionState().DidResume {
775 t.Errorf("first connection unexpectedly used session resumption")
776 }
777
778 cli2 := newTestQUICClient(t, clientConfig)
779 cli2.conn.SetTransportParameters(nil)
780 srv2 := newTestQUICServer(t, serverConfig)
781 srv2.conn.SetTransportParameters(nil)
782 declineEarlyData := func(state *SessionState) {
783 state.EarlyData = false
784 }
785 if server {
786 srv2.onResumeSession = declineEarlyData
787 } else {
788 cli2.onResumeSession = declineEarlyData
789 }
790 if err := runTestQUICConnection(context.Background(), cli2, srv2, nil); err != nil {
791 t.Fatalf("error during second connection handshake: %v", err)
792 }
793 if !cli2.conn.ConnectionState().DidResume {
794 t.Errorf("second connection did not use session resumption")
795 }
796 _, cliEarlyData := cli2.writeSecret[QUICEncryptionLevelEarly]
797 if server {
798 if !cliEarlyData {
799 t.Errorf("client did not receive early data write secret")
800 }
801 if !cli2.earlyDataRejected {
802 t.Errorf("client did not receive QUICEarlyDataRejected")
803 }
804 }
805 if _, srvEarlyData := srv2.readSecret[QUICEncryptionLevelEarly]; srvEarlyData {
806 t.Errorf("server received early data read secret")
807 }
808 }
809
View as plain text