1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! BDD tests for Azure Key Vault provider (mock-based) — Milestone 25
//!
//! Feature: Azure Key Vault provider
//! These tests use a mock Key Vault, not real Azure infrastructure.
// Azure Key Vault tests are gated behind the `azure-kv` feature.
// Run with: cargo test -p secure_data --features azure-kv --test sunlit_owasp_keyvault
#[cfg(feature = "azure-kv")]
mod azure_kv_tests {
use secure_data::key_vault::{AzureKeyVaultProvider, MockVaultClient};
use secure_data::kms::KeyProvider;
/// Scenario: Wrap key via vault
/// Given: Mock Key Vault provider
/// When: wrap_key()
/// Then: Returns wrapped key blob
#[tokio::test]
async fn test_wrap_key_via_vault() {
// Given: mock vault
let mock = MockVaultClient::new();
let provider = AzureKeyVaultProvider::new(mock);
// When: generate data key (wrap)
let result = provider.generate_data_key("vault-key").await;
// Then: succeeds with wrapped key
assert!(result.is_ok(), "wrap_key must succeed with mock vault");
let (_dek, wrapped, version) = result.unwrap();
assert!(!wrapped.is_empty(), "wrapped key must not be empty");
assert!(!version.is_empty(), "version must not be empty");
}
/// Scenario: Unwrap key via vault
/// Given: Mock Key Vault provider and wrapped blob
/// When: unwrap_key()
/// Then: Returns usable DEK
#[tokio::test]
async fn test_unwrap_key_via_vault() {
// Given: generate key pair via mock
let mock = MockVaultClient::new();
let provider = AzureKeyVaultProvider::new(mock);
let (original_dek, wrapped, version) = provider
.generate_data_key("vault-key")
.await
.expect("wrap must succeed");
// When: unwrap
let unwrapped = provider
.unwrap_data_key(&wrapped, "vault-key", &version)
.await
.expect("unwrap must succeed");
// Then: matches original
assert_eq!(
*unwrapped, *original_dek,
"unwrapped key must match original"
);
}
/// Scenario: Vault unavailable
/// Given: Mock vault returns error
/// When: wrap_key()
/// Then: Returns error vault_unavailable; no panic
#[tokio::test]
async fn test_vault_unavailable() {
// Given: failing mock
let mock = MockVaultClient::failing();
let provider = AzureKeyVaultProvider::new(mock);
// When: attempt key generation
let result = provider.generate_data_key("vault-key").await;
// Then: returns error, no panic
assert!(result.is_err(), "must return error when vault unavailable");
let err = result.unwrap_err();
let msg = format!("{err}");
assert!(
msg.contains("unavailable") || msg.contains("vault") || msg.contains("provider"),
"error must mention vault unavailability, got: {msg}"
);
}
}