Initial Diagnose Command for TLS and Listener [VAULT-1896, VAULT-1899] (#11249)

* sanity checks for tls config in diagnose

* backup

* backup

* backup

* added necessary tests

* remove comment

* remove parallels causing test flakiness

* comments

* small fix

* separate out config hcl test case into new hcl file

* newline

* addressed comments

* addressed comments

* addressed comments

* addressed comments

* addressed comments

* reload funcs should be allowed to be nil
This commit is contained in:
Hridoy Roy
2021-04-06 16:40:43 -07:00
committed by GitHub
parent 6a6ce395d3
commit 2fd30841cd
14 changed files with 523 additions and 100 deletions

View File

@@ -2,9 +2,13 @@ package command
import (
"strings"
"sync"
log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/internalshared/listenerutil"
"github.com/hashicorp/vault/internalshared/reloadutil"
"github.com/hashicorp/vault/sdk/version"
"github.com/hashicorp/vault/vault/diagnose"
"github.com/mitchellh/cli"
"github.com/posener/complete"
)
@@ -20,6 +24,12 @@ type OperatorDiagnoseCommand struct {
flagDebug bool
flagSkips []string
flagConfigs []string
cleanupGuard sync.Once
reloadFuncsLock *sync.RWMutex
reloadFuncs *map[string][]reloadutil.ReloadFunc
startedCh chan struct{} // for tests
reloadedCh chan struct{} // for tests
}
func (c *OperatorDiagnoseCommand) Synopsis() string {
@@ -110,7 +120,7 @@ func (c *OperatorDiagnoseCommand) RunWithParsedFlags() int {
}
c.UI.Output(version.GetVersion().FullVersionNumber(true))
rloadFuncs := make(map[string][]reloadutil.ReloadFunc)
server := &ServerCommand{
// TODO: set up a different one?
// In particular, a UI instance that won't output?
@@ -127,6 +137,8 @@ func (c *OperatorDiagnoseCommand) RunWithParsedFlags() int {
logger: log.NewInterceptLogger(nil),
allLoggers: []log.Logger{},
reloadFuncs: &rloadFuncs,
reloadFuncsLock: new(sync.RWMutex),
}
phase := "Parse configuration"
@@ -140,6 +152,61 @@ func (c *OperatorDiagnoseCommand) RunWithParsedFlags() int {
return 1
}
// Check Listener Information
// TODO: Run Diagnose checks on the actual net.Listeners
disableClustering := config.HAStorage.DisableClustering
infoKeys := make([]string, 0, 10)
info := make(map[string]string)
status, lns, _, errMsg := server.InitListeners(config, disableClustering, &infoKeys, &info)
if status != 0 {
c.UI.Output("Error parsing listener configuration.")
c.UI.Error(errMsg.Error())
return 1
}
// Make sure we close all listeners from this point on
listenerCloseFunc := func() {
for _, ln := range lns {
ln.Listener.Close()
}
}
defer c.cleanupGuard.Do(listenerCloseFunc)
sanitizedListeners := make([]listenerutil.Listener, 0, len(config.Listeners))
for _, ln := range lns {
if ln.Config.TLSDisable {
c.UI.Warn("WARNING! TLS is disabled in a Listener config stanza.")
continue
}
if ln.Config.TLSDisableClientCerts {
c.UI.Warn("WARNING! TLS for a listener is turned on without requiring client certs.")
}
// Check ciphersuite and load ca/cert/key files
// TODO: TLSConfig returns a reloadFunc and a TLSConfig. We can use this to
// perform an active probe.
_, _, err := listenerutil.TLSConfig(ln.Config, make(map[string]string), c.UI)
if err != nil {
c.UI.Output("Error creating TLS Configuration out of config file: ")
c.UI.Output(err.Error())
return 1
}
sanitizedListeners = append(sanitizedListeners, listenerutil.Listener{
Listener: ln.Listener,
Config: ln.Config,
})
}
err = diagnose.ListenerChecks(sanitizedListeners)
if err != nil {
c.UI.Output("Diagnose caught configuration errors: ")
c.UI.Output(err.Error())
return 1
}
// Errors in these items could stop Vault from starting but are not yet covered:
// TODO: logging configuration
// TODO: SetupTelemetry

View File

@@ -22,7 +22,6 @@ func testOperatorDiagnoseCommand(tb testing.TB) (*cli.MockUi, *OperatorDiagnoseC
func TestOperatorDiagnoseCommand_Run(t *testing.T) {
t.Parallel()
cases := []struct {
name string
args []string
@@ -32,7 +31,7 @@ func TestOperatorDiagnoseCommand_Run(t *testing.T) {
{
"diagnose_ok",
[]string{
"-config", "./server/test-fixtures/config.hcl",
"-config", "./server/test-fixtures/config_diagnose_ok.hcl",
},
[]string{"Parse configuration\n\x1b[F\x1b[32m[ ok ]\x1b[0m Parse configuration\n[ ] Access storage\n\x1b[F\x1b[32m[ ok ]\x1b[0m Access storage\n"},
0,
@@ -45,6 +44,14 @@ func TestOperatorDiagnoseCommand_Run(t *testing.T) {
[]string{"Parse configuration\n\x1b[F\x1b[32m[ ok ]\x1b[0m Parse configuration\n[ ] Access storage\n\x1b[F\x1b[31m[failed]\x1b[0m Access storage\nA storage backend must be specified\n"},
1,
},
{
"diagnose_listener_config_ok",
[]string{
"-config", "./server/test-fixtures/tls_config_ok.hcl",
},
[]string{"Parse configuration\n\x1b[F\x1b[32m[ ok ]\x1b[0m Parse configuration\n[ ] Access storage\n\x1b[F\x1b[32m[ ok ]\x1b[0m Access storage\n"},
0,
},
}
t.Run("validations", func(t *testing.T) {

View File

@@ -871,6 +871,92 @@ func (c *ServerCommand) setupStorage(config *server.Config) (physical.Backend, e
return backend, nil
}
// InitListeners returns a response code, error message, Listeners, and a TCP Address list.
func (c *ServerCommand) InitListeners(config *server.Config, disableClustering bool, infoKeys *[]string, info *map[string]string) (int, []listenerutil.Listener, []*net.TCPAddr, error) {
clusterAddrs := []*net.TCPAddr{}
// Initialize the listeners
lns := make([]listenerutil.Listener, 0, len(config.Listeners))
c.reloadFuncsLock.Lock()
defer c.reloadFuncsLock.Unlock()
var errMsg error
for i, lnConfig := range config.Listeners {
ln, props, reloadFunc, err := server.NewListener(lnConfig, c.gatedWriter, c.UI)
if err != nil {
errMsg = fmt.Errorf("Error initializing listener of type %s: %s", lnConfig.Type, err)
return 1, nil, nil, errMsg
}
if reloadFunc != nil {
relSlice := (*c.reloadFuncs)["listener|"+lnConfig.Type]
relSlice = append(relSlice, reloadFunc)
(*c.reloadFuncs)["listener|"+lnConfig.Type] = relSlice
}
if !disableClustering && lnConfig.Type == "tcp" {
addr := lnConfig.ClusterAddress
if addr != "" {
tcpAddr, err := net.ResolveTCPAddr("tcp", lnConfig.ClusterAddress)
if err != nil {
errMsg = fmt.Errorf("Error resolving cluster_address: %s", err)
return 1, nil, nil, errMsg
}
clusterAddrs = append(clusterAddrs, tcpAddr)
} else {
tcpAddr, ok := ln.Addr().(*net.TCPAddr)
if !ok {
errMsg = fmt.Errorf("Failed to parse tcp listener")
return 1, nil, nil, errMsg
}
clusterAddr := &net.TCPAddr{
IP: tcpAddr.IP,
Port: tcpAddr.Port + 1,
}
clusterAddrs = append(clusterAddrs, clusterAddr)
addr = clusterAddr.String()
}
props["cluster address"] = addr
}
if lnConfig.MaxRequestSize == 0 {
lnConfig.MaxRequestSize = vaulthttp.DefaultMaxRequestSize
}
props["max_request_size"] = fmt.Sprintf("%d", lnConfig.MaxRequestSize)
if lnConfig.MaxRequestDuration == 0 {
lnConfig.MaxRequestDuration = vault.DefaultMaxRequestDuration
}
props["max_request_duration"] = lnConfig.MaxRequestDuration.String()
lns = append(lns, listenerutil.Listener{
Listener: ln,
Config: lnConfig,
})
// Store the listener props for output later
key := fmt.Sprintf("listener %d", i+1)
propsList := make([]string, 0, len(props))
for k, v := range props {
propsList = append(propsList, fmt.Sprintf(
"%s: %q", k, v))
}
sort.Strings(propsList)
*infoKeys = append(*infoKeys, key)
(*info)[key] = fmt.Sprintf(
"%s (%s)", lnConfig.Type, strings.Join(propsList, ", "))
}
if !disableClustering {
if c.logger.IsDebug() {
c.logger.Debug("cluster listener addresses synthesized", "cluster_addresses", clusterAddrs)
}
}
return 0, lns, clusterAddrs, nil
}
func (c *ServerCommand) Run(args []string) int {
f := c.Flags()
@@ -1482,84 +1568,14 @@ CLUSTER_SYNTHESIS_COMPLETE:
}
}
clusterAddrs := []*net.TCPAddr{}
status, lns, clusterAddrs, errMsg := c.InitListeners(config, disableClustering, &infoKeys, &info)
// Initialize the listeners
lns := make([]listenerutil.Listener, 0, len(config.Listeners))
c.reloadFuncsLock.Lock()
for i, lnConfig := range config.Listeners {
ln, props, reloadFunc, err := server.NewListener(lnConfig, c.gatedWriter, c.UI)
if err != nil {
c.UI.Error(fmt.Sprintf("Error initializing listener of type %s: %s", lnConfig.Type, err))
if status != 0 {
c.UI.Output("Error parsing listener configuration.")
c.UI.Error(errMsg.Error())
return 1
}
if reloadFunc != nil {
relSlice := (*c.reloadFuncs)["listener|"+lnConfig.Type]
relSlice = append(relSlice, reloadFunc)
(*c.reloadFuncs)["listener|"+lnConfig.Type] = relSlice
}
if !disableClustering && lnConfig.Type == "tcp" {
addr := lnConfig.ClusterAddress
if addr != "" {
tcpAddr, err := net.ResolveTCPAddr("tcp", lnConfig.ClusterAddress)
if err != nil {
c.UI.Error(fmt.Sprintf("Error resolving cluster_address: %s", err))
return 1
}
clusterAddrs = append(clusterAddrs, tcpAddr)
} else {
tcpAddr, ok := ln.Addr().(*net.TCPAddr)
if !ok {
c.UI.Error("Failed to parse tcp listener")
return 1
}
clusterAddr := &net.TCPAddr{
IP: tcpAddr.IP,
Port: tcpAddr.Port + 1,
}
clusterAddrs = append(clusterAddrs, clusterAddr)
addr = clusterAddr.String()
}
props["cluster address"] = addr
}
if lnConfig.MaxRequestSize == 0 {
lnConfig.MaxRequestSize = vaulthttp.DefaultMaxRequestSize
}
props["max_request_size"] = fmt.Sprintf("%d", lnConfig.MaxRequestSize)
if lnConfig.MaxRequestDuration == 0 {
lnConfig.MaxRequestDuration = vault.DefaultMaxRequestDuration
}
props["max_request_duration"] = fmt.Sprintf("%s", lnConfig.MaxRequestDuration.String())
lns = append(lns, listenerutil.Listener{
Listener: ln,
Config: lnConfig,
})
// Store the listener props for output later
key := fmt.Sprintf("listener %d", i+1)
propsList := make([]string, 0, len(props))
for k, v := range props {
propsList = append(propsList, fmt.Sprintf(
"%s: %q", k, v))
}
sort.Strings(propsList)
infoKeys = append(infoKeys, key)
info[key] = fmt.Sprintf(
"%s (%s)", lnConfig.Type, strings.Join(propsList, ", "))
}
c.reloadFuncsLock.Unlock()
if !disableClustering {
if c.logger.IsDebug() {
c.logger.Debug("cluster listener addresses synthesized", "cluster_addresses", clusterAddrs)
}
}
// Make sure we close all listeners from this point on
listenerCloseFunc := func() {
for _, ln := range lns {

View File

@@ -0,0 +1,47 @@
disable_cache = true
disable_mlock = true
ui = true
listener "tcp" {
address = "127.0.0.1:1024"
tls_disable = true
}
backend "consul" {
foo = "bar"
advertise_addr = "foo"
}
ha_backend "consul" {
bar = "baz"
advertise_addr = "snafu"
disable_clustering = "true"
}
service_registration "consul" {
foo = "bar"
}
telemetry {
statsd_address = "bar"
usage_gauge_period = "5m"
maximum_gauge_cardinality = 100
statsite_address = "foo"
dogstatsd_addr = "127.0.0.1:7254"
dogstatsd_tags = ["tag_1:val_1", "tag_2:val_2"]
metrics_prefix = "myprefix"
}
sentinel {
additional_enabled_modules = []
}
max_lease_ttl = "10h"
default_lease_ttl = "10h"
cluster_name = "testcluster"
pid_file = "./pidfile"
raw_storage_endpoint = true
disable_sealwrap = true
disable_printable_check = true

View File

@@ -4,8 +4,8 @@ disable_mlock = true
ui = true
listener "tcp" {
address = "127.0.0.1:443"
allow_stuff = true
address = "127.0.0.1:1024"
tls_disable = true
}
ha_backend "consul" {

View File

@@ -0,0 +1,48 @@
disable_cache = true
disable_mlock = true
ui = true
listener "tcp" {
address = "127.0.0.1:1025"
tls_cert_file = "./../api/test-fixtures/keys/cert.pem"
tls_key_file = "./../api/test-fixtures/keys/key.pem"
}
backend "consul" {
foo = "bar"
advertise_addr = "foo"
}
ha_backend "consul" {
bar = "baz"
advertise_addr = "snafu"
disable_clustering = "true"
}
service_registration "consul" {
foo = "bar"
}
telemetry {
statsd_address = "bar"
usage_gauge_period = "5m"
maximum_gauge_cardinality = 100
statsite_address = "foo"
dogstatsd_addr = "127.0.0.1:7254"
dogstatsd_tags = ["tag_1:val_1", "tag_2:val_2"]
metrics_prefix = "myprefix"
}
sentinel {
additional_enabled_modules = []
}
max_lease_ttl = "10h"
default_lease_ttl = "10h"
cluster_name = "testcluster"
pid_file = "./pidfile"
raw_storage_endpoint = true
disable_sealwrap = true
disable_printable_check = true

View File

@@ -5,11 +5,6 @@ import (
"crypto/tls"
"errors"
"fmt"
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/jsonutil"
"github.com/hashicorp/vault/sdk/helper/tlsutil"
"github.com/hashicorp/vault/sdk/logical"
"github.com/hashicorp/vault/sdk/physical"
"io"
"io/ioutil"
"os"
@@ -18,6 +13,12 @@ import (
"sync"
"time"
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/jsonutil"
"github.com/hashicorp/vault/sdk/helper/tlsutil"
"github.com/hashicorp/vault/sdk/logical"
"github.com/hashicorp/vault/sdk/physical"
"github.com/armon/go-metrics"
"github.com/golang/protobuf/proto"
"github.com/hashicorp/errwrap"

View File

@@ -2614,16 +2614,6 @@ func (c *Core) SetConfig(conf *server.Config) {
c.logger.Debug("set config", "sanitized config", string(bz))
}
// SanitizedConfig returns a sanitized version of the current config.
// See server.Config.Sanitized for specific values omitted.
func (c *Core) SanitizedConfig() map[string]interface{} {
conf := c.rawConfig.Load()
if conf == nil {
return nil
}
return conf.(*server.Config).Sanitized()
}
// LogFormat returns the log format current in use.
func (c *Core) LogFormat() string {
conf := c.rawConfig.Load()

View File

@@ -5,6 +5,7 @@ package vault
import (
"context"
"github.com/hashicorp/vault/command/server"
"github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/sdk/helper/license"
"github.com/hashicorp/vault/sdk/logical"
@@ -55,6 +56,26 @@ func (c *Core) setupReplicationResolverHandler() error {
return nil
}
// GetCoreConfigInternal returns the server configuration
// in struct format.
func (c *Core) GetCoreConfigInternal() *server.Config {
conf := c.rawConfig.Load()
if conf == nil {
return nil
}
return conf.(*server.Config)
}
// SanitizedConfig returns a sanitized version of the current config.
// See server.Config.Sanitized for specific values omitted.
func (c *Core) SanitizedConfig() map[string]interface{} {
conf := c.rawConfig.Load()
if conf == nil {
return nil
}
return conf.(*server.Config).Sanitized()
}
func (c *Core) teardownReplicationResolverHandler() {}
func createSecondaries(*Core, *CoreConfig) {}

View File

@@ -0,0 +1 @@
This is a fake cert!

View File

@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDTDCCAjQCFBVkElzevM5tqOIoJxMSJnzPvc1MMA0GCSqGSIb3DQEBCwUAMGMx
CzAJBgNVBAYTAkZSMQ4wDAYDVQQIDAVQYXJpczEOMAwGA1UEBwwFUGFyaXMxDjAM
BgNVBAoMBVVidWR1MQ4wDAYDVQQLDAVVYnVkdTEUMBIGA1UEAwwLU0RBIFJPT1Qg
Q0EwHhcNMjAwNjExMTUzNTIyWhcNMzAwNjA5MTUzNTIyWjBiMQswCQYDVQQGEwJG
UjEOMAwGA1UECAwFUGFyaXMxDjAMBgNVBAcMBVBhcmlzMQ4wDAYDVQQKDAVVQnVk
dTEOMAwGA1UECwwFVWJ1ZHUxEzARBgNVBAMMClNEQSBDTElFTlQwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmDo5b/iLyNfColCwB15pvUDUkYzp5ungr
BCPb5H9Sw7ymcfsiTeBtgADXHyRli+YtfAPjC/55wkkgfBgKRKS8xG8zas0XXt/f
Wpnl2d8oYGXhGBZPdfaPP/fTANSTWIKVF7+My9LKrulJ+CTKNSnTWKsXFzZivN4H
a9aaBdP3s5CjVtJ456Egu5g2EfStBtNJwXzCjPSZyD69v1G0yWx6M8zhvY6+EV+T
uqycAsNfvcf9K0nR83RXkZnNnSNy6ptNg0fMpa5JrCHYirtGU5O7CSBCpA52fy9R
c12NYxl7qFSCTMC/SzZXjGUpIohxNmTzwCttT292A0yc3Bi8aPl/AgMBAAEwDQYJ
KoZIhvcNAQELBQADggEBAIvLrCOMedGTg4oSCYI+HdWB6E4uhG5UFxNnv3QEib0p
GV71S+wrU443ZAfZvxlHFKjkvZDoV8hXT8VIuWOxA9TvaLksoIHeOKdDiGntjVfL
aDMBnYXPXSDEqFDtAXjtUuIua74fkJ/guCJiX+t7fPctWZPo6J89XtgRZrZcnFIF
1RQZg6cMDoVb3aMUWKvKo6YDsoxiP6rM8xNHqxW788oLTyDeu9ceJkv31jIUYIgJ
t4i3bkqf54FAIMdKn/mXmprrqW0b4tvR0fCThD4pgXxVw/Egm3tro/z6/y+qLJ9U
oZa28h/VYGyoJnEOSl09nZhcfOwWUaXxl94n93dBwXIwDDAKBggrBgEFBQcDAg==
-----END CERTIFICATE-----

58
vault/diagnose/tls.go Normal file
View File

@@ -0,0 +1,58 @@
package diagnose
import (
"crypto/tls"
"crypto/x509"
"fmt"
"github.com/hashicorp/vault/internalshared/listenerutil"
"github.com/hashicorp/vault/vault"
)
func ListenerChecks(listeners []listenerutil.Listener) error {
for _, listener := range listeners {
l := listener.Config
err := TLSFileChecks(l.TLSCertFile, l.TLSKeyFile)
if err != nil {
return err
}
}
return nil
}
// TLSChecks contains manual error checks against the TLS configuration
func TLSFileChecks(certFilePath, keyFilePath string) error {
// LoadX509KeyPair will check if the key/cert information can be loaded from files,
// if they exist with keys and certs of the same algorithm type, if there
// is an unknown algorithm type being used, and if the files have trailing
// data.
cert, err := tls.LoadX509KeyPair(certFilePath, keyFilePath)
if err != nil {
return err
}
// LoadX509KeyPair has a nil leaf certificate because it does not retain the
// parsed form, so we have to manually create it ourselves.
x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
if err != nil {
return err
}
cert.Leaf = x509Cert
// TODO: Check root as well via l.TLSClientCAFile
// Check that certificate isn't expired and is of correct usage type
cert.Leaf.Verify(x509.VerifyOptions{
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
})
return nil
}
// ServerListenerActiveProbe attempts to use TLS information to set up a TLS server with each listener
// and generate a successful request through to the server.
// TODO
func ServerListenerActiveProbe(core *vault.Core) error {
return fmt.Errorf("Method not implemented")
}

146
vault/diagnose/tls_test.go Normal file
View File

@@ -0,0 +1,146 @@
package diagnose
import (
"testing"
"github.com/hashicorp/vault/command/server"
"github.com/hashicorp/vault/internalshared/configutil"
"github.com/hashicorp/vault/internalshared/listenerutil"
"github.com/hashicorp/vault/vault"
)
func setup(t *testing.T) *vault.Core {
serverConf := &server.Config{
SharedConfig: &configutil.SharedConfig{
Listeners: []*configutil.Listener{
{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./certs/server.crt",
TLSKeyFile: "./certs/server.key",
TLSClientCAFile: "./certs/rootca.crt",
TLSMinVersion: "tls11",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: true,
},
{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./certs/server2.crt",
TLSKeyFile: "./certs/server2.key",
TLSClientCAFile: "./certs/rootca2.crt",
TLSMinVersion: "tls12",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./certs/server3.crt",
TLSKeyFile: "./certs/server3.key",
TLSClientCAFile: "./certs/rootca3.crt",
TLSMinVersion: "tls13",
TLSRequireAndVerifyClientCert: false,
TLSDisableClientCerts: true,
},
},
},
}
conf := &vault.CoreConfig{
RawConfig: serverConf,
}
core := vault.TestCoreWithConfig(t, conf)
return core
}
func TestTLSValidCert(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./../../api/test-fixtures/keys/cert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMinVersion: "0",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
},
}
err := ListenerChecks(listeners)
if err != nil {
t.Errorf(err.Error())
}
}
func TestTLSFakeCert(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./test-fixtures/fakecert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMinVersion: "0",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
},
}
err := ListenerChecks(listeners)
if err == nil {
t.Errorf("TLS Config check on fake certificate should fail")
}
if err.Error() != "tls: failed to find any PEM data in certificate input" {
t.Errorf("Bad error message: %s", err.Error())
}
}
// TestTLSTrailingData uses a certificate from:
// https://github.com/golang/go/issues/40545 that contains
// an extra DER sequence, and makes sure a trailing data error
// is returned.
func TestTLSTrailingData(t *testing.T) {
listeners := []listenerutil.Listener{
{
Config: &configutil.Listener{
Type: "tcp",
Address: "127.0.0.1:443",
ClusterAddress: "127.0.0.1:8201",
TLSCertFile: "./test-fixtures/trailingdatacert.pem",
TLSKeyFile: "./../../api/test-fixtures/keys/key.pem",
TLSClientCAFile: "./../../api/test-fixtures/root/rootcacert.pem",
TLSMinVersion: "0",
TLSRequireAndVerifyClientCert: true,
TLSDisableClientCerts: false,
},
},
}
err := ListenerChecks(listeners)
if err == nil {
t.Errorf("TLS Config check on fake certificate should fail")
}
if err.Error() != "asn1: syntax error: trailing data" {
t.Errorf("Bad error message: %s", err.Error())
}
}
func TestTLSExpiredCert(t *testing.T) {
}
func TestTLSMismatchedCryptographicInfo(t *testing.T) {}
func TestTLSContradictoryFlags(t *testing.T) {}
func TestTLSBadCipherSuite(t *testing.T) {}
func TestTLSUnknownAlgorithm(t *testing.T) {}
func TestTLSIncorrectUsageType(t *testing.T) {}

View File

@@ -158,6 +158,7 @@ func TestCoreWithSealAndUI(t testing.T, opts *CoreConfig) *Core {
conf.MetricsHelper = opts.MetricsHelper
conf.MetricSink = opts.MetricSink
conf.NumExpirationWorkers = numExpirationWorkersTest
conf.RawConfig = opts.RawConfig
if opts.Logger != nil {
conf.Logger = opts.Logger