Merge pull request #6831 from hashicorp/add_inmemory_certificate

Add option to set certificate in-memory
This commit is contained in:
Mahmood Ali
2019-12-19 08:54:32 -05:00
committed by GitHub
8 changed files with 63 additions and 9 deletions

View File

@@ -178,12 +178,22 @@ type TLSConfig struct {
// the Nomad server SSL certificate.
CAPath string
// CACertPem is the PEM-encoded CA cert to use to verify the Nomad server
// SSL certificate.
CACertPEM []byte
// ClientCert is the path to the certificate for Nomad communication
ClientCert string
// ClientCertPEM is the PEM-encoded certificate for Nomad communication
ClientCertPEM []byte
// ClientKey is the path to the private key for Nomad communication
ClientKey string
// ClientKeyPEM is the PEM-encoded private key for Nomad communication
ClientKeyPEM []byte
// TLSServerName, if set, is used to set the SNI host when connecting via
// TLS.
TLSServerName string
@@ -344,12 +354,24 @@ func ConfigureTLS(httpClient *http.Client, tlsConfig *TLSConfig) error {
} else {
return fmt.Errorf("Both client cert and client key must be provided")
}
} else if len(tlsConfig.ClientCertPEM) != 0 || len(tlsConfig.ClientKeyPEM) != 0 {
if len(tlsConfig.ClientCertPEM) != 0 && len(tlsConfig.ClientKeyPEM) != 0 {
var err error
clientCert, err = tls.X509KeyPair(tlsConfig.ClientCertPEM, tlsConfig.ClientKeyPEM)
if err != nil {
return err
}
foundClientCert = true
} else {
return fmt.Errorf("Both client cert and client key must be provided")
}
}
clientTLSConfig := httpClient.Transport.(*http.Transport).TLSClientConfig
rootConfig := &rootcerts.Config{
CAFile: tlsConfig.CACert,
CAPath: tlsConfig.CAPath,
CAFile: tlsConfig.CACert,
CAPath: tlsConfig.CAPath,
CACertificate: tlsConfig.CACertPEM,
}
if err := rootcerts.ConfigureTLS(clientTLSConfig, rootConfig); err != nil {
return err

View File

@@ -7,7 +7,7 @@ require (
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75
github.com/gorilla/websocket v1.4.1
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/kr/pretty v0.1.0
github.com/mitchellh/go-testing-interface v1.0.0
github.com/stretchr/testify v1.3.0

View File

@@ -10,6 +10,8 @@ github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVo
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
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/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -17,6 +19,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=

View File

@@ -28,8 +28,9 @@ Here's a snippet demonstrating how this library is meant to be used:
func httpClient() (*http.Client, error)
tlsConfig := &tls.Config{}
err := rootcerts.ConfigureTLS(tlsConfig, &rootcerts.Config{
CAFile: os.Getenv("MYAPP_CAFILE"),
CAPath: os.Getenv("MYAPP_CAPATH"),
CAFile: os.Getenv("MYAPP_CAFILE"),
CAPath: os.Getenv("MYAPP_CAPATH"),
Certificate: os.Getenv("MYAPP_CERTIFICATE"),
})
if err != nil {
return nil, err

5
vendor/github.com/hashicorp/go-rootcerts/go.mod generated vendored Normal file
View File

@@ -0,0 +1,5 @@
module github.com/hashicorp/go-rootcerts
go 1.12
require github.com/mitchellh/go-homedir v1.1.0

2
vendor/github.com/hashicorp/go-rootcerts/go.sum generated vendored Normal file
View File

@@ -0,0 +1,2 @@
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=

View File

@@ -3,21 +3,26 @@ package rootcerts
import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
// Config determines where LoadCACerts will load certificates from. When both
// CAFile and CAPath are blank, this library's functions will either load
// Config determines where LoadCACerts will load certificates from. When CAFile,
// CACertificate and CAPath are blank, this library's functions will either load
// system roots explicitly and return them, or set the CertPool to nil to allow
// Go's standard library to load system certs.
type Config struct {
// CAFile is a path to a PEM-encoded certificate file or bundle. Takes
// precedence over CAPath.
// precedence over CACertificate and CAPath.
CAFile string
// CACertificate is a PEM-encoded certificate or bundle. Takes precedence
// over CAPath.
CACertificate []byte
// CAPath is a path to a directory populated with PEM-encoded certificates.
CAPath string
}
@@ -44,6 +49,9 @@ func LoadCACerts(c *Config) (*x509.CertPool, error) {
if c.CAFile != "" {
return LoadCAFile(c.CAFile)
}
if len(c.CACertificate) != 0 {
return AppendCertificate(c.CACertificate)
}
if c.CAPath != "" {
return LoadCAPath(c.CAPath)
}
@@ -68,6 +76,18 @@ func LoadCAFile(caFile string) (*x509.CertPool, error) {
return pool, nil
}
// AppendCertificate appends an in-memory PEM-encoded certificate or bundle and returns a pool.
func AppendCertificate(ca []byte) (*x509.CertPool, error) {
pool := x509.NewCertPool()
ok := pool.AppendCertsFromPEM(ca)
if !ok {
return nil, errors.New("Error appending CA: Couldn't parse PEM")
}
return pool, nil
}
// LoadCAPath walks the provided path and loads all certificates encounted into
// a pool.
func LoadCAPath(caPath string) (*x509.CertPool, error) {

2
vendor/vendor.json vendored
View File

@@ -241,7 +241,7 @@
{"path":"github.com/hashicorp/go-plugin/internal/plugin","checksumSHA1":"uTvnRQ5UWn/bhRxbW/UCfYFseSc=","revision":"809113480b559c989ea9cfcff62e9d387961f60b","revisionTime":"2019-10-04T17:18:45Z"},
{"path":"github.com/hashicorp/go-plugin/internal/proto","checksumSHA1":"Ikbb1FngsPR79bHhr2UmKk4CblI=","revision":"f444068e8f5a19853177f7aa0aea7e7d95b5b528","revisionTime":"2018-12-12T15:08:38Z"},
{"path":"github.com/hashicorp/go-retryablehttp","checksumSHA1":"9SqwC2BzFbsWulQuBG2+QEliTpo=","revision":"73489d0a1476f0c9e6fb03f9c39241523a496dfd","revisionTime":"2019-01-26T20:33:39Z"},
{"path":"github.com/hashicorp/go-rootcerts","checksumSHA1":"A1PcINvF3UiwHRKn8UcgARgvGRs=","revision":"6bb64b370b90e7ef1fa532be9e591a81c3493e00","revisionTime":"2016-05-03T14:34:40Z"},
{"path":"github.com/hashicorp/go-rootcerts","checksumSHA1":"hfxPtUTFbsE5C1P6gY/gCb9KmP4=","revision":"98fadc2a5ba2ad2a534a179b352ecdfd1f4259aa","revisionTime":"2019-12-10T09:55:28Z","version":"=v1.0.2","versionExact":"v1.0.2"},
{"path":"github.com/hashicorp/go-safetemp","checksumSHA1":"CduvzBFfTv77nhjtXPGdIjQQLMI=","revision":"b1a1dbde6fdc11e3ae79efd9039009e22d4ae240","revisionTime":"2018-03-26T21:11:50Z"},
{"path":"github.com/hashicorp/go-sockaddr","checksumSHA1":"J47ySO1q0gcnmoMnir1q1loKzCk=","revision":"6d291a969b86c4b633730bfc6b8b9d64c3aafed9","revisionTime":"2018-03-20T11:50:54Z"},
{"path":"github.com/hashicorp/go-sockaddr/template","checksumSHA1":"PDp9DVLvf3KWxhs4G4DpIwauMSU=","revision":"6d291a969b86c4b633730bfc6b8b9d64c3aafed9","revisionTime":"2018-03-20T11:50:54Z"},