"SendClientVersion-RSA": "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-Client-MissingUncompressed": "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",
"Basic-Client-NoTicket-TLS-Sync": "TODO: first pass, this should be fixed",
}
// 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 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 {
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
// 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) {
}
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
// 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 {
SupportedPoints: []uint8{1},
SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256},
SupportedVersions: []uint16{VersionTLS12},
- }, "doesn't support ECDHE"},
+ }, "only incompatible point formats"},
{ecdsaCert, &ClientHelloInfo{
CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
SupportedCurves: []CurveID{CurveP256},