154 lines
4 KiB
Go
154 lines
4 KiB
Go
// +build !enterprise
|
|
|
|
package command
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"testing"
|
|
|
|
wrapping "github.com/hashicorp/go-kms-wrapping"
|
|
aeadwrapper "github.com/hashicorp/go-kms-wrapping/wrappers/aead"
|
|
"github.com/hashicorp/vault/api"
|
|
"github.com/hashicorp/vault/helper/testhelpers"
|
|
sealhelper "github.com/hashicorp/vault/helper/testhelpers/seal"
|
|
"github.com/hashicorp/vault/helper/testhelpers/teststorage"
|
|
vaulthttp "github.com/hashicorp/vault/http"
|
|
"github.com/hashicorp/vault/vault"
|
|
"github.com/hashicorp/vault/vault/seal"
|
|
)
|
|
|
|
func TestSealMigration_AutoToShamir(t *testing.T) {
|
|
t.Parallel()
|
|
t.Run("inmem", func(t *testing.T) {
|
|
t.Parallel()
|
|
testSealMigrationAutoToShamir(t, teststorage.InmemBackendSetup)
|
|
})
|
|
|
|
t.Run("file", func(t *testing.T) {
|
|
t.Parallel()
|
|
testSealMigrationAutoToShamir(t, teststorage.FileBackendSetup)
|
|
})
|
|
|
|
t.Run("consul", func(t *testing.T) {
|
|
t.Parallel()
|
|
testSealMigrationAutoToShamir(t, teststorage.ConsulBackendSetup)
|
|
})
|
|
|
|
t.Run("raft", func(t *testing.T) {
|
|
t.Parallel()
|
|
testSealMigrationAutoToShamir(t, teststorage.RaftBackendSetup)
|
|
})
|
|
}
|
|
|
|
func testSealMigrationAutoToShamir(t *testing.T, setup teststorage.ClusterSetupMutator) {
|
|
tcluster := sealhelper.NewTransitSealServer(t)
|
|
defer tcluster.Cleanup()
|
|
|
|
tcluster.MakeKey(t, "key1")
|
|
var seals []vault.Seal
|
|
conf, opts := teststorage.ClusterSetup(&vault.CoreConfig{
|
|
DisableSealWrap: true,
|
|
}, &vault.TestClusterOptions{
|
|
HandlerFunc: vaulthttp.Handler,
|
|
SkipInit: true,
|
|
NumCores: 3,
|
|
SealFunc: func() vault.Seal {
|
|
tseal := tcluster.MakeSeal(t, "key1")
|
|
seals = append(seals, tseal)
|
|
return tseal
|
|
},
|
|
},
|
|
setup,
|
|
)
|
|
opts.SetupFunc = nil
|
|
cluster := vault.NewTestCluster(t, conf, opts)
|
|
cluster.Start()
|
|
defer cluster.Cleanup()
|
|
|
|
client := cluster.Cores[0].Client
|
|
initResp, err := client.Sys().Init(&api.InitRequest{
|
|
RecoveryShares: 5,
|
|
RecoveryThreshold: 3,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, k := range initResp.RecoveryKeysB64 {
|
|
b, _ := base64.RawStdEncoding.DecodeString(k)
|
|
cluster.RecoveryKeys = append(cluster.RecoveryKeys, b)
|
|
}
|
|
|
|
testhelpers.WaitForActiveNode(t, cluster)
|
|
|
|
rootToken := initResp.RootToken
|
|
client.SetToken(rootToken)
|
|
if err := client.Sys().Seal(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
logger := cluster.Logger.Named("shamir")
|
|
shamirSeal := vault.NewDefaultSeal(&seal.Access{
|
|
Wrapper: aeadwrapper.NewWrapper(&wrapping.WrapperOptions{
|
|
Logger: logger,
|
|
}),
|
|
})
|
|
|
|
if err := adjustCoreForSealMigration(logger, cluster.Cores[0].Core, shamirSeal, seals[0]); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Although we're unsealing using the recovery keys, this is still an
|
|
// autounseal; if we stopped the transit cluster this would fail.
|
|
var resp *api.SealStatusResponse
|
|
for _, key := range initResp.RecoveryKeysB64 {
|
|
resp, err = client.Sys().UnsealWithOptions(&api.UnsealOpts{Key: key})
|
|
if err == nil {
|
|
t.Fatal("expected error due to lack of migrate parameter")
|
|
}
|
|
resp, err = client.Sys().UnsealWithOptions(&api.UnsealOpts{Key: key, Migrate: true})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if resp == nil || !resp.Sealed {
|
|
break
|
|
}
|
|
}
|
|
if resp == nil || resp.Sealed {
|
|
t.Fatalf("expected unsealed state; got %#v", resp)
|
|
}
|
|
testhelpers.WaitForActiveNode(t, cluster)
|
|
|
|
// Seal and unseal again to verify that things are working fine
|
|
if err := client.Sys().Seal(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
tcluster.Cleanup()
|
|
// Assign nil to Cores so the deferred Cleanup doesn't break.
|
|
tcluster.Cores = nil
|
|
|
|
// Now the recovery keys are actually the barrier unseal keys.
|
|
for _, key := range initResp.RecoveryKeysB64 {
|
|
resp, err = client.Sys().UnsealWithOptions(&api.UnsealOpts{Key: key})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if resp == nil || !resp.Sealed {
|
|
break
|
|
}
|
|
}
|
|
if resp == nil || resp.Sealed {
|
|
t.Fatalf("expected unsealed state; got %#v", resp)
|
|
}
|
|
|
|
b, r, err := cluster.Cores[0].Core.PhysicalSealConfigs(context.Background())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
verifyBarrierConfig(t, b, wrapping.Shamir, 5, 3, 1)
|
|
if r != nil {
|
|
t.Fatalf("expected nil recovery config, got: %#v", r)
|
|
}
|
|
}
|