From 29a422be78e3598b2c3b526b54acfe3970b58c0c Mon Sep 17 00:00:00 2001 From: Vishal Nayak Date: Thu, 16 Jan 2020 19:35:23 -0500 Subject: [PATCH 1/9] Use Shamir as KeK when migrating from auto-seal to shamir --- command/seal_migration_test.go | 78 ++++++++++++++++++++++++++++++++-- vault/core.go | 9 ++++ 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/command/seal_migration_test.go b/command/seal_migration_test.go index ca1d5693cf1b..a6206cba86d6 100644 --- a/command/seal_migration_test.go +++ b/command/seal_migration_test.go @@ -5,21 +5,93 @@ package command import ( "context" "encoding/base64" + "github.com/hashicorp/vault/api" + "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, + }) + if err != nil { + t.Fatal(err) + } + 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 { + 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) + } +} + func TestSealMigration(t *testing.T) { logger := logging.NewVaultLogger(hclog.Trace).Named(t.Name()) phys, err := physInmem.NewInmem(nil, logger) diff --git a/vault/core.go b/vault/core.go index bf01c3ff018c..8d221bb48bce 100644 --- a/vault/core.go +++ b/vault/core.go @@ -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: 1, + SecretThreshold: 1, + StoredShares: 1, + }); err != nil { + return nil, errwrap.Wrapf("failed to store barrier config 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) From 8d589df0ecd176ad4576d8773e2f28ae5f1f9333 Mon Sep 17 00:00:00 2001 From: Nick Cabatoff Date: Fri, 17 Jan 2020 08:58:27 -0500 Subject: [PATCH 2/9] Use the correct number of shares/threshold for the migrated seal. --- vault/core.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vault/core.go b/vault/core.go index 8d221bb48bce..8b1eda39caff 100644 --- a/vault/core.go +++ b/vault/core.go @@ -1275,8 +1275,8 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover if err := c.seal.SetBarrierConfig(ctx, &SealConfig{ Type: wrapping.Shamir, - SecretShares: 1, - SecretThreshold: 1, + SecretShares: config.SecretShares, + SecretThreshold: config.SecretThreshold, StoredShares: 1, }); err != nil { return nil, errwrap.Wrapf("failed to store barrier config migration: {{err}}", err) From b69a72e53fd849ad353ecc8ef180d0a60178bb86 Mon Sep 17 00:00:00 2001 From: Vishal Nayak Date: Fri, 17 Jan 2020 10:21:35 -0500 Subject: [PATCH 3/9] Fix log message --- vault/core.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vault/core.go b/vault/core.go index 8b1eda39caff..7ce2f039b061 100644 --- a/vault/core.go +++ b/vault/core.go @@ -1279,7 +1279,7 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover SecretThreshold: config.SecretThreshold, StoredShares: 1, }); err != nil { - return nil, errwrap.Wrapf("failed to store barrier config migration: {{err}}", err) + 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 From edc946c9716ef8bb7ffb7e357290a6e5d22b4ec8 Mon Sep 17 00:00:00 2001 From: Vishal Nayak Date: Fri, 17 Jan 2020 11:14:41 -0500 Subject: [PATCH 4/9] Add WaitForActiveNode to test --- command/seal_migration_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/command/seal_migration_test.go b/command/seal_migration_test.go index a6206cba86d6..8a6ad14108cb 100644 --- a/command/seal_migration_test.go +++ b/command/seal_migration_test.go @@ -6,6 +6,7 @@ import ( "context" "encoding/base64" "github.com/hashicorp/vault/api" + "github.com/hashicorp/vault/helper/testhelpers" "github.com/hashicorp/vault/shamir" "testing" @@ -53,6 +54,9 @@ func TestSealMigrationAutoToShamir(t *testing.T) { if err != nil { t.Fatal(err) } + + testhelpers.WaitForActiveNode(t, cluster) + keys := resp.RecoveryKeysB64 rootToken := resp.RootToken client.SetToken(rootToken) From 59abbb5e5415e341db15724a83f50164e1b0aabd Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Fri, 17 Jan 2020 12:43:28 -0800 Subject: [PATCH 5/9] Make test fail --- command/seal_migration_test.go | 8 +++++++- vault/core.go | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/command/seal_migration_test.go b/command/seal_migration_test.go index def7ac71d146..744dc76fe36d 100644 --- a/command/seal_migration_test.go +++ b/command/seal_migration_test.go @@ -5,10 +5,11 @@ package command import ( "context" "encoding/base64" + "testing" + "github.com/hashicorp/vault/api" "github.com/hashicorp/vault/helper/testhelpers" "github.com/hashicorp/vault/shamir" - "testing" "github.com/hashicorp/go-hclog" wrapping "github.com/hashicorp/go-kms-wrapping" @@ -62,6 +63,11 @@ func TestSealMigrationAutoToShamir(t *testing.T) { client.SetToken(rootToken) core := cluster.Cores[0].Core + client.SetToken(rootToken) + if err := client.Sys().Seal(); err != nil { + t.Fatal(err) + } + shamirSeal := vault.NewDefaultSeal(&seal.Access{ Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ Logger: logger.Named("shamir"), diff --git a/vault/core.go b/vault/core.go index e2879d93ba13..f92c226b4ecc 100644 --- a/vault/core.go +++ b/vault/core.go @@ -495,7 +495,7 @@ type Core struct { recoveryMode bool clusterNetworkLayer cluster.NetworkLayer - + // PR1103disabled is used to test upgrade workflows: when set to true, // the correct behaviour for namespaced cubbyholes is disabled, so we // can test an upgrade to a version that includes the fixes from @@ -1284,16 +1284,16 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover if recoveryKey == nil { 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, - }); err != nil { - return nil, errwrap.Wrapf("failed to store barrier config during migration: {{err}}", err) - } - + /* + if err := c.seal.SetBarrierConfig(ctx, &SealConfig{ + Type: wrapping.Shamir, + SecretShares: config.SecretShares, + SecretThreshold: config.SecretThreshold, + StoredShares: 1, + }); 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) From c4d0a142e9391a5f7f0d1e930c3016fdecce8555 Mon Sep 17 00:00:00 2001 From: Vishal Nayak Date: Fri, 17 Jan 2020 17:05:22 -0500 Subject: [PATCH 6/9] Minor updates --- command/seal_migration_test.go | 15 +++++++-------- go.mod | 3 +++ vault/core.go | 19 +++++++++---------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/command/seal_migration_test.go b/command/seal_migration_test.go index 744dc76fe36d..a775c4c68d42 100644 --- a/command/seal_migration_test.go +++ b/command/seal_migration_test.go @@ -48,7 +48,7 @@ func TestSealMigrationAutoToShamir(t *testing.T) { defer cluster.Cleanup() client := cluster.Cores[0].Client - resp, err := client.Sys().Init(&api.InitRequest{ + initResp, err := client.Sys().Init(&api.InitRequest{ RecoveryShares: 1, RecoveryThreshold: 1, }) @@ -58,9 +58,8 @@ func TestSealMigrationAutoToShamir(t *testing.T) { testhelpers.WaitForActiveNode(t, cluster) - keys := resp.RecoveryKeysB64 - rootToken := resp.RootToken - client.SetToken(rootToken) + keys := initResp.RecoveryKeysB64 + rootToken := initResp.RootToken core := cluster.Cores[0].Core client.SetToken(rootToken) @@ -79,17 +78,17 @@ func TestSealMigrationAutoToShamir(t *testing.T) { t.Fatal(err) } - var statusResp *api.SealStatusResponse + var resp *api.SealStatusResponse unsealOpts := &api.UnsealOpts{} for _, key := range keys { unsealOpts.Key = key unsealOpts.Migrate = false - statusResp, err = client.Sys().UnsealWithOptions(unsealOpts) + resp, 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) + resp, err = client.Sys().UnsealWithOptions(unsealOpts) if err != nil { t.Fatal(err) } @@ -97,7 +96,7 @@ func TestSealMigrationAutoToShamir(t *testing.T) { t.Fatal("expected response") } } - if statusResp.Sealed { + if resp.Sealed { t.Fatalf("expected unsealed state; got %#v", *resp) } } diff --git a/go.mod b/go.mod index 92a7b4628b25..8acf1f820a9a 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( github.com/cockroachdb/apd v1.1.0 // indirect github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c github.com/coreos/go-semver v0.2.0 + github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d // indirect github.com/denisenkom/go-mssqldb v0.0.0-20190412130859-3b1d194e553a github.com/dnaeon/go-vcr v1.0.1 // indirect github.com/dsnet/compress v0.0.1 // indirect @@ -47,6 +48,7 @@ require ( github.com/golang/protobuf v1.3.2 github.com/google/go-github v17.0.0+incompatible github.com/google/go-metrics-stackdriver v0.0.0-20190816035513-b52628e82e2a + github.com/google/go-querystring v1.0.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.8.5 // indirect github.com/hashicorp/consul-template v0.22.0 github.com/hashicorp/consul/api v1.1.0 @@ -95,6 +97,7 @@ require ( github.com/joyent/triton-go v0.0.0-20190112182421-51ffac552869 github.com/keybase/go-crypto v0.0.0-20190403132359-d65b6b94177f github.com/kr/pretty v0.1.0 + github.com/kr/pty v1.1.3 // indirect github.com/kr/text v0.1.0 github.com/lib/pq v1.2.0 github.com/mattn/go-colorable v0.1.4 diff --git a/vault/core.go b/vault/core.go index f92c226b4ecc..a1da2661026c 100644 --- a/vault/core.go +++ b/vault/core.go @@ -1284,16 +1284,15 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover if recoveryKey == nil { 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, - }); err != nil { - return nil, errwrap.Wrapf("failed to store barrier config during migration: {{err}}", err) - } - */ + if err := c.seal.SetBarrierConfig(ctx, &SealConfig{ + Type: wrapping.Shamir, + SecretShares: config.SecretShares, + SecretThreshold: config.SecretThreshold, + StoredShares: 1, + }); 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) From 8ff515df9c1a78982adb28c984e7f5dfe2eeff3c Mon Sep 17 00:00:00 2001 From: Vishal Nayak Date: Fri, 17 Jan 2020 18:14:01 -0500 Subject: [PATCH 7/9] Test with more shares and a threshold --- command/seal_migration_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/command/seal_migration_test.go b/command/seal_migration_test.go index a775c4c68d42..1e87e81404ca 100644 --- a/command/seal_migration_test.go +++ b/command/seal_migration_test.go @@ -49,8 +49,8 @@ func TestSealMigrationAutoToShamir(t *testing.T) { client := cluster.Cores[0].Client initResp, err := client.Sys().Init(&api.InitRequest{ - RecoveryShares: 1, - RecoveryThreshold: 1, + RecoveryShares: 5, + RecoveryThreshold: 3, }) if err != nil { t.Fatal(err) @@ -95,6 +95,9 @@ func TestSealMigrationAutoToShamir(t *testing.T) { if resp == nil { t.Fatal("expected response") } + if !resp.Sealed { + break + } } if resp.Sealed { t.Fatalf("expected unsealed state; got %#v", *resp) From 90e30bdf2041d6ba76136dfc12a63ea2a0909bfa Mon Sep 17 00:00:00 2001 From: Vishal Nayak Date: Fri, 17 Jan 2020 18:20:53 -0500 Subject: [PATCH 8/9] Add seal/unseal step to the test --- command/seal_migration_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/command/seal_migration_test.go b/command/seal_migration_test.go index 1e87e81404ca..a4df2e4718b3 100644 --- a/command/seal_migration_test.go +++ b/command/seal_migration_test.go @@ -102,6 +102,28 @@ func TestSealMigrationAutoToShamir(t *testing.T) { if resp.Sealed { t.Fatalf("expected unsealed state; got %#v", *resp) } + + // Seal and unseal again to verify that things are working fine + if err := client.Sys().Seal(); err != nil { + t.Fatal(err) + } + unsealOpts.Migrate = false + for _, key := range keys { + unsealOpts.Key = key + resp, err = client.Sys().UnsealWithOptions(unsealOpts) + if err != nil { + t.Fatal(err) + } + if resp == nil { + t.Fatal("expected response") + } + if !resp.Sealed { + break + } + } + if resp.Sealed { + t.Fatalf("expected unsealed state; got %#v", *resp) + } } func TestSealMigration(t *testing.T) { From b36e80069f47d55b359b2043bfb9291c3d7add16 Mon Sep 17 00:00:00 2001 From: Brian Kassouf Date: Tue, 21 Jan 2020 09:24:04 -0800 Subject: [PATCH 9/9] Update the logic that prepares seal migration (#8187) * Update the logic that preps seal migration * Add test and update recovery logic --- command/seal_migration_test.go | 99 ++++++++++++++++++++++++++++++++++ command/server_util.go | 57 ++++++++++++++------ go.mod | 3 -- vault/core.go | 8 --- 4 files changed, 139 insertions(+), 28 deletions(-) diff --git a/command/seal_migration_test.go b/command/seal_migration_test.go index a4df2e4718b3..c4e724132ab9 100644 --- a/command/seal_migration_test.go +++ b/command/seal_migration_test.go @@ -255,6 +255,41 @@ func TestSealMigration(t *testing.T) { t.Fatalf("expected unsealed state; got %#v", *resp) } + // Make sure the seal configs were updated correctly + b, err := autoSeal.BarrierConfig(context.Background()) + if err != nil { + t.Fatal(err) + } + if b.Type != autoSeal.BarrierType() { + t.Fatalf("bad seal config: %#v", b) + } + if b.SecretShares != 1 { + t.Fatalf("bad seal config: %#v", b) + } + if b.SecretThreshold != 1 { + t.Fatalf("bad seal config: %#v", b) + } + if b.StoredShares != 1 { + t.Fatalf("bad seal config: %#v", b) + } + + r, err := autoSeal.RecoveryConfig(context.Background()) + if err != nil { + t.Fatal(err) + } + if r.Type != wrapping.Shamir { + t.Fatalf("bad seal config: %#v", r) + } + if r.SecretShares != 2 { + t.Fatalf("bad seal config: %#v", r) + } + if r.SecretThreshold != 2 { + t.Fatalf("bad seal config: %#v", r) + } + if r.StoredShares != 0 { + t.Fatalf("bad seal config: %#v", r) + } + cluster.Cleanup() cluster.Cores = nil } @@ -349,6 +384,41 @@ func TestSealMigration(t *testing.T) { t.Fatalf("expected unsealed state; got %#v", *resp) } + // Make sure the seal configs were updated correctly + b, err := altSeal.BarrierConfig(context.Background()) + if err != nil { + t.Fatal(err) + } + if b.Type != altSeal.BarrierType() { + t.Fatalf("bad seal config: %#v", b) + } + if b.SecretShares != 1 { + t.Fatalf("bad seal config: %#v", b) + } + if b.SecretThreshold != 1 { + t.Fatalf("bad seal config: %#v", b) + } + if b.StoredShares != 1 { + t.Fatalf("bad seal config: %#v", b) + } + + r, err := altSeal.RecoveryConfig(context.Background()) + if err != nil { + t.Fatal(err) + } + if r.Type != wrapping.Shamir { + t.Fatalf("bad seal config: %#v", r) + } + if r.SecretShares != 2 { + t.Fatalf("bad seal config: %#v", r) + } + if r.SecretThreshold != 2 { + t.Fatalf("bad seal config: %#v", r) + } + if r.StoredShares != 0 { + t.Fatalf("bad seal config: %#v", r) + } + cluster.Cleanup() cluster.Cores = nil } @@ -363,6 +433,12 @@ func TestSealMigration(t *testing.T) { core := cluster.Cores[0].Core + wrapper := vault.NewDefaultSeal(&seal.Access{ + Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ + Logger: logger.Named("shamir"), + }), + }) + if err := adjustCoreForSealMigration(logger, core, wrapper, altSeal); err != nil { t.Fatal(err) } @@ -392,6 +468,29 @@ func TestSealMigration(t *testing.T) { t.Fatalf("expected unsealed state; got %#v", *resp) } + // Make sure the seal configs were updated correctly + b, err := wrapper.BarrierConfig(context.Background()) + if err != nil { + t.Fatal(err) + } + if b.Type != wrapping.Shamir { + t.Fatalf("bad seal config: %#v", b) + } + if b.SecretShares != 2 { + t.Fatalf("bad seal config: %#v", b) + } + if b.SecretThreshold != 2 { + t.Fatalf("bad seal config: %#v", b) + } + if b.StoredShares != 1 { + t.Fatalf("bad seal config: %#v", b) + } + + _, err = wrapper.RecoveryConfig(context.Background()) + if err == nil { + t.Fatal("expected error") + } + cluster.Cleanup() cluster.Cores = nil } diff --git a/command/server_util.go b/command/server_util.go index 0098dfbf586a..6d58028bac12 100644 --- a/command/server_util.go +++ b/command/server_util.go @@ -54,9 +54,6 @@ func adjustCoreForSealMigration(logger log.Logger, core *vault.Core, barrierSeal } } - var existSeal vault.Seal - var newSeal vault.Seal - if existBarrierSealConfig.Type == barrierSeal.BarrierType() { // In this case our migration seal is set so we are using it // (potentially) for unwrapping. Set it on core for that purpose then @@ -69,15 +66,49 @@ func adjustCoreForSealMigration(logger log.Logger, core *vault.Core, barrierSeal return errors.New(`Recovery seal configuration not found for existing seal`) } + if onEnterprise && barrierSeal.BarrierType() == wrapping.Shamir { + return errors.New("Migrating from autoseal to Shamir seal is not currently supported on Vault Enterprise") + } + + var migrationSeal vault.Seal + var newSeal vault.Seal + + // Determine the migrationSeal. This is either going to be an instance of + // shamir or the unwrapSeal. switch existBarrierSealConfig.Type { case wrapping.Shamir: // The value reflected in config is what we're going to - existSeal = vault.NewDefaultSeal(&vaultseal.Access{ + migrationSeal = vault.NewDefaultSeal(&vaultseal.Access{ Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{ Logger: logger.Named("shamir"), }), }) - newSeal = barrierSeal + + default: + // If we're not coming from Shamir we expect the previous seal to be + // in the config and disabled. + migrationSeal = unwrapSeal + } + + // newSeal will be the barrierSeal + newSeal = barrierSeal + + // Set the appropriate barrier and recovery configs. + switch { + case migrationSeal.RecoveryKeySupported() && newSeal.RecoveryKeySupported(): + // Migrating from auto->auto, copy the configs over + newSeal.SetCachedBarrierConfig(existBarrierSealConfig) + newSeal.SetCachedRecoveryConfig(existRecoverySealConfig) + case migrationSeal.RecoveryKeySupported(): + // Migrating from auto->shamir, clone auto's recovery config and set + // stored keys to 1. + newSealConfig := existRecoverySealConfig.Clone() + newSealConfig.StoredShares = 1 + newSeal.SetCachedBarrierConfig(newSealConfig) + case newSeal.RecoveryKeySupported(): + // Migrating from shamir->auto, set a new barrier config and set + // recovery config to a clone of shamir's barrier config with stored + // keys set to 0. newBarrierSealConfig := &vault.SealConfig{ Type: newSeal.BarrierType(), SecretShares: 1, @@ -85,21 +116,13 @@ func adjustCoreForSealMigration(logger log.Logger, core *vault.Core, barrierSeal StoredShares: 1, } newSeal.SetCachedBarrierConfig(newBarrierSealConfig) - newSeal.SetCachedRecoveryConfig(existBarrierSealConfig) - - default: - if onEnterprise && barrierSeal.BarrierType() == wrapping.Shamir { - return errors.New("Migrating from autoseal to Shamir seal is not currently supported on Vault Enterprise") - } - // If we're not coming from Shamir we expect the previous seal to be - // in the config and disabled. - existSeal = unwrapSeal - newSeal = barrierSeal - newSeal.SetCachedBarrierConfig(existRecoverySealConfig) + newRecoveryConfig := existBarrierSealConfig.Clone() + newRecoveryConfig.StoredShares = 0 + newSeal.SetCachedRecoveryConfig(newRecoveryConfig) } - core.SetSealsForMigration(existSeal, newSeal, unwrapSeal) + core.SetSealsForMigration(migrationSeal, newSeal, unwrapSeal) return nil } diff --git a/go.mod b/go.mod index 8acf1f820a9a..92a7b4628b25 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,6 @@ require ( github.com/cockroachdb/apd v1.1.0 // indirect github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c github.com/coreos/go-semver v0.2.0 - github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d // indirect github.com/denisenkom/go-mssqldb v0.0.0-20190412130859-3b1d194e553a github.com/dnaeon/go-vcr v1.0.1 // indirect github.com/dsnet/compress v0.0.1 // indirect @@ -48,7 +47,6 @@ require ( github.com/golang/protobuf v1.3.2 github.com/google/go-github v17.0.0+incompatible github.com/google/go-metrics-stackdriver v0.0.0-20190816035513-b52628e82e2a - github.com/google/go-querystring v1.0.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.8.5 // indirect github.com/hashicorp/consul-template v0.22.0 github.com/hashicorp/consul/api v1.1.0 @@ -97,7 +95,6 @@ require ( github.com/joyent/triton-go v0.0.0-20190112182421-51ffac552869 github.com/keybase/go-crypto v0.0.0-20190403132359-d65b6b94177f github.com/kr/pretty v0.1.0 - github.com/kr/pty v1.1.3 // indirect github.com/kr/text v0.1.0 github.com/lib/pq v1.2.0 github.com/mattn/go-colorable v0.1.4 diff --git a/vault/core.go b/vault/core.go index a1da2661026c..059edb1c2c82 100644 --- a/vault/core.go +++ b/vault/core.go @@ -1284,14 +1284,6 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover if recoveryKey == nil { 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, - }); 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.