Add option to disable client certificate requesting. (#3373)

Fixes #3372
This commit is contained in:
Jeff Mitchell 2017-09-25 14:41:46 -04:00 committed by GitHub
parent 29911bfea8
commit 17a15cd594
5 changed files with 64 additions and 15 deletions

View File

@ -707,6 +707,7 @@ func parseListeners(result *Config, list *ast.ObjectList) error {
"tls_cipher_suites",
"tls_prefer_server_cipher_suites",
"tls_require_and_verify_client_cert",
"tls_disable_client_certs",
"tls_client_ca_file",
"token",
}

View File

@ -269,7 +269,8 @@ listener "tcp" {
tls_key_file = "./certs/server.key"
tls_client_ca_file = "./certs/rootca.crt"
tls_min_version = "tls12"
tls_require_and_verify_client_cert = true
tls_require_and_verify_client_cert = true
tls_disable_client_certs = true
}`))
var config Config
@ -298,6 +299,7 @@ listener "tcp" {
"tls_client_ca_file": "./certs/rootca.crt",
"tls_min_version": "tls12",
"tls_require_and_verify_client_cert": true,
"tls_disable_client_certs": true,
},
},
},

View File

@ -130,12 +130,14 @@ func listenerWrapTLS(
}
tlsConf.PreferServerCipherSuites = preferServer
}
var requireVerifyCerts bool
var err error
if v, ok := config["tls_require_and_verify_client_cert"]; ok {
requireClient, err := parseutil.ParseBool(v)
requireVerifyCerts, err = parseutil.ParseBool(v)
if err != nil {
return nil, nil, nil, fmt.Errorf("invalid value for 'tls_require_and_verify_client_cert': %v", err)
}
if requireClient {
if requireVerifyCerts {
tlsConf.ClientAuth = tls.RequireAndVerifyClientCert
}
if tlsClientCaFile, ok := config["tls_client_ca_file"]; ok {
@ -151,6 +153,16 @@ func listenerWrapTLS(
tlsConf.ClientCAs = caPool
}
}
if v, ok := config["tls_disable_client_certs"]; ok {
disableClientCerts, err := parseutil.ParseBool(v)
if err != nil {
return nil, nil, nil, fmt.Errorf("invalid value for 'tls_disable_client_certs': %v", err)
}
if disableClientCerts && requireVerifyCerts {
return nil, nil, nil, fmt.Errorf("'tls_disable_client_certs' and 'tls_require_and_verify_client_cert' are mutually exclusive")
}
tlsConf.ClientAuth = tls.NoClientCert
}
ln = tls.NewListener(ln, tlsConf)
props["tls"] = "enabled"

View File

@ -64,20 +64,50 @@ func TestTCPListener_tls(t *testing.T) {
cwd+"/test-fixtures/reload/reload_foo.pem",
cwd+"/test-fixtures/reload/reload_foo.key")
connFn := func(lnReal net.Listener) (net.Conn, error) {
conn, err := tls.Dial("tcp", ln.Addr().String(), &tls.Config{
RootCAs: certPool,
Certificates: []tls.Certificate{clientCert},
})
connFn := func(clientCerts bool) func(net.Listener) (net.Conn, error) {
return func(lnReal net.Listener) (net.Conn, error) {
conf := &tls.Config{
RootCAs: certPool,
}
if clientCerts {
conf.Certificates = []tls.Certificate{clientCert}
}
conn, err := tls.Dial("tcp", ln.Addr().String(), conf)
if err != nil {
return nil, err
if err != nil {
return nil, err
}
if err = conn.Handshake(); err != nil {
return nil, err
}
return conn, nil
}
if err = conn.Handshake(); err != nil {
return nil, err
}
return conn, nil
}
testListenerImpl(t, ln, connFn, "foo.example.com")
testListenerImpl(t, ln, connFn(true), "foo.example.com")
ln, _, _, err = tcpListenerFactory(map[string]interface{}{
"address": "127.0.0.1:0",
"tls_cert_file": wd + "reload_foo.pem",
"tls_key_file": wd + "reload_foo.key",
"tls_require_and_verify_client_cert": "true",
"tls_disable_client_certs": "true",
"tls_client_ca_file": wd + "reload_ca.pem",
}, nil)
if err == nil {
t.Fatal("expected error due to mutually exclusive client cert options")
}
ln, _, _, err = tcpListenerFactory(map[string]interface{}{
"address": "127.0.0.1:0",
"tls_cert_file": wd + "reload_foo.pem",
"tls_key_file": wd + "reload_foo.key",
"tls_disable_client_certs": "true",
"tls_client_ca_file": wd + "reload_ca.pem",
}, nil)
if err != nil {
t.Fatalf("err: %s", err)
}
testListenerImpl(t, ln, connFn(false), "foo.example.com")
}

View File

@ -74,6 +74,10 @@ listener "tcp" {
- `tls_client_ca_file` `(string: "")` PEM-encoded Certificate Authority file
used for checking the authenticity of client.
- `tls_disable_client_certs` `(string: "false")` Turns off client
authentication for this listener. The default behavior (when this is false)
is for Vault to request client certificates when available.
## `tcp` Listener Examples
### Configuring TLS