open-vault/vault/generate_root_test.go

314 lines
7.4 KiB
Go

package vault
import (
"context"
"encoding/base64"
"testing"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/pgpkeys"
"github.com/hashicorp/vault/helper/xor"
)
func TestCore_GenerateRoot_Lifecycle(t *testing.T) {
bc, rc := TestSealDefConfigs()
c, masterKeys, _, _ := TestCoreUnsealedWithConfigs(t, bc, rc)
testCore_GenerateRoot_Lifecycle_Common(t, c, masterKeys)
}
func testCore_GenerateRoot_Lifecycle_Common(t *testing.T, c *Core, keys [][]byte) {
// Verify update not allowed
if _, err := c.GenerateRootUpdate(context.Background(), keys[0], "", GenerateStandardRootTokenStrategy); err == nil {
t.Fatalf("no root generation in progress")
}
// Should be no progress
num, err := c.GenerateRootProgress()
if err != nil {
t.Fatalf("err: %v", err)
}
if num != 0 {
t.Fatalf("bad: %d", num)
}
// Should be no config
conf, err := c.GenerateRootConfiguration()
if err != nil {
t.Fatalf("err: %v", err)
}
if conf != nil {
t.Fatalf("bad: %v", conf)
}
// Cancel should be idempotent
err = c.GenerateRootCancel()
if err != nil {
t.Fatalf("err: %v", err)
}
otpBytes, err := GenerateRandBytes(16)
if err != nil {
t.Fatal(err)
}
// Start a root generation
err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "", GenerateStandardRootTokenStrategy)
if err != nil {
t.Fatalf("err: %v", err)
}
// Should get config
conf, err = c.GenerateRootConfiguration()
if err != nil {
t.Fatalf("err: %v", err)
}
// Cancel should be clear
err = c.GenerateRootCancel()
if err != nil {
t.Fatalf("err: %v", err)
}
// Should be no config
conf, err = c.GenerateRootConfiguration()
if err != nil {
t.Fatalf("err: %v", err)
}
if conf != nil {
t.Fatalf("bad: %v", conf)
}
}
func TestCore_GenerateRoot_Init(t *testing.T) {
c, _, _ := TestCoreUnsealed(t)
testCore_GenerateRoot_Init_Common(t, c)
bc, rc := TestSealDefConfigs()
c, _, _, _ = TestCoreUnsealedWithConfigs(t, bc, rc)
testCore_GenerateRoot_Init_Common(t, c)
}
func testCore_GenerateRoot_Init_Common(t *testing.T, c *Core) {
otpBytes, err := GenerateRandBytes(16)
if err != nil {
t.Fatal(err)
}
err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "", GenerateStandardRootTokenStrategy)
if err != nil {
t.Fatalf("err: %v", err)
}
// Second should fail
err = c.GenerateRootInit("", pgpkeys.TestPubKey1, GenerateStandardRootTokenStrategy)
if err == nil {
t.Fatalf("should fail")
}
}
func TestCore_GenerateRoot_InvalidMasterNonce(t *testing.T) {
bc, _ := TestSealDefConfigs()
bc.SecretShares = 3
bc.SecretThreshold = 3
c, masterKeys, _, _ := TestCoreUnsealedWithConfigs(t, bc, nil)
// Pass in master keys as they'll be invalid
masterKeys[0][0]++
testCore_GenerateRoot_InvalidMasterNonce_Common(t, c, masterKeys)
}
func testCore_GenerateRoot_InvalidMasterNonce_Common(t *testing.T, c *Core, keys [][]byte) {
otpBytes, err := GenerateRandBytes(16)
if err != nil {
t.Fatal(err)
}
err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "", GenerateStandardRootTokenStrategy)
if err != nil {
t.Fatalf("err: %v", err)
}
// Fetch new config with generated nonce
rgconf, err := c.GenerateRootConfiguration()
if err != nil {
t.Fatalf("err: %v", err)
}
if rgconf == nil {
t.Fatalf("bad: no rekey config received")
}
// Provide the nonce (invalid)
_, err = c.GenerateRootUpdate(context.Background(), keys[0], "abcd", GenerateStandardRootTokenStrategy)
if err == nil {
t.Fatalf("expected error")
}
// Provide the master (invalid)
for _, key := range keys {
_, err = c.GenerateRootUpdate(context.Background(), key, rgconf.Nonce, GenerateStandardRootTokenStrategy)
}
if err == nil {
t.Fatalf("expected error")
}
}
func TestCore_GenerateRoot_Update_OTP(t *testing.T) {
bc, rc := TestSealDefConfigs()
c, masterKeys, _, _ := TestCoreUnsealedWithConfigs(t, bc, rc)
testCore_GenerateRoot_Update_OTP_Common(t, c, masterKeys[0:bc.SecretThreshold])
}
func testCore_GenerateRoot_Update_OTP_Common(t *testing.T, c *Core, keys [][]byte) {
otpBytes, err := GenerateRandBytes(16)
if err != nil {
t.Fatal(err)
}
otp := base64.StdEncoding.EncodeToString(otpBytes)
// Start a root generation
err = c.GenerateRootInit(otp, "", GenerateStandardRootTokenStrategy)
if err != nil {
t.Fatalf("err: %v", err)
}
// Fetch new config with generated nonce
rkconf, err := c.GenerateRootConfiguration()
if err != nil {
t.Fatalf("err: %v", err)
}
if rkconf == nil {
t.Fatalf("bad: no root generation config received")
}
// Provide the keys
var result *GenerateRootResult
for _, key := range keys {
result, err = c.GenerateRootUpdate(context.Background(), key, rkconf.Nonce, GenerateStandardRootTokenStrategy)
if err != nil {
t.Fatalf("err: %v", err)
}
}
if result == nil {
t.Fatalf("Bad, result is nil")
}
encodedToken := result.EncodedToken
// Should be no progress
num, err := c.GenerateRootProgress()
if err != nil {
t.Fatalf("err: %v", err)
}
if num != 0 {
t.Fatalf("bad: %d", num)
}
// Should be no config
conf, err := c.GenerateRootConfiguration()
if err != nil {
t.Fatalf("err: %v", err)
}
if conf != nil {
t.Fatalf("bad: %v", conf)
}
tokenBytes, err := xor.XORBase64(encodedToken, otp)
if err != nil {
t.Fatal(err)
}
token, err := uuid.FormatUUID(tokenBytes)
if err != nil {
t.Fatal(err)
}
// Ensure that the token is a root token
te, err := c.tokenStore.Lookup(context.Background(), token)
if err != nil {
t.Fatalf("err: %v", err)
}
if te == nil {
t.Fatalf("token was nil")
}
if te.ID != token || te.Parent != "" ||
len(te.Policies) != 1 || te.Policies[0] != "root" {
t.Fatalf("bad: %#v", *te)
}
}
func TestCore_GenerateRoot_Update_PGP(t *testing.T) {
bc, rc := TestSealDefConfigs()
c, masterKeys, _, _ := TestCoreUnsealedWithConfigs(t, bc, rc)
testCore_GenerateRoot_Update_PGP_Common(t, c, masterKeys[0:bc.SecretThreshold])
}
func testCore_GenerateRoot_Update_PGP_Common(t *testing.T, c *Core, keys [][]byte) {
// Start a root generation
err := c.GenerateRootInit("", pgpkeys.TestPubKey1, GenerateStandardRootTokenStrategy)
if err != nil {
t.Fatalf("err: %v", err)
}
// Fetch new config with generated nonce
rkconf, err := c.GenerateRootConfiguration()
if err != nil {
t.Fatalf("err: %v", err)
}
if rkconf == nil {
t.Fatalf("bad: no root generation config received")
}
// Provide the keys
var result *GenerateRootResult
for _, key := range keys {
result, err = c.GenerateRootUpdate(context.Background(), key, rkconf.Nonce, GenerateStandardRootTokenStrategy)
if err != nil {
t.Fatalf("err: %v", err)
}
}
if result == nil {
t.Fatalf("Bad, result is nil")
}
encodedToken := result.EncodedToken
// Should be no progress
num, err := c.GenerateRootProgress()
if err != nil {
t.Fatalf("err: %v", err)
}
if num != 0 {
t.Fatalf("bad: %d", num)
}
// Should be no config
conf, err := c.GenerateRootConfiguration()
if err != nil {
t.Fatalf("err: %v", err)
}
if conf != nil {
t.Fatalf("bad: %v", conf)
}
ptBuf, err := pgpkeys.DecryptBytes(encodedToken, pgpkeys.TestPrivKey1)
if err != nil {
t.Fatal(err)
}
if ptBuf == nil {
t.Fatal("Got nil plaintext key")
}
token := ptBuf.String()
// Ensure that the token is a root token
te, err := c.tokenStore.Lookup(context.Background(), token)
if err != nil {
t.Fatalf("err: %v", err)
}
if te == nil {
t.Fatalf("token was nil")
}
if te.ID != token || te.Parent != "" ||
len(te.Policies) != 1 || te.Policies[0] != "root" {
t.Fatalf("bad: %#v", *te)
}
}