From 039667f830aec0e24337cd960f0f44ce6d084d56 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sun, 25 May 2025 15:36:12 -0400 Subject: [PATCH] crypto/tls: verify server chooses advertised curve When a crypto/tls client using TLS < 1.3 sends supported elliptic_curves in a client hello message the server must limit itself to choosing one of the supported options from our message. If we process a server key exchange message that chooses an unadvertised curve, abort the handshake w/ an error. Previously we would not note that the server chose a curve we didn't include in the client hello message, and would proceed with the handshake as long as the chosen curve was one that we've implemented. However, RFC 8422 5.1 makes it clear this is a server acting out-of-spec, as it says: If a server does not understand the Supported Elliptic Curves Extension, does not understand the Supported Point Formats Extension, or is unable to complete the ECC handshake while restricting itself to the enumerated curves and point formats, it MUST NOT negotiate the use of an ECC cipher suite. Changing our behaviour to enforce this also allows enabling the UnsupportedCurve BoGo test. Updates #72006 Change-Id: I27a2cd231e4b8762b0d9e2dbd3d8ddd5b87fd5cc Reviewed-on: https://go-review.googlesource.com/c/go/+/673735 TryBot-Bypass: Daniel McCarney Reviewed-by: David Chase Auto-Submit: Daniel McCarney Reviewed-by: Filippo Valsorda Reviewed-by: Roland Shoemaker --- key_agreement.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/key_agreement.go b/key_agreement.go index 8429d13..118f259 100644 --- a/key_agreement.go +++ b/key_agreement.go @@ -14,6 +14,7 @@ import ( "errors" "fmt" "io" + "slices" ) // A keyAgreement implements the client and server side of a TLS 1.0–1.2 key @@ -293,6 +294,10 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell return errServerKeyExchange } + if !slices.Contains(clientHello.supportedCurves, curveID) { + return errors.New("tls: server selected unoffered curve") + } + if _, ok := curveForCurveID(curveID); !ok { return errors.New("tls: server selected unsupported curve") }