2015-03-05 21:27:35 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
2015-03-05 22:03:00 +00:00
|
|
|
"bytes"
|
2015-05-27 23:42:42 +00:00
|
|
|
"encoding/json"
|
2015-03-05 21:27:35 +00:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/vault/physical"
|
|
|
|
)
|
|
|
|
|
2015-03-05 22:34:05 +00:00
|
|
|
// mockBarrier returns a physical backend, security barrier, and master key
|
|
|
|
func mockBarrier(t *testing.T) (physical.Backend, SecurityBarrier, []byte) {
|
|
|
|
inm := physical.NewInmem()
|
|
|
|
b, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize and unseal
|
|
|
|
key, _ := b.GenerateKey()
|
|
|
|
b.Initialize(key)
|
|
|
|
b.Unseal(key)
|
|
|
|
return inm, b, key
|
|
|
|
}
|
|
|
|
|
2015-03-05 21:27:35 +00:00
|
|
|
func TestAESGCMBarrier_Basic(t *testing.T) {
|
|
|
|
inm := physical.NewInmem()
|
|
|
|
b, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
testBarrier(t, b)
|
|
|
|
}
|
|
|
|
|
2015-05-28 00:10:08 +00:00
|
|
|
func TestAESGCMBarrier_Rotate(t *testing.T) {
|
|
|
|
inm := physical.NewInmem()
|
|
|
|
b, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
testBarrier_Rotate(t, b)
|
|
|
|
}
|
|
|
|
|
2015-05-28 23:42:32 +00:00
|
|
|
func TestAESGCMBarrier_Upgrade(t *testing.T) {
|
|
|
|
inm := physical.NewInmem()
|
|
|
|
b1, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
b2, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
testBarrier_Upgrade(t, b1, b2)
|
|
|
|
}
|
|
|
|
|
2015-05-29 21:29:55 +00:00
|
|
|
func TestAESGCMBarrier_Upgrade_Rekey(t *testing.T) {
|
|
|
|
inm := physical.NewInmem()
|
|
|
|
b1, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
b2, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
testBarrier_Upgrade_Rekey(t, b1, b2)
|
|
|
|
}
|
|
|
|
|
2015-05-28 00:17:03 +00:00
|
|
|
func TestAESGCMBarrier_Rekey(t *testing.T) {
|
|
|
|
inm := physical.NewInmem()
|
|
|
|
b, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
testBarrier_Rekey(t, b)
|
|
|
|
}
|
|
|
|
|
2015-05-27 23:42:42 +00:00
|
|
|
// Test an upgrade from the old (0.1) barrier/init to the new
|
|
|
|
// core/keyring style
|
|
|
|
func TestAESGCMBarrier_BackwardsCompatible(t *testing.T) {
|
|
|
|
inm := physical.NewInmem()
|
|
|
|
b, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate a barrier/init entry
|
|
|
|
encrypt, _ := b.GenerateKey()
|
|
|
|
init := &barrierInit{
|
|
|
|
Version: 1,
|
|
|
|
Key: encrypt,
|
|
|
|
}
|
|
|
|
buf, _ := json.Marshal(init)
|
|
|
|
|
|
|
|
// Protect with master key
|
|
|
|
master, _ := b.GenerateKey()
|
|
|
|
gcm, _ := b.aeadFromKey(master)
|
|
|
|
value := b.encrypt(initialKeyTerm, gcm, buf)
|
|
|
|
|
|
|
|
// Write to the physical backend
|
|
|
|
pe := &physical.Entry{
|
|
|
|
Key: barrierInitPath,
|
|
|
|
Value: value,
|
|
|
|
}
|
|
|
|
inm.Put(pe)
|
|
|
|
|
|
|
|
// Should still be initialized
|
|
|
|
isInit, err := b.Initialized()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !isInit {
|
|
|
|
t.Fatalf("should be initialized")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unseal should work and migrate online
|
|
|
|
err = b.Unseal(master)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check for migraiton
|
|
|
|
out, err := inm.Get(barrierInitPath)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if out != nil {
|
|
|
|
t.Fatalf("should delete old barrier init")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should have keyring
|
|
|
|
out, err = inm.Get(keyringPath)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if out == nil {
|
|
|
|
t.Fatalf("should have keyring file")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-05 22:03:00 +00:00
|
|
|
// Verify data sent through is encrypted
|
2015-03-05 21:27:35 +00:00
|
|
|
func TestAESGCMBarrier_Confidential(t *testing.T) {
|
2015-03-05 22:03:00 +00:00
|
|
|
inm := physical.NewInmem()
|
|
|
|
b, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize and unseal
|
|
|
|
key, _ := b.GenerateKey()
|
|
|
|
b.Initialize(key)
|
|
|
|
b.Unseal(key)
|
|
|
|
|
|
|
|
// Put a logical entry
|
|
|
|
entry := &Entry{Key: "test", Value: []byte("test")}
|
|
|
|
err = b.Put(entry)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check the physcial entry
|
|
|
|
pe, err := inm.Get("test")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if pe == nil {
|
|
|
|
t.Fatalf("missing physical entry")
|
|
|
|
}
|
|
|
|
|
|
|
|
if pe.Key != "test" {
|
|
|
|
t.Fatalf("bad: %#v", pe)
|
|
|
|
}
|
|
|
|
if bytes.Equal(pe.Value, entry.Value) {
|
|
|
|
t.Fatalf("bad: %#v", pe)
|
|
|
|
}
|
2015-03-05 21:27:35 +00:00
|
|
|
}
|
|
|
|
|
2015-03-05 22:03:00 +00:00
|
|
|
// Verify data sent through is cannot be tampered
|
2015-03-05 21:27:35 +00:00
|
|
|
func TestAESGCMBarrier_Integrity(t *testing.T) {
|
2015-03-05 22:03:00 +00:00
|
|
|
inm := physical.NewInmem()
|
|
|
|
b, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize and unseal
|
|
|
|
key, _ := b.GenerateKey()
|
|
|
|
b.Initialize(key)
|
|
|
|
b.Unseal(key)
|
|
|
|
|
|
|
|
// Put a logical entry
|
|
|
|
entry := &Entry{Key: "test", Value: []byte("test")}
|
|
|
|
err = b.Put(entry)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change a byte in the underlying physical entry
|
|
|
|
pe, _ := inm.Get("test")
|
|
|
|
pe.Value[15]++
|
|
|
|
err = inm.Put(pe)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read from the barrier
|
|
|
|
_, err = b.Get("test")
|
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("should fail!")
|
|
|
|
}
|
2015-03-05 21:27:35 +00:00
|
|
|
}
|
2015-04-30 17:15:41 +00:00
|
|
|
|
|
|
|
func TestEncrypt_Unique(t *testing.T) {
|
|
|
|
inm := physical.NewInmem()
|
|
|
|
b, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
key, _ := b.GenerateKey()
|
|
|
|
b.Initialize(key)
|
|
|
|
b.Unseal(key)
|
|
|
|
|
2015-05-27 23:01:25 +00:00
|
|
|
if b.keyring == nil {
|
2015-04-30 17:37:47 +00:00
|
|
|
t.Fatalf("barrier is sealed")
|
2015-04-30 17:15:41 +00:00
|
|
|
}
|
|
|
|
|
2015-05-27 23:01:25 +00:00
|
|
|
entry := &Entry{Key: "test", Value: []byte("test")}
|
|
|
|
term := b.keyring.ActiveTerm()
|
|
|
|
primary, _ := b.aeadForTerm(term)
|
|
|
|
|
|
|
|
first := b.encrypt(term, primary, entry.Value)
|
|
|
|
second := b.encrypt(term, primary, entry.Value)
|
2015-04-30 17:15:41 +00:00
|
|
|
|
2015-04-30 17:37:47 +00:00
|
|
|
if bytes.Equal(first, second) == true {
|
|
|
|
t.Fatalf("improper random seeding detected")
|
2015-04-30 17:15:41 +00:00
|
|
|
}
|
|
|
|
}
|
2015-04-30 18:12:47 +00:00
|
|
|
|
|
|
|
func TestInitialize_KeyLength(t *testing.T) {
|
|
|
|
inm := physical.NewInmem()
|
|
|
|
b, err := NewAESGCMBarrier(inm)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
long := []byte("ThisKeyDoesNotHaveTheRightLength!")
|
|
|
|
middle := []byte("ThisIsASecretKeyAndMore")
|
|
|
|
short := []byte("Key")
|
|
|
|
|
|
|
|
err = b.Initialize(long)
|
|
|
|
|
|
|
|
if err == nil {
|
2015-04-30 18:27:32 +00:00
|
|
|
t.Fatalf("key length protection failed")
|
2015-04-30 18:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
err = b.Initialize(middle)
|
|
|
|
|
|
|
|
if err == nil {
|
2015-04-30 18:27:32 +00:00
|
|
|
t.Fatalf("key length protection failed")
|
2015-04-30 18:12:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
err = b.Initialize(short)
|
|
|
|
|
|
|
|
if err == nil {
|
2015-04-30 18:27:32 +00:00
|
|
|
t.Fatalf("key length protection failed")
|
2015-04-30 18:12:47 +00:00
|
|
|
}
|
|
|
|
}
|