use serde::{Deserialize, Serialize};
use std::time::Duration;
use crate::security::hsm::audit::AuditLoggerConfig;
use crate::security::hsm::provider::HsmProviderType;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HsmConfig {
#[serde(default = "default_true")]
pub enabled: bool,
pub general: GeneralConfig,
pub provider_type: HsmProviderType,
#[serde(default)]
pub audit_enabled: bool,
#[serde(default)]
pub software: SoftHsmConfig,
#[serde(default)]
pub cloud: CloudHsmConfig,
#[serde(default)]
pub tpm: TpmConfig,
#[serde(default)]
pub pkcs11: Pkcs11Config,
#[serde(default)]
pub simulator: SimulatorConfig,
#[serde(default)]
pub hardware: HardwareConfig,
#[serde(default)]
pub bitcoin: BitcoinConfig,
#[serde(default)]
pub audit: AuditLoggerConfig,
#[serde(default)]
pub key_management: KeyManagementConfig,
}
impl Default for HsmConfig {
fn default() -> Self {
Self {
enabled: true,
general: GeneralConfig::default(),
provider_type: HsmProviderType::SoftwareKeyStore,
audit_enabled: true,
software: SoftHsmConfig::default(),
cloud: CloudHsmConfig::default(),
tpm: TpmConfig::default(),
pkcs11: Pkcs11Config::default(),
simulator: SimulatorConfig::default(),
hardware: HardwareConfig::default(),
bitcoin: BitcoinConfig::default(),
audit: AuditLoggerConfig::default(),
key_management: KeyManagementConfig::default(),
}
}
}
impl HsmConfig {
pub fn development() -> Self {
Self {
enabled: true,
general: GeneralConfig {
enabled: true,
log_level: LogLevel::Debug,
operation_timeout: Duration::from_secs(10),
},
provider_type: HsmProviderType::SoftwareKeyStore,
audit_enabled: true,
software: SoftHsmConfig::default(),
audit: AuditLoggerConfig {
enabled: true,
storage_type: crate::security::hsm::audit::AuditStorageType::File,
file_path: Some("./logs/hsm_audit_dev.log".to_string()),
retention_days: 30,
log_sensitive: true, ..Default::default()
},
..Default::default()
}
}
pub fn production() -> Self {
Self {
enabled: true,
general: GeneralConfig {
enabled: true,
log_level: LogLevel::Info,
operation_timeout: Duration::from_secs(30),
},
provider_type: HsmProviderType::Pkcs11, pkcs11: Pkcs11Config {
library_path: "/usr/lib/libpkcs11.so".to_string(),
slot_id: Some(0),
user_pin: None, ..Default::default()
},
audit: AuditLoggerConfig {
enabled: true,
storage_type: crate::security::hsm::audit::AuditStorageType::Database,
db_connection: Some(
"postgresql://user:password@localhost:5432/auditdb".to_string(),
),
retention_days: 365, log_sensitive: false, ..Default::default()
},
key_management: KeyManagementConfig {
auto_rotation: true,
rotation_interval: Duration::from_secs(7776000), ..Default::default()
},
..Default::default()
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GeneralConfig {
pub enabled: bool,
pub log_level: LogLevel,
#[serde(with = "humantime_serde")]
pub operation_timeout: Duration,
}
impl Default for GeneralConfig {
fn default() -> Self {
Self {
enabled: true,
log_level: LogLevel::Info,
operation_timeout: Duration::from_secs(30),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum LogLevel {
Trace,
Debug,
Info,
Warn,
Error,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SoftHsmConfig {
pub token_dir: String,
pub max_sessions: usize,
pub encryption_key: Option<String>,
pub lock_timeout_seconds: u64,
pub use_testnet: bool,
}
impl Default for SoftHsmConfig {
fn default() -> Self {
Self {
token_dir: ".tokens".to_string(),
max_sessions: 10,
encryption_key: None,
lock_timeout_seconds: 300,
use_testnet: true, }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CloudHsmConfig {
pub provider: CloudProvider,
pub region: String,
pub access_key: Option<String>,
pub secret_key: Option<String>,
pub key_id_prefix: Option<String>,
}
impl Default for CloudHsmConfig {
fn default() -> Self {
Self {
provider: CloudProvider::Aws,
region: "us-east-1".to_string(),
access_key: None,
secret_key: None,
key_id_prefix: None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum CloudProvider {
Aws,
Gcp,
Azure,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TpmConfig {
pub device_path: String,
pub owner_password: Option<String>,
}
impl Default for TpmConfig {
fn default() -> Self {
Self {
device_path: "/dev/tpm0".to_string(),
owner_password: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Pkcs11Config {
pub library_path: String,
pub slot_id: Option<u64>,
pub token_label: Option<String>,
pub user_pin: Option<String>,
pub max_sessions: usize,
pub rw_session: bool,
}
impl Default for Pkcs11Config {
fn default() -> Self {
Self {
library_path: "/usr/lib/libpkcs11.so".to_string(),
slot_id: None,
token_label: None,
user_pin: None,
max_sessions: 10,
rw_session: true,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimulatorConfig {
pub storage_path: String,
pub simulate_latency: bool,
pub latency_ms: u64,
pub simulate_failures: bool,
pub failure_rate: f64,
pub pin_timeout_seconds: u64,
pub max_pin_attempts: u8,
#[serde(default = "default_true")]
pub use_testnet: bool,
}
fn default_true() -> bool {
true
}
impl Default for SimulatorConfig {
fn default() -> Self {
Self {
storage_path: ".simulator".to_string(),
simulate_latency: false,
latency_ms: 100,
simulate_failures: false,
failure_rate: 0.05,
pin_timeout_seconds: 300,
max_pin_attempts: 3,
use_testnet: true, }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum HardwareDeviceType {
YubiHsm,
Ledger,
TrezorModel,
Custom,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HardwareConfig {
pub device_type: HardwareDeviceType,
pub connection_string: String,
pub auth_key_id: Option<String>,
pub password: Option<String>,
pub timeout_seconds: u64,
#[serde(default = "default_true")]
pub use_testnet: bool,
}
impl Default for HardwareConfig {
fn default() -> Self {
Self {
device_type: HardwareDeviceType::YubiHsm,
connection_string: "127.0.0.1:12345".to_string(),
auth_key_id: None,
password: None,
timeout_seconds: 30,
use_testnet: true, }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum BitcoinNetworkType {
Mainnet,
Testnet,
Regtest,
Signet,
}
impl Default for BitcoinNetworkType {
fn default() -> Self {
Self::Testnet }
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BitcoinConfig {
#[serde(default)]
pub network: BitcoinNetworkType,
pub rpc_url: Option<String>,
pub rpc_username: Option<String>,
pub rpc_password: Option<String>,
pub derivation_path_template: String,
pub use_segwit: bool,
pub use_taproot: bool,
pub confirm_transactions: bool,
pub default_fee_rate: u64,
}
impl Default for BitcoinConfig {
fn default() -> Self {
Self {
network: BitcoinNetworkType::Testnet,
rpc_url: Some("http://127.0.0.1:18332".to_string()), rpc_username: None,
rpc_password: None,
derivation_path_template: "m/84'/1'/0'/0/{index}".to_string(), use_segwit: true,
use_taproot: true,
confirm_transactions: true,
default_fee_rate: 5, }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyManagementConfig {
pub auto_rotation: bool,
#[serde(with = "humantime_serde")]
pub rotation_interval: Duration,
pub key_naming_pattern: String,
pub keep_old_versions: bool,
pub max_versions: usize,
#[serde(default)]
pub default_key_types: DefaultKeyTypes,
}
impl Default for KeyManagementConfig {
fn default() -> Self {
Self {
auto_rotation: false,
rotation_interval: Duration::from_secs(7776000), key_naming_pattern: "{type}-{purpose}-{id}".to_string(),
keep_old_versions: true,
max_versions: 3,
default_key_types: DefaultKeyTypes::default(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DefaultKeyTypes {
pub signing: String,
pub encryption: String,
pub key_wrapping: String,
pub authentication: String,
}
impl Default for DefaultKeyTypes {
fn default() -> Self {
Self {
signing: "ec/p256".to_string(),
encryption: "rsa/2048".to_string(),
key_wrapping: "aes/256".to_string(),
authentication: "ec/p256".to_string(),
}
}
}