diff --git a/api/client.go b/api/client.go index 99813a21b..e18027b68 100644 --- a/api/client.go +++ b/api/client.go @@ -36,6 +36,7 @@ const ( EnvVaultAddress = "VAULT_ADDR" EnvVaultAgentAddr = "VAULT_AGENT_ADDR" EnvVaultCACert = "VAULT_CACERT" + EnvVaultCACertBytes = "VAULT_CACERT_BYTES" EnvVaultCAPath = "VAULT_CAPATH" EnvVaultClientCert = "VAULT_CLIENT_CERT" EnvVaultClientKey = "VAULT_CLIENT_KEY" @@ -172,9 +173,14 @@ type Config struct { // used to communicate with Vault. type TLSConfig struct { // CACert is the path to a PEM-encoded CA cert file to use to verify the - // Vault server SSL certificate. + // Vault server SSL certificate. It takes precedence over CACertBytes + // and CAPath. CACert string + // CACertBytes is a PEM-encoded certificate or bundle. It takes precedence + // over CAPath. + CACertBytes []byte + // CAPath is the path to a directory of PEM-encoded CA cert files to verify // the Vault server SSL certificate. CAPath string @@ -266,12 +272,13 @@ func (c *Config) configureTLS(t *TLSConfig) error { return fmt.Errorf("both client cert and client key must be provided") } - if t.CACert != "" || t.CAPath != "" { + if t.CACert != "" || len(t.CACertBytes) != 0 || t.CAPath != "" { c.curlCACert = t.CACert c.curlCAPath = t.CAPath rootConfig := &rootcerts.Config{ - CAFile: t.CACert, - CAPath: t.CAPath, + CAFile: t.CACert, + CACertificate: t.CACertBytes, + CAPath: t.CAPath, } if err := rootcerts.ConfigureTLS(clientTLSConfig, rootConfig); err != nil { return err @@ -313,6 +320,7 @@ func (c *Config) ReadEnvironment() error { var envAddress string var envAgentAddress string var envCACert string + var envCACertBytes []byte var envCAPath string var envClientCert string var envClientKey string @@ -343,6 +351,9 @@ func (c *Config) ReadEnvironment() error { if v := os.Getenv(EnvVaultCACert); v != "" { envCACert = v } + if v := os.Getenv(EnvVaultCACertBytes); v != "" { + envCACertBytes = []byte(v) + } if v := os.Getenv(EnvVaultCAPath); v != "" { envCAPath = v } @@ -398,6 +409,7 @@ func (c *Config) ReadEnvironment() error { // Configure the HTTP clients TLS configuration. t := &TLSConfig{ CACert: envCACert, + CACertBytes: envCACertBytes, CAPath: envCAPath, ClientCert: envClientCert, ClientKey: envClientKey, diff --git a/api/client_test.go b/api/client_test.go index a8434b28c..a5ab991f4 100644 --- a/api/client_test.go +++ b/api/client_test.go @@ -262,24 +262,37 @@ func TestDefaulRetryPolicy(t *testing.T) { func TestClientEnvSettings(t *testing.T) { cwd, _ := os.Getwd() + + caCertBytes, err := os.ReadFile(cwd + "/test-fixtures/keys/cert.pem") + if err != nil { + t.Fatalf("error reading %q cert file: %v", cwd+"/test-fixtures/keys/cert.pem", err) + } + oldCACert := os.Getenv(EnvVaultCACert) + oldCACertBytes := os.Getenv(EnvVaultCACertBytes) oldCAPath := os.Getenv(EnvVaultCAPath) oldClientCert := os.Getenv(EnvVaultClientCert) oldClientKey := os.Getenv(EnvVaultClientKey) oldSkipVerify := os.Getenv(EnvVaultSkipVerify) oldMaxRetries := os.Getenv(EnvVaultMaxRetries) + os.Setenv(EnvVaultCACert, cwd+"/test-fixtures/keys/cert.pem") + os.Setenv(EnvVaultCACertBytes, string(caCertBytes)) os.Setenv(EnvVaultCAPath, cwd+"/test-fixtures/keys") os.Setenv(EnvVaultClientCert, cwd+"/test-fixtures/keys/cert.pem") os.Setenv(EnvVaultClientKey, cwd+"/test-fixtures/keys/key.pem") os.Setenv(EnvVaultSkipVerify, "true") os.Setenv(EnvVaultMaxRetries, "5") - defer os.Setenv(EnvVaultCACert, oldCACert) - defer os.Setenv(EnvVaultCAPath, oldCAPath) - defer os.Setenv(EnvVaultClientCert, oldClientCert) - defer os.Setenv(EnvVaultClientKey, oldClientKey) - defer os.Setenv(EnvVaultSkipVerify, oldSkipVerify) - defer os.Setenv(EnvVaultMaxRetries, oldMaxRetries) + + defer func() { + os.Setenv(EnvVaultCACert, oldCACert) + os.Setenv(EnvVaultCACertBytes, oldCACertBytes) + os.Setenv(EnvVaultCAPath, oldCAPath) + os.Setenv(EnvVaultClientCert, oldClientCert) + os.Setenv(EnvVaultClientKey, oldClientKey) + os.Setenv(EnvVaultSkipVerify, oldSkipVerify) + os.Setenv(EnvVaultMaxRetries, oldMaxRetries) + }() config := DefaultConfig() if err := config.ReadEnvironment(); err != nil { diff --git a/changelog/14753.txt b/changelog/14753.txt new file mode 100644 index 000000000..af7fbb534 --- /dev/null +++ b/changelog/14753.txt @@ -0,0 +1,3 @@ +```release-note:improvement +api: Add ability to pass certificate as PEM bytes to api.Client. +```