use async_trait::async_trait;
use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
use bitcoin::psbt::Psbt;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt::Debug;
use std::str::FromStr;
use std::sync::Arc;
use tokio::sync::Mutex;
use tracing::warn;
use uuid::Uuid;
use crate::security::hsm::config::{
CloudHsmConfig, HsmConfig, Pkcs11Config, SoftHsmConfig, TpmConfig,
};
use crate::security::hsm::error::HsmError;
use crate::security::hsm::providers::{
HardwareHsmProvider, SimulatorHsmProvider, SoftwareHsmProvider,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum HsmProviderType {
SoftwareKeyStore,
CloudHsm,
Tpm,
Pkcs11,
Simulator,
Hardware,
Bitcoin,
Custom,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum HsmProviderStatus {
Ready,
Initializing,
Unavailable,
NeedsAuthentication,
Error(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum KeyType {
Rsa {
bits: usize,
},
Ec {
curve: EcCurve,
},
Ed25519,
X25519,
Aes {
bits: usize,
},
Hmac {
bits: usize,
},
Raw {
bits: usize,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum EcCurve {
Secp256k1,
P256,
P384,
P521,
}
impl FromStr for EcCurve {
type Err = HsmError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"secp256k1" => Ok(EcCurve::Secp256k1),
"p-256" | "p256" => Ok(EcCurve::P256),
"p-384" | "p384" => Ok(EcCurve::P384),
"p-521" | "p521" => Ok(EcCurve::P521),
_ => Err(HsmError::InvalidParameters(format!(
"Unsupported curve: {}",
s
))),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum KeyUsage {
Sign,
Verify,
Encrypt,
Decrypt,
Wrap,
Unwrap,
Derive,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyInfo {
pub id: String,
pub label: Option<String>,
pub key_type: KeyType,
pub extractable: bool,
pub usages: Vec<KeyUsage>,
pub created_at: DateTime<Utc>,
pub expires_at: Option<DateTime<Utc>>,
pub attributes: HashMap<String, String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyPair {
pub id: String,
pub key_type: KeyType,
pub public_key: Vec<u8>,
pub private_key_handle: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyGenParams {
pub id: Option<String>,
pub label: Option<String>,
pub key_type: KeyType,
pub extractable: bool,
pub usages: Vec<KeyUsage>,
pub expires_at: Option<DateTime<Utc>>,
pub attributes: HashMap<String, String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum SigningAlgorithm {
RsaPkcs1Sha256,
RsaPkcs1Sha384,
RsaPkcs1Sha512,
RsaPssSha256,
RsaPssSha384,
RsaPssSha512,
EcdsaSha256,
EcdsaSha384,
EcdsaSha512,
Ed25519,
HmacSha256,
HmacSha384,
HmacSha512,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum EncryptionAlgorithm {
RsaPkcs1,
RsaOaepSha256,
AesGcm128,
AesGcm256,
AesCbc128,
AesCbc256,
ChaCha20Poly1305,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum HsmOperation {
GenerateKey,
Sign,
Verify,
Encrypt,
Decrypt,
ExportPublicKey,
ListKeys,
GetStatus,
DeleteKey,
Custom(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HsmRequest {
pub id: String,
pub operation: HsmOperation,
pub parameters: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HsmResponse {
pub id: String,
pub success: bool,
pub error: Option<String>,
pub data: Option<serde_json::Value>,
}
impl HsmResponse {
pub fn success(id: String, data: Option<serde_json::Value>) -> Self {
Self {
id,
success: true,
error: None,
data,
}
}
pub fn error(id: String, error: String) -> Self {
Self {
id,
success: false,
error: Some(error),
data: None,
}
}
}
#[async_trait]
pub trait HsmProvider: Send + Sync + Debug {
async fn initialize(&self) -> Result<(), HsmError>;
async fn generate_key(&self, params: KeyGenParams) -> Result<(KeyPair, KeyInfo), HsmError>;
async fn sign(
&self,
key_id: &str,
algorithm: SigningAlgorithm,
data: &[u8],
) -> Result<Vec<u8>, HsmError>;
async fn verify(
&self,
_key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
_signature: &[u8],
) -> Result<bool, HsmError> {
Err(HsmError::UnsupportedOperation(
"Verification not implemented".into(),
))
}
async fn sign_psbt(&self, _psbt: &mut Psbt) -> Result<(), HsmError> {
Err(HsmError::UnsupportedOperation(
"PSBT signing not implemented".into(),
))
}
async fn export_public_key(&self, key_id: &str) -> Result<Vec<u8>, HsmError>;
async fn list_keys(&self) -> Result<Vec<KeyInfo>, HsmError>;
async fn delete_key(&self, key_id: &str) -> Result<(), HsmError>;
async fn get_status(&self) -> Result<HsmProviderStatus, HsmError>;
async fn close(&self) -> Result<(), HsmError>;
async fn execute_operation(&self, request: HsmRequest) -> Result<HsmResponse, HsmError>;
async fn perform_health_check(&self) -> Result<bool, HsmError> {
let _status = self.get_status().await?;
let test_params = KeyGenParams {
id: Some(format!("health_check_{}", Utc::now().timestamp())),
label: Some("health_check_test_key".to_string()),
key_type: KeyType::Ec {
curve: EcCurve::Secp256k1,
},
extractable: true,
usages: vec![KeyUsage::Sign, KeyUsage::Verify],
expires_at: None,
attributes: HashMap::new(),
};
let (key_pair, _) = match self.generate_key(test_params).await {
Ok(result) => result,
Err(e) => {
warn!("HSM health check failed: Key generation error: {}", e);
return Ok(false);
}
};
let test_data = b"HSM health check test data";
let signature = match self
.sign(&key_pair.id, SigningAlgorithm::EcdsaSha256, test_data)
.await
{
Ok(sig) => sig,
Err(e) => {
warn!("HSM health check failed: Signing error: {}", e);
let _ = self.delete_key(&key_pair.id).await;
return Ok(false);
}
};
let verify_result = match self
.verify(
&key_pair.id,
SigningAlgorithm::EcdsaSha256,
test_data,
&signature,
)
.await
{
Ok(result) => result,
Err(e) => {
warn!("HSM health check failed: Verification error: {}", e);
let _ = self.delete_key(&key_pair.id).await;
return Ok(false);
}
};
match self.delete_key(&key_pair.id).await {
Ok(_) => {}
Err(e) => {
warn!("HSM health check warning: Could not delete test key: {}", e);
}
};
Ok(verify_result)
}
}
pub async fn create_hsm_provider(config: &HsmConfig) -> Result<Arc<dyn HsmProvider>, HsmError> {
match config.provider_type {
HsmProviderType::SoftwareKeyStore => {
let audit_config = crate::security::hsm::audit::AuditLoggerConfig::default();
let audit_logger =
Arc::new(crate::security::hsm::audit::AuditLogger::new(&audit_config).await?);
let provider = SoftwareHsmProvider::new(
config.software.clone(),
bitcoin::Network::from(config.bitcoin.network),
audit_logger,
)
.await?;
Ok(Arc::new(provider))
}
HsmProviderType::CloudHsm => {
Err(HsmError::ProviderError(
"CloudHsm provider not implemented".to_string(),
))
}
HsmProviderType::Tpm => {
Err(HsmError::ProviderError(
"Tpm provider not implemented".to_string(),
))
}
HsmProviderType::Pkcs11 => {
Err(HsmError::ProviderError(
"Pkcs11 provider not implemented".to_string(),
))
}
HsmProviderType::Simulator => {
let provider = SimulatorHsmProvider::new(&config.simulator)?;
Ok(Arc::new(provider))
}
HsmProviderType::Hardware => {
let audit_config = crate::security::hsm::audit::AuditLoggerConfig::default();
let audit_logger =
Arc::new(crate::security::hsm::audit::AuditLogger::new(&audit_config).await?);
let provider = HardwareHsmProvider::new(
&config.hardware,
bitcoin::Network::from(config.bitcoin.network),
audit_logger,
)
.await?;
Ok(Arc::new(provider))
}
HsmProviderType::Bitcoin => {
Err(HsmError::ProviderError(
"Use Hardware provider with Bitcoin configuration".to_string(),
))
}
HsmProviderType::Custom => Err(HsmError::ProviderError(
"Custom provider requires implementation".to_string(),
)),
}
}
#[derive(Debug)]
pub struct SoftHsmProvider {
keys: Mutex<HashMap<String, KeyInfo>>,
key_data: Mutex<HashMap<String, Vec<u8>>>, }
impl SoftHsmProvider {
pub fn new(_config: &SoftHsmConfig) -> Result<Self, HsmError> {
Ok(Self {
keys: Mutex::new(HashMap::new()),
key_data: Mutex::new(HashMap::new()),
})
}
}
#[async_trait]
impl HsmProvider for SoftHsmProvider {
async fn initialize(&self) -> Result<(), HsmError> {
Ok(())
}
async fn generate_key(&self, _params: KeyGenParams) -> Result<(KeyPair, KeyInfo), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn sign(
&self,
_key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
) -> Result<Vec<u8>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn verify(
&self,
_key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
_signature: &[u8],
) -> Result<bool, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn export_public_key(&self, _key_id: &str) -> Result<Vec<u8>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn list_keys(&self) -> Result<Vec<KeyInfo>, HsmError> {
let keys = self.keys.lock().await;
Ok(keys.values().cloned().collect())
}
async fn delete_key(&self, key_id: &str) -> Result<(), HsmError> {
let mut keys = self.keys.lock().await;
let mut key_data = self.key_data.lock().await;
if !keys.contains_key(key_id) {
return Err(HsmError::KeyNotFound(key_id.to_string()));
}
keys.remove(key_id);
key_data.remove(key_id);
Ok(())
}
async fn get_status(&self) -> Result<HsmProviderStatus, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn close(&self) -> Result<(), HsmError> {
Ok(())
}
async fn execute_operation(&self, request: HsmRequest) -> Result<HsmResponse, HsmError> {
tracing::debug!("Executing operation: {:?}", request.operation);
match request.operation {
HsmOperation::GenerateKey => {
let params: KeyGenParams = serde_json::from_value(request.parameters.clone())
.map_err(|e| {
HsmError::InvalidParameters(format!("Invalid parameters: {}", e))
})?;
let key_id = params.id.unwrap_or_else(|| Uuid::new_v4().to_string());
let created_at = chrono::Utc::now();
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,
expires_at: params.expires_at,
attributes: params.attributes.clone(),
};
let key_data = vec![0u8; 32];
let mut keys = self.keys.lock().await;
let mut key_data_map = self.key_data.lock().await;
keys.insert(key_id.clone(), key_info.clone());
key_data_map.insert(key_id.clone(), key_data);
let response_data = serde_json::to_value(key_info).map_err(|e| {
HsmError::SerializationError(format!("Failed to serialize key info: {}", e))
})?;
Ok(HsmResponse::success(request.id, Some(response_data)))
}
HsmOperation::Sign => {
let key_id: String = match request.parameters.get("key_id") {
Some(value) if value.is_string() => value
.as_str()
.ok_or_else(|| {
HsmError::InvalidParameters("key_id is not a valid string".to_string())
})?
.to_string(),
_ => {
return Err(HsmError::InvalidParameters(
"Missing or invalid key_id parameter".to_string(),
))
}
};
let data_base64: String = match request.parameters.get("data") {
Some(value) if value.is_string() => value
.as_str()
.ok_or_else(|| {
HsmError::InvalidParameters("data is not a valid string".to_string())
})?
.to_string(),
_ => {
return Err(HsmError::InvalidParameters(
"Missing or invalid data parameter".to_string(),
))
}
};
let _data = BASE64.decode(&data_base64).map_err(|e| {
HsmError::InvalidParameters(format!("Invalid base64 data: {}", e))
})?;
let keys = self.keys.lock().await;
let _key_data_map = self.key_data.lock().await;
if !keys.contains_key(&key_id) {
return Err(HsmError::KeyNotFound(key_id));
}
let signature = vec![0u8; 64];
let response_data = serde_json::json!({
"signature": BASE64.encode(&signature),
});
Ok(HsmResponse::success(request.id, Some(response_data)))
}
HsmOperation::Verify => {
let response_data = serde_json::json!({
"verified": true,
});
Ok(HsmResponse::success(request.id, Some(response_data)))
}
HsmOperation::Encrypt => {
let response_data = serde_json::json!({
"encrypted_data": "dGhpcyBpcyBhIGR1bW15IGVuY3J5cHRlZCB2YWx1ZQ==", });
Ok(HsmResponse::success(request.id, Some(response_data)))
}
HsmOperation::Decrypt => {
let response_data = serde_json::json!({
"decrypted_data": "dGhpcyBpcyBhIGR1bW15IGRlY3J5cHRlZCB2YWx1ZQ==", });
Ok(HsmResponse::success(request.id, Some(response_data)))
}
HsmOperation::ExportPublicKey => {
let key_id: String = match request.parameters.get("key_id") {
Some(value) if value.is_string() => value
.as_str()
.ok_or(HsmError::InvalidParameters(
"Invalid string value".to_string(),
))?
.to_string(),
_ => {
return Err(HsmError::InvalidParameters(
"Missing or invalid key_id parameter".to_string(),
))
}
};
let keys = self.keys.lock().await;
if !keys.contains_key(&key_id) {
return Err(HsmError::KeyNotFound(key_id));
}
let public_key = vec![0u8; 65];
let response_data = serde_json::json!({
"public_key": BASE64.encode(&public_key),
});
Ok(HsmResponse::success(request.id, Some(response_data)))
}
HsmOperation::ListKeys => {
let keys = self.keys.lock().await;
let key_list: Vec<KeyInfo> = keys.values().cloned().collect();
let response_data = serde_json::to_value(key_list).map_err(|e| {
HsmError::SerializationError(format!("Failed to serialize key list: {}", e))
})?;
Ok(HsmResponse::success(request.id, Some(response_data)))
}
HsmOperation::DeleteKey => {
let key_id: String = match request.parameters.get("key_id") {
Some(value) if value.is_string() => value
.as_str()
.ok_or(HsmError::InvalidParameters(
"Invalid string value".to_string(),
))?
.to_string(),
_ => {
return Err(HsmError::InvalidParameters(
"Missing or invalid key_id parameter".to_string(),
))
}
};
let mut keys = self.keys.lock().await;
let mut key_data_map = self.key_data.lock().await;
if !keys.contains_key(&key_id) {
return Err(HsmError::KeyNotFound(key_id));
}
keys.remove(&key_id);
key_data_map.remove(&key_id);
Ok(HsmResponse::success(request.id, None))
}
HsmOperation::GetStatus => {
let status = HsmProviderStatus::Ready;
let response_data = serde_json::to_value(status).map_err(|e| {
HsmError::SerializationError(format!("Failed to serialize status: {}", e))
})?;
Ok(HsmResponse::success(request.id, Some(response_data)))
}
HsmOperation::Custom(op) => {
Err(HsmError::OperationNotSupported(format!(
"Custom operation not supported: {}",
op
)))
}
}
}
}
#[derive(Debug)]
pub struct CloudHsmProvider;
impl CloudHsmProvider {
pub fn new(_config: &CloudHsmConfig) -> Result<Self, HsmError> {
Ok(Self)
}
}
#[async_trait]
impl HsmProvider for CloudHsmProvider {
async fn initialize(&self) -> Result<(), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn generate_key(&self, _params: KeyGenParams) -> Result<(KeyPair, KeyInfo), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn sign(
&self,
_key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
) -> Result<Vec<u8>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn verify(
&self,
_key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
_signature: &[u8],
) -> Result<bool, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn export_public_key(&self, _key_id: &str) -> Result<Vec<u8>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn list_keys(&self) -> Result<Vec<KeyInfo>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn delete_key(&self, _key_id: &str) -> Result<(), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn get_status(&self) -> Result<HsmProviderStatus, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn close(&self) -> Result<(), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn execute_operation(&self, _request: HsmRequest) -> Result<HsmResponse, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
}
#[derive(Debug)]
pub struct TpmProvider;
impl TpmProvider {
pub fn new(_config: &TpmConfig) -> Result<Self, HsmError> {
Ok(Self)
}
}
#[async_trait]
impl HsmProvider for TpmProvider {
async fn initialize(&self) -> Result<(), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn generate_key(&self, _params: KeyGenParams) -> Result<(KeyPair, KeyInfo), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn sign(
&self,
_key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
) -> Result<Vec<u8>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn verify(
&self,
_key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
_signature: &[u8],
) -> Result<bool, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn export_public_key(&self, _key_id: &str) -> Result<Vec<u8>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn list_keys(&self) -> Result<Vec<KeyInfo>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn delete_key(&self, _key_id: &str) -> Result<(), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn get_status(&self) -> Result<HsmProviderStatus, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn close(&self) -> Result<(), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn execute_operation(&self, _request: HsmRequest) -> Result<HsmResponse, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
}
#[derive(Debug)]
pub struct Pkcs11Provider;
impl Pkcs11Provider {
pub fn new(_config: &Pkcs11Config) -> Result<Self, HsmError> {
Ok(Self)
}
}
#[async_trait]
impl HsmProvider for Pkcs11Provider {
async fn initialize(&self) -> Result<(), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn generate_key(&self, _params: KeyGenParams) -> Result<(KeyPair, KeyInfo), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn sign(
&self,
_key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
) -> Result<Vec<u8>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn verify(
&self,
_key_id: &str,
_algorithm: SigningAlgorithm,
_data: &[u8],
_signature: &[u8],
) -> Result<bool, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn export_public_key(&self, _key_id: &str) -> Result<Vec<u8>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn list_keys(&self) -> Result<Vec<KeyInfo>, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn delete_key(&self, _key_id: &str) -> Result<(), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn get_status(&self) -> Result<HsmProviderStatus, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn close(&self) -> Result<(), HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
async fn execute_operation(&self, _request: HsmRequest) -> Result<HsmResponse, HsmError> {
Err(HsmError::UnsupportedOperation(
"Not implemented".to_string(),
))
}
}