2019-05-31 09:45:11 +00:00
|
|
|
/*
|
|
|
|
Copyright 2017 The Kubernetes 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 flag
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"k8s.io/apimachinery/pkg/util/sets"
|
|
|
|
)
|
|
|
|
|
2021-12-08 13:50:47 +00:00
|
|
|
var (
|
|
|
|
// ciphers maps strings into tls package cipher constants in
|
|
|
|
// https://golang.org/pkg/crypto/tls/#pkg-constants
|
|
|
|
ciphers = map[string]uint16{}
|
|
|
|
insecureCiphers = map[string]uint16{}
|
|
|
|
)
|
2019-05-31 09:45:11 +00:00
|
|
|
|
2021-12-08 13:50:47 +00:00
|
|
|
func init() {
|
|
|
|
for _, suite := range tls.CipherSuites() {
|
|
|
|
ciphers[suite.Name] = suite.ID
|
|
|
|
}
|
|
|
|
// keep legacy names for backward compatibility
|
|
|
|
ciphers["TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"] = tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
|
|
|
ciphers["TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"] = tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
|
|
|
|
|
|
|
for _, suite := range tls.InsecureCipherSuites() {
|
|
|
|
insecureCiphers[suite.Name] = suite.ID
|
|
|
|
}
|
2020-12-17 12:28:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// InsecureTLSCiphers returns the cipher suites implemented by crypto/tls which have
|
|
|
|
// security issues.
|
|
|
|
func InsecureTLSCiphers() map[string]uint16 {
|
|
|
|
cipherKeys := make(map[string]uint16, len(insecureCiphers))
|
|
|
|
for k, v := range insecureCiphers {
|
|
|
|
cipherKeys[k] = v
|
|
|
|
}
|
|
|
|
return cipherKeys
|
|
|
|
}
|
|
|
|
|
|
|
|
// InsecureTLSCipherNames returns a list of cipher suite names implemented by crypto/tls
|
|
|
|
// which have security issues.
|
|
|
|
func InsecureTLSCipherNames() []string {
|
|
|
|
cipherKeys := sets.NewString()
|
|
|
|
for key := range insecureCiphers {
|
|
|
|
cipherKeys.Insert(key)
|
|
|
|
}
|
|
|
|
return cipherKeys.List()
|
|
|
|
}
|
|
|
|
|
|
|
|
// PreferredTLSCipherNames returns a list of cipher suite names implemented by crypto/tls.
|
|
|
|
func PreferredTLSCipherNames() []string {
|
2019-05-31 09:45:11 +00:00
|
|
|
cipherKeys := sets.NewString()
|
|
|
|
for key := range ciphers {
|
|
|
|
cipherKeys.Insert(key)
|
|
|
|
}
|
|
|
|
return cipherKeys.List()
|
|
|
|
}
|
|
|
|
|
2020-12-17 12:28:29 +00:00
|
|
|
func allCiphers() map[string]uint16 {
|
|
|
|
acceptedCiphers := make(map[string]uint16, len(ciphers)+len(insecureCiphers))
|
|
|
|
for k, v := range ciphers {
|
|
|
|
acceptedCiphers[k] = v
|
|
|
|
}
|
|
|
|
for k, v := range insecureCiphers {
|
|
|
|
acceptedCiphers[k] = v
|
|
|
|
}
|
|
|
|
return acceptedCiphers
|
|
|
|
}
|
|
|
|
|
|
|
|
// TLSCipherPossibleValues returns all acceptable cipher suite names.
|
|
|
|
// This is a combination of both InsecureTLSCipherNames() and PreferredTLSCipherNames().
|
|
|
|
func TLSCipherPossibleValues() []string {
|
|
|
|
cipherKeys := sets.NewString()
|
|
|
|
acceptedCiphers := allCiphers()
|
|
|
|
for key := range acceptedCiphers {
|
|
|
|
cipherKeys.Insert(key)
|
|
|
|
}
|
|
|
|
return cipherKeys.List()
|
|
|
|
}
|
|
|
|
|
|
|
|
// TLSCipherSuites returns a list of cipher suite IDs from the cipher suite names passed.
|
2019-05-31 09:45:11 +00:00
|
|
|
func TLSCipherSuites(cipherNames []string) ([]uint16, error) {
|
|
|
|
if len(cipherNames) == 0 {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
ciphersIntSlice := make([]uint16, 0)
|
2020-12-17 12:28:29 +00:00
|
|
|
possibleCiphers := allCiphers()
|
2019-05-31 09:45:11 +00:00
|
|
|
for _, cipher := range cipherNames {
|
2020-12-17 12:28:29 +00:00
|
|
|
intValue, ok := possibleCiphers[cipher]
|
2019-05-31 09:45:11 +00:00
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("Cipher suite %s not supported or doesn't exist", cipher)
|
|
|
|
}
|
|
|
|
ciphersIntSlice = append(ciphersIntSlice, intValue)
|
|
|
|
}
|
|
|
|
return ciphersIntSlice, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var versions = map[string]uint16{
|
|
|
|
"VersionTLS10": tls.VersionTLS10,
|
|
|
|
"VersionTLS11": tls.VersionTLS11,
|
|
|
|
"VersionTLS12": tls.VersionTLS12,
|
2019-06-14 09:24:43 +00:00
|
|
|
"VersionTLS13": tls.VersionTLS13,
|
2019-05-31 09:45:11 +00:00
|
|
|
}
|
|
|
|
|
2020-12-17 12:28:29 +00:00
|
|
|
// TLSPossibleVersions returns all acceptable values for TLS Version.
|
2019-05-31 09:45:11 +00:00
|
|
|
func TLSPossibleVersions() []string {
|
|
|
|
versionsKeys := sets.NewString()
|
|
|
|
for key := range versions {
|
|
|
|
versionsKeys.Insert(key)
|
|
|
|
}
|
|
|
|
return versionsKeys.List()
|
|
|
|
}
|
|
|
|
|
2020-12-17 12:28:29 +00:00
|
|
|
// TLSVersion returns the TLS Version ID for the version name passed.
|
2019-05-31 09:45:11 +00:00
|
|
|
func TLSVersion(versionName string) (uint16, error) {
|
|
|
|
if len(versionName) == 0 {
|
|
|
|
return DefaultTLSVersion(), nil
|
|
|
|
}
|
|
|
|
if version, ok := versions[versionName]; ok {
|
|
|
|
return version, nil
|
|
|
|
}
|
|
|
|
return 0, fmt.Errorf("unknown tls version %q", versionName)
|
|
|
|
}
|
|
|
|
|
2020-12-17 12:28:29 +00:00
|
|
|
// DefaultTLSVersion defines the default TLS Version.
|
2019-05-31 09:45:11 +00:00
|
|
|
func DefaultTLSVersion() uint16 {
|
|
|
|
// Can't use SSLv3 because of POODLE and BEAST
|
|
|
|
// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
|
|
|
|
// Can't use TLSv1.1 because of RC4 cipher usage
|
|
|
|
return tls.VersionTLS12
|
|
|
|
}
|