1use 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;
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(|e| {
165 if e.kind() == std::io::ErrorKind::NotFound {
166 EncryptionError::key_not_found(key_id)
167 } else {
168 EncryptionError::generic(format!("Failed to read key {}: {}", key_id, e))
169 }
170 })
171 })
172 .await
173 .map_err(|e| EncryptionError::generic(format!("Task join error: {}", e)))?
174 }
175
176 pub async fn delete_key_async(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
178 let file_path = self.key_file_path(key_id);
179 let key_id = key_id.clone();
180
181 tokio::task::spawn_blocking(move || match std::fs::remove_file(&file_path) {
182 Ok(()) => Ok(()),
183 Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
184 Err(e) => {
185 Err(EncryptionError::generic(format!("Failed to delete key {}: {}", key_id, e)))
186 }
187 })
188 .await
189 .map_err(|e| EncryptionError::generic(format!("Task join error: {}", e)))?
190 }
191}
192
193impl KeyStorage for FileKeyStorage {
194 fn store_key(&mut self, key_id: &KeyId, encrypted_key: &[u8]) -> EncryptionResult<()> {
195 self.ensure_base_dir()?;
196 let file_path = self.key_file_path(key_id);
197 std::fs::write(&file_path, encrypted_key)
198 .map_err(|e| EncryptionError::generic(format!("Failed to store key {}: {}", key_id, e)))
199 }
200
201 fn retrieve_key(&self, key_id: &KeyId) -> EncryptionResult<Vec<u8>> {
202 let file_path = self.key_file_path(key_id);
203 std::fs::read(&file_path).map_err(|e| {
204 if e.kind() == std::io::ErrorKind::NotFound {
205 EncryptionError::key_not_found(key_id.clone())
206 } else {
207 EncryptionError::generic(format!("Failed to read key {}: {}", key_id, e))
208 }
209 })
210 }
211
212 fn delete_key(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
213 let file_path = self.key_file_path(key_id);
214 match std::fs::remove_file(&file_path) {
215 Ok(()) => Ok(()),
216 Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), Err(e) => {
218 Err(EncryptionError::generic(format!("Failed to delete key {}: {}", key_id, e)))
219 }
220 }
221 }
222
223 fn key_exists(&self, key_id: &KeyId) -> bool {
224 self.key_file_path(key_id).exists()
225 }
226
227 fn list_keys(&self) -> Vec<KeyId> {
228 if !self.base_path.exists() {
229 return Vec::new();
230 }
231
232 std::fs::read_dir(&self.base_path)
233 .map(|entries| {
234 entries
235 .filter_map(|entry| {
236 entry.ok().and_then(|e| {
237 e.path()
238 .file_stem()
239 .and_then(|stem| stem.to_str())
240 .map(|s| s.to_string())
241 })
242 })
243 .collect()
244 })
245 .unwrap_or_default()
246 }
247}
248
249impl Default for FileKeyStorage {
250 fn default() -> Self {
251 Self::new()
252 }
253}
254
255#[derive(Debug, Clone, Serialize, Deserialize)]
257pub struct KeyMetadata {
258 pub key_id: KeyId,
260 pub algorithm: EncryptionAlgorithm,
262 pub created_at: DateTime<Utc>,
264 pub last_used_at: Option<DateTime<Utc>>,
266 pub expires_at: Option<DateTime<Utc>>,
268 pub version: u32,
270 pub purpose: String,
272 pub is_active: bool,
274 pub usage_count: u64,
276}
277
278pub struct KeyStore {
280 storage: Box<dyn KeyStorage + Send + Sync>,
282 metadata: HashMap<KeyId, KeyMetadata>,
284 master_key: Option<EncryptionKey>,
286 derivation_manager: Arc<KeyDerivationManager>,
288}
289
290impl std::fmt::Debug for KeyStore {
291 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
292 f.debug_struct("KeyStore")
293 .field("storage", &"KeyStorage")
294 .field("metadata", &self.metadata)
295 .field("master_key", &self.master_key.is_some())
296 .field("derivation_manager", &self.derivation_manager)
297 .finish()
298 }
299}
300
301impl KeyStore {
302 pub fn new() -> Self {
304 Self {
305 storage: Box::new(MemoryKeyStorage::new()),
306 metadata: HashMap::new(),
307 master_key: None,
308 derivation_manager: Arc::new(KeyDerivationManager::new()),
309 }
310 }
311
312 pub fn with_storage(storage: Box<dyn KeyStorage + Send + Sync>) -> Self {
314 Self {
315 storage,
316 metadata: HashMap::new(),
317 master_key: None,
318 derivation_manager: Arc::new(KeyDerivationManager::new()),
319 }
320 }
321
322 pub fn initialize_master_key(&mut self, master_password: &str) -> EncryptionResult<()> {
324 let master_key = self.derivation_manager.derive_master_key(master_password)?;
325
326 self.master_key = Some(master_key);
327 Ok(())
328 }
329
330 pub fn generate_key(
332 &mut self,
333 key_id: KeyId,
334 algorithm: EncryptionAlgorithm,
335 purpose: String,
336 ) -> EncryptionResult<()> {
337 if self.storage.key_exists(&key_id) {
338 return Err(EncryptionError::generic(format!("Key {} already exists", key_id)));
339 }
340
341 let key = EncryptionKey::generate(algorithm.clone())?;
343
344 let encrypted_key = if let Some(master_key) = &self.master_key {
346 let key_data = key.to_base64();
347 let encrypted = crate::encryption::algorithms::EncryptionEngine::encrypt(
348 master_key,
349 key_data.as_bytes(),
350 None,
351 )?;
352 serde_json::to_vec(&encrypted)
353 .map_err(|e| EncryptionError::serialization_error(e.to_string()))?
354 } else {
355 key.to_base64().into_bytes()
357 };
358
359 self.storage.store_key(&key_id, &encrypted_key)?;
361
362 let metadata = KeyMetadata {
364 key_id: key_id.clone(),
365 algorithm,
366 created_at: Utc::now(),
367 last_used_at: None,
368 expires_at: None,
369 version: 1,
370 purpose,
371 is_active: true,
372 usage_count: 0,
373 };
374
375 self.metadata.insert(key_id, metadata);
376 Ok(())
377 }
378
379 pub fn get_key(&self, key_id: &KeyId) -> EncryptionResult<EncryptionKey> {
381 let encrypted_data: Vec<u8> = self.storage.retrieve_key(key_id)?;
383
384 let encrypted: crate::encryption::algorithms::EncryptedData =
386 serde_json::from_slice(&encrypted_data)
387 .map_err(|e| EncryptionError::serialization_error(e.to_string()))?;
388
389 let master_key = self
391 .master_key
392 .as_ref()
393 .ok_or_else(|| EncryptionError::key_store_error("Master key not initialized"))?;
394
395 let decrypted_bytes =
396 crate::encryption::algorithms::EncryptionEngine::decrypt(master_key, &encrypted)?;
397
398 let key_data = String::from_utf8(decrypted_bytes)
399 .map_err(|e| EncryptionError::serialization_error(e.to_string()))?;
400
401 let metadata = self
403 .metadata
404 .get(key_id)
405 .ok_or_else(|| EncryptionError::key_not_found(key_id.clone()))?;
406
407 EncryptionKey::from_base64(&key_data, metadata.algorithm.clone())
408 }
409
410 pub fn record_key_usage(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
412 if let Some(metadata) = self.metadata.get_mut(key_id) {
413 metadata.last_used_at = Some(Utc::now());
414 metadata.usage_count += 1;
415 }
416 Ok(())
417 }
418
419 pub fn rotate_key(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
421 let old_metadata = self
422 .metadata
423 .get(key_id)
424 .ok_or_else(|| EncryptionError::key_not_found(key_id.clone()))?
425 .clone();
426
427 if !old_metadata.is_active {
428 return Err(EncryptionError::generic(format!("Key {} is not active", key_id)));
429 }
430
431 let new_key = EncryptionKey::generate(old_metadata.algorithm.clone())?;
433
434 let encrypted_key = if let Some(master_key) = &self.master_key {
436 let key_data = new_key.to_base64();
437 let encrypted = crate::encryption::algorithms::EncryptionEngine::encrypt(
438 master_key,
439 key_data.as_bytes(),
440 None,
441 )?;
442 serde_json::to_vec(&encrypted)
443 .map_err(|e| EncryptionError::serialization_error(e.to_string()))?
444 } else {
445 return Err(EncryptionError::key_store_error("Master key not initialized"));
446 };
447
448 self.storage.store_key(key_id, &encrypted_key)?;
449
450 if let Some(metadata) = self.metadata.get_mut(key_id) {
452 metadata.version += 1;
453 metadata.created_at = Utc::now(); }
455
456 Ok(())
457 }
458
459 pub fn delete_key(&mut self, key_id: &KeyId) -> EncryptionResult<()> {
461 self.storage.delete_key(key_id)?;
462 self.metadata.remove(key_id);
463 Ok(())
464 }
465
466 pub fn list_keys(&self) -> Vec<&KeyMetadata> {
468 self.metadata.values().collect()
469 }
470
471 pub fn get_key_metadata(&self, key_id: &KeyId) -> Option<&KeyMetadata> {
473 self.metadata.get(key_id)
474 }
475
476 pub fn key_exists(&self, key_id: &KeyId) -> bool {
478 self.storage.key_exists(key_id)
479 && self.metadata.get(key_id).map(|meta| meta.is_active).unwrap_or(false)
480 }
481
482 pub fn set_key_expiration(
484 &mut self,
485 key_id: &KeyId,
486 expires_at: DateTime<Utc>,
487 ) -> EncryptionResult<()> {
488 if let Some(metadata) = self.metadata.get_mut(key_id) {
489 metadata.expires_at = Some(expires_at);
490 Ok(())
491 } else {
492 Err(EncryptionError::key_not_found(key_id.clone()))
493 }
494 }
495
496 pub fn cleanup_expired_keys(&mut self) -> EncryptionResult<Vec<KeyId>> {
498 let now = Utc::now();
499
500 let expired_key_ids: Vec<KeyId> = self
502 .metadata
503 .iter()
504 .filter_map(|(key_id, metadata)| {
505 if let Some(expires_at) = metadata.expires_at {
506 if now > expires_at && metadata.is_active {
507 Some(key_id.clone())
508 } else {
509 None
510 }
511 } else {
512 None
513 }
514 })
515 .collect();
516
517 for key_id in &expired_key_ids {
519 if let Some(metadata) = self.metadata.get_mut(key_id) {
520 metadata.is_active = false;
521 }
522 }
523
524 let expired_keys = expired_key_ids;
525 Ok(expired_keys)
526 }
527
528 pub fn get_statistics(&self) -> KeyStoreStatistics {
530 let total_keys = self.metadata.len();
531 let active_keys = self.metadata.values().filter(|meta| meta.is_active).count();
532 let expired_keys = self
533 .metadata
534 .values()
535 .filter(|meta| meta.expires_at.is_some_and(|exp| Utc::now() > exp))
536 .count();
537
538 let total_usage: u64 = self.metadata.values().map(|meta| meta.usage_count).sum();
539
540 KeyStoreStatistics {
541 total_keys,
542 active_keys,
543 expired_keys,
544 total_usage,
545 oldest_key: self
546 .metadata
547 .values()
548 .min_by_key(|meta| meta.created_at)
549 .map(|meta| meta.created_at),
550 newest_key: self
551 .metadata
552 .values()
553 .max_by_key(|meta| meta.created_at)
554 .map(|meta| meta.created_at),
555 }
556 }
557
558 pub fn export_metadata(&self) -> EncryptionResult<String> {
560 let metadata: Vec<&KeyMetadata> = self.metadata.values().collect();
561 serde_json::to_string_pretty(&metadata)
562 .map_err(|e| EncryptionError::serialization_error(e.to_string()))
563 }
564
565 pub fn import_metadata(&mut self, metadata_json: &str) -> EncryptionResult<()> {
567 let imported_metadata: Vec<KeyMetadata> = serde_json::from_str(metadata_json)
568 .map_err(|e| EncryptionError::serialization_error(e.to_string()))?;
569
570 for metadata in imported_metadata {
571 self.metadata.insert(metadata.key_id.clone(), metadata);
572 }
573
574 Ok(())
575 }
576}
577
578impl Default for KeyStore {
579 fn default() -> Self {
580 Self::new()
581 }
582}
583
584#[derive(Debug, Clone)]
586pub struct KeyStoreStatistics {
587 pub total_keys: usize,
589 pub active_keys: usize,
591 pub expired_keys: usize,
593 pub total_usage: u64,
595 pub oldest_key: Option<DateTime<Utc>>,
597 pub newest_key: Option<DateTime<Utc>>,
599}
600
601#[cfg(test)]
602mod tests {
603 use super::*;
604 use crate::encryption::algorithms::EncryptionAlgorithm;
605
606 #[test]
607 fn test_memory_key_storage_new() {
608 let storage = MemoryKeyStorage::new();
609 assert!(storage.keys.is_empty());
610 }
611
612 #[test]
613 fn test_memory_key_storage_default() {
614 let storage = MemoryKeyStorage::default();
615 assert!(storage.keys.is_empty());
616 }
617
618 #[test]
619 fn test_memory_key_storage_store_and_retrieve() {
620 let mut storage = MemoryKeyStorage::new();
621 let key_id = "test-key".to_string();
622 let encrypted_key = b"encrypted_data".to_vec();
623
624 storage.store_key(&key_id, &encrypted_key).unwrap();
625 assert!(storage.key_exists(&key_id));
626
627 let retrieved = storage.retrieve_key(&key_id).unwrap();
628 assert_eq!(retrieved, encrypted_key);
629 }
630
631 #[test]
632 fn test_memory_key_storage_delete() {
633 let mut storage = MemoryKeyStorage::new();
634 let key_id = "test-key".to_string();
635 storage.store_key(&key_id, b"data".as_slice()).unwrap();
636
637 storage.delete_key(&key_id).unwrap();
638 assert!(!storage.key_exists(&key_id));
639 }
640
641 #[test]
642 fn test_memory_key_storage_list_keys() {
643 let mut storage = MemoryKeyStorage::new();
644 storage.store_key(&"key1".to_string(), b"data1".as_slice()).unwrap();
645 storage.store_key(&"key2".to_string(), b"data2".as_slice()).unwrap();
646
647 let keys = storage.list_keys();
648 assert_eq!(keys.len(), 2);
649 assert!(keys.contains(&"key1".to_string()));
650 assert!(keys.contains(&"key2".to_string()));
651 }
652
653 #[test]
654 fn test_memory_key_storage_retrieve_nonexistent() {
655 let storage = MemoryKeyStorage::new();
656 let result = storage.retrieve_key(&"nonexistent".to_string());
657 assert!(result.is_err());
658 }
659
660 #[test]
661 fn test_file_key_storage_new() {
662 let storage = FileKeyStorage::new();
663 let _ = storage;
665 }
666
667 #[test]
668 fn test_file_key_storage_with_path() {
669 let storage = FileKeyStorage::with_path("/tmp/test-keys");
670 let _ = storage;
672 }
673
674 #[test]
675 fn test_file_key_storage_default() {
676 let storage = FileKeyStorage::default();
677 let _ = storage;
679 }
680
681 #[test]
682 fn test_key_metadata_creation() {
683 let metadata = KeyMetadata {
684 key_id: "test-key".to_string(),
685 algorithm: EncryptionAlgorithm::Aes256Gcm,
686 created_at: Utc::now(),
687 last_used_at: Some(Utc::now()),
688 expires_at: None,
689 version: 1,
690 purpose: "test".to_string(),
691 is_active: true,
692 usage_count: 0,
693 };
694
695 assert_eq!(metadata.key_id, "test-key");
696 assert_eq!(metadata.version, 1);
697 assert!(metadata.is_active);
698 }
699
700 #[test]
701 fn test_key_metadata_serialization() {
702 let metadata = KeyMetadata {
703 key_id: "test-key".to_string(),
704 algorithm: EncryptionAlgorithm::Aes256Gcm,
705 created_at: Utc::now(),
706 last_used_at: None,
707 expires_at: None,
708 version: 1,
709 purpose: "test".to_string(),
710 is_active: true,
711 usage_count: 5,
712 };
713
714 let json = serde_json::to_string(&metadata).unwrap();
715 assert!(json.contains("test-key"));
716 assert!(json.contains("test"));
717 }
718
719 #[test]
720 fn test_key_store_new() {
721 let store = KeyStore::new();
722 let _ = store;
724 }
725
726 #[test]
727 fn test_key_store_with_storage() {
728 let storage = Box::new(MemoryKeyStorage::new());
729 let store = KeyStore::with_storage(storage);
730 let _ = store;
732 }
733
734 #[test]
735 fn test_key_store_default() {
736 let store = KeyStore::default();
737 let _ = store;
739 }
740
741 #[test]
742 fn test_key_store_list_keys_empty() {
743 let store = KeyStore::new();
744 let keys = store.list_keys();
745 assert!(keys.is_empty());
746 }
747
748 #[test]
749 fn test_key_store_get_key_metadata_nonexistent() {
750 let store = KeyStore::new();
751 let metadata = store.get_key_metadata(&"nonexistent".to_string());
752 assert!(metadata.is_none());
753 }
754
755 #[test]
756 fn test_key_store_key_exists_false() {
757 let store = KeyStore::new();
758 assert!(!store.key_exists(&"nonexistent".to_string()));
759 }
760
761 #[test]
762 fn test_key_store_statistics_creation() {
763 let stats = KeyStoreStatistics {
764 total_keys: 10,
765 active_keys: 8,
766 expired_keys: 2,
767 total_usage: 100,
768 oldest_key: Some(Utc::now()),
769 newest_key: Some(Utc::now()),
770 };
771
772 assert_eq!(stats.total_keys, 10);
773 assert_eq!(stats.active_keys, 8);
774 assert_eq!(stats.expired_keys, 2);
775 assert_eq!(stats.total_usage, 100);
776 }
777
778 #[test]
779 fn test_key_store_statistics_with_none_timestamps() {
780 let stats = KeyStoreStatistics {
781 total_keys: 5,
782 active_keys: 4,
783 expired_keys: 1,
784 total_usage: 50,
785 oldest_key: None,
786 newest_key: None,
787 };
788
789 assert_eq!(stats.total_keys, 5);
790 assert!(stats.oldest_key.is_none());
791 assert!(stats.newest_key.is_none());
792 }
793
794 #[test]
795 fn test_key_store_get_statistics() {
796 let store = KeyStore::new();
797 let stats = store.get_statistics();
798 assert_eq!(stats.total_keys, 0);
799 assert_eq!(stats.active_keys, 0);
800 assert_eq!(stats.expired_keys, 0);
801 }
802}