use serde::{Deserialize, Serialize};
use thiserror::Error;
pub mod encryption;
pub mod compression;
pub mod hashing;
pub mod authentication;
pub mod gdpr;
#[derive(Error, Debug)]
pub enum SecurityError {
#[error("Encryption error: {0}")]
Encryption(String),
#[error("Decryption error: {0}")]
Decryption(String),
#[error("Compression error: {0}")]
Compression(String),
#[error("Decompression error: {0}")]
Decompression(String),
#[error("Hash error: {0}")]
Hash(String),
#[error("Invalid key: {0}")]
InvalidKey(String),
#[error("Invalid algorithm: {0}")]
InvalidAlgorithm(String),
#[error("Invalid data: {0}")]
InvalidData(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SecurityConfig {
pub encryption_enabled: bool,
pub compression_enabled: bool,
pub encryption_algorithm: EncryptionAlgorithm,
pub compression_algorithm: CompressionAlgorithm,
pub key_derivation: KeyDerivationConfig,
pub integrity_checking: bool,
}
impl Default for SecurityConfig {
fn default() -> Self {
Self {
encryption_enabled: true,
compression_enabled: true,
encryption_algorithm: EncryptionAlgorithm::Aes256,
compression_algorithm: CompressionAlgorithm::Lz4,
key_derivation: KeyDerivationConfig::default(),
integrity_checking: true,
}
}
}
pub use encryption::EncryptionAlgorithm;
pub use compression::CompressionAlgorithm;
pub use authentication::{AuthenticationManager, AuthProvider, UserSession, User, AuthConfig};
pub use gdpr::{GDPRCompliance, DataSubject, DataProcessingPurpose, PersonalDataRecord, AuditLogEntry};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeyDerivationConfig {
pub algorithm: KeyDerivationAlgorithm,
pub iterations: u32,
pub salt_length: usize,
pub key_length: usize,
}
impl Default for KeyDerivationConfig {
fn default() -> Self {
Self {
algorithm: KeyDerivationAlgorithm::Argon2,
iterations: 100_000,
salt_length: 32,
key_length: 32,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum KeyDerivationAlgorithm {
Argon2,
Pbkdf2,
Scrypt,
}
pub struct SecurityManager {
config: SecurityConfig,
encryption: encryption::EncryptionManager,
compression: compression::CompressionManager,
hashing: hashing::HashManager,
}
impl SecurityManager {
pub fn new(config: SecurityConfig) -> Result<Self, SecurityError> {
let encryption = encryption::EncryptionManager::new(config.encryption_algorithm.clone());
let compression = compression::CompressionManager::new(config.compression_algorithm.clone())?;
let hashing = hashing::HashManager::new()?;
Ok(Self {
config,
encryption,
compression,
hashing,
})
}
pub async fn secure_data(
&self,
data: &[u8],
key: &encryption::EncryptionKey,
) -> Result<Vec<u8>, SecurityError> {
let mut processed_data = data.to_vec();
if self.config.compression_enabled {
processed_data = self.compression.compress(&processed_data)?;
}
if self.config.encryption_enabled {
processed_data = self.encryption.encrypt(&processed_data, key).await
.map_err(|e| SecurityError::Encryption(e.to_string()))?;
}
if self.config.integrity_checking {
let hash = self.hashing.hash(&processed_data)?;
processed_data.extend_from_slice(&hash);
}
Ok(processed_data)
}
pub async fn unsecure_data(
&self,
data: &[u8],
key: &encryption::EncryptionKey,
) -> Result<Vec<u8>, SecurityError> {
let mut processed_data = data.to_vec();
if self.config.integrity_checking {
let expected_hash_len = 32; if processed_data.len() < expected_hash_len {
return Err(SecurityError::InvalidData("Data too short for integrity check".to_string()));
}
let data_len = processed_data.len() - expected_hash_len;
let (data_part, hash_part) = processed_data.split_at(data_len);
let actual_hash = self.hashing.hash(data_part)?;
if actual_hash != hash_part {
return Err(SecurityError::Hash("Integrity check failed".to_string()));
}
processed_data = data_part.to_vec();
}
if self.config.encryption_enabled {
processed_data = self.encryption.decrypt(&processed_data, key).await
.map_err(|e| SecurityError::Decryption(e.to_string()))?;
}
if self.config.compression_enabled {
processed_data = self.compression.decompress(&processed_data)?;
}
Ok(processed_data)
}
pub async fn derive_key(
&self,
password: &str,
salt: Option<&[u8]>,
) -> Result<Vec<u8>, SecurityError> {
let salt = salt.unwrap_or_else(|| b"default_salt");
match self.config.key_derivation.algorithm {
KeyDerivationAlgorithm::Argon2 => {
self.hashing.derive_key_argon2(
password.as_bytes(),
salt,
self.config.key_derivation.iterations,
self.config.key_derivation.key_length,
)
}
KeyDerivationAlgorithm::Pbkdf2 => {
self.hashing.derive_key_pbkdf2(
password.as_bytes(),
salt,
self.config.key_derivation.iterations,
self.config.key_derivation.key_length,
)
}
KeyDerivationAlgorithm::Scrypt => {
self.hashing.derive_key_scrypt(
password.as_bytes(),
salt,
self.config.key_derivation.iterations,
self.config.key_derivation.key_length,
)
}
}
}
pub fn generate_nonce(&self) -> Result<Vec<u8>, SecurityError> {
use rand::{Rng, rngs::OsRng};
let mut nonce = [0u8; 12];
OsRng.fill(&mut nonce);
Ok(nonce.to_vec())
}
pub fn config(&self) -> &SecurityConfig {
&self.config
}
pub fn update_config(&mut self, config: SecurityConfig) -> Result<(), SecurityError> {
let encryption = encryption::EncryptionManager::new(config.encryption_algorithm.clone());
let compression = compression::CompressionManager::new(config.compression_algorithm.clone())?;
self.config = config;
self.encryption = encryption;
self.compression = compression;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_security_manager_creation() {
let config = SecurityConfig::default();
let manager = SecurityManager::new(config);
assert!(manager.is_ok());
}
#[tokio::test]
async fn test_security_config_default() {
let config = SecurityConfig::default();
assert!(config.encryption_enabled);
assert!(config.compression_enabled);
assert!(config.integrity_checking);
}
#[tokio::test]
async fn test_key_derivation_config_default() {
let config = KeyDerivationConfig::default();
assert_eq!(config.iterations, 100_000);
assert_eq!(config.salt_length, 32);
assert_eq!(config.key_length, 32);
}
}