mod encryption;
mod keystore;
mod auth;
mod secure_memory;
pub use encryption::*;
pub use keystore::*;
pub use auth::*;
pub use secure_memory::*;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use tracing::{info, warn};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecurityConfig {
pub encrypt_storage: bool,
pub encrypt_network: bool,
pub kdf_iterations: u32,
pub session_timeout_secs: u64,
pub audit_logging: bool,
pub min_password_length: usize,
}
impl Default for SecurityConfig {
fn default() -> Self {
Self {
encrypt_storage: true,
encrypt_network: true,
kdf_iterations: 100_000,
session_timeout_secs: 3600, audit_logging: true,
min_password_length: 12,
}
}
}
pub struct SecurityManager {
config: SecurityConfig,
cipher: AesGcmCipher,
keystore: KeyStore,
auth: AuthManager,
audit: Option<AuditLog>,
}
impl SecurityManager {
pub fn new(config: SecurityConfig) -> Result<Self> {
let keystore = KeyStore::new()?;
let cipher = AesGcmCipher::new()?;
let auth = AuthManager::new(config.min_password_length);
let audit = if config.audit_logging {
Some(AuditLog::new())
} else {
None
};
Ok(Self {
config,
cipher,
keystore,
auth,
audit,
})
}
pub fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>> {
self.cipher.encrypt(plaintext)
}
pub fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>> {
self.cipher.decrypt(ciphertext)
}
pub fn hash_password(&self, password: &str) -> Result<String> {
self.auth.hash_password(password)
}
pub fn verify_password(&self, password: &str, hash: &str) -> Result<bool> {
self.auth.verify_password(password, hash)
}
pub fn random_bytes(&self, len: usize) -> Vec<u8> {
secure_random_bytes(len)
}
pub fn log_audit(&self, event: AuditEvent) {
if let Some(ref audit) = self.audit {
audit.log(event);
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditEvent {
pub timestamp: chrono::DateTime<chrono::Utc>,
pub event_type: AuditEventType,
pub description: String,
pub user: Option<String>,
pub ip_address: Option<String>,
pub success: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AuditEventType {
Login,
Logout,
PasswordChange,
DataAccess,
DataExport,
ConfigChange,
SessionExpired,
AuthFailure,
EncryptionOperation,
SystemStart,
SystemStop,
}
pub struct AuditLog {
events: std::sync::RwLock<Vec<AuditEvent>>,
}
impl AuditLog {
pub fn new() -> Self {
Self {
events: std::sync::RwLock::new(Vec::new()),
}
}
pub fn log(&self, event: AuditEvent) {
if let Ok(mut events) = self.events.write() {
info!(
event_type = ?event.event_type,
success = event.success,
"Audit: {}", event.description
);
events.push(event);
if events.len() > 10000 {
let drain_count = events.len() - 10000;
events.drain(0..drain_count);
}
}
}
pub fn get_events(&self, limit: usize) -> Vec<AuditEvent> {
self.events.read()
.map(|events| events.iter().rev().take(limit).cloned().collect())
.unwrap_or_default()
}
}
pub fn secure_random_bytes(len: usize) -> Vec<u8> {
use ring::rand::{SecureRandom, SystemRandom};
let rng = SystemRandom::new();
let mut bytes = vec![0u8; len];
rng.fill(&mut bytes).expect("Failed to generate random bytes");
bytes
}