mirror of https://github.com/hashicorp/consul
tlsutil: initial implementation of types/TLSVersion
tlsutil: add test for parsing deprecated agent TLS version strings tlsutil: return TLSVersionInvalid with errorpull/11647/head
parent
5ec561c8d6
commit
37f8880291
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/logging"
|
"github.com/hashicorp/consul/logging"
|
||||||
|
"github.com/hashicorp/consul/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ALPNWrapper is a function that is used to wrap a non-TLS connection and
|
// ALPNWrapper is a function that is used to wrap a non-TLS connection and
|
||||||
|
@ -35,13 +36,35 @@ type DCWrapper func(dc string, conn net.Conn) (net.Conn, error)
|
||||||
// a constant value. This is usually done by currying DCWrapper.
|
// a constant value. This is usually done by currying DCWrapper.
|
||||||
type Wrapper func(conn net.Conn) (net.Conn, error)
|
type Wrapper func(conn net.Conn) (net.Conn, error)
|
||||||
|
|
||||||
// tlsLookup maps the tls_min_version configuration to the internal value
|
// GoTLSVersions maps types.TLSVersion to the Go internal value
|
||||||
var tlsLookup = map[string]uint16{
|
var GoTLSVersions = map[types.TLSVersion]uint16{
|
||||||
"": tls.VersionTLS10, // default in golang
|
types.TLSVersionAuto: tls.VersionTLS10, // default in golang
|
||||||
"tls10": tls.VersionTLS10,
|
types.TLSv1_0: tls.VersionTLS10,
|
||||||
"tls11": tls.VersionTLS11,
|
types.TLSv1_1: tls.VersionTLS11,
|
||||||
"tls12": tls.VersionTLS12,
|
types.TLSv1_2: tls.VersionTLS12,
|
||||||
"tls13": tls.VersionTLS13,
|
types.TLSv1_3: tls.VersionTLS13,
|
||||||
|
}
|
||||||
|
|
||||||
|
// tlsLookup maps a TLS version configuration string to the internal value
|
||||||
|
func tlsLookup(tlsVersionString string) (types.TLSVersion, error) {
|
||||||
|
// Handle empty string case for unspecified config
|
||||||
|
if tlsVersionString == "" {
|
||||||
|
return types.TLSVersionAuto, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if tlsVersion, ok := types.TLSVersions[tlsVersionString]; ok {
|
||||||
|
return tlsVersion, nil
|
||||||
|
} else {
|
||||||
|
// NOTE: This inner check for deprecated values should eventually be removed
|
||||||
|
if tlsVersion, ok := types.DeprecatedAgentTLSVersions[tlsVersionString]; ok {
|
||||||
|
// TODO: log warning about deprecated config
|
||||||
|
return tlsVersion, nil
|
||||||
|
} else {
|
||||||
|
// Only suggest non-deprecated values if configured value is invalid
|
||||||
|
versions := strings.Join(tlsVersions(), ", ")
|
||||||
|
return types.TLSVersionInvalid, fmt.Errorf("TLSMinVersion: value %s not supported, please specify one of [%s]", tlsVersionString, versions)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config used to create tls.Config
|
// Config used to create tls.Config
|
||||||
|
@ -131,10 +154,8 @@ type Config struct {
|
||||||
|
|
||||||
func tlsVersions() []string {
|
func tlsVersions() []string {
|
||||||
versions := []string{}
|
versions := []string{}
|
||||||
for v := range tlsLookup {
|
for v := range types.TLSVersions {
|
||||||
if v != "" {
|
versions = append(versions, v)
|
||||||
versions = append(versions, v)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sort.Strings(versions)
|
sort.Strings(versions)
|
||||||
return versions
|
return versions
|
||||||
|
@ -371,12 +392,11 @@ func newX509CertPool(groups ...[]string) (*x509.CertPool, error) {
|
||||||
// validateConfig checks that config is valid and does not conflict with the pool
|
// validateConfig checks that config is valid and does not conflict with the pool
|
||||||
// or cert.
|
// or cert.
|
||||||
func validateConfig(config Config, pool *x509.CertPool, cert *tls.Certificate) error {
|
func validateConfig(config Config, pool *x509.CertPool, cert *tls.Certificate) error {
|
||||||
// Check if a minimum TLS version was set
|
// Check if a minimum TLS version was set,
|
||||||
if config.TLSMinVersion != "" {
|
// returns TLSVersionAuto if config.TLSMinVersion is empty
|
||||||
if _, ok := tlsLookup[config.TLSMinVersion]; !ok {
|
_, err := tlsLookup(config.TLSMinVersion)
|
||||||
versions := strings.Join(tlsVersions(), ", ")
|
if err != nil {
|
||||||
return fmt.Errorf("TLSMinVersion: value %s not supported, please specify one of [%s]", config.TLSMinVersion, versions)
|
return err
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure we have a CA if VerifyOutgoing is set
|
// Ensure we have a CA if VerifyOutgoing is set
|
||||||
|
@ -515,10 +535,12 @@ func (c *Configurator) commonTLSConfig(verifyIncoming bool) *tls.Config {
|
||||||
tlsConfig.ClientCAs = c.caPool
|
tlsConfig.ClientCAs = c.caPool
|
||||||
tlsConfig.RootCAs = c.caPool
|
tlsConfig.RootCAs = c.caPool
|
||||||
|
|
||||||
// This is possible because tlsLookup also contains "" with golang's
|
// Error handling is not needed here because tlsLookup handles "" as
|
||||||
// default (tls10). And because the initial check makes sure the
|
// TLSVersionAuto with GoTLSVersions mapping TLSVersionAuto to Go's
|
||||||
// version correctly matches.
|
// default (tls10) and because the initial check in validateConfig makes
|
||||||
tlsConfig.MinVersion = tlsLookup[c.base.TLSMinVersion]
|
// sure the version is not invalid.
|
||||||
|
tlsVersion, _ := tlsLookup(c.base.TLSMinVersion)
|
||||||
|
tlsConfig.MinVersion = GoTLSVersions[tlsVersion]
|
||||||
|
|
||||||
// Set ClientAuth if necessary
|
// Set ClientAuth if necessary
|
||||||
if verifyIncoming {
|
if verifyIncoming {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/hashicorp/consul/sdk/testutil"
|
"github.com/hashicorp/consul/sdk/testutil"
|
||||||
|
"github.com/hashicorp/consul/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startRPCTLSServer(config *Config) (net.Conn, chan error) {
|
func startRPCTLSServer(config *Config) (net.Conn, chan error) {
|
||||||
|
@ -719,12 +720,24 @@ func TestConfigurator_CommonTLSConfigCAs(t *testing.T) {
|
||||||
func TestConfigurator_CommonTLSConfigTLSMinVersion(t *testing.T) {
|
func TestConfigurator_CommonTLSConfigTLSMinVersion(t *testing.T) {
|
||||||
c, err := NewConfigurator(Config{TLSMinVersion: ""}, nil)
|
c, err := NewConfigurator(Config{TLSMinVersion: ""}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, c.commonTLSConfig(false).MinVersion, tlsLookup["tls10"])
|
tlsVersion, _ := tlsLookup("TLSv1_0")
|
||||||
|
require.Equal(t, c.commonTLSConfig(false).MinVersion, GoTLSVersions[tlsVersion])
|
||||||
|
|
||||||
for _, version := range tlsVersions() {
|
for _, version := range tlsVersions() {
|
||||||
require.NoError(t, c.Update(Config{TLSMinVersion: version}))
|
require.NoError(t, c.Update(Config{TLSMinVersion: version}))
|
||||||
|
tlsVersion, _ := tlsLookup(version)
|
||||||
require.Equal(t, c.commonTLSConfig(false).MinVersion,
|
require.Equal(t, c.commonTLSConfig(false).MinVersion,
|
||||||
tlsLookup[version])
|
GoTLSVersions[tlsVersion])
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: checks for deprecated TLS version string warnings,
|
||||||
|
// should be removed when removing support for these config values
|
||||||
|
for version := range types.DeprecatedAgentTLSVersions {
|
||||||
|
// TODO: check for warning log message? how?
|
||||||
|
require.NoError(t, c.Update(Config{TLSMinVersion: version}))
|
||||||
|
tlsVersion, _ := tlsLookup(version)
|
||||||
|
require.Equal(t, c.commonTLSConfig(false).MinVersion,
|
||||||
|
GoTLSVersions[tlsVersion])
|
||||||
}
|
}
|
||||||
|
|
||||||
require.Error(t, c.Update(Config{TLSMinVersion: "tlsBOGUS"}))
|
require.Error(t, c.Update(Config{TLSMinVersion: "tlsBOGUS"}))
|
||||||
|
@ -1439,7 +1452,7 @@ func certChain(t *testing.T, certs ...string) []*x509.Certificate {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfig_tlsVersions(t *testing.T) {
|
func TestConfig_tlsVersions(t *testing.T) {
|
||||||
require.Equal(t, []string{"tls10", "tls11", "tls12", "tls13"}, tlsVersions())
|
require.Equal(t, []string{"TLS_AUTO", "TLSv1_0", "TLSv1_1", "TLSv1_2", "TLSv1_3"}, tlsVersions())
|
||||||
expected := "tls10, tls11, tls12, tls13"
|
expected := "TLS_AUTO, TLSv1_0, TLSv1_1, TLSv1_2, TLSv1_3"
|
||||||
require.Equal(t, expected, strings.Join(tlsVersions(), ", "))
|
require.Equal(t, expected, strings.Join(tlsVersions(), ", "))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue