1package vault 2 3import ( 4 "bytes" 5 "context" 6 "encoding/json" 7 "testing" 8 9 log "github.com/hashicorp/go-hclog" 10 "github.com/hashicorp/vault/sdk/helper/logging" 11 "github.com/hashicorp/vault/sdk/logical" 12 "github.com/hashicorp/vault/sdk/physical" 13 "github.com/hashicorp/vault/sdk/physical/inmem" 14) 15 16var ( 17 logger = logging.NewVaultLogger(log.Trace) 18) 19 20// mockBarrier returns a physical backend, security barrier, and master key 21func mockBarrier(t testing.TB) (physical.Backend, SecurityBarrier, []byte) { 22 inm, err := inmem.NewInmem(nil, logger) 23 if err != nil { 24 t.Fatalf("err: %v", err) 25 } 26 b, err := NewAESGCMBarrier(inm) 27 if err != nil { 28 t.Fatalf("err: %v", err) 29 } 30 31 // Initialize and unseal 32 key, _ := b.GenerateKey() 33 b.Initialize(context.Background(), key) 34 b.Unseal(context.Background(), key) 35 return inm, b, key 36} 37 38func TestAESGCMBarrier_Basic(t *testing.T) { 39 inm, err := inmem.NewInmem(nil, logger) 40 if err != nil { 41 t.Fatalf("err: %v", err) 42 } 43 b, err := NewAESGCMBarrier(inm) 44 if err != nil { 45 t.Fatalf("err: %v", err) 46 } 47 testBarrier(t, b) 48} 49 50func TestAESGCMBarrier_Rotate(t *testing.T) { 51 inm, err := inmem.NewInmem(nil, logger) 52 if err != nil { 53 t.Fatalf("err: %v", err) 54 } 55 b, err := NewAESGCMBarrier(inm) 56 if err != nil { 57 t.Fatalf("err: %v", err) 58 } 59 testBarrier_Rotate(t, b) 60} 61 62func TestAESGCMBarrier_Upgrade(t *testing.T) { 63 inm, err := inmem.NewInmem(nil, logger) 64 if err != nil { 65 t.Fatalf("err: %v", err) 66 } 67 b1, err := NewAESGCMBarrier(inm) 68 if err != nil { 69 t.Fatalf("err: %v", err) 70 } 71 b2, err := NewAESGCMBarrier(inm) 72 if err != nil { 73 t.Fatalf("err: %v", err) 74 } 75 testBarrier_Upgrade(t, b1, b2) 76} 77 78func TestAESGCMBarrier_Upgrade_Rekey(t *testing.T) { 79 inm, err := inmem.NewInmem(nil, logger) 80 if err != nil { 81 t.Fatalf("err: %v", err) 82 } 83 b1, err := NewAESGCMBarrier(inm) 84 if err != nil { 85 t.Fatalf("err: %v", err) 86 } 87 b2, err := NewAESGCMBarrier(inm) 88 if err != nil { 89 t.Fatalf("err: %v", err) 90 } 91 testBarrier_Upgrade_Rekey(t, b1, b2) 92} 93 94func TestAESGCMBarrier_Rekey(t *testing.T) { 95 inm, err := inmem.NewInmem(nil, logger) 96 if err != nil { 97 t.Fatalf("err: %v", err) 98 } 99 b, err := NewAESGCMBarrier(inm) 100 if err != nil { 101 t.Fatalf("err: %v", err) 102 } 103 testBarrier_Rekey(t, b) 104} 105 106// Test an upgrade from the old (0.1) barrier/init to the new 107// core/keyring style 108func TestAESGCMBarrier_BackwardsCompatible(t *testing.T) { 109 inm, err := inmem.NewInmem(nil, logger) 110 if err != nil { 111 t.Fatalf("err: %v", err) 112 } 113 b, err := NewAESGCMBarrier(inm) 114 if err != nil { 115 t.Fatalf("err: %v", err) 116 } 117 118 // Generate a barrier/init entry 119 encrypt, _ := b.GenerateKey() 120 init := &barrierInit{ 121 Version: 1, 122 Key: encrypt, 123 } 124 buf, _ := json.Marshal(init) 125 126 // Protect with master key 127 master, _ := b.GenerateKey() 128 gcm, _ := b.aeadFromKey(master) 129 value, err := b.encrypt(barrierInitPath, initialKeyTerm, gcm, buf) 130 if err != nil { 131 t.Fatal(err) 132 } 133 134 // Write to the physical backend 135 pe := &physical.Entry{ 136 Key: barrierInitPath, 137 Value: value, 138 } 139 inm.Put(context.Background(), pe) 140 141 // Create a fake key 142 gcm, _ = b.aeadFromKey(encrypt) 143 value, err = b.encrypt("test/foo", initialKeyTerm, gcm, []byte("test")) 144 if err != nil { 145 t.Fatal(err) 146 } 147 pe = &physical.Entry{ 148 Key: "test/foo", 149 Value: value, 150 } 151 inm.Put(context.Background(), pe) 152 153 // Should still be initialized 154 isInit, err := b.Initialized(context.Background()) 155 if err != nil { 156 t.Fatalf("err: %v", err) 157 } 158 if !isInit { 159 t.Fatalf("should be initialized") 160 } 161 162 // Unseal should work and migrate online 163 err = b.Unseal(context.Background(), master) 164 if err != nil { 165 t.Fatalf("err: %v", err) 166 } 167 168 // Check for migration 169 out, err := inm.Get(context.Background(), barrierInitPath) 170 if err != nil { 171 t.Fatalf("err: %v", err) 172 } 173 if out != nil { 174 t.Fatalf("should delete old barrier init") 175 } 176 177 // Should have keyring 178 out, err = inm.Get(context.Background(), keyringPath) 179 if err != nil { 180 t.Fatalf("err: %v", err) 181 } 182 if out == nil { 183 t.Fatalf("should have keyring file") 184 } 185 186 // Attempt to read encrypted key 187 entry, err := b.Get(context.Background(), "test/foo") 188 if err != nil { 189 t.Fatalf("err: %v", err) 190 } 191 if string(entry.Value) != "test" { 192 t.Fatalf("bad: %#v", entry) 193 } 194} 195 196// Verify data sent through is encrypted 197func TestAESGCMBarrier_Confidential(t *testing.T) { 198 inm, err := inmem.NewInmem(nil, logger) 199 if err != nil { 200 t.Fatalf("err: %v", err) 201 } 202 b, err := NewAESGCMBarrier(inm) 203 if err != nil { 204 t.Fatalf("err: %v", err) 205 } 206 207 // Initialize and unseal 208 key, _ := b.GenerateKey() 209 b.Initialize(context.Background(), key) 210 b.Unseal(context.Background(), key) 211 212 // Put a logical entry 213 entry := &logical.StorageEntry{Key: "test", Value: []byte("test")} 214 err = b.Put(context.Background(), entry) 215 if err != nil { 216 t.Fatalf("err: %v", err) 217 } 218 219 // Check the physical entry 220 pe, err := inm.Get(context.Background(), "test") 221 if err != nil { 222 t.Fatalf("err: %v", err) 223 } 224 if pe == nil { 225 t.Fatalf("missing physical entry") 226 } 227 228 if pe.Key != "test" { 229 t.Fatalf("bad: %#v", pe) 230 } 231 if bytes.Equal(pe.Value, entry.Value) { 232 t.Fatalf("bad: %#v", pe) 233 } 234} 235 236// Verify data sent through cannot be tampered with 237func TestAESGCMBarrier_Integrity(t *testing.T) { 238 inm, err := inmem.NewInmem(nil, logger) 239 if err != nil { 240 t.Fatalf("err: %v", err) 241 } 242 b, err := NewAESGCMBarrier(inm) 243 if err != nil { 244 t.Fatalf("err: %v", err) 245 } 246 247 // Initialize and unseal 248 key, _ := b.GenerateKey() 249 b.Initialize(context.Background(), key) 250 b.Unseal(context.Background(), key) 251 252 // Put a logical entry 253 entry := &logical.StorageEntry{Key: "test", Value: []byte("test")} 254 err = b.Put(context.Background(), entry) 255 if err != nil { 256 t.Fatalf("err: %v", err) 257 } 258 259 // Change a byte in the underlying physical entry 260 pe, _ := inm.Get(context.Background(), "test") 261 pe.Value[15]++ 262 err = inm.Put(context.Background(), pe) 263 if err != nil { 264 t.Fatalf("err: %v", err) 265 } 266 267 // Read from the barrier 268 _, err = b.Get(context.Background(), "test") 269 if err == nil { 270 t.Fatalf("should fail!") 271 } 272} 273 274// Verify data sent through cannot be moved 275func TestAESGCMBarrier_MoveIntegrityV1(t *testing.T) { 276 inm, err := inmem.NewInmem(nil, logger) 277 if err != nil { 278 t.Fatalf("err: %v", err) 279 } 280 b, err := NewAESGCMBarrier(inm) 281 if err != nil { 282 t.Fatalf("err: %v", err) 283 } 284 b.currentAESGCMVersionByte = AESGCMVersion1 285 286 // Initialize and unseal 287 key, _ := b.GenerateKey() 288 err = b.Initialize(context.Background(), key) 289 if err != nil { 290 t.Fatalf("err: %v", err) 291 } 292 err = b.Unseal(context.Background(), key) 293 if err != nil { 294 t.Fatalf("err: %v", err) 295 } 296 297 // Put a logical entry 298 entry := &logical.StorageEntry{Key: "test", Value: []byte("test")} 299 err = b.Put(context.Background(), entry) 300 if err != nil { 301 t.Fatalf("err: %v", err) 302 } 303 304 // Change the location of the underlying physical entry 305 pe, _ := inm.Get(context.Background(), "test") 306 pe.Key = "moved" 307 err = inm.Put(context.Background(), pe) 308 if err != nil { 309 t.Fatalf("err: %v", err) 310 } 311 312 // Read from the barrier 313 _, err = b.Get(context.Background(), "moved") 314 if err != nil { 315 t.Fatalf("should succeed with version 1!") 316 } 317} 318 319func TestAESGCMBarrier_MoveIntegrityV2(t *testing.T) { 320 inm, err := inmem.NewInmem(nil, logger) 321 if err != nil { 322 t.Fatalf("err: %v", err) 323 } 324 b, err := NewAESGCMBarrier(inm) 325 if err != nil { 326 t.Fatalf("err: %v", err) 327 } 328 b.currentAESGCMVersionByte = AESGCMVersion2 329 330 // Initialize and unseal 331 key, _ := b.GenerateKey() 332 err = b.Initialize(context.Background(), key) 333 if err != nil { 334 t.Fatalf("err: %v", err) 335 } 336 err = b.Unseal(context.Background(), key) 337 if err != nil { 338 t.Fatalf("err: %v", err) 339 } 340 341 // Put a logical entry 342 entry := &logical.StorageEntry{Key: "test", Value: []byte("test")} 343 err = b.Put(context.Background(), entry) 344 if err != nil { 345 t.Fatalf("err: %v", err) 346 } 347 348 // Change the location of the underlying physical entry 349 pe, _ := inm.Get(context.Background(), "test") 350 pe.Key = "moved" 351 err = inm.Put(context.Background(), pe) 352 if err != nil { 353 t.Fatalf("err: %v", err) 354 } 355 356 // Read from the barrier 357 _, err = b.Get(context.Background(), "moved") 358 if err == nil { 359 t.Fatalf("should fail with version 2!") 360 } 361} 362 363func TestAESGCMBarrier_UpgradeV1toV2(t *testing.T) { 364 inm, err := inmem.NewInmem(nil, logger) 365 if err != nil { 366 t.Fatalf("err: %v", err) 367 } 368 b, err := NewAESGCMBarrier(inm) 369 if err != nil { 370 t.Fatalf("err: %v", err) 371 } 372 b.currentAESGCMVersionByte = AESGCMVersion1 373 374 // Initialize and unseal 375 key, _ := b.GenerateKey() 376 err = b.Initialize(context.Background(), key) 377 if err != nil { 378 t.Fatalf("err: %v", err) 379 } 380 err = b.Unseal(context.Background(), key) 381 if err != nil { 382 t.Fatalf("err: %v", err) 383 } 384 385 // Put a logical entry 386 entry := &logical.StorageEntry{Key: "test", Value: []byte("test")} 387 err = b.Put(context.Background(), entry) 388 if err != nil { 389 t.Fatalf("err: %v", err) 390 } 391 392 // Seal 393 err = b.Seal() 394 if err != nil { 395 t.Fatalf("err: %v", err) 396 } 397 398 // Open again as version 2 399 b, err = NewAESGCMBarrier(inm) 400 if err != nil { 401 t.Fatalf("err: %v", err) 402 } 403 b.currentAESGCMVersionByte = AESGCMVersion2 404 405 // Unseal 406 err = b.Unseal(context.Background(), key) 407 if err != nil { 408 t.Fatalf("err: %v", err) 409 } 410 411 // Check successful decryption 412 _, err = b.Get(context.Background(), "test") 413 if err != nil { 414 t.Fatalf("Upgrade unsuccessful") 415 } 416} 417 418func TestEncrypt_Unique(t *testing.T) { 419 inm, err := inmem.NewInmem(nil, logger) 420 if err != nil { 421 t.Fatalf("err: %v", err) 422 } 423 b, err := NewAESGCMBarrier(inm) 424 if err != nil { 425 t.Fatalf("err: %v", err) 426 } 427 428 key, _ := b.GenerateKey() 429 b.Initialize(context.Background(), key) 430 b.Unseal(context.Background(), key) 431 432 if b.keyring == nil { 433 t.Fatalf("barrier is sealed") 434 } 435 436 entry := &logical.StorageEntry{Key: "test", Value: []byte("test")} 437 term := b.keyring.ActiveTerm() 438 primary, _ := b.aeadForTerm(term) 439 440 first, err := b.encrypt("test", term, primary, entry.Value) 441 if err != nil { 442 t.Fatal(err) 443 } 444 second, err := b.encrypt("test", term, primary, entry.Value) 445 if err != nil { 446 t.Fatal(err) 447 } 448 449 if bytes.Equal(first, second) == true { 450 t.Fatalf("improper random seeding detected") 451 } 452} 453 454func TestInitialize_KeyLength(t *testing.T) { 455 inm, err := inmem.NewInmem(nil, logger) 456 if err != nil { 457 t.Fatalf("err: %v", err) 458 } 459 b, err := NewAESGCMBarrier(inm) 460 if err != nil { 461 t.Fatalf("err: %v", err) 462 } 463 464 long := []byte("ThisKeyDoesNotHaveTheRightLength!") 465 middle := []byte("ThisIsASecretKeyAndMore") 466 short := []byte("Key") 467 468 err = b.Initialize(context.Background(), long) 469 470 if err == nil { 471 t.Fatalf("key length protection failed") 472 } 473 474 err = b.Initialize(context.Background(), middle) 475 476 if err == nil { 477 t.Fatalf("key length protection failed") 478 } 479 480 err = b.Initialize(context.Background(), short) 481 482 if err == nil { 483 t.Fatalf("key length protection failed") 484 } 485} 486 487func TestEncrypt_BarrierEncryptor(t *testing.T) { 488 inm, err := inmem.NewInmem(nil, logger) 489 if err != nil { 490 t.Fatalf("err: %v", err) 491 } 492 if err != nil { 493 t.Fatalf("err: %v", err) 494 } 495 b, err := NewAESGCMBarrier(inm) 496 if err != nil { 497 t.Fatalf("err: %v", err) 498 } 499 500 // Initialize and unseal 501 key, _ := b.GenerateKey() 502 b.Initialize(context.Background(), key) 503 b.Unseal(context.Background(), key) 504 505 cipher, err := b.Encrypt(context.Background(), "foo", []byte("quick brown fox")) 506 if err != nil { 507 t.Fatalf("err: %v", err) 508 } 509 510 plain, err := b.Decrypt(context.Background(), "foo", cipher) 511 if err != nil { 512 t.Fatalf("err: %v", err) 513 } 514 515 if string(plain) != "quick brown fox" { 516 t.Fatalf("bad: %s", plain) 517 } 518} 519 520func TestAESGCMBarrier_ReloadKeyring(t *testing.T) { 521 inm, err := inmem.NewInmem(nil, logger) 522 if err != nil { 523 t.Fatalf("err: %v", err) 524 } 525 b, err := NewAESGCMBarrier(inm) 526 if err != nil { 527 t.Fatalf("err: %v", err) 528 } 529 530 // Initialize and unseal 531 key, _ := b.GenerateKey() 532 b.Initialize(context.Background(), key) 533 b.Unseal(context.Background(), key) 534 535 keyringRaw, err := inm.Get(context.Background(), keyringPath) 536 if err != nil { 537 t.Fatalf("err: %v", err) 538 } 539 540 // Encrypt something to test cache invalidation 541 _, err = b.Encrypt(context.Background(), "foo", []byte("quick brown fox")) 542 if err != nil { 543 t.Fatalf("err: %v", err) 544 } 545 546 { 547 // Create a second barrier and rotate the keyring 548 b2, err := NewAESGCMBarrier(inm) 549 if err != nil { 550 t.Fatalf("err: %v", err) 551 } 552 b2.Unseal(context.Background(), key) 553 _, err = b2.Rotate(context.Background()) 554 if err != nil { 555 t.Fatalf("err: %v", err) 556 } 557 } 558 559 // Reload the keyring on the first 560 err = b.ReloadKeyring(context.Background()) 561 if err != nil { 562 t.Fatalf("err: %v", err) 563 } 564 565 if b.keyring.ActiveTerm() != 2 { 566 t.Fatal("failed to reload keyring") 567 } 568 if len(b.cache) != 0 { 569 t.Fatal("failed to clear cache") 570 } 571 572 // Encrypt something to test cache invalidation 573 _, err = b.Encrypt(context.Background(), "foo", []byte("quick brown fox")) 574 if err != nil { 575 t.Fatalf("err: %v", err) 576 } 577 578 // Restore old keyring to test rolling back 579 err = inm.Put(context.Background(), keyringRaw) 580 if err != nil { 581 t.Fatalf("err: %v", err) 582 } 583 584 // Reload the keyring on the first 585 err = b.ReloadKeyring(context.Background()) 586 if err != nil { 587 t.Fatalf("err: %v", err) 588 } 589 590 if b.keyring.ActiveTerm() != 1 { 591 t.Fatal("failed to reload keyring") 592 } 593 if len(b.cache) != 0 { 594 t.Fatal("failed to clear cache") 595 } 596 597} 598