2015-03-11 18:52:01 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
2015-03-11 18:57:05 +00:00
|
|
|
"reflect"
|
2015-03-11 18:52:01 +00:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/vault/physical"
|
|
|
|
)
|
|
|
|
|
2015-03-12 18:20:27 +00:00
|
|
|
var (
|
|
|
|
// invalidKey is used to test Unseal
|
|
|
|
invalidKey = []byte("abcdefghijklmnopqrstuvwxyz")[:17]
|
|
|
|
)
|
|
|
|
|
2015-03-11 21:25:16 +00:00
|
|
|
func testCore(t *testing.T) *Core {
|
|
|
|
inm := physical.NewInmem()
|
2015-03-12 17:22:12 +00:00
|
|
|
conf := &CoreConfig{Physical: inm}
|
2015-03-11 21:25:16 +00:00
|
|
|
c, err := NewCore(conf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2015-03-11 22:33:25 +00:00
|
|
|
func testUnsealedCore(t *testing.T) (*Core, []byte) {
|
|
|
|
c := testCore(t)
|
|
|
|
sealConf := &SealConfig{
|
|
|
|
SecretShares: 1,
|
|
|
|
SecretThreshold: 1,
|
|
|
|
}
|
|
|
|
res, err := c.Initialize(sealConf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
master := make([]byte, len(res.SecretShares[0]))
|
|
|
|
copy(master, res.SecretShares[0])
|
|
|
|
unseal, err := c.Unseal(res.SecretShares[0])
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !unseal {
|
|
|
|
t.Fatalf("should be unsealed")
|
|
|
|
}
|
|
|
|
return c, master
|
|
|
|
}
|
|
|
|
|
2015-03-11 18:52:01 +00:00
|
|
|
func TestCore_Init(t *testing.T) {
|
|
|
|
inm := physical.NewInmem()
|
2015-03-12 17:22:12 +00:00
|
|
|
conf := &CoreConfig{Physical: inm}
|
2015-03-11 18:52:01 +00:00
|
|
|
c, err := NewCore(conf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
init, err := c.Initialized()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if init {
|
|
|
|
t.Fatalf("should not be init")
|
|
|
|
}
|
|
|
|
|
2015-03-11 18:57:05 +00:00
|
|
|
// Check the seal configuration
|
|
|
|
outConf, err := c.SealConfig()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if outConf != nil {
|
|
|
|
t.Fatalf("bad: %v", outConf)
|
|
|
|
}
|
|
|
|
|
2015-03-11 18:52:01 +00:00
|
|
|
sealConf := &SealConfig{
|
|
|
|
SecretShares: 1,
|
|
|
|
SecretThreshold: 1,
|
|
|
|
}
|
|
|
|
res, err := c.Initialize(sealConf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(res.SecretShares) != 1 {
|
|
|
|
t.Fatalf("Bad: %v", res)
|
|
|
|
}
|
|
|
|
|
2015-03-11 18:57:05 +00:00
|
|
|
_, err = c.Initialize(sealConf)
|
|
|
|
if err != ErrAlreadyInit {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2015-03-11 18:52:01 +00:00
|
|
|
init, err = c.Initialized()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !init {
|
|
|
|
t.Fatalf("should be init")
|
|
|
|
}
|
|
|
|
|
2015-03-11 18:57:05 +00:00
|
|
|
// Check the seal configuration
|
|
|
|
outConf, err = c.SealConfig()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(outConf, sealConf) {
|
|
|
|
t.Fatalf("bad: %v expect: %v", outConf, sealConf)
|
|
|
|
}
|
|
|
|
|
2015-03-11 18:52:01 +00:00
|
|
|
// New Core, same backend
|
|
|
|
c2, err := NewCore(conf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2015-03-11 18:57:05 +00:00
|
|
|
_, err = c2.Initialize(sealConf)
|
|
|
|
if err != ErrAlreadyInit {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2015-03-11 18:52:01 +00:00
|
|
|
init, err = c2.Initialized()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !init {
|
|
|
|
t.Fatalf("should be init")
|
|
|
|
}
|
2015-03-11 18:57:05 +00:00
|
|
|
|
|
|
|
// Check the seal configuration
|
|
|
|
outConf, err = c2.SealConfig()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(outConf, sealConf) {
|
|
|
|
t.Fatalf("bad: %v expect: %v", outConf, sealConf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCore_Init_MultiShare(t *testing.T) {
|
2015-03-11 21:25:16 +00:00
|
|
|
c := testCore(t)
|
2015-03-11 18:57:05 +00:00
|
|
|
sealConf := &SealConfig{
|
|
|
|
SecretShares: 5,
|
|
|
|
SecretThreshold: 3,
|
|
|
|
}
|
|
|
|
res, err := c.Initialize(sealConf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(res.SecretShares) != 5 {
|
|
|
|
t.Fatalf("Bad: %v", res)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check the seal configuration
|
|
|
|
outConf, err := c.SealConfig()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(outConf, sealConf) {
|
|
|
|
t.Fatalf("bad: %v expect: %v", outConf, sealConf)
|
|
|
|
}
|
2015-03-11 18:52:01 +00:00
|
|
|
}
|
2015-03-11 21:25:16 +00:00
|
|
|
|
|
|
|
func TestCore_Unseal_MultiShare(t *testing.T) {
|
|
|
|
c := testCore(t)
|
|
|
|
|
2015-03-12 18:20:27 +00:00
|
|
|
_, err := c.Unseal(invalidKey)
|
2015-03-11 21:25:16 +00:00
|
|
|
if err != ErrNotInit {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
sealConf := &SealConfig{
|
|
|
|
SecretShares: 5,
|
|
|
|
SecretThreshold: 3,
|
|
|
|
}
|
|
|
|
res, err := c.Initialize(sealConf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
sealed, err := c.Sealed()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !sealed {
|
|
|
|
t.Fatalf("should be sealed")
|
|
|
|
}
|
|
|
|
|
|
|
|
if prog := c.SecretProgress(); prog != 0 {
|
|
|
|
t.Fatalf("bad progress: %d", prog)
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := 0; i < 5; i++ {
|
|
|
|
unseal, err := c.Unseal(res.SecretShares[i])
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ignore redundant
|
|
|
|
_, err = c.Unseal(res.SecretShares[i])
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if i >= 2 {
|
|
|
|
if !unseal {
|
|
|
|
t.Fatalf("should be unsealed")
|
|
|
|
}
|
|
|
|
if prog := c.SecretProgress(); prog != 0 {
|
|
|
|
t.Fatalf("bad progress: %d", prog)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if unseal {
|
|
|
|
t.Fatalf("should not be unsealed")
|
|
|
|
}
|
|
|
|
if prog := c.SecretProgress(); prog != i+1 {
|
|
|
|
t.Fatalf("bad progress: %d", prog)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sealed, err = c.Sealed()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if sealed {
|
|
|
|
t.Fatalf("should not be sealed")
|
|
|
|
}
|
|
|
|
|
|
|
|
err = c.Seal()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ignore redundant
|
|
|
|
err = c.Seal()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
sealed, err = c.Sealed()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !sealed {
|
|
|
|
t.Fatalf("should be sealed")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCore_Unseal_Single(t *testing.T) {
|
|
|
|
c := testCore(t)
|
|
|
|
|
2015-03-12 18:20:27 +00:00
|
|
|
_, err := c.Unseal(invalidKey)
|
2015-03-11 21:25:16 +00:00
|
|
|
if err != ErrNotInit {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
sealConf := &SealConfig{
|
|
|
|
SecretShares: 1,
|
|
|
|
SecretThreshold: 1,
|
|
|
|
}
|
|
|
|
res, err := c.Initialize(sealConf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
sealed, err := c.Sealed()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !sealed {
|
|
|
|
t.Fatalf("should be sealed")
|
|
|
|
}
|
|
|
|
|
|
|
|
if prog := c.SecretProgress(); prog != 0 {
|
|
|
|
t.Fatalf("bad progress: %d", prog)
|
|
|
|
}
|
|
|
|
|
|
|
|
unseal, err := c.Unseal(res.SecretShares[0])
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if !unseal {
|
|
|
|
t.Fatalf("should be unsealed")
|
|
|
|
}
|
|
|
|
if prog := c.SecretProgress(); prog != 0 {
|
|
|
|
t.Fatalf("bad progress: %d", prog)
|
|
|
|
}
|
|
|
|
|
|
|
|
sealed, err = c.Sealed()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if sealed {
|
|
|
|
t.Fatalf("should not be sealed")
|
|
|
|
}
|
|
|
|
}
|
2015-03-11 21:31:55 +00:00
|
|
|
|
|
|
|
func TestCore_Route_Sealed(t *testing.T) {
|
|
|
|
c := testCore(t)
|
|
|
|
sealConf := &SealConfig{
|
|
|
|
SecretShares: 1,
|
|
|
|
SecretThreshold: 1,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should not route anything
|
|
|
|
req := &Request{
|
|
|
|
Operation: ReadOperation,
|
2015-03-11 22:19:41 +00:00
|
|
|
Path: "sys/mounts",
|
2015-03-11 21:31:55 +00:00
|
|
|
}
|
|
|
|
_, err := c.HandleRequest(req)
|
|
|
|
if err != ErrSealed {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := c.Initialize(sealConf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
unseal, err := c.Unseal(res.SecretShares[0])
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !unseal {
|
|
|
|
t.Fatalf("should be unsealed")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should not error after unseal
|
|
|
|
_, err = c.HandleRequest(req)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
2015-03-13 18:16:24 +00:00
|
|
|
|
|
|
|
// Attempt to unseal after doing a first seal
|
|
|
|
func TestCore_SealUnseal(t *testing.T) {
|
|
|
|
c, key := testUnsealedCore(t)
|
|
|
|
if err := c.Seal(); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if unseal, err := c.Unseal(key); err != nil || !unseal {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|