open-vault/helper/keysutil/encrypted_key_storage_test.go
Brian Kassouf 5c84c36915
command/kv: Add a "kv" subcommand for using the key-value store (#4168)
* Add more cli subcommands

* Add metadata commands

* Add more subcommands

* Update cli

* Move archive commands to delete

* Add helpers for making http calls to the kv backend

* rename cli header

* Format the various maps from kv

* Add list command

* Update help text

* Add a command to enable versioning on a backend

* Rename enable-versions command

* Some review feedback

* Fix listing of top level keys

* Fix issue when metadata is nil

* Add test for lising top level keys

* Fix some typos

* Add a note about deleting all versions
2018-03-21 15:02:41 -07:00

427 lines
8.4 KiB
Go

package keysutil
import (
"context"
"fmt"
"reflect"
"sync"
"testing"
"github.com/hashicorp/vault/logical"
)
var compilerOpt []string
func TestBase58(t *testing.T) {
tCases := []struct {
in string
out string
}{
{
"",
"0",
},
{
"foo",
"sapp",
},
{
"5d5746d044b9a9429249966c9e3fee178ca679b91487b11d4b73c9865202104c",
"cozMP2pOYdDiNGeFQ2afKAOGIzO0HVpJ8OPFXuVPNbHasFyenK9CzIIPuOG7EFWOCy4YWvKGZa671N4kRSoaxZ",
},
{
"5ba33e16d742f3c785f6e7e8bb6f5fe82346ffa1c47aa8e95da4ddd5a55bb334",
"cotpEJPnhuTRofLi4lDe5iKw2fkSGc6TpUYeuWoBp8eLYJBWLRUVDZI414OjOCWXKZ0AI8gqNMoxd4eLOklwYk",
},
{
" ",
"w",
},
{
"-",
"J",
},
{
"0",
"M",
},
{
"1",
"N",
},
{
"-1",
"30B",
},
{
"11",
"3h7",
},
{
"abc",
"qMin",
},
{
"1234598760",
"1a0AFzKIPnihTq",
},
{
"abcdefghijklmnopqrstuvwxyz",
"hUBXsgd3F2swSlEgbVi2p0Ncr6kzVeJTLaW",
},
}
for _, c := range tCases {
e := Base62Encode([]byte(c.in))
d := string(Base62Decode(e))
if d != c.in {
t.Fatalf("decoded value didn't match input %#v %#v", c.in, d)
}
if e != c.out {
t.Fatalf("encoded value didn't match expected %#v, %#v", e, c.out)
}
}
d := Base62Decode("!0000/")
if len(d) != 0 {
t.Fatalf("Decode of invalid string should be empty, got %#v", d)
}
}
func TestEncrytedKeysStorage_BadPolicy(t *testing.T) {
policy := &Policy{
Name: "metadata",
Type: KeyType_AES256_GCM96,
Derived: false,
KDF: Kdf_hkdf_sha256,
ConvergentEncryption: true,
ConvergentVersion: 2,
VersionTemplate: EncryptedKeyPolicyVersionTpl,
versionPrefixCache: &sync.Map{},
}
_, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
Policy: policy,
Prefix: "prefix",
})
if err != ErrPolicyDerivedKeys {
t.Fatalf("Unexpected Error: %s", err)
}
policy = &Policy{
Name: "metadata",
Type: KeyType_AES256_GCM96,
Derived: true,
KDF: Kdf_hkdf_sha256,
ConvergentEncryption: false,
ConvergentVersion: 2,
VersionTemplate: EncryptedKeyPolicyVersionTpl,
versionPrefixCache: &sync.Map{},
}
_, err = NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
Policy: policy,
Prefix: "prefix",
})
if err != ErrPolicyConvergentEncryption {
t.Fatalf("Unexpected Error: %s", err)
}
policy = &Policy{
Name: "metadata",
Type: KeyType_AES256_GCM96,
Derived: true,
KDF: Kdf_hkdf_sha256,
ConvergentEncryption: true,
ConvergentVersion: 1,
VersionTemplate: EncryptedKeyPolicyVersionTpl,
versionPrefixCache: &sync.Map{},
}
_, err = NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
Policy: policy,
Prefix: "prefix",
})
if err != ErrPolicyConvergentVersion {
t.Fatalf("Unexpected Error: %s", err)
}
policy = &Policy{
Name: "metadata",
Type: KeyType_AES256_GCM96,
Derived: true,
KDF: Kdf_hkdf_sha256,
ConvergentEncryption: true,
ConvergentVersion: 2,
VersionTemplate: EncryptedKeyPolicyVersionTpl,
versionPrefixCache: &sync.Map{},
}
}
func TestEncryptedKeysStorage_List(t *testing.T) {
s := &logical.InmemStorage{}
policy := &Policy{
Name: "metadata",
Type: KeyType_AES256_GCM96,
Derived: true,
KDF: Kdf_hkdf_sha256,
ConvergentEncryption: true,
ConvergentVersion: 2,
VersionTemplate: EncryptedKeyPolicyVersionTpl,
versionPrefixCache: &sync.Map{},
}
ctx := context.Background()
err := policy.Rotate(ctx, s)
if err != nil {
t.Fatal(err)
}
es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
Policy: policy,
Prefix: "prefix",
})
if err != nil {
t.Fatal(err)
}
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
Key: "test",
Value: []byte("test"),
})
if err != nil {
t.Fatal(err)
}
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
Key: "test/foo",
Value: []byte("test"),
})
if err != nil {
t.Fatal(err)
}
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
Key: "test/foo1/test",
Value: []byte("test"),
})
if err != nil {
t.Fatal(err)
}
keys, err := es.Wrap(s).List(ctx, "test/")
if err != nil {
t.Fatal(err)
}
// Test prefixed with "/"
keys, err = es.Wrap(s).List(ctx, "/test/")
if err != nil {
t.Fatal(err)
}
if len(keys) != 2 || keys[0] != "foo1/" || keys[1] != "foo" {
t.Fatalf("bad keys: %#v", keys)
}
keys, err = es.Wrap(s).List(ctx, "/")
if err != nil {
t.Fatal(err)
}
if len(keys) != 2 || keys[0] != "test" || keys[1] != "test/" {
t.Fatalf("bad keys: %#v", keys)
}
keys, err = es.Wrap(s).List(ctx, "")
if err != nil {
t.Fatal(err)
}
if len(keys) != 2 || keys[0] != "test" || keys[1] != "test/" {
t.Fatalf("bad keys: %#v", keys)
}
}
func TestEncryptedKeysStorage_CRUD(t *testing.T) {
s := &logical.InmemStorage{}
policy := &Policy{
Name: "metadata",
Type: KeyType_AES256_GCM96,
Derived: true,
KDF: Kdf_hkdf_sha256,
ConvergentEncryption: true,
ConvergentVersion: 2,
VersionTemplate: EncryptedKeyPolicyVersionTpl,
versionPrefixCache: &sync.Map{},
}
ctx := context.Background()
err := policy.Rotate(ctx, s)
if err != nil {
t.Fatal(err)
}
es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
Policy: policy,
Prefix: "prefix",
})
if err != nil {
t.Fatal(err)
}
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
Key: "test/foo",
Value: []byte("test"),
})
if err != nil {
t.Fatal(err)
}
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
Key: "test/foo1/test",
Value: []byte("test"),
})
if err != nil {
t.Fatal(err)
}
keys, err := es.Wrap(s).List(ctx, "test/")
if err != nil {
t.Fatal(err)
}
// Test prefixed with "/"
keys, err = es.Wrap(s).List(ctx, "/test/")
if err != nil {
t.Fatal(err)
}
if len(keys) != 2 || keys[0] != "foo1/" || keys[1] != "foo" {
t.Fatalf("bad keys: %#v", keys)
}
// Test the cached value is correct
keys, err = es.Wrap(s).List(ctx, "test/")
if err != nil {
t.Fatal(err)
}
if len(keys) != 2 || keys[0] != "foo1/" || keys[1] != "foo" {
t.Fatalf("bad keys: %#v", keys)
}
data, err := es.Wrap(s).Get(ctx, "test/foo")
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(data.Value, []byte("test")) {
t.Fatalf("bad data: %#v", data)
}
err = es.Wrap(s).Delete(ctx, "test/foo")
if err != nil {
t.Fatal(err)
}
data, err = es.Wrap(s).Get(ctx, "test/foo")
if err != nil {
t.Fatal(err)
}
if data != nil {
t.Fatal("data should be nil")
}
}
func BenchmarkEncrytedKeyStorage_List(b *testing.B) {
s := &logical.InmemStorage{}
policy := &Policy{
Name: "metadata",
Type: KeyType_AES256_GCM96,
Derived: true,
KDF: Kdf_hkdf_sha256,
ConvergentEncryption: true,
ConvergentVersion: 2,
VersionTemplate: EncryptedKeyPolicyVersionTpl,
versionPrefixCache: &sync.Map{},
}
ctx := context.Background()
err := policy.Rotate(ctx, s)
if err != nil {
b.Fatal(err)
}
es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
Policy: policy,
Prefix: "prefix",
})
if err != nil {
b.Fatal(err)
}
for i := 0; i < 10000; i++ {
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
Key: fmt.Sprintf("test/%d", i),
Value: []byte("test"),
})
if err != nil {
b.Fatal(err)
}
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
keys, err := es.Wrap(s).List(ctx, "test/")
if err != nil {
b.Fatal(err)
}
compilerOpt = keys
}
}
func BenchmarkEncrytedKeyStorage_Put(b *testing.B) {
s := &logical.InmemStorage{}
policy := &Policy{
Name: "metadata",
Type: KeyType_AES256_GCM96,
Derived: true,
KDF: Kdf_hkdf_sha256,
ConvergentEncryption: true,
ConvergentVersion: 2,
VersionTemplate: EncryptedKeyPolicyVersionTpl,
versionPrefixCache: &sync.Map{},
}
ctx := context.Background()
err := policy.Rotate(ctx, s)
if err != nil {
b.Fatal(err)
}
es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
Policy: policy,
Prefix: "prefix",
})
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
Key: fmt.Sprintf("test/%d", i),
Value: []byte("test"),
})
if err != nil {
b.Fatal(err)
}
}
}