Skip to content

Commit

Permalink
api: add option to set TLS options in-memory for API client (#7093)
Browse files Browse the repository at this point in the history
This PR adds the option to set in-memory certificates to the API client instead of requiring the certificate to be stored on disk in a file.

This allows us to define API client TLS options per Consul secret backend in Vault.
Related issue hashicorp/vault#4800
  • Loading branch information
michelvocks authored and hanshasselberg committed Jan 28, 2020
1 parent 0890966 commit 6681be9
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 10 deletions.
31 changes: 28 additions & 3 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,14 +327,26 @@ type TLSConfig struct {
// Consul communication, defaults to the system bundle if not specified.
CAPath string

// CAPem is the optional PEM-encoded CA certificate used for Consul
// communication, defaults to the system bundle if not specified.
CAPem []byte

// CertFile is the optional path to the certificate for Consul
// communication. If this is set then you need to also set KeyFile.
CertFile string

// CertPEM is the optional PEM-encoded certificate for Consul
// communication. If this is set then you need to also set KeyPEM.
CertPEM []byte

// KeyFile is the optional path to the private key for Consul communication.
// If this is set then you need to also set CertFile.
KeyFile string

// KeyPEM is the optional PEM-encoded private key for Consul communication.
// If this is set then you need to also set CertPEM.
KeyPEM []byte

// InsecureSkipVerify if set to true will disable TLS host verification.
InsecureSkipVerify bool
}
Expand Down Expand Up @@ -458,18 +470,31 @@ func SetupTLSConfig(tlsConfig *TLSConfig) (*tls.Config, error) {
tlsClientConfig.ServerName = server
}

if len(tlsConfig.CertPEM) != 0 && len(tlsConfig.KeyPEM) != 0 {
tlsCert, err := tls.X509KeyPair(tlsConfig.CertPEM, tlsConfig.KeyPEM)
if err != nil {
return nil, err
}
tlsClientConfig.Certificates = []tls.Certificate{tlsCert}
} else if len(tlsConfig.CertPEM) != 0 || len(tlsConfig.KeyPEM) != 0 {
return nil, fmt.Errorf("both client cert and client key must be provided")
}

if tlsConfig.CertFile != "" && tlsConfig.KeyFile != "" {
tlsCert, err := tls.LoadX509KeyPair(tlsConfig.CertFile, tlsConfig.KeyFile)
if err != nil {
return nil, err
}
tlsClientConfig.Certificates = []tls.Certificate{tlsCert}
} else if tlsConfig.CertFile != "" || tlsConfig.KeyFile != "" {
return nil, fmt.Errorf("both client cert and client key must be provided")
}

if tlsConfig.CAFile != "" || tlsConfig.CAPath != "" {
if tlsConfig.CAFile != "" || tlsConfig.CAPath != "" || len(tlsConfig.CAPem) != 0 {
rootConfig := &rootcerts.Config{
CAFile: tlsConfig.CAFile,
CAPath: tlsConfig.CAPath,
CAFile: tlsConfig.CAFile,
CAPath: tlsConfig.CAPath,
CACertificate: tlsConfig.CAPem,
}
if err := rootcerts.ConfigureTLS(tlsClientConfig, rootConfig); err != nil {
return nil, err
Expand Down
31 changes: 31 additions & 0 deletions api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
crand "crypto/rand"
"crypto/tls"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
Expand Down Expand Up @@ -575,6 +576,36 @@ func TestAPI_SetupTLSConfig(t *testing.T) {
if len(cc.RootCAs.Subjects()) != 2 {
t.Fatalf("didn't load root CAs")
}

// Load certs in-memory
certPEM, err := ioutil.ReadFile("../test/hostname/Alice.crt")
if err != nil {
t.Fatalf("err: %v", err)
}
keyPEM, err := ioutil.ReadFile("../test/hostname/Alice.key")
if err != nil {
t.Fatalf("err: %v", err)
}
caPEM, err := ioutil.ReadFile("../test/hostname/CertAuth.crt")
if err != nil {
t.Fatalf("err: %v", err)
}

// Setup config with in-memory certs
cc, err = SetupTLSConfig(&TLSConfig{
CertPEM: certPEM,
KeyPEM: keyPEM,
CAPem: caPEM,
})
if err != nil {
t.Fatalf("err: %v", err)
}
if len(cc.Certificates) != 1 {
t.Fatalf("missing certificate: %v", cc.Certificates)
}
if cc.RootCAs == nil {
t.Fatalf("didn't load root CAs")
}
}

func TestAPI_ClientTLSOptions(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ replace github.com/hashicorp/consul/sdk => ../sdk
require (
github.com/hashicorp/consul/sdk v0.2.0
github.com/hashicorp/go-cleanhttp v0.5.1
github.com/hashicorp/go-rootcerts v1.0.0
github.com/hashicorp/go-rootcerts v1.0.2
github.com/hashicorp/go-uuid v1.0.1
github.com/hashicorp/serf v0.8.2
github.com/mitchellh/mapstructure v1.1.2
Expand Down
4 changes: 4 additions & 0 deletions api/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uP
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
Expand All @@ -43,6 +45,8 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82k
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-rootcerts v1.0.1 h1:DMo4fmknnz0E0evoNYnV48RjWndOsmd6OW+09R3cEP8=
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
Expand Down
5 changes: 3 additions & 2 deletions vendor/github.com/hashicorp/go-rootcerts/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 23 additions & 3 deletions vendor/github.com/hashicorp/go-rootcerts/rootcerts.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ github.com/hashicorp/go-raftchunking
github.com/hashicorp/go-raftchunking/types
# github.com/hashicorp/go-retryablehttp v0.5.4
github.com/hashicorp/go-retryablehttp
# github.com/hashicorp/go-rootcerts v1.0.1
# github.com/hashicorp/go-rootcerts v1.0.2
github.com/hashicorp/go-rootcerts
# github.com/hashicorp/go-sockaddr v1.0.2
github.com/hashicorp/go-sockaddr/template
Expand Down

0 comments on commit 6681be9

Please sign in to comment.