From 11872f1162d22a2a5ce2db3eac4574712148d7ce Mon Sep 17 00:00:00 2001 From: Matthew Stevenson <52979934+matthewstevenson88@users.noreply.github.com> Date: Wed, 29 May 2024 09:02:03 -0700 Subject: [PATCH] advancedtls: add CipherSuites to Options (#7269) --- security/advancedtls/advancedtls.go | 12 ++++++-- security/advancedtls/advancedtls_test.go | 35 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/security/advancedtls/advancedtls.go b/security/advancedtls/advancedtls.go index 4a3daec86..e8ed9765b 100644 --- a/security/advancedtls/advancedtls.go +++ b/security/advancedtls/advancedtls.go @@ -284,6 +284,10 @@ type Options struct { // which is currently TLS 1.3. This default may be changed over time // affecting backwards compatibility. MaxTLSVersion uint16 + // CipherSuites is an unordered list of supported TLS 1.0–1.2 + // ciphersuites. TLS 1.3 ciphersuites are not configurable. If nil, a + // safe default list is used. + CipherSuites []uint16 // serverNameOverride is for testing only and only relevant on the client // side. If set to a non-empty string, it will override the virtual host // name of authority (e.g. :authority header field) in requests and the @@ -353,6 +357,7 @@ func (o *Options) clientConfig() (*tls.Config, error) { InsecureSkipVerify: true, MinVersion: o.MinTLSVersion, MaxVersion: o.MaxTLSVersion, + CipherSuites: o.CipherSuites, } // Propagate root-certificate-related fields in tls.Config. switch { @@ -467,9 +472,10 @@ func (o *Options) serverConfig() (*tls.Config, error) { o.MaxTLSVersion = tls.VersionTLS13 } config := &tls.Config{ - ClientAuth: clientAuth, - MinVersion: o.MinTLSVersion, - MaxVersion: o.MaxTLSVersion, + ClientAuth: clientAuth, + MinVersion: o.MinTLSVersion, + MaxVersion: o.MaxTLSVersion, + CipherSuites: o.CipherSuites, } // Propagate root-certificate-related fields in tls.Config. switch { diff --git a/security/advancedtls/advancedtls_test.go b/security/advancedtls/advancedtls_test.go index e7d0fad2e..7a39b241d 100644 --- a/security/advancedtls/advancedtls_test.go +++ b/security/advancedtls/advancedtls_test.go @@ -29,6 +29,7 @@ import ( "os" "testing" + "github.com/google/go-cmp/cmp" lru "github.com/hashicorp/golang-lru" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/tls/certprovider" @@ -172,6 +173,7 @@ func (s) TestClientOptionsConfigSuccessCases(t *testing.T) { RootOptions RootCertificateOptions MinVersion uint16 MaxVersion uint16 + cipherSuites []uint16 }{ { desc: "Use system default if no fields in RootCertificateOptions is specified", @@ -196,6 +198,15 @@ func (s) TestClientOptionsConfigSuccessCases(t *testing.T) { RootCACerts: x509.NewCertPool(), }, }, + { + desc: "Ciphersuite plumbing through client options", + cipherSuites: []uint16{ + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + }, + }, } for _, test := range tests { test := test @@ -206,6 +217,7 @@ func (s) TestClientOptionsConfigSuccessCases(t *testing.T) { RootOptions: test.RootOptions, MinTLSVersion: test.MinVersion, MaxTLSVersion: test.MaxVersion, + CipherSuites: test.cipherSuites, } clientConfig, err := clientOptions.clientConfig() if err != nil { @@ -237,6 +249,9 @@ func (s) TestClientOptionsConfigSuccessCases(t *testing.T) { t.Fatalf("Default max tls version not set correctly") } } + if diff := cmp.Diff(clientConfig.CipherSuites, test.cipherSuites); diff != "" { + t.Errorf("cipherSuites diff (-want +got):\n%s", diff) + } }) } } @@ -335,6 +350,7 @@ func (s) TestServerOptionsConfigSuccessCases(t *testing.T) { RootOptions RootCertificateOptions MinVersion uint16 MaxVersion uint16 + cipherSuites []uint16 }{ { desc: "Use system default if no fields in RootCertificateOptions is specified", @@ -368,6 +384,21 @@ func (s) TestServerOptionsConfigSuccessCases(t *testing.T) { RootCACerts: x509.NewCertPool(), }, }, + { + desc: "Ciphersuite plumbing through server options", + IdentityOptions: IdentityCertificateOptions{ + Certificates: []tls.Certificate{}, + }, + RootOptions: RootCertificateOptions{ + RootCACerts: x509.NewCertPool(), + }, + cipherSuites: []uint16{ + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + }, + }, } for _, test := range tests { test := test @@ -379,6 +410,7 @@ func (s) TestServerOptionsConfigSuccessCases(t *testing.T) { RootOptions: test.RootOptions, MinTLSVersion: test.MinVersion, MaxTLSVersion: test.MaxVersion, + CipherSuites: test.cipherSuites, } serverConfig, err := serverOptions.serverConfig() if err != nil { @@ -392,6 +424,9 @@ func (s) TestServerOptionsConfigSuccessCases(t *testing.T) { t.Fatalf("Failed to assign system-provided certificates on the server side.") } } + if diff := cmp.Diff(serverConfig.CipherSuites, test.cipherSuites); diff != "" { + t.Errorf("cipherSuites diff (-want +got):\n%s", diff) + } }) } }