mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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 <roland@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
992d154717
commit
00b6348658
5 changed files with 31 additions and 7 deletions
|
|
@ -131,7 +131,6 @@
|
||||||
"SendClientVersion-RSA": "TODO: first pass, this should be fixed",
|
"SendClientVersion-RSA": "TODO: first pass, this should be fixed",
|
||||||
"NoCommonCurves": "TODO: first pass, this should be fixed",
|
"NoCommonCurves": "TODO: first pass, this should be fixed",
|
||||||
"PointFormat-EncryptedExtensions-TLS13": "TODO: first pass, this should be fixed",
|
"PointFormat-EncryptedExtensions-TLS13": "TODO: first pass, this should be fixed",
|
||||||
"PointFormat-Client-MissingUncompressed": "TODO: first pass, this should be fixed",
|
|
||||||
"TLS13-SendNoKEMModesWithPSK-Server": "TODO: first pass, this should be fixed",
|
"TLS13-SendNoKEMModesWithPSK-Server": "TODO: first pass, this should be fixed",
|
||||||
"TLS13-DuplicateTicketEarlyDataSupport": "TODO: first pass, this should be fixed",
|
"TLS13-DuplicateTicketEarlyDataSupport": "TODO: first pass, this should be fixed",
|
||||||
"Basic-Client-NoTicket-TLS-Sync": "TODO: first pass, this should be fixed",
|
"Basic-Client-NoTicket-TLS-Sync": "TODO: first pass, this should be fixed",
|
||||||
|
|
|
||||||
|
|
@ -1372,7 +1372,11 @@ func (chi *ClientHelloInfo) SupportsCertificate(c *Certificate) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The only signed key exchange we support is ECDHE.
|
// 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"))
|
return supportsRSAFallback(errors.New("client doesn't support ECDHE, can only use legacy RSA key exchange"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -893,6 +893,19 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
|
||||||
return false, errors.New("tls: server selected unsupported compression format")
|
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 {
|
if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
|
||||||
c.secureRenegotiation = true
|
c.secureRenegotiation = true
|
||||||
if len(hs.serverHello.secureRenegotiation) != 0 {
|
if len(hs.serverHello.secureRenegotiation) != 0 {
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,11 @@ func (hs *serverHandshakeState) processClientHello() error {
|
||||||
hs.hello.scts = hs.cert.SignedCertificateTimestamps
|
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 {
|
if hs.ecdheOk && len(hs.clientHello.supportedPoints) > 0 {
|
||||||
// Although omitting the ec_point_formats extension is permitted, some
|
// Although omitting the ec_point_formats extension is permitted, some
|
||||||
|
|
@ -343,7 +347,7 @@ func negotiateALPN(serverProtos, clientProtos []string, quic bool) (string, erro
|
||||||
|
|
||||||
// supportsECDHE returns whether ECDHE key exchanges can be used with this
|
// supportsECDHE returns whether ECDHE key exchanges can be used with this
|
||||||
// pre-TLS 1.3 client.
|
// 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
|
supportsCurve := false
|
||||||
for _, curve := range supportedCurves {
|
for _, curve := range supportedCurves {
|
||||||
if c.supportsCurve(version, curve) {
|
if c.supportsCurve(version, curve) {
|
||||||
|
|
@ -353,10 +357,12 @@ func supportsECDHE(c *Config, version uint16, supportedCurves []CurveID, support
|
||||||
}
|
}
|
||||||
|
|
||||||
supportsPointFormat := false
|
supportsPointFormat := false
|
||||||
|
offeredNonCompressedFormat := false
|
||||||
for _, pointFormat := range supportedPoints {
|
for _, pointFormat := range supportedPoints {
|
||||||
if pointFormat == pointFormatUncompressed {
|
if pointFormat == pointFormatUncompressed {
|
||||||
supportsPointFormat = true
|
supportsPointFormat = true
|
||||||
break
|
} else {
|
||||||
|
offeredNonCompressedFormat = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Per RFC 8422, Section 5.1.2, if the Supported Point Formats extension is
|
// Per RFC 8422, Section 5.1.2, if the Supported Point Formats extension is
|
||||||
|
|
@ -365,9 +371,11 @@ func supportsECDHE(c *Config, version uint16, supportedCurves []CurveID, support
|
||||||
// the parser. See https://go.dev/issue/49126.
|
// the parser. See https://go.dev/issue/49126.
|
||||||
if len(supportedPoints) == 0 {
|
if len(supportedPoints) == 0 {
|
||||||
supportsPointFormat = true
|
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 {
|
func (hs *serverHandshakeState) pickCipherSuite() error {
|
||||||
|
|
|
||||||
|
|
@ -1479,7 +1479,7 @@ func TestClientHelloInfo_SupportsCertificate(t *testing.T) {
|
||||||
SupportedPoints: []uint8{1},
|
SupportedPoints: []uint8{1},
|
||||||
SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256},
|
SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256},
|
||||||
SupportedVersions: []uint16{VersionTLS12},
|
SupportedVersions: []uint16{VersionTLS12},
|
||||||
}, "doesn't support ECDHE"},
|
}, "only incompatible point formats"},
|
||||||
{ecdsaCert, &ClientHelloInfo{
|
{ecdsaCert, &ClientHelloInfo{
|
||||||
CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
|
CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
|
||||||
SupportedCurves: []CurveID{CurveP256},
|
SupportedCurves: []CurveID{CurveP256},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue