From 1c9abbdc8e9032cd613bd147c78b166ebacc8a2e Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Thu, 29 Jan 2026 11:32:25 +0100 Subject: [PATCH] crypto/tls: document resumption behavior across Configs Updates #77113 Updates #77217 Updates CVE-2025-68121 Change-Id: Ia47904a9ed001275aad0243a6a0ce57e6a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/740240 LUCI-TryBot-Result: Go LUCI Reviewed-by: Roland Shoemaker Reviewed-by: Michael Pratt Auto-Submit: Filippo Valsorda --- src/crypto/tls/common.go | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go index dfd24d70b04..c7a35d0bb52 100644 --- a/src/crypto/tls/common.go +++ b/src/crypto/tls/common.go @@ -632,10 +632,13 @@ type Config struct { // If GetConfigForClient is nil, the Config passed to Server() will be // used for all connections. // - // If SessionTicketKey was explicitly set on the returned Config, or if - // SetSessionTicketKeys was called on the returned Config, those keys will + // If SessionTicketKey is explicitly set on the returned Config, or if + // SetSessionTicketKeys is called on the returned Config, those keys will // be used. Otherwise, the original Config keys will be used (and possibly - // rotated if they are automatically managed). + // rotated if they are automatically managed). WARNING: this allows session + // resumtion of connections originally established with the parent (or a + // sibling) Config, which may bypass the [Config.VerifyPeerCertificate] + // value of the returned Config. GetConfigForClient func(*ClientHelloInfo) (*Config, error) // VerifyPeerCertificate, if not nil, is called after normal @@ -653,8 +656,10 @@ type Config struct { // rawCerts may be empty on the server if ClientAuth is RequestClientCert or // VerifyClientCertIfGiven. // - // This callback is not invoked on resumed connections, as certificates are - // not re-verified on resumption. + // This callback is not invoked on resumed connections. WARNING: this + // includes connections resumed across Configs returned by [Config.Clone] or + // [Config.GetConfigForClient] and their parents. If that is not intended, + // use [Config.VerifyConnection] instead, or set [Config.SessionTicketsDisabled]. // // verifiedChains and its contents should not be modified. VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error @@ -978,8 +983,15 @@ func (c *Config) ticketKeyFromBytes(b [32]byte) (key ticketKey) { // ticket, and the lifetime we set for all tickets we send. const maxSessionTicketLifetime = 7 * 24 * time.Hour -// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a [Config] that is -// being used concurrently by a TLS client or server. +// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a +// [Config] that is being used concurrently by a TLS client or server. +// +// The returned Config can share session ticket keys with the original Config, +// which means connections could be resumed across the two Configs. WARNING: +// [Config.VerifyPeerCertificate] does not get called on resumed connections, +// including connections that were originally established on the parent Config. +// If that is not intended, use [Config.VerifyConnection] instead, or set +// [Config.SessionTicketsDisabled]. func (c *Config) Clone() *Config { if c == nil { return nil