From 84d21a00065f1386f428b747bca511c1c10aeed6 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sat, 10 May 2025 15:17:34 -0400 Subject: [PATCH] crypto/tls: properly return ECH retry configs When ECH is rejected, properly take retry configs from the encrypted extensions message. Also fix the bogo shim to properly test for this behavior. We should properly map the full BoringSSL -> Go errors so that we don't run into a similar failure in the future, but this is left for a follow up CL. Fixes #70915 Change-Id: Icc1878ff6f87df059e7b83e0a431f50f1fea833c Reviewed-on: https://go-review.googlesource.com/c/go/+/638583 Reviewed-by: Damien Neil Reviewed-by: Filippo Valsorda LUCI-TryBot-Result: Go LUCI --- handshake_client.go | 1 + handshake_client_tls13.go | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/handshake_client.go b/handshake_client.go index de2afed..73ef3b8 100644 --- a/handshake_client.go +++ b/handshake_client.go @@ -260,6 +260,7 @@ type echClientContext struct { kdfID uint16 aeadID uint16 echRejected bool + retryConfigs []byte } func (c *Conn) clientHandshake(ctx context.Context) (err error) { diff --git a/handshake_client_tls13.go b/handshake_client_tls13.go index d599244..2623a2e 100644 --- a/handshake_client_tls13.go +++ b/handshake_client_tls13.go @@ -85,7 +85,6 @@ func (hs *clientHandshakeStateTLS13) handshake() error { } } - var echRetryConfigList []byte if hs.echContext != nil { confTranscript := cloneHash(hs.echContext.innerTranscript, hs.suite.hash) confTranscript.Write(hs.serverHello.original[:30]) @@ -114,9 +113,6 @@ func (hs *clientHandshakeStateTLS13) handshake() error { } } else { hs.echContext.echRejected = true - // If the server sent us retry configs, we'll return these to - // the user so they can update their Config. - echRetryConfigList = hs.serverHello.encryptedClientHello } } @@ -155,7 +151,7 @@ func (hs *clientHandshakeStateTLS13) handshake() error { if hs.echContext != nil && hs.echContext.echRejected { c.sendAlert(alertECHRequired) - return &ECHRejectionError{echRetryConfigList} + return &ECHRejectionError{hs.echContext.retryConfigs} } c.isHandshakeComplete.Store(true) @@ -601,9 +597,13 @@ func (hs *clientHandshakeStateTLS13) readServerParameters() error { return errors.New("tls: server accepted 0-RTT with the wrong ALPN") } } - if hs.echContext != nil && !hs.echContext.echRejected && encryptedExtensions.echRetryConfigs != nil { - c.sendAlert(alertUnsupportedExtension) - return errors.New("tls: server sent encrypted client hello retry configs after accepting encrypted client hello") + if hs.echContext != nil { + if hs.echContext.echRejected { + hs.echContext.retryConfigs = encryptedExtensions.echRetryConfigs + } else if encryptedExtensions.echRetryConfigs != nil { + c.sendAlert(alertUnsupportedExtension) + return errors.New("tls: server sent encrypted client hello retry configs after accepting encrypted client hello") + } } return nil