diff --git a/pkg/tlsutil/cipher_suites.go b/pkg/tlsutil/cipher_suites.go index f278a61f8..eac2497c9 100644 --- a/pkg/tlsutil/cipher_suites.go +++ b/pkg/tlsutil/cipher_suites.go @@ -1,3 +1,5 @@ +// +build !go1.15 + // Copyright 2018 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,24 +18,36 @@ package tlsutil import "crypto/tls" +// cipher suites implemented by Go +// https://github.com/golang/go/blob/dev.boringcrypto.go1.10/src/crypto/tls/cipher_suites.go +var cipherSuites = map[string]uint16{ + "TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA, + "TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA, + "TLS_RSA_WITH_AES_256_CBC_SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_RSA_WITH_AES_128_CBC_SHA256, + "TLS_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_RSA_WITH_AES_128_GCM_SHA256, + "TLS_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_RSA_WITH_RC4_128_SHA": tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, + "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, +} + // GetCipherSuite returns the corresponding cipher suite, // and boolean value if it is supported. func GetCipherSuite(s string) (uint16, bool) { - for _, c := range tls.CipherSuites() { - if s == c.Name { - return c.ID, true - } - } - for _, c := range tls.InsecureCipherSuites() { - if s == c.Name { - return c.ID, true - } - } - switch s { - case "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305": - return tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, true - case "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": - return tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, true - } - return 0, false + v, ok := cipherSuites[s] + return v, ok } diff --git a/pkg/tlsutil/cipher_suites_go1.15.go b/pkg/tlsutil/cipher_suites_go1.15.go new file mode 100644 index 000000000..de2044214 --- /dev/null +++ b/pkg/tlsutil/cipher_suites_go1.15.go @@ -0,0 +1,41 @@ +// +build go1.15 + +// Copyright 2018 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tlsutil + +import "crypto/tls" + +// GetCipherSuite returns the corresponding cipher suite, +// and boolean value if it is supported. +func GetCipherSuite(s string) (uint16, bool) { + for _, c := range tls.CipherSuites() { + if s == c.Name { + return c.ID, true + } + } + for _, c := range tls.InsecureCipherSuites() { + if s == c.Name { + return c.ID, true + } + } + switch s { + case "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305": + return tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, true + case "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305": + return tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, true + } + return 0, false +} diff --git a/pkg/tlsutil/cipher_suites_go1.15_test.go b/pkg/tlsutil/cipher_suites_go1.15_test.go new file mode 100644 index 000000000..c00eef373 --- /dev/null +++ b/pkg/tlsutil/cipher_suites_go1.15_test.go @@ -0,0 +1,52 @@ +// +build go1.15 + +// Copyright 2018 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tlsutil + +import ( + "crypto/tls" + "testing" +) + +func TestGetCipherSuite_not_existing(t *testing.T) { + _, ok := GetCipherSuite("not_existing") + if ok { + t.Fatal("Expected not ok") + } +} + +func CipherSuiteExpectedToExist(tb testing.TB, cipher string, expectedId uint16) { + vid, ok := GetCipherSuite(cipher) + if !ok { + tb.Errorf("Expected %v cipher to exist", cipher) + } + if vid != expectedId { + tb.Errorf("For %v expected=%v found=%v", cipher, expectedId, vid) + } +} + +func TestGetCipherSuite_success(t *testing.T) { + CipherSuiteExpectedToExist(t, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) + CipherSuiteExpectedToExist(t, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) + + // Explicit test for legacy names + CipherSuiteExpectedToExist(t, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) + CipherSuiteExpectedToExist(t, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) +} + +func TestGetCipherSuite_insecure(t *testing.T) { + CipherSuiteExpectedToExist(t, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA) +} diff --git a/pkg/tlsutil/cipher_suites_test.go b/pkg/tlsutil/cipher_suites_test.go index a17b46c2f..4b60cff05 100644 --- a/pkg/tlsutil/cipher_suites_test.go +++ b/pkg/tlsutil/cipher_suites_test.go @@ -1,3 +1,5 @@ +// +build !go1.15 + // Copyright 2018 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,36 +17,28 @@ package tlsutil import ( - "crypto/tls" + "go/importer" + "reflect" + "strings" "testing" ) -func TestGetCipherSuite_not_existing(t *testing.T) { - _, ok := GetCipherSuite("not_existing") - if ok { - t.Fatal("Expected not ok") +func TestGetCipherSuites(t *testing.T) { + pkg, err := importer.For("source", nil).Import("crypto/tls") + if err != nil { + t.Fatal(err) + } + cm := make(map[string]uint16) + for _, s := range pkg.Scope().Names() { + if strings.HasPrefix(s, "TLS_RSA_") || strings.HasPrefix(s, "TLS_ECDHE_") { + v, ok := GetCipherSuite(s) + if !ok { + t.Fatalf("Go implements missing cipher suite %q (%v)", s, v) + } + cm[s] = v + } + } + if !reflect.DeepEqual(cm, cipherSuites) { + t.Fatalf("found unmatched cipher suites %v (Go) != %v", cm, cipherSuites) } } - -func CipherSuiteExpectedToExist(tb testing.TB, cipher string, expectedId uint16) { - vid, ok := GetCipherSuite(cipher) - if !ok { - tb.Errorf("Expected %v cipher to exist", cipher) - } - if vid != expectedId { - tb.Errorf("For %v expected=%v found=%v", cipher, expectedId, vid) - } -} - -func TestGetCipherSuite_success(t *testing.T) { - CipherSuiteExpectedToExist(t, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) - CipherSuiteExpectedToExist(t, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) - - // Explicit test for legacy names - CipherSuiteExpectedToExist(t, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) - CipherSuiteExpectedToExist(t, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) -} - -func TestGetCipherSuite_insecure(t *testing.T) { - CipherSuiteExpectedToExist(t, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA) -}