From f38ac662b21e333b77951848a7e0549e4f69799e Mon Sep 17 00:00:00 2001
From: Filippo Valsorda <filippo@golang.org>
Date: Thu, 29 Jan 2026 11:32:25 +0100
Subject: [PATCH] [release-branch.go1.24] crypto/tls: document resumption
 behavior across Configs

Updates #77113
Updates #77217
Updates CVE-2025-68121

CVE: CVE-2025-68121
Upstream-Status: Backport [https://github.com/golang/go/commit/6a501314718b]

Change-Id: Ia47904a9ed001275aad0243a6a0ce57e6a6a6964
Reviewed-on: https://go-review.googlesource.com/c/go/+/740240
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
(cherry picked from commit 1c9abbdc8e9032cd613bd147c78b166ebacc8a2e)
Reviewed-on: https://go-review.googlesource.com/c/go/+/741180
Auto-Submit: Michael Pratt <mpratt@google.com>
(cherry picked from commit 6a501314718b6d69bad1723b3065ca6067b560ea)
Signed-off-by: Deepak Rathore <deeratho@cisco.com>
---
 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 299d6f32cb..348bdf0866 100644
--- a/src/crypto/tls/common.go
+++ b/src/crypto/tls/common.go
@@ -595,10 +595,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
@@ -616,8 +619,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
@@ -825,8 +830,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
--
2.35.6
