From 399f0e14086216fbaa87e1aa33e306eb6c56204d Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sat, 10 May 2025 15:41:07 -0400 Subject: [PATCH] crypto/tls: ignore TLS 1.3 user canceled alerts When encountering alertUserCanceled in a TLS 1.3 handshake, ignore the alert and retry reading a record. This matches existing logic for how TLS 1.2 alertLevelWarning alerts are handled. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For broader context, TLS 1.3 removed warning-level alerts except for alertUserCanceled (RFC 8446, § 6.1). Since at least one major implementation (https://bugs.openjdk.org/browse/JDK-8323517) misuses this alert, many TLS stacks now ignore it outright when seen in a TLS 1.3 handshake (e.g. BoringSSL, NSS, Rustls). With the crypto/tls behaviour changed to match peer implementations we can now enable the "SendUserCanceledAlerts-TLS13" BoGo test. "SendUserCanceledAlerts-TooMany-TLS13" remains ignored, because like "SendWarningAlerts*" fixing the test requires some general spam protocol message enhancements be done first. Updates #72006 Change-Id: I570c1fa674b5a4760836c514d35ee17f746fe28d Reviewed-on: https://go-review.googlesource.com/c/go/+/650716 Reviewed-by: Michael Pratt LUCI-TryBot-Result: Go LUCI Reviewed-by: Roland Shoemaker --- conn.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/conn.go b/conn.go index 3db488d..6f792cd 100644 --- a/conn.go +++ b/conn.go @@ -758,6 +758,15 @@ func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error { return c.in.setErrorLocked(io.EOF) } if c.vers == VersionTLS13 { + // TLS 1.3 removed warning-level alerts except for alertUserCanceled + // (RFC 8446, § 6.1). Since at least one major implementation + // (https://bugs.openjdk.org/browse/JDK-8323517) misuses this alert, + // many TLS stacks now ignore it outright when seen in a TLS 1.3 + // handshake (e.g. BoringSSL, NSS, Rustls). + if alert(data[1]) == alertUserCanceled { + // Like TLS 1.2 alertLevelWarning alerts, we drop the record and retry. + return c.retryReadRecord(expectChangeCipherSpec) + } return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])}) } switch data[0] {