From b5e214e5fed4e401ba77135998c24b62ac8ad382 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sat, 10 May 2025 23:46:21 -0400 Subject: [PATCH] crypto/tls: err for unsupported point format configs If a client or server explicitly offers point formats, and the point formats don't include the uncompressed format, then error. This matches BoringSSL and Rustls behaviour and allows enabling the PointFormat-Client-MissingUncompressed bogo test. Updates #72006 Change-Id: I27a2cd231e4b8762b0d9e2dbd3d8ddd5b87fd5c5 Reviewed-on: https://go-review.googlesource.com/c/go/+/669157 Reviewed-by: Roland Shoemaker Reviewed-by: Cherry Mui LUCI-TryBot-Result: Go LUCI --- common.go | 6 +++++- handshake_client.go | 13 +++++++++++++ handshake_server.go | 16 ++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/common.go b/common.go index f8243f1..ed987ac 100644 --- a/common.go +++ b/common.go @@ -1394,7 +1394,11 @@ func (chi *ClientHelloInfo) SupportsCertificate(c *Certificate) error { } // The only signed key exchange we support is ECDHE. - if !supportsECDHE(config, vers, chi.SupportedCurves, chi.SupportedPoints) { + ecdheSupported, err := supportsECDHE(config, vers, chi.SupportedCurves, chi.SupportedPoints) + if err != nil { + return err + } + if !ecdheSupported { return supportsRSAFallback(errors.New("client doesn't support ECDHE, can only use legacy RSA key exchange")) } diff --git a/handshake_client.go b/handshake_client.go index 4ad6aa2..de5c420 100644 --- a/handshake_client.go +++ b/handshake_client.go @@ -886,6 +886,19 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) { return false, errors.New("tls: server selected unsupported compression format") } + supportsPointFormat := false + offeredNonCompressedFormat := false + for _, format := range hs.serverHello.supportedPoints { + if format == pointFormatUncompressed { + supportsPointFormat = true + } else { + offeredNonCompressedFormat = true + } + } + if !supportsPointFormat && offeredNonCompressedFormat { + return false, errors.New("tls: server offered only incompatible point formats") + } + if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported { c.secureRenegotiation = true if len(hs.serverHello.secureRenegotiation) != 0 { diff --git a/handshake_server.go b/handshake_server.go index 03d0553..3d5ea81 100644 --- a/handshake_server.go +++ b/handshake_server.go @@ -268,7 +268,11 @@ func (hs *serverHandshakeState) processClientHello() error { hs.hello.scts = hs.cert.SignedCertificateTimestamps } - hs.ecdheOk = supportsECDHE(c.config, c.vers, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints) + hs.ecdheOk, err = supportsECDHE(c.config, c.vers, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints) + if err != nil { + c.sendAlert(alertMissingExtension) + return err + } if hs.ecdheOk && len(hs.clientHello.supportedPoints) > 0 { // Although omitting the ec_point_formats extension is permitted, some @@ -339,7 +343,7 @@ func negotiateALPN(serverProtos, clientProtos []string, quic bool) (string, erro // supportsECDHE returns whether ECDHE key exchanges can be used with this // pre-TLS 1.3 client. -func supportsECDHE(c *Config, version uint16, supportedCurves []CurveID, supportedPoints []uint8) bool { +func supportsECDHE(c *Config, version uint16, supportedCurves []CurveID, supportedPoints []uint8) (bool, error) { supportsCurve := false for _, curve := range supportedCurves { if c.supportsCurve(version, curve) { @@ -349,10 +353,12 @@ func supportsECDHE(c *Config, version uint16, supportedCurves []CurveID, support } supportsPointFormat := false + offeredNonCompressedFormat := false for _, pointFormat := range supportedPoints { if pointFormat == pointFormatUncompressed { supportsPointFormat = true - break + } else { + offeredNonCompressedFormat = true } } // Per RFC 8422, Section 5.1.2, if the Supported Point Formats extension is @@ -361,9 +367,11 @@ func supportsECDHE(c *Config, version uint16, supportedCurves []CurveID, support // the parser. See https://go.dev/issue/49126. if len(supportedPoints) == 0 { supportsPointFormat = true + } else if offeredNonCompressedFormat && !supportsPointFormat { + return false, errors.New("tls: client offered only incompatible point formats") } - return supportsCurve && supportsPointFormat + return supportsCurve && supportsPointFormat, nil } func (hs *serverHandshakeState) pickCipherSuite() error {