Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Shamir as KeK when migrating from auto-seal to shamir #8172

Merged
merged 10 commits into from
Jan 21, 2020
82 changes: 79 additions & 3 deletions command/seal_migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,97 @@ package command
import (
"context"
"encoding/base64"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/helper/testhelpers"
"github.com/hashicorp/vault/shamir"
"testing"

hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-hclog"
wrapping "github.com/hashicorp/go-kms-wrapping"
aeadwrapper "github.com/hashicorp/go-kms-wrapping/wrappers/aead"
"github.com/hashicorp/vault/api"
vaulthttp "github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/sdk/helper/logging"
"github.com/hashicorp/vault/sdk/physical"
physInmem "github.com/hashicorp/vault/sdk/physical/inmem"
"github.com/hashicorp/vault/shamir"
"github.com/hashicorp/vault/vault"
"github.com/hashicorp/vault/vault/seal"
)

func TestSealMigrationAutoToShamir(t *testing.T) {
logger := logging.NewVaultLogger(hclog.Trace).Named(t.Name())
phys, err := physInmem.NewInmem(nil, logger)
if err != nil {
t.Fatal(err)
}
haPhys, err := physInmem.NewInmemHA(nil, logger)
if err != nil {
t.Fatal(err)
}
autoSeal := vault.NewAutoSeal(seal.NewTestSeal(nil))
cluster := vault.NewTestCluster(t, &vault.CoreConfig{
Seal: autoSeal,
Physical: phys,
HAPhysical: haPhys.(physical.HABackend),
DisableSealWrap: true,
}, &vault.TestClusterOptions{
Logger: logger,
HandlerFunc: vaulthttp.Handler,
SkipInit: true,
NumCores: 1,
})
cluster.Start()
defer cluster.Cleanup()

client := cluster.Cores[0].Client
resp, err := client.Sys().Init(&api.InitRequest{
RecoveryShares: 1,
RecoveryThreshold: 1,
vishalnayak marked this conversation as resolved.
Show resolved Hide resolved
})
if err != nil {
t.Fatal(err)
}

testhelpers.WaitForActiveNode(t, cluster)

keys := resp.RecoveryKeysB64
rootToken := resp.RootToken
client.SetToken(rootToken)
core := cluster.Cores[0].Core

shamirSeal := vault.NewDefaultSeal(&seal.Access{
Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{
Logger: logger.Named("shamir"),
}),
})
shamirSeal.SetCore(core)

if err := adjustCoreForSealMigration(logger, core, shamirSeal, autoSeal); err != nil {
vishalnayak marked this conversation as resolved.
Show resolved Hide resolved
t.Fatal(err)
}

var statusResp *api.SealStatusResponse
unsealOpts := &api.UnsealOpts{}
for _, key := range keys {
unsealOpts.Key = key
unsealOpts.Migrate = false
statusResp, err = client.Sys().UnsealWithOptions(unsealOpts)
if err == nil {
t.Fatal("expected error due to lack of migrate parameter")
}
unsealOpts.Migrate = true
statusResp, err = client.Sys().UnsealWithOptions(unsealOpts)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected response")
}
}
if statusResp.Sealed {
t.Fatalf("expected unsealed state; got %#v", *resp)
}
vishalnayak marked this conversation as resolved.
Show resolved Hide resolved
}

func TestSealMigration(t *testing.T) {
logger := logging.NewVaultLogger(hclog.Trace).Named(t.Name())
phys, err := physInmem.NewInmem(nil, logger)
Expand Down
9 changes: 9 additions & 0 deletions vault/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,15 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover
return nil, errors.New("did not get expected recovery information to set new seal during migration")
}

if err := c.seal.SetBarrierConfig(ctx, &SealConfig{
Type: wrapping.Shamir,
SecretShares: config.SecretShares,
SecretThreshold: config.SecretThreshold,
StoredShares: 1,
vishalnayak marked this conversation as resolved.
Show resolved Hide resolved
}); err != nil {
return nil, errwrap.Wrapf("failed to store barrier config during migration: {{err}}", err)
}

// We have recovery keys; we're going to use them as the new
// shamir KeK.
err = c.seal.GetAccess().Wrapper.(*aeadwrapper.Wrapper).SetAESGCMKeyBytes(recoveryKey)
Expand Down