Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 0 additions & 37 deletions api/go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/Azure/azure-sdk-for-go v36.2.0+incompatible
github.com/Azure/go-autorest/autorest v0.10.1
github.com/DataDog/zstd v1.4.5 // indirect
github.com/Microsoft/hcsshim v0.8.9 // indirect
github.com/NYTimes/gziphandler v1.1.1
github.com/SAP/go-hdb v0.14.1
github.com/Sectorbob/mlab-ns2 v0.0.0-20171030222938-d3aa0c295a8a
Expand Down
85 changes: 85 additions & 0 deletions sdk/testing/internal/reloadutil/reload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package reloadutil

import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"sync"

"github.com/hashicorp/errwrap"
)

// ReloadFunc are functions that are called when a reload is requested
type ReloadFunc func() error

// CertificateGetter satisfies ReloadFunc and its GetCertificate method
// satisfies the tls.GetCertificate function signature. Currently it does not
// allow changing paths after the fact.
type CertificateGetter struct {
sync.RWMutex

cert *tls.Certificate

certFile string
keyFile string
passphrase string
}

func NewCertificateGetter(certFile, keyFile, passphrase string) *CertificateGetter {
return &CertificateGetter{
certFile: certFile,
keyFile: keyFile,
passphrase: passphrase,
}
}

func (cg *CertificateGetter) Reload() error {
certPEMBlock, err := ioutil.ReadFile(cg.certFile)
if err != nil {
return err
}
keyPEMBlock, err := ioutil.ReadFile(cg.keyFile)
if err != nil {
return err
}

// Check for encrypted pem block
keyBlock, _ := pem.Decode(keyPEMBlock)
if keyBlock == nil {
return errors.New("decoded PEM is blank")
}

if x509.IsEncryptedPEMBlock(keyBlock) {
keyBlock.Bytes, err = x509.DecryptPEMBlock(keyBlock, []byte(cg.passphrase))
if err != nil {
return errwrap.Wrapf("Decrypting PEM block failed {{err}}", err)
}
keyPEMBlock = pem.EncodeToMemory(keyBlock)
}

cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
if err != nil {
return err
}

cg.Lock()
defer cg.Unlock()

cg.cert = &cert

return nil
}

func (cg *CertificateGetter) GetCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
cg.RLock()
defer cg.RUnlock()

if cg.cert == nil {
return nil, fmt.Errorf("nil certificate")
}

return cg.cert, nil
}
74 changes: 74 additions & 0 deletions sdk/testing/internal/reloadutil/reload_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package reloadutil

import (
"crypto/x509"
"io/ioutil"
"testing"

"github.com/hashicorp/errwrap"
)

func TestReload_KeyWithPassphrase(t *testing.T) {
password := "password"
cert := []byte(`-----BEGIN CERTIFICATE-----
MIICLzCCAZgCCQCq27CeP4WhlDANBgkqhkiG9w0BAQUFADBcMQswCQYDVQQGEwJV
UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoM
CUhhc2hpQ29ycDEUMBIGA1UEAwwLbXl2YXVsdC5jb20wHhcNMTcxMjEzMjEzNTM3
WhcNMTgxMjEzMjEzNTM3WjBcMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFjAU
BgNVBAcMDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoMCUhhc2hpQ29ycDEUMBIGA1UE
AwwLbXl2YXVsdC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMvsz/9l
EJIlRG6DOw4fXdB/aJgJk2rR8cU0D8+vECIzb+MdDK0cBHtLiVpZC/RnZMdMzjGn
Z++Fp3dEnT6CD0IjKdJcD+qSyZSjHIuYpHjnjrVlM/Le0xST7egoG+fXkSt4myzG
ec2WK1jcZefRRGPycvMqx1yUWU76jDdFZSL5AgMBAAEwDQYJKoZIhvcNAQEFBQAD
gYEAQfYE26FLZ9SPPU8bHNDxoxDmGrn8yJ78C490Qpix/w6gdLaBtILenrZbhpnB
3L3okraM8mplaN2KdAcpnsr4wPv9hbYkam0coxCQEKs8ltHSBaXT6uKRWb00nkGu
yAXDRpuPdFRqbXW3ZFC5broUrz4ujxTDKfVeIn0zpPZkv24=
-----END CERTIFICATE-----`)
key := []byte(`-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,64B032D83BD6A6DC

qVJ+mXEBKMkUPrQ8odHunMpPgChQUny4CX73/dAcm7O9iXIv9eXQSxj2qfgCOloj
vthg7jYNwtRb0ydzCEnEud35zWw38K/l19/pe4ULfNXlOddlsk4XIHarBiz+KUaX
WTbNk0H+DwdcEwhprPgpTk8gp88lZBiHCnTG/s8v/JNt+wkdqjfAp0Xbm9m+OZ7s
hlNxZin1OuBdprBqfKWBltUALZYiIBhspMTmh+jGQSyEKNTAIBejIiRH5+xYWuOy
xKencq8UpQMOMPR2ZiSw42dU9j8HHMgldI7KszU2FDIEFXG7aSjcxNyyybeBT+Uz
YPoxGxSdUYWqaz50UszvHg/QWR8NlPlQc3nFAUVpGKUF9MEQCIAK8HjcpMP+IAVO
ertp4cTa2Rpm9YeoFrY6tabvmXApXlQPw6rBn6o5KpceWG3ceOsDOsT+e3edHu9g
SGO4hjggbRpO+dBOuwfw4rMn9X1BbqXKJcREAmrgVVSf9/s942E4YOQ+IGJPdtmY
WHAFk8hiJepsVCA2NpwVlAD+QbPPaR2RtvYOtq3IKlWRuVQ+6dpxDsz5FlJhs2L+
HsX6XqtwuQM8kk1hO8Gm3VeV7+b64r9kfbO8jCM18GexCYiCtig51mJW6IO42d1K
bS1axMx/KeDc/sy7LKEbHnjnYanpGz2Wa2EWhnWAeNXD1nUfUNFPp2SsIGbCMnat
mC4O4cO7YRl3+iJg3kHtTPGtgtCjrZcjlyBtxT2VC7SsTcTXZBWovczMIstyr4Ka
opM24uvQT3Bc0UM0WNh3tdRFuboxDeBDh7PX/2RIoiaMuCCiRZ3O0A==
-----END RSA PRIVATE KEY-----`)
tempDir, err := ioutil.TempDir("", "vault-test")
if err != nil {
t.Fatalf("Error creating temporary directory: %s", err)
}
keyFile := tempDir + "/server.key"
certFile := tempDir + "/server.crt"

err = ioutil.WriteFile(certFile, cert, 0755)
if err != nil {
t.Fatalf("Error writing to temp file: %s", err)
}
err = ioutil.WriteFile(keyFile, key, 0755)
if err != nil {
t.Fatalf("Error writing to temp file: %s", err)
}

cg := NewCertificateGetter(certFile, keyFile, "")
err = cg.Reload()
if err == nil {
t.Fatal("error expected")
}
if !errwrap.Contains(err, x509.IncorrectPasswordError.Error()) {
t.Fatalf("expected incorrect password error, got %v", err)
}

cg = NewCertificateGetter(certFile, keyFile, password)
if err := cg.Reload(); err != nil {
t.Fatalf("err: %v", err)
}
}
3 changes: 2 additions & 1 deletion sdk/testing/stepwise/environments/docker/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
uuid "github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/testing/internal/reloadutil"
"github.com/hashicorp/vault/sdk/testing/stepwise"
"golang.org/x/net/http2"
)
Expand Down Expand Up @@ -431,7 +432,7 @@ func (n *dockerClusterNode) setupCert() error {
return err
}

certGetter := stepwise.NewCertificateGetter(n.ServerCertPEMFile, n.ServerKeyPEMFile, "")
certGetter := reloadutil.NewCertificateGetter(n.ServerCertPEMFile, n.ServerKeyPEMFile, "")
if err := certGetter.Reload(); err != nil {
return err
}
Expand Down
78 changes: 0 additions & 78 deletions sdk/testing/stepwise/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,13 @@ package stepwise
import (
"bytes"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"github.com/hashicorp/errwrap"
"io"
"io/ioutil"
"os"
"os/exec"
"path"
"strings"
"sync"
)

const pluginPrefix = "vault-plugin-"
Expand Down Expand Up @@ -59,75 +53,3 @@ func CompilePlugin(name, pluginName, srcDir, tmpDir string) (string, string, str

return binName, binPath, sha256value, nil
}

// ReloadFunc are functions that are called when a reload is requested
type ReloadFunc func() error

// CertificateGetter satisfies ReloadFunc and its GetCertificate method
// satisfies the tls.GetCertificate function signature. Currently it does not
// allow changing paths after the fact.
type CertificateGetter struct {
sync.RWMutex

cert *tls.Certificate

certFile string
keyFile string
passphrase string
}

func NewCertificateGetter(certFile, keyFile, passphrase string) *CertificateGetter {
return &CertificateGetter{
certFile: certFile,
keyFile: keyFile,
passphrase: passphrase,
}
}

func (cg *CertificateGetter) Reload() error {
certPEMBlock, err := ioutil.ReadFile(cg.certFile)
if err != nil {
return err
}
keyPEMBlock, err := ioutil.ReadFile(cg.keyFile)
if err != nil {
return err
}

// Check for encrypted pem block
keyBlock, _ := pem.Decode(keyPEMBlock)
if keyBlock == nil {
return errors.New("decoded PEM is blank")
}

if x509.IsEncryptedPEMBlock(keyBlock) {
keyBlock.Bytes, err = x509.DecryptPEMBlock(keyBlock, []byte(cg.passphrase))
if err != nil {
return errwrap.Wrapf("Decrypting PEM block failed {{err}}", err)
}
keyPEMBlock = pem.EncodeToMemory(keyBlock)
}

cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
if err != nil {
return err
}

cg.Lock()
defer cg.Unlock()

cg.cert = &cert

return nil
}

func (cg *CertificateGetter) GetCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
cg.RLock()
defer cg.RUnlock()

if cg.cert == nil {
return nil, fmt.Errorf("nil certificate")
}

return cg.cert, nil
}
Loading