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