Skip to content

Commit

Permalink
OSS portion of wrapper-v2 (hashicorp#16811)
Browse files Browse the repository at this point in the history
* OSS portion of wrapper-v2

* Prefetch barrier type to avoid encountering an error in the simple BarrierType() getter

* Rename the OveriddenType to WrapperType and use it for the barrier type prefetch

* Fix unit test
  • Loading branch information
sgmiller authored Aug 23, 2022
1 parent 986e43b commit 0d6a42c
Show file tree
Hide file tree
Showing 40 changed files with 404 additions and 286 deletions.
6 changes: 3 additions & 3 deletions command/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ func (c *AgentCommand) Run(args []string) int {
c.UI.Warn(fmt.Sprintf("Failed to close persistent cache file after getting retrieval token: %s", err))
}

km, err := keymanager.NewPassthroughKeyManager(token)
km, err := keymanager.NewPassthroughKeyManager(ctx, token)
if err != nil {
c.UI.Error(fmt.Sprintf("failed to configure persistence encryption for cache: %s", err))
return 1
Expand Down Expand Up @@ -657,7 +657,7 @@ func (c *AgentCommand) Run(args []string) int {
}
}
} else {
km, err := keymanager.NewPassthroughKeyManager(nil)
km, err := keymanager.NewPassthroughKeyManager(ctx, nil)
if err != nil {
c.UI.Error(fmt.Sprintf("failed to configure persistence encryption for cache: %s", err))
return 1
Expand All @@ -675,7 +675,7 @@ func (c *AgentCommand) Run(args []string) int {
cacheLogger.Info("configured persistent storage", "path", config.Cache.Persist.Path)

// Stash the key material in bolt
token, err := km.RetrievalToken()
token, err := km.RetrievalToken(ctx)
if err != nil {
c.UI.Error(fmt.Sprintf("Error getting persistent key: %s", err))
return 1
Expand Down
8 changes: 4 additions & 4 deletions command/agent/cache/cacheboltdb/bolt.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

"github.com/golang/protobuf/proto"
"github.com/hashicorp/go-hclog"
wrapping "github.com/hashicorp/go-kms-wrapping"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
"github.com/hashicorp/go-multierror"
bolt "go.etcd.io/bbolt"
)
Expand Down Expand Up @@ -228,7 +228,7 @@ func autoIncrementedLeaseKey(tx *bolt.Tx, id string) ([]byte, error) {

// Set an index (token or lease) in bolt storage
func (b *BoltStorage) Set(ctx context.Context, id string, plaintext []byte, indexType string) error {
blob, err := b.wrapper.Encrypt(ctx, plaintext, []byte(b.aad))
blob, err := b.wrapper.Encrypt(ctx, plaintext, wrapping.WithAad([]byte(b.aad)))
if err != nil {
return fmt.Errorf("error encrypting %s index: %w", indexType, err)
}
Expand Down Expand Up @@ -296,12 +296,12 @@ func (b *BoltStorage) Delete(id string, indexType string) error {
}

func (b *BoltStorage) decrypt(ctx context.Context, ciphertext []byte) ([]byte, error) {
var blob wrapping.EncryptedBlobInfo
var blob wrapping.BlobInfo
if err := proto.Unmarshal(ciphertext, &blob); err != nil {
return nil, err
}

return b.wrapper.Decrypt(ctx, &blob, []byte(b.aad))
return b.wrapper.Decrypt(ctx, &blob, wrapping.WithAad([]byte(b.aad)))
}

// GetByType returns a list of stored items of the specified type
Expand Down
4 changes: 2 additions & 2 deletions command/agent/cache/cacheboltdb/bolt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
func getTestKeyManager(t *testing.T) keymanager.KeyManager {
t.Helper()

km, err := keymanager.NewPassthroughKeyManager(nil)
km, err := keymanager.NewPassthroughKeyManager(context.Background(), nil)
require.NoError(t, err)

return km
Expand Down Expand Up @@ -286,7 +286,7 @@ func TestBolt_MigrateFromV1ToV2Schema(t *testing.T) {

// Manually insert some items into the v1 schema.
err = db.Update(func(tx *bolt.Tx) error {
blob, err := b.wrapper.Encrypt(ctx, []byte("ignored-contents"), []byte(""))
blob, err := b.wrapper.Encrypt(ctx, []byte("ignored-contents"))
if err != nil {
return fmt.Errorf("error encrypting contents: %w", err)
}
Expand Down
8 changes: 6 additions & 2 deletions command/agent/cache/keymanager/manager.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package keymanager

import wrapping "github.com/hashicorp/go-kms-wrapping"
import (
"context"

wrapping "github.com/hashicorp/go-kms-wrapping/v2"
)

const (
KeyID = "root"
Expand All @@ -12,5 +16,5 @@ type KeyManager interface {
// RetrievalToken is the material returned which can be used to source back the
// encryption key. Depending on the implementation, the token can be the
// encryption key itself or a token/identifier used to exchange the token.
RetrievalToken() ([]byte, error)
RetrievalToken(ctx context.Context) ([]byte, error)
}
17 changes: 9 additions & 8 deletions command/agent/cache/keymanager/passthrough.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package keymanager

import (
"context"
"crypto/rand"
"fmt"

wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-kms-wrapping/wrappers/aead"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
"github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2"
)

var _ KeyManager = (*PassthroughKeyManager)(nil)
Expand All @@ -17,7 +18,7 @@ type PassthroughKeyManager struct {
// NewPassthroughKeyManager returns a new instance of the Kube encryption key.
// If a key is provided, it will be used as the encryption key for the wrapper,
// otherwise one will be generated.
func NewPassthroughKeyManager(key []byte) (*PassthroughKeyManager, error) {
func NewPassthroughKeyManager(ctx context.Context, key []byte) (*PassthroughKeyManager, error) {
var rootKey []byte = nil
switch len(key) {
case 0:
Expand All @@ -33,13 +34,13 @@ func NewPassthroughKeyManager(key []byte) (*PassthroughKeyManager, error) {
return nil, fmt.Errorf("invalid key size, should be 32, got %d", len(key))
}

wrapper := aead.NewWrapper(nil)
wrapper := aead.NewWrapper()

if _, err := wrapper.SetConfig(map[string]string{"key_id": KeyID}); err != nil {
if _, err := wrapper.SetConfig(ctx, wrapping.WithConfigMap(map[string]string{"key_id": KeyID})); err != nil {
return nil, err
}

if err := wrapper.SetAESGCMKeyBytes(rootKey); err != nil {
if err := wrapper.SetAesGcmKeyBytes(rootKey); err != nil {
return nil, err
}

Expand All @@ -58,10 +59,10 @@ func (w *PassthroughKeyManager) Wrapper() wrapping.Wrapper {
// RetrievalToken returns the key that was used on the wrapper since this key
// manager is simply a passthrough and does not provide a mechanism to abstract
// this key.
func (w *PassthroughKeyManager) RetrievalToken() ([]byte, error) {
func (w *PassthroughKeyManager) RetrievalToken(ctx context.Context) ([]byte, error) {
if w.wrapper == nil {
return nil, fmt.Errorf("unable to get wrapper for token retrieval")
}

return w.wrapper.GetKeyBytes(), nil
return w.wrapper.KeyBytes(ctx)
}
6 changes: 4 additions & 2 deletions command/agent/cache/keymanager/passthrough_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keymanager

import (
"bytes"
"context"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -30,9 +31,10 @@ func TestKeyManager_PassthrougKeyManager(t *testing.T) {
},
}

ctx := context.Background()
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
m, err := NewPassthroughKeyManager(tc.key)
m, err := NewPassthroughKeyManager(ctx, tc.key)
if tc.wantErr {
require.Error(t, err)
return
Expand All @@ -43,7 +45,7 @@ func TestKeyManager_PassthrougKeyManager(t *testing.T) {
t.Fatalf("expected non-nil wrapper from the key manager")
}

token, err := m.RetrievalToken()
token, err := m.RetrievalToken(ctx)
if err != nil {
t.Fatalf("unable to retrieve token: %s", err)
}
Expand Down
2 changes: 1 addition & 1 deletion command/agent/cache/lease_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ func TestLeaseCache_Concurrent_Cacheable(t *testing.T) {
func setupBoltStorage(t *testing.T) (tempCacheDir string, boltStorage *cacheboltdb.BoltStorage) {
t.Helper()

km, err := keymanager.NewPassthroughKeyManager(nil)
km, err := keymanager.NewPassthroughKeyManager(context.Background(), nil)
require.NoError(t, err)

tempCacheDir, err = ioutil.TempDir("", "agent-cache-test")
Expand Down
6 changes: 3 additions & 3 deletions command/operator_diagnose.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

"golang.org/x/term"

wrapping "github.com/hashicorp/go-kms-wrapping"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"

"github.com/docker/docker/pkg/ioutils"
"github.com/hashicorp/consul/api"
Expand Down Expand Up @@ -455,7 +455,7 @@ func (c *OperatorDiagnoseCommand) offlineDiagnostics(ctx context.Context) error
}
// Ensure that the seal finalizer is called, even if using verify-only
defer func(seal *vault.Seal) {
sealType := diagnose.CapitalizeFirstLetter((*seal).BarrierType())
sealType := diagnose.CapitalizeFirstLetter((*seal).BarrierType().String())
finalizeSealContext, finalizeSealSpan := diagnose.StartSpan(ctx, "Finalize "+sealType+" Seal")
err = (*seal).Finalize(finalizeSealContext)
if err != nil {
Expand Down Expand Up @@ -675,7 +675,7 @@ SEALFAIL:
if barrierSeal == nil {
return fmt.Errorf("Diagnose could not create a barrier seal object.")
}
if barrierSeal.BarrierType() == wrapping.Shamir {
if barrierSeal.BarrierType() == wrapping.WrapperTypeShamir {
diagnose.Skipped(ctx, "Skipping barrier encryption test. Only supported for auto-unseal.")
return nil
}
Expand Down
39 changes: 23 additions & 16 deletions command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
systemd "github.com/coreos/go-systemd/daemon"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/go-hclog"
wrapping "github.com/hashicorp/go-kms-wrapping"
aeadwrapper "github.com/hashicorp/go-kms-wrapping/wrappers/aead"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
aeadwrapper "github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-secure-stdlib/gatedwriter"
"github.com/hashicorp/go-secure-stdlib/mlock"
Expand Down Expand Up @@ -556,7 +556,7 @@ func (c *ServerCommand) runRecoveryMode() int {
var wrapper wrapping.Wrapper

if len(config.Seals) == 0 {
config.Seals = append(config.Seals, &configutil.KMS{Type: wrapping.Shamir})
config.Seals = append(config.Seals, &configutil.KMS{Type: wrapping.WrapperTypeShamir.String()})
}

if len(config.Seals) > 1 {
Expand All @@ -565,7 +565,7 @@ func (c *ServerCommand) runRecoveryMode() int {
}

configSeal := config.Seals[0]
sealType := wrapping.Shamir
sealType := wrapping.WrapperTypeShamir.String()
if !configSeal.Disabled && os.Getenv("VAULT_SEAL_TYPE") != "" {
sealType = os.Getenv("VAULT_SEAL_TYPE")
configSeal.Type = sealType
Expand All @@ -578,9 +578,7 @@ func (c *ServerCommand) runRecoveryMode() int {

var seal vault.Seal
defaultSeal := vault.NewDefaultSeal(&vaultseal.Access{
Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{
Logger: c.logger.Named("shamir"),
}),
Wrapper: aeadwrapper.NewShamirWrapper(),
})
sealLogger := c.logger.ResetNamed(fmt.Sprintf("seal.%s", sealType))
wrapper, sealConfigError = configutil.ConfigureWrapper(configSeal, &infoKeys, &info, sealLogger)
Expand All @@ -594,9 +592,12 @@ func (c *ServerCommand) runRecoveryMode() int {
if wrapper == nil {
seal = defaultSeal
} else {
seal = vault.NewAutoSeal(&vaultseal.Access{
seal, err = vault.NewAutoSeal(&vaultseal.Access{
Wrapper: wrapper,
})
if err != nil {
c.UI.Error(fmt.Sprintf("error creating auto seal: %v", err))
}
}
barrierSeal = seal

Expand Down Expand Up @@ -2350,24 +2351,28 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
var wrapper wrapping.Wrapper
var barrierWrapper wrapping.Wrapper
if c.flagDevAutoSeal {
barrierSeal = vault.NewAutoSeal(vaultseal.NewTestSeal(nil))
var err error
barrierSeal, err = vault.NewAutoSeal(vaultseal.NewTestSeal(nil))
if err != nil {
return nil, nil, nil, nil, nil, err
}
return barrierSeal, nil, nil, nil, nil, nil
}

// Handle the case where no seal is provided
switch len(config.Seals) {
case 0:
config.Seals = append(config.Seals, &configutil.KMS{Type: wrapping.Shamir})
config.Seals = append(config.Seals, &configutil.KMS{Type: wrapping.WrapperTypeShamir.String()})
case 1:
// If there's only one seal and it's disabled assume they want to
// migrate to a shamir seal and simply didn't provide it
if config.Seals[0].Disabled {
config.Seals = append(config.Seals, &configutil.KMS{Type: wrapping.Shamir})
config.Seals = append(config.Seals, &configutil.KMS{Type: wrapping.WrapperTypeShamir.String()})
}
}
var createdSeals []vault.Seal = make([]vault.Seal, len(config.Seals))
for _, configSeal := range config.Seals {
sealType := wrapping.Shamir
sealType := wrapping.WrapperTypeShamir.String()
if !configSeal.Disabled && os.Getenv("VAULT_SEAL_TYPE") != "" {
sealType = os.Getenv("VAULT_SEAL_TYPE")
configSeal.Type = sealType
Expand All @@ -2379,9 +2384,7 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
sealLogger := c.logger.ResetNamed(fmt.Sprintf("seal.%s", sealType))
c.allLoggers = append(c.allLoggers, sealLogger)
defaultSeal := vault.NewDefaultSeal(&vaultseal.Access{
Wrapper: aeadwrapper.NewShamirWrapper(&wrapping.WrapperOptions{
Logger: c.logger.Named("shamir"),
}),
Wrapper: aeadwrapper.NewShamirWrapper(),
})
var sealInfoKeys []string
sealInfoMap := map[string]string{}
Expand All @@ -2395,9 +2398,13 @@ func setSeal(c *ServerCommand, config *server.Config, infoKeys []string, info ma
if wrapper == nil {
seal = defaultSeal
} else {
seal = vault.NewAutoSeal(&vaultseal.Access{
var err error
seal, err = vault.NewAutoSeal(&vaultseal.Access{
Wrapper: wrapper,
})
if err != nil {
return nil, nil, nil, nil, nil, err
}
}
infoPrefix := ""
if configSeal.Disabled {
Expand Down
4 changes: 2 additions & 2 deletions command/server/server_seal_transit_acc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestTransitWrapper_Lifecycle(t *testing.T) {
"key_name": config.keyName,
}

kms, _, err := configutil.GetTransitKMSFunc(nil, &configutil.KMS{Config: wrapperConfig})
kms, _, err := configutil.GetTransitKMSFunc(&configutil.KMS{Config: wrapperConfig})
if err != nil {
t.Fatalf("error setting wrapper config: %v", err)
}
Expand Down Expand Up @@ -72,7 +72,7 @@ func TestTransitSeal_TokenRenewal(t *testing.T) {
"mount_path": config.mountPath,
"key_name": config.keyName,
}
kms, _, err := configutil.GetTransitKMSFunc(nil, &configutil.KMS{Config: wrapperConfig})
kms, _, err := configutil.GetTransitKMSFunc(&configutil.KMS{Config: wrapperConfig})
if err != nil {
t.Fatalf("error setting wrapper config: %v", err)
}
Expand Down
Loading

0 comments on commit 0d6a42c

Please sign in to comment.