crypto/tls: disable 3-DES by default

Fixes #66214

Change-Id: Iba8006a17fc7cd33c7485ab1a1ef8f56531c0ed1
Reviewed-on: https://go-review.googlesource.com/c/go/+/587295
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
Filippo Valsorda 2024-05-22 11:39:41 +02:00 committed by Gopher Robot
parent bbd7da73e1
commit 470b5f1f9d
5 changed files with 41 additions and 24 deletions

View file

@ -17,7 +17,9 @@ import (
"fmt"
"hash"
"internal/cpu"
"internal/godebug"
"runtime"
"slices"
"golang.org/x/crypto/chacha20poly1305"
)
@ -334,6 +336,8 @@ var disabledCipherSuites = map[uint16]bool{
TLS_RSA_WITH_RC4_128_SHA: true,
}
var tlsrsakex = godebug.New("tlsrsakex")
// rsaKexCiphers contains the ciphers which use RSA based key exchange,
// which we also disable by default unless a GODEBUG is set.
var rsaKexCiphers = map[uint16]bool{
@ -346,21 +350,22 @@ var rsaKexCiphers = map[uint16]bool{
TLS_RSA_WITH_AES_256_GCM_SHA384: true,
}
var defaultCipherSuites []uint16
var defaultCipherSuitesWithRSAKex []uint16
var tls3des = godebug.New("tls3des")
func init() {
defaultCipherSuites = make([]uint16, 0, len(cipherSuitesPreferenceOrder))
defaultCipherSuitesWithRSAKex = make([]uint16, 0, len(cipherSuitesPreferenceOrder))
for _, c := range cipherSuitesPreferenceOrder {
if disabledCipherSuites[c] {
continue
}
if !rsaKexCiphers[c] {
defaultCipherSuites = append(defaultCipherSuites, c)
}
defaultCipherSuitesWithRSAKex = append(defaultCipherSuitesWithRSAKex, c)
}
// tdesCiphers contains 3DES ciphers,
// which we also disable by default unless a GODEBUG is set.
var tdesCiphers = map[uint16]bool{
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: true,
TLS_RSA_WITH_3DES_EDE_CBC_SHA: true,
}
func defaultCipherSuites() []uint16 {
suites := slices.Clone(cipherSuitesPreferenceOrder)
return slices.DeleteFunc(suites, func(c uint16) bool {
return disabledCipherSuites[c] ||
tlsrsakex.Value() != "1" && rsaKexCiphers[c] ||
tls3des.Value() != "1" && tdesCiphers[c]
})
}
// defaultCipherSuitesTLS13 is also the preference order, since there are no

View file

@ -687,7 +687,9 @@ type Config struct {
// If CipherSuites is nil, a safe default list is used. The default cipher
// suites might change over time. In Go 1.22 RSA key exchange based cipher
// suites were removed from the default list, but can be re-added with the
// GODEBUG setting tlsrsakex=1.
// GODEBUG setting tlsrsakex=1. In Go 1.23 3DES cipher suites were removed
// from the default list, but can be re-added with the GODEBUG setting
// tls3des=1.
CipherSuites []uint16
// PreferServerCipherSuites is a legacy field and has no effect.
@ -1025,8 +1027,6 @@ func (c *Config) time() time.Time {
return t()
}
var tlsrsakex = godebug.New("tlsrsakex")
func (c *Config) cipherSuites() []uint16 {
if needFIPS() {
return fipsCipherSuites(c)
@ -1034,10 +1034,7 @@ func (c *Config) cipherSuites() []uint16 {
if c.CipherSuites != nil {
return c.CipherSuites
}
if tlsrsakex.Value() == "1" {
return defaultCipherSuitesWithRSAKex
}
return defaultCipherSuites
return defaultCipherSuites()
}
var supportedVersions = []uint16{

View file

@ -551,6 +551,10 @@ func (hs *clientHandshakeState) pickCipherSuite() error {
tlsrsakex.Value() // ensure godebug is initialized
tlsrsakex.IncNonDefault()
}
if hs.c.config.CipherSuites == nil && !needFIPS() && tdesCiphers[hs.suite.id] {
tls3des.Value() // ensure godebug is initialized
tls3des.IncNonDefault()
}
hs.c.cipherSuite = hs.suite.id
return nil

View file

@ -376,6 +376,10 @@ func (hs *serverHandshakeState) pickCipherSuite() error {
tlsrsakex.Value() // ensure godebug is initialized
tlsrsakex.IncNonDefault()
}
if c.config.CipherSuites == nil && !needFIPS() && tdesCiphers[hs.suite.id] {
tls3des.Value() // ensure godebug is initialized
tls3des.IncNonDefault()
}
for _, id := range hs.clientHello.cipherSuites {
if id == TLS_FALLBACK_SCSV {

View file

@ -1458,6 +1458,16 @@ func TestCipherSuites(t *testing.T) {
t.Errorf("%#04x: suite TLS 1.0-1.2, but SupportedVersions is %v", c.id, cc.SupportedVersions)
}
if cc.Insecure {
if slices.Contains(defaultCipherSuites(), c.id) {
t.Errorf("%#04x: insecure suite in default list", c.id)
}
} else {
if !slices.Contains(defaultCipherSuites(), c.id) {
t.Errorf("%#04x: secure suite not in default list", c.id)
}
}
if got := CipherSuiteName(c.id); got != cc.Name {
t.Errorf("%#04x: unexpected CipherSuiteName: got %q, expected %q", c.id, got, cc.Name)
}
@ -1491,9 +1501,6 @@ func TestCipherSuites(t *testing.T) {
if len(cipherSuitesPreferenceOrderNoAES) != len(cipherSuitesPreferenceOrder) {
t.Errorf("cipherSuitesPreferenceOrderNoAES is not the same size as cipherSuitesPreferenceOrder")
}
if len(defaultCipherSuites) >= len(defaultCipherSuitesWithRSAKex) {
t.Errorf("defaultCipherSuitesWithRSAKex should be longer than defaultCipherSuites")
}
// Check that disabled suites are marked insecure.
for _, badSuites := range []map[uint16]bool{disabledCipherSuites, rsaKexCiphers} {