github.com/hashicorp/vault/sdk@v0.11.0/helper/testcluster/docker/cert.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package docker 5 6 import ( 7 "crypto/tls" 8 "crypto/x509" 9 "encoding/pem" 10 "errors" 11 "fmt" 12 "io/ioutil" 13 "sync" 14 15 "github.com/hashicorp/errwrap" 16 ) 17 18 // ReloadFunc are functions that are called when a reload is requested 19 type ReloadFunc func() error 20 21 // CertificateGetter satisfies ReloadFunc and its GetCertificate method 22 // satisfies the tls.GetCertificate function signature. Currently it does not 23 // allow changing paths after the fact. 24 type CertificateGetter struct { 25 sync.RWMutex 26 27 cert *tls.Certificate 28 29 certFile string 30 keyFile string 31 passphrase string 32 } 33 34 func NewCertificateGetter(certFile, keyFile, passphrase string) *CertificateGetter { 35 return &CertificateGetter{ 36 certFile: certFile, 37 keyFile: keyFile, 38 passphrase: passphrase, 39 } 40 } 41 42 func (cg *CertificateGetter) Reload() error { 43 certPEMBlock, err := ioutil.ReadFile(cg.certFile) 44 if err != nil { 45 return err 46 } 47 keyPEMBlock, err := ioutil.ReadFile(cg.keyFile) 48 if err != nil { 49 return err 50 } 51 52 // Check for encrypted pem block 53 keyBlock, _ := pem.Decode(keyPEMBlock) 54 if keyBlock == nil { 55 return errors.New("decoded PEM is blank") 56 } 57 58 if x509.IsEncryptedPEMBlock(keyBlock) { 59 keyBlock.Bytes, err = x509.DecryptPEMBlock(keyBlock, []byte(cg.passphrase)) 60 if err != nil { 61 return errwrap.Wrapf("Decrypting PEM block failed {{err}}", err) 62 } 63 keyPEMBlock = pem.EncodeToMemory(keyBlock) 64 } 65 66 cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock) 67 if err != nil { 68 return err 69 } 70 71 cg.Lock() 72 defer cg.Unlock() 73 74 cg.cert = &cert 75 76 return nil 77 } 78 79 func (cg *CertificateGetter) GetCertificate(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) { 80 cg.RLock() 81 defer cg.RUnlock() 82 83 if cg.cert == nil { 84 return nil, fmt.Errorf("nil certificate") 85 } 86 87 return cg.cert, nil 88 }