use async_trait::async_trait;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::error::Result;
use crate::types::*;
pub mod api;
pub mod memory_kms;
#[async_trait]
pub trait KeyManagementService: Send + Sync {
async fn initialize(&mut self, config: KmsConfig) -> Result<()>;
async fn create_tenant_kek(&self, tenant_id: &str) -> Result<TenantKek>;
async fn create_agent_dek(&self, agent_id: &str, tenant_id: &str) -> Result<AgentDek>;
async fn wrap_key(&self, key_data: &[u8], parent_key_id: &KeyId) -> Result<Vec<u8>>;
async fn unwrap_key(&self, wrapped_key: &[u8], parent_key_id: &KeyId) -> Result<Vec<u8>>;
async fn rotate_key(&self, key_id: &KeyId) -> Result<KeyId>;
async fn destroy_key(&self, key_id: &KeyId) -> Result<()>;
async fn get_key_metadata(&self, key_id: &KeyId) -> Result<KeyInfo>;
async fn get_audit_logs(
&self,
start: DateTime<Utc>,
end: DateTime<Utc>,
filter: Option<AuditFilter>,
) -> Result<Vec<KeyAuditEntry>>;
async fn import_customer_key(
&self,
tenant_id: &str,
wrapped_key: &[u8],
key_metadata: CustomerKeyMetadata,
) -> Result<KeyId>;
async fn register_customer_held_key(
&self,
tenant_id: &str,
key_reference: CustomerKeyReference,
) -> Result<KeyId>;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KmsConfig {
pub hsm_type: HsmType,
pub root_key_source: RootKeySource,
pub audit_retention_days: u32,
pub key_rotation_days: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum HsmType {
Software,
AwsCloudHsm { cluster_id: String },
AzureKeyVault { vault_url: String },
HashicorpVault { url: String, namespace: Option<String> },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RootKeySource {
Generate,
Import { wrapped_key: Vec<u8> },
Existing { key_id: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyInfo {
pub key_id: KeyId,
pub key_type: KeyType,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub expires_at: Option<DateTime<Utc>>,
pub rotation_due: Option<DateTime<Utc>>,
pub state: KeyState,
pub metadata: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum KeyType {
Root,
TenantKek { tenant_id: String },
AgentDek { agent_id: String, tenant_id: String },
CustomerKey { tenant_id: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum KeyState {
Active,
Rotating,
Expired,
Destroyed,
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct AuditFilter {
pub key_ids: Option<Vec<KeyId>>,
pub operations: Option<Vec<KeyOperation>>,
pub actors: Option<Vec<String>>,
pub success_only: Option<bool>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CustomerKeyMetadata {
pub algorithm: String,
pub key_size: u32,
pub usage: Vec<String>,
pub expires_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CustomerKeyReference {
pub provider: String,
pub key_id: String,
pub region: Option<String>,
pub permissions: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum KeyWrapAlgorithm {
AesKwp256,
Rsa4096OaepSha256,
ChaCha20Poly1305,
}
pub struct KeyHierarchy;
impl KeyHierarchy {
pub fn derive_tenant_kek(root_key: &[u8], tenant_id: &str) -> Vec<u8> {
let salt = format!("tenant_kek_{}", tenant_id);
let mut hasher = blake3::Hasher::new_derive_key(&salt);
hasher.update(root_key);
let mut output = vec![0u8; 32];
hasher.finalize_xof().fill(&mut output);
output
}
pub fn generate_dek() -> Vec<u8> {
use rand::RngCore;
let mut key = vec![0u8; 32];
rand::thread_rng().fill_bytes(&mut key);
key
}
}