never allow 0-RTT when using Dial, even if the session ticket allows it (#4125)

When resuming a TLS session using Dial (and not DialEarly), 0-RTT should
be disabled at the TLS layer, even if the session ticket allows for
0-RTT resumption.

This bug is not critical, since Dial doesn't return an EarlyConnection,
so the client wouldn't be able to actually send 0-RTT data in practice.
This commit is contained in:
Marten Seemann
2023-10-25 22:20:23 +07:00
committed by GitHub
parent 1bcec70978
commit 746290b78a
11 changed files with 93 additions and 14 deletions

View File

@@ -96,6 +96,7 @@ func NewCryptoSetupClient(
quicConf := &qtls.QUICConfig{TLSConfig: tlsConf}
qtls.SetupConfigForClient(quicConf, cs.marshalDataForSessionState, cs.handleDataFromSessionState)
cs.tlsConf = tlsConf
cs.allow0RTT = enable0RTT
cs.conn = qtls.QUICClient(quicConf)
cs.conn.SetTransportParameters(cs.ourParams.Marshal(protocol.PerspectiveClient))
@@ -316,13 +317,20 @@ func (h *cryptoSetup) marshalDataForSessionState() []byte {
return h.peerParams.MarshalForSessionTicket(b)
}
func (h *cryptoSetup) handleDataFromSessionState(data []byte) {
func (h *cryptoSetup) handleDataFromSessionState(data []byte) (allowEarlyData bool) {
tp, err := h.handleDataFromSessionStateImpl(data)
if err != nil {
h.logger.Debugf("Restoring of transport parameters from session ticket failed: %s", err.Error())
return
}
h.zeroRTTParameters = tp
// The session ticket might have been saved from a connection that allowed 0-RTT,
// and therefore contain transport parameters.
// Only use them if 0-RTT is actually used on the new connection.
if tp != nil && h.allow0RTT {
h.zeroRTTParameters = tp
return true
}
return false
}
func (h *cryptoSetup) handleDataFromSessionStateImpl(data []byte) (*wire.TransportParameters, error) {
@@ -383,7 +391,9 @@ func (h *cryptoSetup) GetSessionTicket() ([]byte, error) {
}
// handleSessionTicket is called for the server when receiving the client's session ticket.
// It reads parameters from the session ticket and decides whether to accept 0-RTT when the session ticket is used for 0-RTT.
// It reads parameters from the session ticket and checks whether to accept 0-RTT if the session ticket enabled 0-RTT.
// Note that the fact that the session ticket allows 0-RTT doesn't mean that the actual TLS handshake enables 0-RTT:
// A client may use a 0-RTT enabled session to resume a TLS session without using 0-RTT.
func (h *cryptoSetup) handleSessionTicket(sessionTicketData []byte, using0RTT bool) bool {
var t sessionTicket
if err := t.Unmarshal(sessionTicketData, using0RTT); err != nil {