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