2016-01-09 02:21:02 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/base64"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/go-uuid"
|
|
|
|
"github.com/hashicorp/vault/helper/pgpkeys"
|
|
|
|
"github.com/hashicorp/vault/helper/xor"
|
|
|
|
)
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
func TestCore_GenerateRoot_Lifecycle(t *testing.T) {
|
2016-01-09 02:21:02 +00:00
|
|
|
c, master, _ := TestCoreUnsealed(t)
|
|
|
|
|
|
|
|
// Verify update not allowed
|
2016-01-15 15:55:35 +00:00
|
|
|
if _, err := c.GenerateRootUpdate(master, ""); err == nil {
|
2016-01-09 02:21:02 +00:00
|
|
|
t.Fatalf("no root generation in progress")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should be no progress
|
2016-01-15 15:55:35 +00:00
|
|
|
num, err := c.GenerateRootProgress()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if num != 0 {
|
|
|
|
t.Fatalf("bad: %d", num)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should be no config
|
2016-01-15 15:55:35 +00:00
|
|
|
conf, err := c.GenerateRootConfiguration()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if conf != nil {
|
|
|
|
t.Fatalf("bad: %v", conf)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cancel should be idempotent
|
2016-01-15 15:55:35 +00:00
|
|
|
err = c.GenerateRootCancel()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
otpBytes, err := GenerateRandBytes(16)
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start a root generation
|
2016-01-15 15:55:35 +00:00
|
|
|
err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "")
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should get config
|
2016-01-15 15:55:35 +00:00
|
|
|
conf, err = c.GenerateRootConfiguration()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cancel should be clear
|
2016-01-15 15:55:35 +00:00
|
|
|
err = c.GenerateRootCancel()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should be no config
|
2016-01-15 15:55:35 +00:00
|
|
|
conf, err = c.GenerateRootConfiguration()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if conf != nil {
|
|
|
|
t.Fatalf("bad: %v", conf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
func TestCore_GenerateRoot_Init(t *testing.T) {
|
2016-01-09 02:21:02 +00:00
|
|
|
c, _, _ := TestCoreUnsealed(t)
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
otpBytes, err := GenerateRandBytes(16)
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "")
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Second should fail
|
2016-01-15 15:55:35 +00:00
|
|
|
err = c.GenerateRootInit("", pgpkeys.TestPubKey1)
|
2016-01-09 02:21:02 +00:00
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("should fail")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
func TestCore_GenerateRoot_InvalidMaster(t *testing.T) {
|
2016-01-09 02:21:02 +00:00
|
|
|
c, master, _ := TestCoreUnsealed(t)
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
otpBytes, err := GenerateRandBytes(16)
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "")
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fetch new config with generated nonce
|
2016-01-15 15:55:35 +00:00
|
|
|
rgconf, err := c.GenerateRootConfiguration()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if rgconf == nil {
|
|
|
|
t.Fatalf("bad: no rekey config received")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Provide the master (invalid)
|
|
|
|
master[0]++
|
2016-01-15 15:55:35 +00:00
|
|
|
_, err = c.GenerateRootUpdate(master, rgconf.Nonce)
|
2016-01-09 02:21:02 +00:00
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expected error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
func TestCore_GenerateRoot_InvalidNonce(t *testing.T) {
|
2016-01-09 02:21:02 +00:00
|
|
|
c, master, _ := TestCoreUnsealed(t)
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
otpBytes, err := GenerateRandBytes(16)
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
err = c.GenerateRootInit(base64.StdEncoding.EncodeToString(otpBytes), "")
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Provide the nonce (invalid)
|
2016-01-15 15:55:35 +00:00
|
|
|
_, err = c.GenerateRootUpdate(master, "abcd")
|
2016-01-09 02:21:02 +00:00
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expected error")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
func TestCore_GenerateRoot_Update_OTP(t *testing.T) {
|
2016-01-09 02:21:02 +00:00
|
|
|
c, master, _ := TestCoreUnsealed(t)
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
otpBytes, err := GenerateRandBytes(16)
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
otp := base64.StdEncoding.EncodeToString(otpBytes)
|
|
|
|
// Start a root generation
|
2016-01-15 15:55:35 +00:00
|
|
|
err = c.GenerateRootInit(otp, "")
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fetch new config with generated nonce
|
2016-01-15 15:55:35 +00:00
|
|
|
rkconf, err := c.GenerateRootConfiguration()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if rkconf == nil {
|
|
|
|
t.Fatalf("bad: no root generation config received")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Provide the master
|
2016-01-15 15:55:35 +00:00
|
|
|
result, err := c.GenerateRootUpdate(master, rkconf.Nonce)
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if result == nil {
|
|
|
|
t.Fatalf("Bad, result is nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
encodedRootToken := result.EncodedRootToken
|
|
|
|
|
|
|
|
// Should be no progress
|
2016-01-15 15:55:35 +00:00
|
|
|
num, err := c.GenerateRootProgress()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if num != 0 {
|
|
|
|
t.Fatalf("bad: %d", num)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should be no config
|
2016-01-15 15:55:35 +00:00
|
|
|
conf, err := c.GenerateRootConfiguration()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if conf != nil {
|
|
|
|
t.Fatalf("bad: %v", conf)
|
|
|
|
}
|
|
|
|
|
|
|
|
tokenBytes, err := xor.XORBase64(encodedRootToken, 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(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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-15 15:55:35 +00:00
|
|
|
func TestCore_GenerateRoot_Update_PGP(t *testing.T) {
|
2016-01-09 02:21:02 +00:00
|
|
|
c, master, _ := TestCoreUnsealed(t)
|
|
|
|
|
|
|
|
// Start a root generation
|
2016-01-15 15:55:35 +00:00
|
|
|
err := c.GenerateRootInit("", pgpkeys.TestPubKey1)
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fetch new config with generated nonce
|
2016-01-15 15:55:35 +00:00
|
|
|
rkconf, err := c.GenerateRootConfiguration()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if rkconf == nil {
|
|
|
|
t.Fatalf("bad: no root generation config received")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Provide the master
|
2016-01-15 15:55:35 +00:00
|
|
|
result, err := c.GenerateRootUpdate(master, rkconf.Nonce)
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if result == nil {
|
|
|
|
t.Fatalf("Bad, result is nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
encodedRootToken := result.EncodedRootToken
|
|
|
|
|
|
|
|
// Should be no progress
|
2016-01-15 15:55:35 +00:00
|
|
|
num, err := c.GenerateRootProgress()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if num != 0 {
|
|
|
|
t.Fatalf("bad: %d", num)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should be no config
|
2016-01-15 15:55:35 +00:00
|
|
|
conf, err := c.GenerateRootConfiguration()
|
2016-01-09 02:21:02 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if conf != nil {
|
|
|
|
t.Fatalf("bad: %v", conf)
|
|
|
|
}
|
|
|
|
|
|
|
|
ptBuf, err := pgpkeys.DecryptBytes(encodedRootToken, 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(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)
|
|
|
|
}
|
|
|
|
}
|