use crate::security::hsm::audit::AuditLogger;
use crate::security::hsm::config::TpmConfig;
use crate::security::hsm::error::{AuditEventResult, AuditEventSeverity, AuditEventType, HsmError};
use crate::security::hsm::provider::{
HsmOperation, HsmProvider, HsmProviderStatus, HsmRequest, HsmResponse, KeyGenParams, KeyInfo,
KeyPair, SigningAlgorithm,
};
use async_trait::async_trait;
use chrono::Utc;
use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::Arc;
use std::sync::Mutex;
#[derive(Debug)]
pub struct TpmHsmProvider {
audit_logger: Arc<AuditLogger>,
key_store: Mutex<HashMap<String, KeyInfo>>,
key_data: Mutex<HashMap<String, Vec<u8>>>,
}
impl TpmHsmProvider {
pub fn new(_config: &TpmConfig, audit_logger: Arc<AuditLogger>) -> Result<Self, HsmError> {
Ok(Self {
audit_logger,
key_store: Mutex::new(HashMap::new()),
key_data: Mutex::new(HashMap::new()),
})
}
async fn log_operation(&self, operation: &str, key_id: &str, success: bool) {
let event_type = match operation {
"initialize" => AuditEventType::HsmInitialize,
"generate_key" => AuditEventType::KeyGeneration,
"sign" => AuditEventType::Sign,
"verify" => AuditEventType::Verify,
"delete_key" => AuditEventType::KeyDeletion,
_ => AuditEventType::Custom(operation.to_string()),
};
let result = if success {
AuditEventResult::Success
} else {
AuditEventResult::Failure
};
let details = serde_json::json!({
"operation": operation,
"key_id": key_id,
"provider": "TPM"
});
let _ = self
.audit_logger
.log_event(event_type, result, AuditEventSeverity::Info, details)
.await;
}
}
#[async_trait]
impl HsmProvider for TpmHsmProvider {
async fn initialize(&self) -> Result<(), HsmError> {
self.log_operation("initialize", "", true).await;
Ok(())
}
async fn generate_key(&self, params: KeyGenParams) -> Result<(KeyPair, KeyInfo), HsmError> {
let key_id = params
.id
.clone()
.unwrap_or_else(|| format!("tpm_key_{}", Utc::now().timestamp()));
let key_material = vec![0u8; 32]; let public_key = vec![0u8; 33];
let key_info = KeyInfo {
id: key_id.clone(),
label: params.label.clone(),
key_type: params.key_type.clone(),
extractable: params.extractable,
usages: params.usages.clone(),
created_at: Utc::now(),
expires_at: params.expires_at,
attributes: params.attributes.clone(),
};
let key_pair = KeyPair {
id: key_id.clone(),
key_type: params.key_type,
public_key,
private_key_handle: key_id.clone(),
};
{
let mut key_store = self
.key_store
.lock()
.map_err(|_| HsmError::InternalError("Failed to lock key store".to_string()))?;
let mut key_data = self
.key_data
.lock()
.map_err(|_| HsmError::InternalError("Failed to lock key data".to_string()))?;
key_store.insert(key_id.clone(), key_info.clone());
key_data.insert(key_id.clone(), key_material);
}
self.log_operation("generate_key", &key_id, true).await;
Ok((key_pair, key_info))
}
async fn sign(
&self,
key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
) -> Result<Vec<u8>, HsmError> {
let found_key = {
let key_store = self
.key_store
.lock()
.map_err(|_| HsmError::InternalError("Failed to lock key store".to_string()))?;
key_store.contains_key(key_id)
};
if !found_key {
self.log_operation("sign", key_id, false).await;
return Err(HsmError::KeyNotFound(format!("Key {} not found", key_id)));
}
let signature_data = vec![0u8; 64];
self.log_operation("sign", key_id, true).await;
Ok(signature_data)
}
async fn verify(
&self,
key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
_signature: &[u8],
) -> Result<bool, HsmError> {
let key_store = self
.key_store
.lock()
.map_err(|_| HsmError::InternalError("Failed to lock key store".to_string()))?;
if !key_store.contains_key(key_id) {
return Err(HsmError::KeyNotFound(format!("Key {} not found", key_id)));
}
Ok(true)
}
async fn export_public_key(&self, key_id: &str) -> Result<Vec<u8>, HsmError> {
let key_store = self
.key_store
.lock()
.map_err(|_| HsmError::InternalError("Failed to lock key store".to_string()))?;
if !key_store.contains_key(key_id) {
return Err(HsmError::KeyNotFound(format!("Key {} not found", key_id)));
}
let public_key_data = vec![0u8; 33];
Ok(public_key_data)
}
async fn list_keys(&self) -> Result<Vec<KeyInfo>, HsmError> {
let key_store = self
.key_store
.lock()
.map_err(|_| HsmError::InternalError("Failed to lock key store".to_string()))?;
Ok(key_store.values().cloned().collect())
}
async fn delete_key(&self, key_id: &str) -> Result<(), HsmError> {
let key_removed = {
let mut key_store = self
.key_store
.lock()
.map_err(|_| HsmError::InternalError("Failed to lock key store".to_string()))?;
let mut key_data = self
.key_data
.lock()
.map_err(|_| HsmError::InternalError("Failed to lock key data".to_string()))?;
if key_store.remove(key_id).is_some() {
key_data.remove(key_id);
true
} else {
false
}
};
if key_removed {
self.log_operation("delete_key", key_id, true).await;
Ok(())
} else {
self.log_operation("delete_key", key_id, false).await;
Err(HsmError::KeyNotFound(format!("Key {} not found", key_id)))
}
}
async fn get_status(&self) -> Result<HsmProviderStatus, HsmError> {
Ok(HsmProviderStatus::Ready)
}
async fn close(&self) -> Result<(), HsmError> {
self.log_operation("close", "", true).await;
Ok(())
}
async fn execute_operation(&self, request: HsmRequest) -> Result<HsmResponse, HsmError> {
match request.operation {
HsmOperation::GenerateKey => {
let response = HsmResponse::success(request.id, None);
Ok(response)
}
HsmOperation::Sign => {
let response = HsmResponse::success(request.id, None);
Ok(response)
}
HsmOperation::Verify => {
let response =
HsmResponse::success(request.id, Some(serde_json::json!({"verified": true})));
Ok(response)
}
HsmOperation::ExportPublicKey => {
let response = HsmResponse::success(request.id, None);
Ok(response)
}
HsmOperation::ListKeys => {
let keys = self.list_keys().await?;
let key_list: Vec<serde_json::Value> = keys
.iter()
.map(|k| {
serde_json::json!({
"label": k.label,
"key_type": format!("{:?}", k.key_type),
"created_at": k.created_at.to_rfc3339()
})
})
.collect();
let response = HsmResponse::success(request.id, Some(serde_json::json!(key_list)));
Ok(response)
}
HsmOperation::GetStatus => {
let status = self.get_status().await?;
let response = HsmResponse::success(
request.id,
Some(serde_json::json!({"status": format!("{:?}", status)})),
);
Ok(response)
}
HsmOperation::DeleteKey => {
let response = HsmResponse::success(request.id, None);
Ok(response)
}
HsmOperation::Custom(_) => {
let response =
HsmResponse::error(request.id, "Custom operations not supported".to_string());
Ok(response)
}
HsmOperation::Encrypt => {
let response =
HsmResponse::error(request.id, "Encrypt not implemented".to_string());
Ok(response)
}
HsmOperation::Decrypt => {
let response =
HsmResponse::error(request.id, "Decrypt not implemented".to_string());
Ok(response)
}
}
}
}