mirror of https://github.com/golang/go.git
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:
parent
5fee159bc2
commit
032660573c
|
|
@ -197,6 +197,10 @@ Go 1.23 re-enabled support in html/template for ECMAScript 6 template literals b
|
||||||
The [`jstmpllitinterp` setting](/pkg/html/template#hdr-Security_Model) no longer has
|
The [`jstmpllitinterp` setting](/pkg/html/template#hdr-Security_Model) no longer has
|
||||||
any effect.
|
any effect.
|
||||||
|
|
||||||
|
Go 1.23 changed the default TLS cipher suites used by clients and servers when
|
||||||
|
not explicitly configured, removing 3DES cipher suites. The default can be reverted
|
||||||
|
using the [`tls3des` setting](/pkg/crypto/tls/#Config.CipherSuites).
|
||||||
|
|
||||||
### Go 1.22
|
### Go 1.22
|
||||||
|
|
||||||
Go 1.22 adds a configurable limit to control the maximum acceptable RSA key size
|
Go 1.22 adds a configurable limit to control the maximum acceptable RSA key size
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
3DES cipher suites were removed from the default list used when
|
||||||
|
[Config.CipherSuites] is nil. The default can be reverted adding `tls3des=1` to
|
||||||
|
the GODEBUG environment variable.
|
||||||
|
|
@ -17,7 +17,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
"internal/cpu"
|
"internal/cpu"
|
||||||
|
"internal/godebug"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"golang.org/x/crypto/chacha20poly1305"
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
)
|
)
|
||||||
|
|
@ -334,6 +336,8 @@ var disabledCipherSuites = map[uint16]bool{
|
||||||
TLS_RSA_WITH_RC4_128_SHA: true,
|
TLS_RSA_WITH_RC4_128_SHA: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tlsrsakex = godebug.New("tlsrsakex")
|
||||||
|
|
||||||
// rsaKexCiphers contains the ciphers which use RSA based key exchange,
|
// rsaKexCiphers contains the ciphers which use RSA based key exchange,
|
||||||
// which we also disable by default unless a GODEBUG is set.
|
// which we also disable by default unless a GODEBUG is set.
|
||||||
var rsaKexCiphers = map[uint16]bool{
|
var rsaKexCiphers = map[uint16]bool{
|
||||||
|
|
@ -346,21 +350,22 @@ var rsaKexCiphers = map[uint16]bool{
|
||||||
TLS_RSA_WITH_AES_256_GCM_SHA384: true,
|
TLS_RSA_WITH_AES_256_GCM_SHA384: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultCipherSuites []uint16
|
var tls3des = godebug.New("tls3des")
|
||||||
var defaultCipherSuitesWithRSAKex []uint16
|
|
||||||
|
|
||||||
func init() {
|
// tdesCiphers contains 3DES ciphers,
|
||||||
defaultCipherSuites = make([]uint16, 0, len(cipherSuitesPreferenceOrder))
|
// which we also disable by default unless a GODEBUG is set.
|
||||||
defaultCipherSuitesWithRSAKex = make([]uint16, 0, len(cipherSuitesPreferenceOrder))
|
var tdesCiphers = map[uint16]bool{
|
||||||
for _, c := range cipherSuitesPreferenceOrder {
|
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: true,
|
||||||
if disabledCipherSuites[c] {
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA: true,
|
||||||
continue
|
}
|
||||||
}
|
|
||||||
if !rsaKexCiphers[c] {
|
func defaultCipherSuites() []uint16 {
|
||||||
defaultCipherSuites = append(defaultCipherSuites, c)
|
suites := slices.Clone(cipherSuitesPreferenceOrder)
|
||||||
}
|
return slices.DeleteFunc(suites, func(c uint16) bool {
|
||||||
defaultCipherSuitesWithRSAKex = append(defaultCipherSuitesWithRSAKex, c)
|
return disabledCipherSuites[c] ||
|
||||||
}
|
tlsrsakex.Value() != "1" && rsaKexCiphers[c] ||
|
||||||
|
tls3des.Value() != "1" && tdesCiphers[c]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultCipherSuitesTLS13 is also the preference order, since there are no
|
// defaultCipherSuitesTLS13 is also the preference order, since there are no
|
||||||
|
|
|
||||||
|
|
@ -687,7 +687,9 @@ type Config struct {
|
||||||
// If CipherSuites is nil, a safe default list is used. The default cipher
|
// 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 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
|
// 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
|
CipherSuites []uint16
|
||||||
|
|
||||||
// PreferServerCipherSuites is a legacy field and has no effect.
|
// PreferServerCipherSuites is a legacy field and has no effect.
|
||||||
|
|
@ -1025,8 +1027,6 @@ func (c *Config) time() time.Time {
|
||||||
return t()
|
return t()
|
||||||
}
|
}
|
||||||
|
|
||||||
var tlsrsakex = godebug.New("tlsrsakex")
|
|
||||||
|
|
||||||
func (c *Config) cipherSuites() []uint16 {
|
func (c *Config) cipherSuites() []uint16 {
|
||||||
if needFIPS() {
|
if needFIPS() {
|
||||||
return fipsCipherSuites(c)
|
return fipsCipherSuites(c)
|
||||||
|
|
@ -1034,10 +1034,7 @@ func (c *Config) cipherSuites() []uint16 {
|
||||||
if c.CipherSuites != nil {
|
if c.CipherSuites != nil {
|
||||||
return c.CipherSuites
|
return c.CipherSuites
|
||||||
}
|
}
|
||||||
if tlsrsakex.Value() == "1" {
|
return defaultCipherSuites()
|
||||||
return defaultCipherSuitesWithRSAKex
|
|
||||||
}
|
|
||||||
return defaultCipherSuites
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var supportedVersions = []uint16{
|
var supportedVersions = []uint16{
|
||||||
|
|
|
||||||
|
|
@ -551,6 +551,10 @@ func (hs *clientHandshakeState) pickCipherSuite() error {
|
||||||
tlsrsakex.Value() // ensure godebug is initialized
|
tlsrsakex.Value() // ensure godebug is initialized
|
||||||
tlsrsakex.IncNonDefault()
|
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
|
hs.c.cipherSuite = hs.suite.id
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -376,6 +376,10 @@ func (hs *serverHandshakeState) pickCipherSuite() error {
|
||||||
tlsrsakex.Value() // ensure godebug is initialized
|
tlsrsakex.Value() // ensure godebug is initialized
|
||||||
tlsrsakex.IncNonDefault()
|
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 {
|
for _, id := range hs.clientHello.cipherSuites {
|
||||||
if id == TLS_FALLBACK_SCSV {
|
if id == TLS_FALLBACK_SCSV {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
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 {
|
if got := CipherSuiteName(c.id); got != cc.Name {
|
||||||
t.Errorf("%#04x: unexpected CipherSuiteName: got %q, expected %q", 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) {
|
if len(cipherSuitesPreferenceOrderNoAES) != len(cipherSuitesPreferenceOrder) {
|
||||||
t.Errorf("cipherSuitesPreferenceOrderNoAES is not the same size as 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.
|
// Check that disabled suites are marked insecure.
|
||||||
for _, badSuites := range []map[uint16]bool{disabledCipherSuites, rsaKexCiphers} {
|
for _, badSuites := range []map[uint16]bool{disabledCipherSuites, rsaKexCiphers} {
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ var All = []Info{
|
||||||
{Name: "randautoseed", Package: "math/rand"},
|
{Name: "randautoseed", Package: "math/rand"},
|
||||||
{Name: "tarinsecurepath", Package: "archive/tar"},
|
{Name: "tarinsecurepath", Package: "archive/tar"},
|
||||||
{Name: "tls10server", Package: "crypto/tls", Changed: 22, Old: "1"},
|
{Name: "tls10server", Package: "crypto/tls", Changed: 22, Old: "1"},
|
||||||
|
{Name: "tls3des", Package: "crypto/tls", Changed: 23, Old: "1"},
|
||||||
{Name: "tlskyber", Package: "crypto/tls", Changed: 23, Old: "0", Opaque: true},
|
{Name: "tlskyber", Package: "crypto/tls", Changed: 23, Old: "0", Opaque: true},
|
||||||
{Name: "tlsmaxrsasize", Package: "crypto/tls"},
|
{Name: "tlsmaxrsasize", Package: "crypto/tls"},
|
||||||
{Name: "tlsrsakex", Package: "crypto/tls", Changed: 22, Old: "1"},
|
{Name: "tlsrsakex", Package: "crypto/tls", Changed: 22, Old: "1"},
|
||||||
|
|
|
||||||
|
|
@ -946,7 +946,7 @@ func testResponseSetsTLSConnectionState(t *testing.T, mode testMode) {
|
||||||
|
|
||||||
c := ts.Client()
|
c := ts.Client()
|
||||||
tr := c.Transport.(*Transport)
|
tr := c.Transport.(*Transport)
|
||||||
tr.TLSClientConfig.CipherSuites = []uint16{tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA}
|
tr.TLSClientConfig.CipherSuites = []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
|
||||||
tr.TLSClientConfig.MaxVersion = tls.VersionTLS12 // to get to pick the cipher suite
|
tr.TLSClientConfig.MaxVersion = tls.VersionTLS12 // to get to pick the cipher suite
|
||||||
tr.Dial = func(netw, addr string) (net.Conn, error) {
|
tr.Dial = func(netw, addr string) (net.Conn, error) {
|
||||||
return net.Dial(netw, ts.Listener.Addr().String())
|
return net.Dial(netw, ts.Listener.Addr().String())
|
||||||
|
|
@ -959,7 +959,7 @@ func testResponseSetsTLSConnectionState(t *testing.T, mode testMode) {
|
||||||
if res.TLS == nil {
|
if res.TLS == nil {
|
||||||
t.Fatal("Response didn't set TLS Connection State.")
|
t.Fatal("Response didn't set TLS Connection State.")
|
||||||
}
|
}
|
||||||
if got, want := res.TLS.CipherSuite, tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA; got != want {
|
if got, want := res.TLS.CipherSuite, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256; got != want {
|
||||||
t.Errorf("TLS Cipher Suite = %d; want %d", got, want)
|
t.Errorf("TLS Cipher Suite = %d; want %d", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,10 @@ Below is the full list of supported metrics, ordered lexicographically.
|
||||||
The number of non-default behaviors executed by the crypto/tls
|
The number of non-default behaviors executed by the crypto/tls
|
||||||
package due to a non-default GODEBUG=tls10server=... setting.
|
package due to a non-default GODEBUG=tls10server=... setting.
|
||||||
|
|
||||||
|
/godebug/non-default-behavior/tls3des:events
|
||||||
|
The number of non-default behaviors executed by the crypto/tls
|
||||||
|
package due to a non-default GODEBUG=tls3des=... setting.
|
||||||
|
|
||||||
/godebug/non-default-behavior/tlsmaxrsasize:events
|
/godebug/non-default-behavior/tlsmaxrsasize:events
|
||||||
The number of non-default behaviors executed by the crypto/tls
|
The number of non-default behaviors executed by the crypto/tls
|
||||||
package due to a non-default GODEBUG=tlsmaxrsasize=... setting.
|
package due to a non-default GODEBUG=tlsmaxrsasize=... setting.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue