mockforge_core/encryption/
key_management.rs

1//! Key generation, storage, and lifecycle management
2//!
3//! This module provides comprehensive key management functionality including
4//! key generation, storage, rotation, and secure key lifecycle management.
5
6use crate::encryption::algorithms::{EncryptionAlgorithm, EncryptionKey};
7use crate::encryption::derivation::KeyDerivationManager;
8use crate::encryption::errors::{EncryptionError, EncryptionResult};
9use chrono::{DateTime, Utc};
10use serde::{Deserialize, Serialize};
11use std::collections::HashMap;
12use std::sync::{Arc, OnceLock, RwLock};
13
14/// Key identifier for lookup and management
15pub type KeyId = String;
16
17/// Key storage interface for different key storage backends
18pub trait KeyStorage: Send + Sync {
19    /// Store an encrypted key
20    fn store_key(&mut self, key_id: &KeyId, encrypted_key: &[u8]) -> EncryptionResult<()>;
21
22    /// Retrieve an encrypted key
23    fn retrieve_key(&self, key_id: &KeyId) -> EncryptionResult<Vec<u8>>;
24
25    /// Delete a key
26    fn delete_key(&mut self, key_id: &KeyId) -> EncryptionResult<()>;
27
28    /// Check if a key exists
29    fn key_exists(&self, key_id: &KeyId) -> bool;
30
31    /// List all key IDs
32    fn list_keys(&self) -> Vec<KeyId>;
33}
34
35/// In-memory key storage implementation
36#[derive(Debug, Clone)]
37pub struct MemoryKeyStorage {
38    keys: HashMap<KeyId, Vec<u8>>,
39}
40
41impl MemoryKeyStorage {
42    /// Create a new in-memory key storage
43    pub fn new() -> Self {
44        Self {
45            keys: HashMap::new(),
46        }
47    }
48}
49
50impl KeyStorage for MemoryKeyStorage {
51    fn store_key(&mut self, key_id: &KeyId, encrypted_key: &[u8]) -> EncryptionResult<()> {
52        self.keys.insert(key_id.clone(), encrypted_key.to_vec());
53        Ok(())
54    }
55
56    fn retrieve_key(&self, key_id: &KeyId) -> EncryptionResult<Vec<u8>> {
57        self.keys
58            .get(key_id)
59            .cloned()
60            .ok_or_else(|| EncryptionError::key_not_found(key_id.clone()))
61    }
62
63    fn delete_key(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
64        self.keys.remove(key_id);
65        Ok(())
66    }
67
68    fn key_exists(&self, key_id: &KeyId) -> bool {
69        self.keys.contains_key(key_id)
70    }
71
72    fn list_keys(&self) -> Vec<KeyId> {
73        self.keys.keys().cloned().collect()
74    }
75}
76
77impl Default for MemoryKeyStorage {
78    fn default() -> Self {
79        Self::new()
80    }
81}
82
83/// File-based key storage implementation
84#[derive(Debug, Clone)]
85pub struct FileKeyStorage {
86    base_path: std::path::PathBuf,
87}
88
89impl FileKeyStorage {
90    /// Create a new file-based key storage with default path
91    pub fn new() -> Self {
92        Self {
93            base_path: std::path::PathBuf::from(".mockforge/keys"),
94        }
95    }
96
97    /// Create a new file-based key storage with custom base path
98    pub fn with_path<P: AsRef<std::path::Path>>(path: P) -> Self {
99        Self {
100            base_path: path.as_ref().to_path_buf(),
101        }
102    }
103
104    /// Get the file path for a key
105    fn key_file_path(&self, key_id: &KeyId) -> std::path::PathBuf {
106        self.base_path.join(format!("{}.key", key_id))
107    }
108
109    /// Ensure the base directory exists (blocking)
110    fn ensure_base_dir(&self) -> EncryptionResult<()> {
111        if !self.base_path.exists() {
112            std::fs::create_dir_all(&self.base_path).map_err(|e| {
113                EncryptionError::generic(format!("Failed to create key storage directory: {}", e))
114            })?;
115        }
116        Ok(())
117    }
118
119    /// Ensure the base directory exists (async)
120    async fn ensure_base_dir_async(&self) -> EncryptionResult<()> {
121        let base_path = self.base_path.clone();
122        tokio::task::spawn_blocking(move || {
123            if !base_path.exists() {
124                std::fs::create_dir_all(&base_path).map_err(|e| {
125                    EncryptionError::generic(format!(
126                        "Failed to create key storage directory: {}",
127                        e
128                    ))
129                })
130            } else {
131                Ok(())
132            }
133        })
134        .await
135        .map_err(|e| EncryptionError::generic(format!("Task join error: {}", e)))?
136    }
137
138    /// Store a key asynchronously (non-blocking)
139    pub async fn store_key_async(
140        &mut self,
141        key_id: &KeyId,
142        encrypted_key: &[u8],
143    ) -> EncryptionResult<()> {
144        self.ensure_base_dir_async().await?;
145        let file_path = self.key_file_path(key_id);
146        let key_id = key_id.clone();
147        let encrypted_key = encrypted_key.to_vec();
148
149        tokio::task::spawn_blocking(move || {
150            std::fs::write(&file_path, encrypted_key).map_err(|e| {
151                EncryptionError::generic(format!("Failed to store key {}: {}", key_id, e))
152            })
153        })
154        .await
155        .map_err(|e| EncryptionError::generic(format!("Task join error: {}", e)))?
156    }
157
158    /// Retrieve a key asynchronously (non-blocking)
159    pub async fn retrieve_key_async(&self, key_id: &KeyId) -> EncryptionResult<Vec<u8>> {
160        let file_path = self.key_file_path(key_id);
161        let key_id = key_id.clone();
162
163        tokio::task::spawn_blocking(move || {
164            std::fs::read(&file_path).map_err(|_| EncryptionError::key_not_found(key_id))
165        })
166        .await
167        .map_err(|e| EncryptionError::generic(format!("Task join error: {}", e)))?
168    }
169
170    /// Delete a key asynchronously (non-blocking)
171    pub async fn delete_key_async(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
172        let file_path = self.key_file_path(key_id);
173        let key_id = key_id.clone();
174
175        tokio::task::spawn_blocking(move || match std::fs::remove_file(&file_path) {
176            Ok(()) => Ok(()),
177            Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
178            Err(e) => {
179                Err(EncryptionError::generic(format!("Failed to delete key {}: {}", key_id, e)))
180            }
181        })
182        .await
183        .map_err(|e| EncryptionError::generic(format!("Task join error: {}", e)))?
184    }
185}
186
187impl KeyStorage for FileKeyStorage {
188    fn store_key(&mut self, key_id: &KeyId, encrypted_key: &[u8]) -> EncryptionResult<()> {
189        self.ensure_base_dir()?;
190        let file_path = self.key_file_path(key_id);
191        std::fs::write(&file_path, encrypted_key)
192            .map_err(|e| EncryptionError::generic(format!("Failed to store key {}: {}", key_id, e)))
193    }
194
195    fn retrieve_key(&self, key_id: &KeyId) -> EncryptionResult<Vec<u8>> {
196        let file_path = self.key_file_path(key_id);
197        std::fs::read(&file_path).map_err(|_| EncryptionError::key_not_found(key_id.clone()))
198    }
199
200    fn delete_key(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
201        let file_path = self.key_file_path(key_id);
202        match std::fs::remove_file(&file_path) {
203            Ok(()) => Ok(()),
204            Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), // Key doesn't exist, consider it deleted
205            Err(e) => {
206                Err(EncryptionError::generic(format!("Failed to delete key {}: {}", key_id, e)))
207            }
208        }
209    }
210
211    fn key_exists(&self, key_id: &KeyId) -> bool {
212        self.key_file_path(key_id).exists()
213    }
214
215    fn list_keys(&self) -> Vec<KeyId> {
216        if !self.base_path.exists() {
217            return Vec::new();
218        }
219
220        std::fs::read_dir(&self.base_path)
221            .map(|entries| {
222                entries
223                    .filter_map(|entry| {
224                        entry.ok().and_then(|e| {
225                            e.path()
226                                .file_stem()
227                                .and_then(|stem| stem.to_str())
228                                .map(|s| s.to_string())
229                        })
230                    })
231                    .collect()
232            })
233            .unwrap_or_default()
234    }
235}
236
237impl Default for FileKeyStorage {
238    fn default() -> Self {
239        Self::new()
240    }
241}
242
243/// Key metadata for tracking key properties and lifecycle
244#[derive(Debug, Clone, Serialize, Deserialize)]
245pub struct KeyMetadata {
246    /// Key identifier
247    pub key_id: KeyId,
248    /// Encryption algorithm used
249    pub algorithm: EncryptionAlgorithm,
250    /// Key creation timestamp
251    pub created_at: DateTime<Utc>,
252    /// Key last used timestamp
253    pub last_used_at: Option<DateTime<Utc>>,
254    /// Key expiration timestamp (optional)
255    pub expires_at: Option<DateTime<Utc>>,
256    /// Key version for rotation
257    pub version: u32,
258    /// Key purpose/description
259    pub purpose: String,
260    /// Whether the key is currently active
261    pub is_active: bool,
262    /// Usage count for analytics
263    pub usage_count: u64,
264}
265
266/// Key store for managing encryption keys
267pub struct KeyStore {
268    /// Key storage backend
269    storage: Box<dyn KeyStorage + Send + Sync>,
270    /// Key metadata tracking
271    metadata: HashMap<KeyId, KeyMetadata>,
272    /// Master key for encrypting stored keys
273    master_key: Option<EncryptionKey>,
274    /// Key derivation manager
275    derivation_manager: Arc<KeyDerivationManager>,
276}
277
278impl std::fmt::Debug for KeyStore {
279    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
280        f.debug_struct("KeyStore")
281            .field("storage", &"KeyStorage")
282            .field("metadata", &self.metadata)
283            .field("master_key", &self.master_key.is_some())
284            .field("derivation_manager", &self.derivation_manager)
285            .finish()
286    }
287}
288
289impl KeyStore {
290    /// Create a new key store with memory storage
291    pub fn new() -> Self {
292        Self {
293            storage: Box::new(MemoryKeyStorage::new()),
294            metadata: HashMap::new(),
295            master_key: None,
296            derivation_manager: Arc::new(KeyDerivationManager::new()),
297        }
298    }
299
300    /// Create a key store with custom storage backend
301    pub fn with_storage(storage: Box<dyn KeyStorage + Send + Sync>) -> Self {
302        Self {
303            storage,
304            metadata: HashMap::new(),
305            master_key: None,
306            derivation_manager: Arc::new(KeyDerivationManager::new()),
307        }
308    }
309
310    /// Initialize the master key for the key store
311    pub fn initialize_master_key(&mut self, master_password: &str) -> EncryptionResult<()> {
312        let master_key = self.derivation_manager.derive_master_key(master_password)?;
313
314        self.master_key = Some(master_key);
315        Ok(())
316    }
317
318    /// Generate a new encryption key
319    pub fn generate_key(
320        &mut self,
321        key_id: KeyId,
322        algorithm: EncryptionAlgorithm,
323        purpose: String,
324    ) -> EncryptionResult<()> {
325        if self.storage.key_exists(&key_id) {
326            return Err(EncryptionError::generic(format!("Key {} already exists", key_id)));
327        }
328
329        // Generate the key
330        let key = EncryptionKey::generate(algorithm.clone())?;
331
332        // Store the key encrypted with master key
333        let encrypted_key = if let Some(master_key) = &self.master_key {
334            let key_data = key.to_base64();
335            let encrypted = crate::encryption::algorithms::EncryptionEngine::encrypt(
336                master_key,
337                key_data.as_bytes(),
338                None,
339            )?;
340            serde_json::to_vec(&encrypted)
341                .map_err(|e| EncryptionError::serialization_error(e.to_string()))?
342        } else {
343            // Store unencrypted (development/testing only)
344            key.to_base64().into_bytes()
345        };
346
347        // Store the key
348        self.storage.store_key(&key_id, &encrypted_key)?;
349
350        // Create metadata
351        let metadata = KeyMetadata {
352            key_id: key_id.clone(),
353            algorithm,
354            created_at: Utc::now(),
355            last_used_at: None,
356            expires_at: None,
357            version: 1,
358            purpose,
359            is_active: true,
360            usage_count: 0,
361        };
362
363        self.metadata.insert(key_id, metadata);
364        Ok(())
365    }
366
367    /// Retrieve and decrypt a key
368    pub fn get_key(&self, key_id: &KeyId) -> EncryptionResult<EncryptionKey> {
369        // Get encrypted key data
370        let encrypted_data: Vec<u8> = self.storage.retrieve_key(key_id)?;
371
372        // Deserialize encrypted data
373        let encrypted: crate::encryption::algorithms::EncryptedData =
374            serde_json::from_slice(&encrypted_data)
375                .map_err(|e| EncryptionError::serialization_error(e.to_string()))?;
376
377        // Decrypt the key
378        let master_key = self
379            .master_key
380            .as_ref()
381            .ok_or_else(|| EncryptionError::key_store_error("Master key not initialized"))?;
382
383        let decrypted_bytes =
384            crate::encryption::algorithms::EncryptionEngine::decrypt(master_key, &encrypted)?;
385
386        let key_data = String::from_utf8(decrypted_bytes)
387            .map_err(|e| EncryptionError::serialization_error(e.to_string()))?;
388
389        // Get metadata to determine algorithm
390        let metadata = self
391            .metadata
392            .get(key_id)
393            .ok_or_else(|| EncryptionError::key_not_found(key_id.clone()))?;
394
395        EncryptionKey::from_base64(&key_data, metadata.algorithm.clone())
396    }
397
398    /// Update key usage statistics
399    pub fn record_key_usage(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
400        if let Some(metadata) = self.metadata.get_mut(key_id) {
401            metadata.last_used_at = Some(Utc::now());
402            metadata.usage_count += 1;
403        }
404        Ok(())
405    }
406
407    /// Rotate a key (generate new version)
408    pub fn rotate_key(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
409        let old_metadata = self
410            .metadata
411            .get(key_id)
412            .ok_or_else(|| EncryptionError::key_not_found(key_id.clone()))?
413            .clone();
414
415        if !old_metadata.is_active {
416            return Err(EncryptionError::generic(format!("Key {} is not active", key_id)));
417        }
418
419        // Generate new key with same algorithm
420        let new_key = EncryptionKey::generate(old_metadata.algorithm.clone())?;
421
422        // Store new key
423        let encrypted_key = if let Some(master_key) = &self.master_key {
424            let key_data = new_key.to_base64();
425            let encrypted = crate::encryption::algorithms::EncryptionEngine::encrypt(
426                master_key,
427                key_data.as_bytes(),
428                None,
429            )?;
430            serde_json::to_vec(&encrypted)
431                .map_err(|e| EncryptionError::serialization_error(e.to_string()))?
432        } else {
433            return Err(EncryptionError::key_store_error("Master key not initialized"));
434        };
435
436        self.storage.store_key(key_id, &encrypted_key)?;
437
438        // Update metadata
439        if let Some(metadata) = self.metadata.get_mut(key_id) {
440            metadata.version += 1;
441            metadata.created_at = Utc::now(); // Update creation time for new version
442        }
443
444        Ok(())
445    }
446
447    /// Delete a key
448    pub fn delete_key(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
449        self.storage.delete_key(key_id)?;
450        self.metadata.remove(key_id);
451        Ok(())
452    }
453
454    /// List all keys with metadata
455    pub fn list_keys(&self) -> Vec<&KeyMetadata> {
456        self.metadata.values().collect()
457    }
458
459    /// Get key metadata
460    pub fn get_key_metadata(&self, key_id: &KeyId) -> Option<&KeyMetadata> {
461        self.metadata.get(key_id)
462    }
463
464    /// Check if a key exists and is active
465    pub fn key_exists(&self, key_id: &KeyId) -> bool {
466        self.storage.key_exists(key_id)
467            && self.metadata.get(key_id).map(|meta| meta.is_active).unwrap_or(false)
468    }
469
470    /// Set key expiration
471    pub fn set_key_expiration(
472        &mut self,
473        key_id: &KeyId,
474        expires_at: DateTime<Utc>,
475    ) -> EncryptionResult<()> {
476        if let Some(metadata) = self.metadata.get_mut(key_id) {
477            metadata.expires_at = Some(expires_at);
478            Ok(())
479        } else {
480            Err(EncryptionError::key_not_found(key_id.clone()))
481        }
482    }
483
484    /// Clean up expired keys
485    pub fn cleanup_expired_keys(&mut self) -> EncryptionResult<Vec<KeyId>> {
486        let now = Utc::now();
487
488        // Find expired keys
489        let expired_key_ids: Vec<KeyId> = self
490            .metadata
491            .iter()
492            .filter_map(|(key_id, metadata)| {
493                if let Some(expires_at) = metadata.expires_at {
494                    if now > expires_at && metadata.is_active {
495                        Some(key_id.clone())
496                    } else {
497                        None
498                    }
499                } else {
500                    None
501                }
502            })
503            .collect();
504
505        // Mark expired keys as inactive
506        for key_id in &expired_key_ids {
507            if let Some(metadata) = self.metadata.get_mut(key_id) {
508                metadata.is_active = false;
509            }
510        }
511
512        let expired_keys = expired_key_ids;
513        Ok(expired_keys)
514    }
515
516    /// Get key statistics
517    pub fn get_statistics(&self) -> KeyStoreStatistics {
518        let total_keys = self.metadata.len();
519        let active_keys = self.metadata.values().filter(|meta| meta.is_active).count();
520        let expired_keys = self
521            .metadata
522            .values()
523            .filter(|meta| meta.expires_at.is_some_and(|exp| chrono::Utc::now() > exp))
524            .count();
525
526        let total_usage: u64 = self.metadata.values().map(|meta| meta.usage_count).sum();
527
528        KeyStoreStatistics {
529            total_keys,
530            active_keys,
531            expired_keys,
532            total_usage,
533            oldest_key: self
534                .metadata
535                .values()
536                .min_by_key(|meta| meta.created_at)
537                .map(|meta| meta.created_at),
538            newest_key: self
539                .metadata
540                .values()
541                .max_by_key(|meta| meta.created_at)
542                .map(|meta| meta.created_at),
543        }
544    }
545
546    /// Export key metadata for backup
547    pub fn export_metadata(&self) -> EncryptionResult<String> {
548        let metadata: Vec<&KeyMetadata> = self.metadata.values().collect();
549        serde_json::to_string_pretty(&metadata)
550            .map_err(|e| EncryptionError::serialization_error(e.to_string()))
551    }
552
553    /// Import key metadata
554    pub fn import_metadata(&mut self, metadata_json: &str) -> EncryptionResult<()> {
555        let imported_metadata: Vec<KeyMetadata> = serde_json::from_str(metadata_json)
556            .map_err(|e| EncryptionError::serialization_error(e.to_string()))?;
557
558        for metadata in imported_metadata {
559            self.metadata.insert(metadata.key_id.clone(), metadata);
560        }
561
562        Ok(())
563    }
564}
565
566impl Default for KeyStore {
567    fn default() -> Self {
568        Self::new()
569    }
570}
571
572/// Global key store instance
573static GLOBAL_KEY_STORE: OnceLock<Arc<RwLock<KeyStore>>> = OnceLock::new();
574
575/// Initialize the global key store
576pub fn init_key_store() -> &'static Arc<RwLock<KeyStore>> {
577    GLOBAL_KEY_STORE.get_or_init(|| Arc::new(RwLock::new(KeyStore::new())))
578}
579
580/// Get the global key store instance
581pub fn get_key_store() -> Option<&'static Arc<RwLock<KeyStore>>> {
582    GLOBAL_KEY_STORE.get()
583}
584
585/// Key store statistics
586#[derive(Debug, Clone)]
587pub struct KeyStoreStatistics {
588    /// Total number of keys
589    pub total_keys: usize,
590    /// Number of active keys
591    pub active_keys: usize,
592    /// Number of expired keys
593    pub expired_keys: usize,
594    /// Total key usage count
595    pub total_usage: u64,
596    /// Timestamp of the oldest key
597    pub oldest_key: Option<DateTime<Utc>>,
598    /// Timestamp of the newest key
599    pub newest_key: Option<DateTime<Utc>>,
600}
601
602/// Key management utilities
603pub mod utils {
604    use super::*;
605    use crate::encryption::errors::EncryptionResult;
606
607    /// Generate a unique key ID
608    pub fn generate_key_id() -> KeyId {
609        use std::time::{SystemTime, UNIX_EPOCH};
610        let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos();
611
612        format!("key_{}", timestamp)
613    }
614
615    /// Validate key ID format
616    pub fn validate_key_id(key_id: &str) -> EncryptionResult<()> {
617        if key_id.is_empty() {
618            return Err(EncryptionError::invalid_key("Key ID cannot be empty"));
619        }
620
621        if key_id.len() > 255 {
622            return Err(EncryptionError::invalid_key("Key ID too long (max 255 characters)"));
623        }
624
625        if !key_id.chars().all(|c| c.is_alphanumeric() || c == '_' || c == '-' || c == '.') {
626            return Err(EncryptionError::invalid_key("Key ID contains invalid characters"));
627        }
628
629        Ok(())
630    }
631
632    /// Sanitize key ID for safe storage
633    pub fn sanitize_key_id(key_id: &str) -> String {
634        key_id
635            .chars()
636            .map(|c| {
637                if c.is_alphanumeric() || c == '_' || c == '-' {
638                    c
639                } else {
640                    '_'
641                }
642            })
643            .collect::<String>()
644            .trim_matches('_')
645            .to_string()
646    }
647
648    /// Check if a key is expired
649    pub fn is_key_expired(metadata: &KeyMetadata) -> bool {
650        if let Some(expires_at) = metadata.expires_at {
651            chrono::Utc::now() > expires_at
652        } else {
653            false
654        }
655    }
656
657    /// Get key age in days
658    pub fn get_key_age_days(metadata: &KeyMetadata) -> i64 {
659        let now = chrono::Utc::now();
660        (now - metadata.created_at).num_days()
661    }
662
663    /// Format key size for display
664    pub fn format_key_size(key: &EncryptionKey) -> String {
665        let bits = key.len() * 8;
666        format!("{} bits", bits)
667    }
668}