Skip to content

Commit 90bcc55

Browse files
committed
crypto/tls: apply QUIC session event flag to QUICResumeSession events
Go 1.23 adds two new events to QUICConns: QUICStoreSessionEvent and QUICResumeSessionEvent. We added a QUICConfig.EnableStoreSessionEvent flag to control whether the store-session event is provided or not, because receiving this event requires additional action from the caller: the session must be explicitly stored with QUICConn.StoreSession. We did not add a control for whether the resume-session event is provided, because this event requires no action and the caller is expected to ignore unknown events. However, we never documented the expectation that callers ignore unknown events, and quic-go produces an error when receiving an unexpected event. So change the EnableStoreSessionEvent flag to apply to both new events. Fixes #68124 For #63691 Change-Id: I84af487e52b3815f7b648e09884608f8915cd645 Reviewed-on: https://go-review.googlesource.com/c/go/+/594475 Reviewed-by: Marten Seemann <martenseemann@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Roland Shoemaker <roland@golang.org>
1 parent b1fd047 commit 90bcc55

File tree

6 files changed

+100
-84
lines changed

6 files changed

+100
-84
lines changed

api/go1.23.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pkg crypto/tls, type Config struct, EncryptedClientHelloRejectionVerify func(Con
1818
pkg crypto/tls, type ConnectionState struct, ECHAccepted bool #63369
1919
pkg crypto/tls, type ECHRejectionError struct #63369
2020
pkg crypto/tls, type ECHRejectionError struct, RetryConfigList []uint8 #63369
21-
pkg crypto/tls, type QUICConfig struct, EnableStoreSessionEvent bool #63691
21+
pkg crypto/tls, type QUICConfig struct, EnableSessionEvents bool #63691
2222
pkg crypto/tls, type QUICEvent struct, SessionState *SessionState #63691
2323
pkg crypto/tls, type QUICSessionTicketOptions struct, Extra [][]uint8 #63691
2424
pkg crypto/x509, func ParseOID(string) (OID, error) #66249

src/crypto/tls/handshake_client.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,9 @@ func (c *Conn) loadSession(hello *clientHelloMsg) (
478478
}
479479

480480
if c.quic != nil {
481-
c.quicResumeSession(session)
481+
if c.quic.enableSessionEvents {
482+
c.quicResumeSession(session)
483+
}
482484

483485
// For 0-RTT, the cipher suite has to match exactly, and we need to be
484486
// offering the same ALPN.

src/crypto/tls/handshake_client_tls13.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
900900
session.ageAdd = msg.ageAdd
901901
session.EarlyData = c.quic != nil && msg.maxEarlyData == 0xffffffff // RFC 9001, Section 4.6.1
902902
session.ticket = msg.label
903-
if c.quic != nil && c.quic.enableStoreSessionEvent {
903+
if c.quic != nil && c.quic.enableSessionEvents {
904904
c.quicStoreSession(session)
905905
return nil
906906
}

src/crypto/tls/handshake_server_tls13.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
377377
continue
378378
}
379379

380-
if c.quic != nil {
380+
if c.quic != nil && c.quic.enableSessionEvents {
381381
if err := c.quicResumeSession(sessionState); err != nil {
382382
return err
383383
}

src/crypto/tls/quic.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ type QUICConn struct {
5050
type QUICConfig struct {
5151
TLSConfig *Config
5252

53-
// EnableStoreSessionEvent may be set to true to enable the
54-
// [QUICStoreSession] event for client connections.
53+
// EnableSessionEvents may be set to true to enable the
54+
// [QUICStoreSession] and [QUICResumeSession] events for client connections.
5555
// When this event is enabled, sessions are not automatically
5656
// stored in the client session cache.
5757
// The application should use [QUICConn.StoreSession] to store sessions.
58-
EnableStoreSessionEvent bool
58+
EnableSessionEvents bool
5959
}
6060

6161
// A QUICEventKind is a type of operation on a QUIC connection.
@@ -113,7 +113,7 @@ const (
113113
// QUICStoreSession indicates that the server has provided state permitting
114114
// the client to resume the session.
115115
// [QUICEvent.SessionState] is set.
116-
// The application should use [QUICConn.Store] session to store the [SessionState].
116+
// The application should use [QUICConn.StoreSession] session to store the [SessionState].
117117
// The application may modify the [SessionState] before storing it.
118118
// This event only occurs on client connections.
119119
QUICStoreSession
@@ -165,7 +165,7 @@ type quicState struct {
165165

166166
transportParams []byte // to send to the peer
167167

168-
enableStoreSessionEvent bool
168+
enableSessionEvents bool
169169
}
170170

171171
// QUICClient returns a new TLS client side connection using QUICTransport as the
@@ -186,9 +186,9 @@ func QUICServer(config *QUICConfig) *QUICConn {
186186

187187
func newQUICConn(conn *Conn, config *QUICConfig) *QUICConn {
188188
conn.quic = &quicState{
189-
signalc: make(chan struct{}),
190-
blockedc: make(chan struct{}),
191-
enableStoreSessionEvent: config.EnableStoreSessionEvent,
189+
signalc: make(chan struct{}),
190+
blockedc: make(chan struct{}),
191+
enableSessionEvents: config.EnableSessionEvents,
192192
}
193193
conn.quic.events = conn.quic.eventArr[:0]
194194
return &QUICConn{

src/crypto/tls/quic_test.go

+86-72
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,22 @@ type testQUICConn struct {
2424
complete bool
2525
}
2626

27-
func newTestQUICClient(t *testing.T, config *Config) *testQUICConn {
28-
q := &testQUICConn{t: t}
29-
q.conn = QUICClient(&QUICConfig{
30-
TLSConfig: config,
31-
})
27+
func newTestQUICClient(t *testing.T, config *QUICConfig) *testQUICConn {
28+
q := &testQUICConn{
29+
t: t,
30+
conn: QUICClient(config),
31+
}
3232
t.Cleanup(func() {
3333
q.conn.Close()
3434
})
3535
return q
3636
}
3737

38-
func newTestQUICServer(t *testing.T, config *Config) *testQUICConn {
39-
q := &testQUICConn{t: t}
40-
q.conn = QUICServer(&QUICConfig{
41-
TLSConfig: config,
42-
})
38+
func newTestQUICServer(t *testing.T, config *QUICConfig) *testQUICConn {
39+
q := &testQUICConn{
40+
t: t,
41+
conn: QUICServer(config),
42+
}
4343
t.Cleanup(func() {
4444
q.conn.Close()
4545
})
@@ -140,6 +140,11 @@ func runTestQUICConnection(ctx context.Context, cli, srv *testQUICConn, onEvent
140140
return err
141141
}
142142
}
143+
case QUICStoreSession:
144+
if a != cli {
145+
return errors.New("unexpected QUICStoreSession event received by server")
146+
}
147+
a.conn.StoreSession(e.SessionState)
143148
case QUICResumeSession:
144149
if a.onResumeSession != nil {
145150
a.onResumeSession(e.SessionState)
@@ -154,8 +159,8 @@ func runTestQUICConnection(ctx context.Context, cli, srv *testQUICConn, onEvent
154159
}
155160

156161
func TestQUICConnection(t *testing.T) {
157-
config := testConfig.Clone()
158-
config.MinVersion = VersionTLS13
162+
config := &QUICConfig{TLSConfig: testConfig.Clone()}
163+
config.TLSConfig.MinVersion = VersionTLS13
159164

160165
cli := newTestQUICClient(t, config)
161166
cli.conn.SetTransportParameters(nil)
@@ -196,13 +201,13 @@ func TestQUICConnection(t *testing.T) {
196201
}
197202

198203
func TestQUICSessionResumption(t *testing.T) {
199-
clientConfig := testConfig.Clone()
200-
clientConfig.MinVersion = VersionTLS13
201-
clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
202-
clientConfig.ServerName = "example.go.dev"
204+
clientConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
205+
clientConfig.TLSConfig.MinVersion = VersionTLS13
206+
clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
207+
clientConfig.TLSConfig.ServerName = "example.go.dev"
203208

204-
serverConfig := testConfig.Clone()
205-
serverConfig.MinVersion = VersionTLS13
209+
serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
210+
serverConfig.TLSConfig.MinVersion = VersionTLS13
206211

207212
cli := newTestQUICClient(t, clientConfig)
208213
cli.conn.SetTransportParameters(nil)
@@ -228,13 +233,13 @@ func TestQUICSessionResumption(t *testing.T) {
228233
}
229234

230235
func TestQUICFragmentaryData(t *testing.T) {
231-
clientConfig := testConfig.Clone()
232-
clientConfig.MinVersion = VersionTLS13
233-
clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
234-
clientConfig.ServerName = "example.go.dev"
236+
clientConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
237+
clientConfig.TLSConfig.MinVersion = VersionTLS13
238+
clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
239+
clientConfig.TLSConfig.ServerName = "example.go.dev"
235240

236-
serverConfig := testConfig.Clone()
237-
serverConfig.MinVersion = VersionTLS13
241+
serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
242+
serverConfig.TLSConfig.MinVersion = VersionTLS13
238243

239244
cli := newTestQUICClient(t, clientConfig)
240245
cli.conn.SetTransportParameters(nil)
@@ -260,8 +265,8 @@ func TestQUICFragmentaryData(t *testing.T) {
260265

261266
func TestQUICPostHandshakeClientAuthentication(t *testing.T) {
262267
// RFC 9001, Section 4.4.
263-
config := testConfig.Clone()
264-
config.MinVersion = VersionTLS13
268+
config := &QUICConfig{TLSConfig: testConfig.Clone()}
269+
config.TLSConfig.MinVersion = VersionTLS13
265270
cli := newTestQUICClient(t, config)
266271
cli.conn.SetTransportParameters(nil)
267272
srv := newTestQUICServer(t, config)
@@ -288,8 +293,8 @@ func TestQUICPostHandshakeClientAuthentication(t *testing.T) {
288293

289294
func TestQUICPostHandshakeKeyUpdate(t *testing.T) {
290295
// RFC 9001, Section 6.
291-
config := testConfig.Clone()
292-
config.MinVersion = VersionTLS13
296+
config := &QUICConfig{TLSConfig: testConfig.Clone()}
297+
config.TLSConfig.MinVersion = VersionTLS13
293298
cli := newTestQUICClient(t, config)
294299
cli.conn.SetTransportParameters(nil)
295300
srv := newTestQUICServer(t, config)
@@ -312,8 +317,8 @@ func TestQUICPostHandshakeKeyUpdate(t *testing.T) {
312317
}
313318

314319
func TestQUICPostHandshakeMessageTooLarge(t *testing.T) {
315-
config := testConfig.Clone()
316-
config.MinVersion = VersionTLS13
320+
config := &QUICConfig{TLSConfig: testConfig.Clone()}
321+
config.TLSConfig.MinVersion = VersionTLS13
317322
cli := newTestQUICClient(t, config)
318323
cli.conn.SetTransportParameters(nil)
319324
srv := newTestQUICServer(t, config)
@@ -334,13 +339,13 @@ func TestQUICPostHandshakeMessageTooLarge(t *testing.T) {
334339
}
335340

336341
func TestQUICHandshakeError(t *testing.T) {
337-
clientConfig := testConfig.Clone()
338-
clientConfig.MinVersion = VersionTLS13
339-
clientConfig.InsecureSkipVerify = false
340-
clientConfig.ServerName = "name"
342+
clientConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
343+
clientConfig.TLSConfig.MinVersion = VersionTLS13
344+
clientConfig.TLSConfig.InsecureSkipVerify = false
345+
clientConfig.TLSConfig.ServerName = "name"
341346

342-
serverConfig := testConfig.Clone()
343-
serverConfig.MinVersion = VersionTLS13
347+
serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
348+
serverConfig.TLSConfig.MinVersion = VersionTLS13
344349

345350
cli := newTestQUICClient(t, clientConfig)
346351
cli.conn.SetTransportParameters(nil)
@@ -360,9 +365,9 @@ func TestQUICHandshakeError(t *testing.T) {
360365
// and that it reports the application protocol as soon as it has been
361366
// negotiated.
362367
func TestQUICConnectionState(t *testing.T) {
363-
config := testConfig.Clone()
364-
config.MinVersion = VersionTLS13
365-
config.NextProtos = []string{"h3"}
368+
config := &QUICConfig{TLSConfig: testConfig.Clone()}
369+
config.TLSConfig.MinVersion = VersionTLS13
370+
config.TLSConfig.NextProtos = []string{"h3"}
366371
cli := newTestQUICClient(t, config)
367372
cli.conn.SetTransportParameters(nil)
368373
srv := newTestQUICServer(t, config)
@@ -391,10 +396,10 @@ func TestQUICStartContextPropagation(t *testing.T) {
391396
const key = "key"
392397
const value = "value"
393398
ctx := context.WithValue(context.Background(), key, value)
394-
config := testConfig.Clone()
395-
config.MinVersion = VersionTLS13
399+
config := &QUICConfig{TLSConfig: testConfig.Clone()}
400+
config.TLSConfig.MinVersion = VersionTLS13
396401
calls := 0
397-
config.GetConfigForClient = func(info *ClientHelloInfo) (*Config, error) {
402+
config.TLSConfig.GetConfigForClient = func(info *ClientHelloInfo) (*Config, error) {
398403
calls++
399404
got, _ := info.Context().Value(key).(string)
400405
if got != value {
@@ -415,13 +420,13 @@ func TestQUICStartContextPropagation(t *testing.T) {
415420
}
416421

417422
func TestQUICDelayedTransportParameters(t *testing.T) {
418-
clientConfig := testConfig.Clone()
419-
clientConfig.MinVersion = VersionTLS13
420-
clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
421-
clientConfig.ServerName = "example.go.dev"
423+
clientConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
424+
clientConfig.TLSConfig.MinVersion = VersionTLS13
425+
clientConfig.TLSConfig.ClientSessionCache = NewLRUClientSessionCache(1)
426+
clientConfig.TLSConfig.ServerName = "example.go.dev"
422427

423-
serverConfig := testConfig.Clone()
424-
serverConfig.MinVersion = VersionTLS13
428+
serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
429+
serverConfig.TLSConfig.MinVersion = VersionTLS13
425430

426431
cliParams := "client params"
427432
srvParams := "server params"
@@ -449,8 +454,8 @@ func TestQUICDelayedTransportParameters(t *testing.T) {
449454
}
450455

451456
func TestQUICEmptyTransportParameters(t *testing.T) {
452-
config := testConfig.Clone()
453-
config.MinVersion = VersionTLS13
457+
config := &QUICConfig{TLSConfig: testConfig.Clone()}
458+
config.TLSConfig.MinVersion = VersionTLS13
454459

455460
cli := newTestQUICClient(t, config)
456461
cli.conn.SetTransportParameters(nil)
@@ -475,8 +480,8 @@ func TestQUICEmptyTransportParameters(t *testing.T) {
475480
}
476481

477482
func TestQUICCanceledWaitingForData(t *testing.T) {
478-
config := testConfig.Clone()
479-
config.MinVersion = VersionTLS13
483+
config := &QUICConfig{TLSConfig: testConfig.Clone()}
484+
config.TLSConfig.MinVersion = VersionTLS13
480485
cli := newTestQUICClient(t, config)
481486
cli.conn.SetTransportParameters(nil)
482487
cli.conn.Start(context.Background())
@@ -489,8 +494,8 @@ func TestQUICCanceledWaitingForData(t *testing.T) {
489494
}
490495

491496
func TestQUICCanceledWaitingForTransportParams(t *testing.T) {
492-
config := testConfig.Clone()
493-
config.MinVersion = VersionTLS13
497+
config := &QUICConfig{TLSConfig: testConfig.Clone()}
498+
config.TLSConfig.MinVersion = VersionTLS13
494499
cli := newTestQUICClient(t, config)
495500
cli.conn.Start(context.Background())
496501
for cli.conn.NextEvent().Kind != QUICTransportParametersRequired {
@@ -502,15 +507,15 @@ func TestQUICCanceledWaitingForTransportParams(t *testing.T) {
502507
}
503508

504509
func TestQUICEarlyData(t *testing.T) {
505-
clientConfig := testConfig.Clone()
506-
clientConfig.MinVersion = VersionTLS13
507-
clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
508-
clientConfig.ServerName = "example.go.dev"
509-
clientConfig.NextProtos = []string{"h3"}
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"}
510515

511-
serverConfig := testConfig.Clone()
512-
serverConfig.MinVersion = VersionTLS13
513-
serverConfig.NextProtos = []string{"h3"}
516+
serverConfig := &QUICConfig{TLSConfig: testConfig.Clone()}
517+
serverConfig.TLSConfig.MinVersion = VersionTLS13
518+
serverConfig.TLSConfig.NextProtos = []string{"h3"}
514519

515520
cli := newTestQUICClient(t, clientConfig)
516521
cli.conn.SetTransportParameters(nil)
@@ -528,7 +533,14 @@ func TestQUICEarlyData(t *testing.T) {
528533
cli2.conn.SetTransportParameters(nil)
529534
srv2 := newTestQUICServer(t, serverConfig)
530535
srv2.conn.SetTransportParameters(nil)
531-
if err := runTestQUICConnection(context.Background(), cli2, srv2, nil); err != 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 {
532544
t.Fatalf("error during second connection handshake: %v", err)
533545
}
534546
if !cli2.conn.ConnectionState().DidResume {
@@ -557,15 +569,17 @@ func TestQUICEarlyDataDeclined(t *testing.T) {
557569
}
558570

559571
func testQUICEarlyDataDeclined(t *testing.T, server bool) {
560-
clientConfig := testConfig.Clone()
561-
clientConfig.MinVersion = VersionTLS13
562-
clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
563-
clientConfig.ServerName = "example.go.dev"
564-
clientConfig.NextProtos = []string{"h3"}
565-
566-
serverConfig := testConfig.Clone()
567-
serverConfig.MinVersion = VersionTLS13
568-
serverConfig.NextProtos = []string{"h3"}
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"}
569583

570584
cli := newTestQUICClient(t, clientConfig)
571585
cli.conn.SetTransportParameters(nil)

0 commit comments

Comments
 (0)