1package keysutil 2 3import ( 4 "context" 5 "crypto/rand" 6 "fmt" 7 "reflect" 8 "testing" 9 10 "github.com/hashicorp/vault/sdk/helper/strutil" 11 "github.com/hashicorp/vault/sdk/logical" 12) 13 14var compilerOpt []string 15 16func TestEncrytedKeysStorage_BadPolicy(t *testing.T) { 17 policy := NewPolicy(PolicyConfig{ 18 Name: "metadata", 19 Type: KeyType_AES256_GCM96, 20 Derived: false, 21 KDF: Kdf_hkdf_sha256, 22 ConvergentEncryption: true, 23 VersionTemplate: EncryptedKeyPolicyVersionTpl, 24 }) 25 26 _, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{ 27 Policy: policy, 28 Prefix: "prefix", 29 }) 30 if err != ErrPolicyDerivedKeys { 31 t.Fatalf("Unexpected Error: %s", err) 32 } 33 34 policy = NewPolicy(PolicyConfig{ 35 Name: "metadata", 36 Type: KeyType_AES256_GCM96, 37 Derived: true, 38 KDF: Kdf_hkdf_sha256, 39 ConvergentEncryption: false, 40 VersionTemplate: EncryptedKeyPolicyVersionTpl, 41 }) 42 43 _, err = NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{ 44 Policy: policy, 45 Prefix: "prefix", 46 }) 47 if err != ErrPolicyConvergentEncryption { 48 t.Fatalf("Unexpected Error: %s", err) 49 } 50 51 policy = NewPolicy(PolicyConfig{ 52 Name: "metadata", 53 Type: KeyType_AES256_GCM96, 54 Derived: true, 55 KDF: Kdf_hkdf_sha256, 56 ConvergentEncryption: true, 57 VersionTemplate: EncryptedKeyPolicyVersionTpl, 58 }) 59 _, err = NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{ 60 Policy: policy, 61 Prefix: "prefix", 62 }) 63 if err != nil { 64 t.Fatalf("Unexpected Error: %s", err) 65 } 66} 67 68func TestEncryptedKeysStorage_List(t *testing.T) { 69 s := &logical.InmemStorage{} 70 policy := NewPolicy(PolicyConfig{ 71 Name: "metadata", 72 Type: KeyType_AES256_GCM96, 73 Derived: true, 74 KDF: Kdf_hkdf_sha256, 75 ConvergentEncryption: true, 76 VersionTemplate: EncryptedKeyPolicyVersionTpl, 77 }) 78 79 ctx := context.Background() 80 81 err := policy.Rotate(ctx, s, rand.Reader) 82 if err != nil { 83 t.Fatal(err) 84 } 85 86 es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{ 87 Policy: policy, 88 Prefix: "prefix", 89 }) 90 if err != nil { 91 t.Fatal(err) 92 } 93 94 err = es.Wrap(s).Put(ctx, &logical.StorageEntry{ 95 Key: "test", 96 Value: []byte("test"), 97 }) 98 if err != nil { 99 t.Fatal(err) 100 } 101 102 err = es.Wrap(s).Put(ctx, &logical.StorageEntry{ 103 Key: "test/foo", 104 Value: []byte("test"), 105 }) 106 if err != nil { 107 t.Fatal(err) 108 } 109 110 err = es.Wrap(s).Put(ctx, &logical.StorageEntry{ 111 Key: "test/foo1/test", 112 Value: []byte("test"), 113 }) 114 if err != nil { 115 t.Fatal(err) 116 } 117 118 keys, err := es.Wrap(s).List(ctx, "test/") 119 if err != nil { 120 t.Fatal(err) 121 } 122 123 // Test prefixed with "/" 124 keys, err = es.Wrap(s).List(ctx, "/test/") 125 if err != nil { 126 t.Fatal(err) 127 } 128 129 if len(keys) != 2 || keys[1] != "foo1/" || keys[0] != "foo" { 130 t.Fatalf("bad keys: %#v", keys) 131 } 132 133 keys, err = es.Wrap(s).List(ctx, "/") 134 if err != nil { 135 t.Fatal(err) 136 } 137 if len(keys) != 2 || keys[0] != "test" || keys[1] != "test/" { 138 t.Fatalf("bad keys: %#v", keys) 139 } 140 141 keys, err = es.Wrap(s).List(ctx, "") 142 if err != nil { 143 t.Fatal(err) 144 } 145 if len(keys) != 2 || keys[0] != "test" || keys[1] != "test/" { 146 t.Fatalf("bad keys: %#v", keys) 147 } 148} 149 150func TestEncryptedKeysStorage_CRUD(t *testing.T) { 151 s := &logical.InmemStorage{} 152 policy := NewPolicy(PolicyConfig{ 153 Name: "metadata", 154 Type: KeyType_AES256_GCM96, 155 Derived: true, 156 KDF: Kdf_hkdf_sha256, 157 ConvergentEncryption: true, 158 VersionTemplate: EncryptedKeyPolicyVersionTpl, 159 }) 160 161 ctx := context.Background() 162 163 err := policy.Rotate(ctx, s, rand.Reader) 164 if err != nil { 165 t.Fatal(err) 166 } 167 168 es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{ 169 Policy: policy, 170 Prefix: "prefix", 171 }) 172 if err != nil { 173 t.Fatal(err) 174 } 175 176 err = es.Wrap(s).Put(ctx, &logical.StorageEntry{ 177 Key: "test/foo", 178 Value: []byte("test"), 179 }) 180 if err != nil { 181 t.Fatal(err) 182 } 183 184 err = es.Wrap(s).Put(ctx, &logical.StorageEntry{ 185 Key: "test/foo1/test", 186 Value: []byte("test"), 187 }) 188 if err != nil { 189 t.Fatal(err) 190 } 191 192 keys, err := es.Wrap(s).List(ctx, "test/") 193 if err != nil { 194 t.Fatal(err) 195 } 196 197 // Test prefixed with "/" 198 keys, err = es.Wrap(s).List(ctx, "/test/") 199 if err != nil { 200 t.Fatal(err) 201 } 202 203 if len(keys) != 2 || !strutil.StrListContains(keys, "foo1/") || !strutil.StrListContains(keys, "foo") { 204 t.Fatalf("bad keys: %#v", keys) 205 } 206 207 // Test the cached value is correct 208 keys, err = es.Wrap(s).List(ctx, "test/") 209 if err != nil { 210 t.Fatal(err) 211 } 212 213 if len(keys) != 2 || !strutil.StrListContains(keys, "foo1/") || !strutil.StrListContains(keys, "foo") { 214 t.Fatalf("bad keys: %#v", keys) 215 } 216 217 data, err := es.Wrap(s).Get(ctx, "test/foo") 218 if err != nil { 219 t.Fatal(err) 220 } 221 if !reflect.DeepEqual(data.Value, []byte("test")) { 222 t.Fatalf("bad data: %#v", data) 223 } 224 225 err = es.Wrap(s).Delete(ctx, "test/foo") 226 if err != nil { 227 t.Fatal(err) 228 } 229 230 data, err = es.Wrap(s).Get(ctx, "test/foo") 231 if err != nil { 232 t.Fatal(err) 233 } 234 if data != nil { 235 t.Fatal("data should be nil") 236 } 237 238} 239 240func BenchmarkEncrytedKeyStorage_List(b *testing.B) { 241 s := &logical.InmemStorage{} 242 policy := NewPolicy(PolicyConfig{ 243 Name: "metadata", 244 Type: KeyType_AES256_GCM96, 245 Derived: true, 246 KDF: Kdf_hkdf_sha256, 247 ConvergentEncryption: true, 248 VersionTemplate: EncryptedKeyPolicyVersionTpl, 249 }) 250 251 ctx := context.Background() 252 253 err := policy.Rotate(ctx, s, rand.Reader) 254 if err != nil { 255 b.Fatal(err) 256 } 257 258 es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{ 259 Policy: policy, 260 Prefix: "prefix", 261 }) 262 if err != nil { 263 b.Fatal(err) 264 } 265 266 for i := 0; i < 10000; i++ { 267 err = es.Wrap(s).Put(ctx, &logical.StorageEntry{ 268 Key: fmt.Sprintf("test/%d", i), 269 Value: []byte("test"), 270 }) 271 if err != nil { 272 b.Fatal(err) 273 } 274 } 275 b.ResetTimer() 276 277 for i := 0; i < b.N; i++ { 278 keys, err := es.Wrap(s).List(ctx, "test/") 279 if err != nil { 280 b.Fatal(err) 281 } 282 compilerOpt = keys 283 } 284} 285 286func BenchmarkEncrytedKeyStorage_Put(b *testing.B) { 287 s := &logical.InmemStorage{} 288 policy := NewPolicy(PolicyConfig{ 289 Name: "metadata", 290 Type: KeyType_AES256_GCM96, 291 Derived: true, 292 KDF: Kdf_hkdf_sha256, 293 ConvergentEncryption: true, 294 VersionTemplate: EncryptedKeyPolicyVersionTpl, 295 }) 296 297 ctx := context.Background() 298 299 err := policy.Rotate(ctx, s, rand.Reader) 300 if err != nil { 301 b.Fatal(err) 302 } 303 304 es, err := NewEncryptedKeyStorageWrapper(EncryptedKeyStorageConfig{ 305 Policy: policy, 306 Prefix: "prefix", 307 }) 308 if err != nil { 309 b.Fatal(err) 310 } 311 312 b.ResetTimer() 313 314 for i := 0; i < b.N; i++ { 315 err = es.Wrap(s).Put(ctx, &logical.StorageEntry{ 316 Key: fmt.Sprintf("test/%d", i), 317 Value: []byte("test"), 318 }) 319 if err != nil { 320 b.Fatal(err) 321 } 322 } 323} 324