Skip to main content

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;
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::key_store_error(format!(
114                    "Failed to create key storage directory: {}",
115                    e
116                ))
117            })?;
118        }
119        Ok(())
120    }
121
122    /// Ensure the base directory exists (async)
123    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    /// Store a key asynchronously (non-blocking)
142    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    /// Retrieve a key asynchronously (non-blocking)
162    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    /// Delete a key asynchronously (non-blocking)
183    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(()), // Key doesn't exist, consider it deleted
225            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/// Key metadata for tracking key properties and lifecycle
265#[derive(Debug, Clone, Serialize, Deserialize)]
266pub struct KeyMetadata {
267    /// Key identifier
268    pub key_id: KeyId,
269    /// Encryption algorithm used
270    pub algorithm: EncryptionAlgorithm,
271    /// Key creation timestamp
272    pub created_at: DateTime<Utc>,
273    /// Key last used timestamp
274    pub last_used_at: Option<DateTime<Utc>>,
275    /// Key expiration timestamp (optional)
276    pub expires_at: Option<DateTime<Utc>>,
277    /// Key version for rotation
278    pub version: u32,
279    /// Key purpose/description
280    pub purpose: String,
281    /// Whether the key is currently active
282    pub is_active: bool,
283    /// Usage count for analytics
284    pub usage_count: u64,
285}
286
287/// Key store for managing encryption keys
288pub struct KeyStore {
289    /// Key storage backend
290    storage: Box<dyn KeyStorage + Send + Sync>,
291    /// Key metadata tracking
292    metadata: HashMap<KeyId, KeyMetadata>,
293    /// Master key for encrypting stored keys
294    master_key: Option<EncryptionKey>,
295    /// Key derivation manager
296    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    /// Create a new key store with memory storage
312    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    /// Create a key store with custom storage backend
322    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    /// Initialize the master key for the key store
332    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    /// Generate a new encryption key
340    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        // Generate the key
351        let key = EncryptionKey::generate(algorithm.clone())?;
352
353        // Store the key encrypted with master key
354        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            // Store unencrypted (development/testing only)
365            key.to_base64().into_bytes()
366        };
367
368        // Store the key
369        self.storage.store_key(&key_id, &encrypted_key)?;
370
371        // Create metadata
372        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    /// Retrieve and decrypt a key
389    pub fn get_key(&self, key_id: &KeyId) -> EncryptionResult<EncryptionKey> {
390        // Get encrypted key data
391        let encrypted_data: Vec<u8> = self.storage.retrieve_key(key_id)?;
392
393        // Deserialize encrypted data
394        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        // Decrypt the key
399        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        // Get metadata to determine algorithm
411        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    /// Update key usage statistics
420    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    /// Rotate a key (generate new version)
429    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        // Generate new key with same algorithm
441        let new_key = EncryptionKey::generate(old_metadata.algorithm.clone())?;
442
443        // Store new key
444        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        // Update metadata
460        if let Some(metadata) = self.metadata.get_mut(key_id) {
461            metadata.version += 1;
462            metadata.created_at = Utc::now(); // Update creation time for new version
463        }
464
465        Ok(())
466    }
467
468    /// Delete a key
469    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    /// List all keys with metadata
476    pub fn list_keys(&self) -> Vec<&KeyMetadata> {
477        self.metadata.values().collect()
478    }
479
480    /// Get key metadata
481    pub fn get_key_metadata(&self, key_id: &KeyId) -> Option<&KeyMetadata> {
482        self.metadata.get(key_id)
483    }
484
485    /// Check if a key exists and is active
486    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    /// Set key expiration
492    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    /// Clean up expired keys
506    pub fn cleanup_expired_keys(&mut self) -> EncryptionResult<Vec<KeyId>> {
507        let now = Utc::now();
508
509        // Find expired keys
510        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        // Mark expired keys as inactive
527        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    /// Get key statistics
538    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    /// Export key metadata for backup
568    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    /// Import key metadata
575    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/// Key store statistics
594#[derive(Debug, Clone)]
595pub struct KeyStoreStatistics {
596    /// Total number of keys
597    pub total_keys: usize,
598    /// Number of active keys
599    pub active_keys: usize,
600    /// Number of expired keys
601    pub expired_keys: usize,
602    /// Total key usage count
603    pub total_usage: u64,
604    /// Timestamp of the oldest key
605    pub oldest_key: Option<DateTime<Utc>>,
606    /// Timestamp of the newest key
607    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        // Just verify it can be created
673        let _ = storage;
674    }
675
676    #[test]
677    fn test_file_key_storage_with_path() {
678        let storage = FileKeyStorage::with_path("/tmp/test-keys");
679        // Just verify it can be created
680        let _ = storage;
681    }
682
683    #[test]
684    fn test_file_key_storage_default() {
685        let storage = FileKeyStorage::default();
686        // Just verify it can be created
687        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        // Just verify it can be created
732        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        // Just verify it can be created
740        let _ = store;
741    }
742
743    #[test]
744    fn test_key_store_default() {
745        let store = KeyStore::default();
746        // Just verify it can be created
747        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}