]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/tls: disable 3-DES by default
authorFilippo Valsorda <filippo@golang.org>
Wed, 22 May 2024 09:39:41 +0000 (11:39 +0200)
committerGopher Robot <gobot@golang.org>
Wed, 22 May 2024 21:30:50 +0000 (21:30 +0000)
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>

doc/godebug.md
doc/next/6-stdlib/99-minor/crypto/tls/66214.md [new file with mode: 0644]
src/crypto/tls/cipher_suites.go
src/crypto/tls/common.go
src/crypto/tls/handshake_client.go
src/crypto/tls/handshake_server.go
src/crypto/tls/tls_test.go
src/internal/godebugs/table.go
src/net/http/client_test.go
src/runtime/metrics/doc.go

index b3a00a0c2b34f9eaa485e6486db0c154bd05bb7e..d5455e337cd63c06a840460b31870633941ab2e3 100644 (file)
@@ -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
 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 adds a configurable limit to control the maximum acceptable RSA key size
diff --git a/doc/next/6-stdlib/99-minor/crypto/tls/66214.md b/doc/next/6-stdlib/99-minor/crypto/tls/66214.md
new file mode 100644 (file)
index 0000000..4a32ca9
--- /dev/null
@@ -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.
index 6f5bc37197a4f4a1f23f816f829ac1368a80b5a7..622ad9b3e40121e95770f08a9d1926cc47c80970 100644 (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
index 1b0f19da9e0e883c7096bde102f7dc740c5b92a7..dcefa2ac9a90a8770987ec4a4f876793d17db592 100644 (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{
index 1a1738591130e2e587d20ff5ed1e0e1257324f98..d80b2326b37377da040f4fea2c127f0a14eb70b7 100644 (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
index 09ca8a4e5498bf696db76495db07b83b782e6725..ac3d915d1746d754f2e110a605faca5e6aedb6cb 100644 (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 {
index ce1c967c57f30a1db985dfbdf38cab1d91100835..69b57de1e680c7397c4f62f07fb42249e0285681 100644 (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} {
index 4ead2e09c6084e808688775de35e4d82ba50170f..eaa95d5aa9f9ff498c221a5f5e2d8d14c16598f1 100644 (file)
@@ -47,6 +47,7 @@ var All = []Info{
        {Name: "randautoseed", Package: "math/rand"},
        {Name: "tarinsecurepath", Package: "archive/tar"},
        {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: "tlsmaxrsasize", Package: "crypto/tls"},
        {Name: "tlsrsakex", Package: "crypto/tls", Changed: 22, Old: "1"},
index 33e69467c6a3f467e8c33231d0bdc4600b807b56..1faa1516479e75d9c04c59406e3c20f6f18bd04a 100644 (file)
@@ -946,7 +946,7 @@ func testResponseSetsTLSConnectionState(t *testing.T, mode testMode) {
 
        c := ts.Client()
        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.Dial = func(netw, addr string) (net.Conn, error) {
                return net.Dial(netw, ts.Listener.Addr().String())
@@ -959,7 +959,7 @@ func testResponseSetsTLSConnectionState(t *testing.T, mode testMode) {
        if res.TLS == nil {
                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)
        }
 }
index 8e99846e6d0f9534de4e67a704dffac318765fdb..2dd8ce261c14fecc61ef30edde264cf13d40b4b3 100644 (file)
@@ -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
                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
                The number of non-default behaviors executed by the crypto/tls
                package due to a non-default GODEBUG=tlsmaxrsasize=... setting.