Skip to content

Commit

Permalink
crypto/tls: support ECDHE when ec_point_formats is missing
Browse files Browse the repository at this point in the history
Fixes #49126

Change-Id: I9d6f6392b1a6748bdac1d2c6371b22d75829a2b6
Reviewed-on: https://go-review.googlesource.com/c/go/+/425295
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Alex Scheel <alex.scheel@hashicorp.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: David Chase <drchase@google.com>
  • Loading branch information
FiloSottile authored and gopherbot committed Aug 25, 2022
1 parent e4be2ac commit 1df2a03
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 15 deletions.
9 changes: 8 additions & 1 deletion src/crypto/tls/handshake_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func (hs *serverHandshakeState) processClientHello() error {

hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints)

if hs.ecdheOk {
if hs.ecdheOk && len(hs.clientHello.supportedPoints) > 0 {
// Although omitting the ec_point_formats extension is permitted, some
// old OpenSSL version will refuse to handshake if not present.
//
Expand Down Expand Up @@ -320,6 +320,13 @@ func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8
break
}
}
// Per RFC 8422, Section 5.1.2, if the Supported Point Formats extension is
// missing, uncompressed points are supported. If supportedPoints is empty,
// the extension must be missing, as an empty extension body is rejected by
// the parser. See https://go.dev/issue/49126.
if len(supportedPoints) == 0 {
supportsPointFormat = true
}

return supportsCurve && supportsPointFormat
}
Expand Down
21 changes: 7 additions & 14 deletions src/crypto/tls/handshake_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,16 +281,19 @@ func TestTLS12OnlyCipherSuites(t *testing.T) {

func TestTLSPointFormats(t *testing.T) {
// Test that a Server returns the ec_point_format extension when ECC is
// negotiated, and not returned on RSA handshake.
// negotiated, and not on a RSA handshake or if ec_point_format is missing.
tests := []struct {
name string
cipherSuites []uint16
supportedCurves []CurveID
supportedPoints []uint8
wantSupportedPoints bool
}{
{"ECC", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{compressionNone}, true},
{"ECC", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{pointFormatUncompressed}, true},
{"ECC without ec_point_format", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, nil, false},
{"ECC with extra values", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{13, 37, pointFormatUncompressed, 42}, true},
{"RSA", []uint16{TLS_RSA_WITH_AES_256_GCM_SHA384}, nil, nil, false},
{"RSA with ec_point_format", []uint16{TLS_RSA_WITH_AES_256_GCM_SHA384}, nil, []uint8{pointFormatUncompressed}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -330,18 +333,8 @@ func TestTLSPointFormats(t *testing.T) {
t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply)
}
if tt.wantSupportedPoints {
if len(serverHello.supportedPoints) < 1 {
t.Fatal("missing ec_point_format extension from server")
}
found := false
for _, p := range serverHello.supportedPoints {
if p == pointFormatUncompressed {
found = true
break
}
}
if !found {
t.Fatal("missing uncompressed format in ec_point_format extension from server")
if !bytes.Equal(serverHello.supportedPoints, []uint8{pointFormatUncompressed}) {
t.Fatal("incorrect ec_point_format extension from server")
}
} else {
if len(serverHello.supportedPoints) != 0 {
Expand Down

0 comments on commit 1df2a03

Please sign in to comment.