2023-03-15 16:00:52 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2018-03-09 01:58:50 +00:00
|
|
|
package keysutil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-10-17 17:33:00 +00:00
|
|
|
"crypto/rand"
|
2018-03-09 01:58:50 +00:00
|
|
|
"fmt"
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
|
2021-07-16 00:17:31 +00:00
|
|
|
"github.com/hashicorp/go-secure-stdlib/strutil"
|
2019-04-12 21:54:35 +00:00
|
|
|
"github.com/hashicorp/vault/sdk/logical"
|
2018-03-09 01:58:50 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var compilerOpt []string
|
|
|
|
|
|
|
|
func TestEncrytedKeysStorage_BadPolicy(t *testing.T) {
|
2018-06-05 22:51:35 +00:00
|
|
|
policy := NewPolicy(PolicyConfig{
|
2018-03-09 01:58:50 +00:00
|
|
|
Name: "metadata",
|
|
|
|
Type: KeyType_AES256_GCM96,
|
|
|
|
Derived: false,
|
|
|
|
KDF: Kdf_hkdf_sha256,
|
|
|
|
ConvergentEncryption: true,
|
|
|
|
VersionTemplate: EncryptedKeyPolicyVersionTpl,
|
2018-06-05 22:51:35 +00:00
|
|
|
})
|
2018-03-09 01:58:50 +00:00
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
_, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
|
|
|
|
Policy: policy,
|
|
|
|
Prefix: "prefix",
|
2018-03-09 01:58:50 +00:00
|
|
|
})
|
|
|
|
if err != ErrPolicyDerivedKeys {
|
|
|
|
t.Fatalf("Unexpected Error: %s", err)
|
|
|
|
}
|
|
|
|
|
2018-06-05 22:51:35 +00:00
|
|
|
policy = NewPolicy(PolicyConfig{
|
2018-03-09 01:58:50 +00:00
|
|
|
Name: "metadata",
|
|
|
|
Type: KeyType_AES256_GCM96,
|
|
|
|
Derived: true,
|
|
|
|
KDF: Kdf_hkdf_sha256,
|
|
|
|
ConvergentEncryption: false,
|
|
|
|
VersionTemplate: EncryptedKeyPolicyVersionTpl,
|
2018-06-05 22:51:35 +00:00
|
|
|
})
|
2018-03-09 01:58:50 +00:00
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
_, err = NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
|
|
|
|
Policy: policy,
|
|
|
|
Prefix: "prefix",
|
2018-03-09 01:58:50 +00:00
|
|
|
})
|
|
|
|
if err != ErrPolicyConvergentEncryption {
|
|
|
|
t.Fatalf("Unexpected Error: %s", err)
|
|
|
|
}
|
|
|
|
|
2018-06-05 22:51:35 +00:00
|
|
|
policy = NewPolicy(PolicyConfig{
|
2018-03-09 01:58:50 +00:00
|
|
|
Name: "metadata",
|
|
|
|
Type: KeyType_AES256_GCM96,
|
|
|
|
Derived: true,
|
|
|
|
KDF: Kdf_hkdf_sha256,
|
|
|
|
ConvergentEncryption: true,
|
|
|
|
VersionTemplate: EncryptedKeyPolicyVersionTpl,
|
2018-06-05 22:51:35 +00:00
|
|
|
})
|
2018-03-18 19:59:07 +00:00
|
|
|
_, err = NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
|
|
|
|
Policy: policy,
|
|
|
|
Prefix: "prefix",
|
2018-03-09 01:58:50 +00:00
|
|
|
})
|
2018-06-05 22:51:35 +00:00
|
|
|
if err != nil {
|
2018-03-09 01:58:50 +00:00
|
|
|
t.Fatalf("Unexpected Error: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-21 22:02:41 +00:00
|
|
|
func TestEncryptedKeysStorage_List(t *testing.T) {
|
|
|
|
s := &logical.InmemStorage{}
|
2018-06-05 22:51:35 +00:00
|
|
|
policy := NewPolicy(PolicyConfig{
|
2018-03-21 22:02:41 +00:00
|
|
|
Name: "metadata",
|
|
|
|
Type: KeyType_AES256_GCM96,
|
|
|
|
Derived: true,
|
|
|
|
KDF: Kdf_hkdf_sha256,
|
|
|
|
ConvergentEncryption: true,
|
|
|
|
VersionTemplate: EncryptedKeyPolicyVersionTpl,
|
2018-06-05 22:51:35 +00:00
|
|
|
})
|
2018-03-21 22:02:41 +00:00
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2019-10-17 17:33:00 +00:00
|
|
|
err := policy.Rotate(ctx, s, rand.Reader)
|
2018-03-21 22:02:41 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2018-06-27 18:48:59 +00:00
|
|
|
if len(keys) != 2 || keys[1] != "foo1/" || keys[0] != "foo" {
|
2018-03-21 22:02:41 +00:00
|
|
|
t.Fatalf("bad keys: %#v", keys)
|
|
|
|
}
|
|
|
|
|
|
|
|
keys, err = es.Wrap(s).List(ctx, "/")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2018-06-27 18:48:59 +00:00
|
|
|
if len(keys) != 2 || keys[0] != "test" || keys[1] != "test/" {
|
2018-03-21 22:02:41 +00:00
|
|
|
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) {
|
2018-03-09 01:58:50 +00:00
|
|
|
s := &logical.InmemStorage{}
|
2018-06-05 22:51:35 +00:00
|
|
|
policy := NewPolicy(PolicyConfig{
|
2018-03-09 01:58:50 +00:00
|
|
|
Name: "metadata",
|
|
|
|
Type: KeyType_AES256_GCM96,
|
|
|
|
Derived: true,
|
|
|
|
KDF: Kdf_hkdf_sha256,
|
|
|
|
ConvergentEncryption: true,
|
|
|
|
VersionTemplate: EncryptedKeyPolicyVersionTpl,
|
2018-06-05 22:51:35 +00:00
|
|
|
})
|
2018-03-09 01:58:50 +00:00
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2019-10-17 17:33:00 +00:00
|
|
|
err := policy.Rotate(ctx, s, rand.Reader)
|
2018-03-09 01:58:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
|
|
|
|
Policy: policy,
|
|
|
|
Prefix: "prefix",
|
2018-03-09 01:58:50 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
|
2018-03-09 01:58:50 +00:00
|
|
|
Key: "test/foo",
|
|
|
|
Value: []byte("test"),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
|
2018-03-09 01:58:50 +00:00
|
|
|
Key: "test/foo1/test",
|
|
|
|
Value: []byte("test"),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
keys, err := es.Wrap(s).List(ctx, "test/")
|
2018-03-09 01:58:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test prefixed with "/"
|
2018-03-18 19:59:07 +00:00
|
|
|
keys, err = es.Wrap(s).List(ctx, "/test/")
|
2018-03-09 01:58:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-06-05 22:51:35 +00:00
|
|
|
if len(keys) != 2 || !strutil.StrListContains(keys, "foo1/") || !strutil.StrListContains(keys, "foo") {
|
2018-03-09 01:58:50 +00:00
|
|
|
t.Fatalf("bad keys: %#v", keys)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test the cached value is correct
|
2018-03-18 19:59:07 +00:00
|
|
|
keys, err = es.Wrap(s).List(ctx, "test/")
|
2018-03-09 01:58:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-06-05 22:51:35 +00:00
|
|
|
if len(keys) != 2 || !strutil.StrListContains(keys, "foo1/") || !strutil.StrListContains(keys, "foo") {
|
2018-03-09 01:58:50 +00:00
|
|
|
t.Fatalf("bad keys: %#v", keys)
|
|
|
|
}
|
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
data, err := es.Wrap(s).Get(ctx, "test/foo")
|
2018-03-09 01:58:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(data.Value, []byte("test")) {
|
|
|
|
t.Fatalf("bad data: %#v", data)
|
|
|
|
}
|
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
err = es.Wrap(s).Delete(ctx, "test/foo")
|
2018-03-09 01:58:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
data, err = es.Wrap(s).Get(ctx, "test/foo")
|
2018-03-09 01:58:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if data != nil {
|
|
|
|
t.Fatal("data should be nil")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkEncrytedKeyStorage_List(b *testing.B) {
|
|
|
|
s := &logical.InmemStorage{}
|
2018-06-05 22:51:35 +00:00
|
|
|
policy := NewPolicy(PolicyConfig{
|
2018-03-09 01:58:50 +00:00
|
|
|
Name: "metadata",
|
|
|
|
Type: KeyType_AES256_GCM96,
|
|
|
|
Derived: true,
|
|
|
|
KDF: Kdf_hkdf_sha256,
|
|
|
|
ConvergentEncryption: true,
|
|
|
|
VersionTemplate: EncryptedKeyPolicyVersionTpl,
|
2018-06-05 22:51:35 +00:00
|
|
|
})
|
2018-03-09 01:58:50 +00:00
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2019-10-17 17:33:00 +00:00
|
|
|
err := policy.Rotate(ctx, s, rand.Reader)
|
2018-03-09 01:58:50 +00:00
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
|
|
|
|
Policy: policy,
|
|
|
|
Prefix: "prefix",
|
2018-03-09 01:58:50 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := 0; i < 10000; i++ {
|
2018-03-18 19:59:07 +00:00
|
|
|
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
|
2018-03-09 01:58:50 +00:00
|
|
|
Key: fmt.Sprintf("test/%d", i),
|
|
|
|
Value: []byte("test"),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
2018-03-18 19:59:07 +00:00
|
|
|
keys, err := es.Wrap(s).List(ctx, "test/")
|
2018-03-09 01:58:50 +00:00
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
compilerOpt = keys
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkEncrytedKeyStorage_Put(b *testing.B) {
|
|
|
|
s := &logical.InmemStorage{}
|
2018-06-05 22:51:35 +00:00
|
|
|
policy := NewPolicy(PolicyConfig{
|
2018-03-09 01:58:50 +00:00
|
|
|
Name: "metadata",
|
|
|
|
Type: KeyType_AES256_GCM96,
|
|
|
|
Derived: true,
|
|
|
|
KDF: Kdf_hkdf_sha256,
|
|
|
|
ConvergentEncryption: true,
|
|
|
|
VersionTemplate: EncryptedKeyPolicyVersionTpl,
|
2018-06-05 22:51:35 +00:00
|
|
|
})
|
2018-03-09 01:58:50 +00:00
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2019-10-17 17:33:00 +00:00
|
|
|
err := policy.Rotate(ctx, s, rand.Reader)
|
2018-03-09 01:58:50 +00:00
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-03-18 19:59:07 +00:00
|
|
|
es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{
|
|
|
|
Policy: policy,
|
|
|
|
Prefix: "prefix",
|
2018-03-09 01:58:50 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
for i := 0; i < b.N; i++ {
|
2018-03-18 19:59:07 +00:00
|
|
|
err = es.Wrap(s).Put(ctx, &logical.StorageEntry{
|
2018-03-09 01:58:50 +00:00
|
|
|
Key: fmt.Sprintf("test/%d", i),
|
|
|
|
Value: []byte("test"),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|