mockforge_core/encryption/
key_management.rs1use 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
14pub type KeyId = String;
16
17pub trait KeyStorage: Send + Sync {
19 fn store_key(&mut self, key_id: &KeyId, encrypted_key: &[u8]) -> EncryptionResult<()>;
21
22 fn retrieve_key(&self, key_id: &KeyId) -> EncryptionResult<Vec<u8>>;
24
25 fn delete_key(&mut self, key_id: &KeyId) -> EncryptionResult<()>;
27
28 fn key_exists(&self, key_id: &KeyId) -> bool;
30
31 fn list_keys(&self) -> Vec<KeyId>;
33}
34
35#[derive(Debug, Clone)]
37pub struct MemoryKeyStorage {
38 keys: HashMap<KeyId, Vec<u8>>,
39}
40
41impl MemoryKeyStorage {
42 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#[derive(Debug, Clone)]
85pub struct FileKeyStorage {
86 base_path: std::path::PathBuf,
87}
88
89impl FileKeyStorage {
90 pub fn new() -> Self {
92 Self {
93 base_path: std::path::PathBuf::from(".mockforge/keys"),
94 }
95 }
96
97 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 fn key_file_path(&self, key_id: &KeyId) -> std::path::PathBuf {
106 self.base_path.join(format!("{}.key", key_id))
107 }
108
109 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 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 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 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 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(()), 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#[derive(Debug, Clone, Serialize, Deserialize)]
245pub struct KeyMetadata {
246 pub key_id: KeyId,
248 pub algorithm: EncryptionAlgorithm,
250 pub created_at: DateTime<Utc>,
252 pub last_used_at: Option<DateTime<Utc>>,
254 pub expires_at: Option<DateTime<Utc>>,
256 pub version: u32,
258 pub purpose: String,
260 pub is_active: bool,
262 pub usage_count: u64,
264}
265
266pub struct KeyStore {
268 storage: Box<dyn KeyStorage + Send + Sync>,
270 metadata: HashMap<KeyId, KeyMetadata>,
272 master_key: Option<EncryptionKey>,
274 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 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 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 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 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 let key = EncryptionKey::generate(algorithm.clone())?;
331
332 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 key.to_base64().into_bytes()
345 };
346
347 self.storage.store_key(&key_id, &encrypted_key)?;
349
350 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 pub fn get_key(&self, key_id: &KeyId) -> EncryptionResult<EncryptionKey> {
369 let encrypted_data: Vec<u8> = self.storage.retrieve_key(key_id)?;
371
372 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 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 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 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 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 let new_key = EncryptionKey::generate(old_metadata.algorithm.clone())?;
421
422 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 if let Some(metadata) = self.metadata.get_mut(key_id) {
440 metadata.version += 1;
441 metadata.created_at = Utc::now(); }
443
444 Ok(())
445 }
446
447 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 pub fn list_keys(&self) -> Vec<&KeyMetadata> {
456 self.metadata.values().collect()
457 }
458
459 pub fn get_key_metadata(&self, key_id: &KeyId) -> Option<&KeyMetadata> {
461 self.metadata.get(key_id)
462 }
463
464 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 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 pub fn cleanup_expired_keys(&mut self) -> EncryptionResult<Vec<KeyId>> {
486 let now = Utc::now();
487
488 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 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 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 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 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
572static GLOBAL_KEY_STORE: OnceLock<Arc<RwLock<KeyStore>>> = OnceLock::new();
574
575pub fn init_key_store() -> &'static Arc<RwLock<KeyStore>> {
577 GLOBAL_KEY_STORE.get_or_init(|| Arc::new(RwLock::new(KeyStore::new())))
578}
579
580pub fn get_key_store() -> Option<&'static Arc<RwLock<KeyStore>>> {
582 GLOBAL_KEY_STORE.get()
583}
584
585#[derive(Debug, Clone)]
587pub struct KeyStoreStatistics {
588 pub total_keys: usize,
590 pub active_keys: usize,
592 pub expired_keys: usize,
594 pub total_usage: u64,
596 pub oldest_key: Option<DateTime<Utc>>,
598 pub newest_key: Option<DateTime<Utc>>,
600}
601
602pub mod utils {
604 use super::*;
605 use crate::encryption::errors::EncryptionResult;
606
607 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 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 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 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 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 pub fn format_key_size(key: &EncryptionKey) -> String {
665 let bits = key.len() * 8;
666 format!("{} bits", bits)
667 }
668}