1use crate::{
48 encryption::{EncryptionKey, decrypt, encrypt, generate_nonce},
49 hmac::{HmacKey, HmacTag, compute_hmac, verify_hmac},
50 kdf::KeyDerivation,
51 zeroizing::secure_zero,
52};
53use serde::{Deserialize, Serialize};
54use std::collections::HashMap;
55use std::time::{SystemTime, UNIX_EPOCH};
56
57#[derive(Debug, thiserror::Error)]
59pub enum KeyStoreError {
60 #[error("Key not found: {0}")]
61 KeyNotFound(String),
62
63 #[error("Key already exists: {0}")]
64 KeyAlreadyExists(String),
65
66 #[error("Encryption error: {0}")]
67 EncryptionError(String),
68
69 #[error("Decryption error: {0}")]
70 DecryptionError(String),
71
72 #[error("Invalid master key")]
73 InvalidMasterKey,
74
75 #[error("Integrity check failed")]
76 IntegrityCheckFailed,
77
78 #[error("Serialization error: {0}")]
79 SerializationError(String),
80
81 #[error("I/O error: {0}")]
82 IoError(String),
83
84 #[error("Invalid key type")]
85 InvalidKeyType,
86}
87
88pub type KeyStoreResult<T> = Result<T, KeyStoreError>;
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
93pub enum KeyType {
94 Signing,
96 Encryption,
98 Authentication,
100 Generic,
102 KeyExchange,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct KeyMetadata {
109 pub key_id: String,
111 pub key_type: KeyType,
113 pub created_at: u64,
115 pub last_accessed: u64,
117 pub description: Option<String>,
119 pub version: u32,
121 pub active: bool,
123}
124
125impl KeyMetadata {
126 pub fn new(key_id: String, key_type: KeyType) -> Self {
128 let now = SystemTime::now()
129 .duration_since(UNIX_EPOCH)
130 .unwrap()
131 .as_secs();
132
133 Self {
134 key_id,
135 key_type,
136 created_at: now,
137 last_accessed: now,
138 description: None,
139 version: 1,
140 active: true,
141 }
142 }
143
144 pub fn touch(&mut self) {
146 self.last_accessed = SystemTime::now()
147 .duration_since(UNIX_EPOCH)
148 .unwrap()
149 .as_secs();
150 }
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize)]
155struct EncryptedKeyEntry {
156 metadata: KeyMetadata,
158 ciphertext: Vec<u8>,
160 hmac: Vec<u8>,
162}
163
164pub struct SecureKeyStore {
170 master_key: EncryptionKey,
172 hmac_key: HmacKey,
174 entries: HashMap<String, EncryptedKeyEntry>,
176 salt: [u8; 32],
178}
179
180impl SecureKeyStore {
181 pub fn new(password: &[u8]) -> KeyStoreResult<Self> {
194 use rand::RngCore;
196 let mut salt = [0u8; 32];
197 rand::thread_rng().fill_bytes(&mut salt);
198
199 Self::with_salt(password, salt)
200 }
201
202 pub fn with_salt(password: &[u8], salt: [u8; 32]) -> KeyStoreResult<Self> {
204 let kdf = KeyDerivation::new(password, Some(&salt));
206 let master_key = kdf
207 .derive_encryption_key(b"keystore-encryption")
208 .map_err(|e| KeyStoreError::EncryptionError(e.to_string()))?;
209
210 let hmac_key_bytes = kdf
211 .derive_bytes(b"keystore-hmac", 32)
212 .map_err(|e| KeyStoreError::EncryptionError(e.to_string()))?;
213 let hmac_key = HmacKey::from_bytes(&hmac_key_bytes)
214 .map_err(|e| KeyStoreError::EncryptionError(e.to_string()))?;
215
216 Ok(Self {
217 master_key,
218 hmac_key,
219 entries: HashMap::new(),
220 salt,
221 })
222 }
223
224 pub fn store_key(
248 &mut self,
249 key_id: &str,
250 key_data: &[u8],
251 key_type: KeyType,
252 ) -> KeyStoreResult<()> {
253 if self.entries.contains_key(key_id) {
254 return Err(KeyStoreError::KeyAlreadyExists(key_id.to_string()));
255 }
256
257 let nonce = generate_nonce();
259
260 let encrypted = encrypt(key_data, &self.master_key, &nonce)
262 .map_err(|e| KeyStoreError::EncryptionError(e.to_string()))?;
263
264 let mut ciphertext = Vec::with_capacity(12 + encrypted.len());
266 ciphertext.extend_from_slice(&nonce);
267 ciphertext.extend_from_slice(&encrypted);
268
269 let hmac = compute_hmac(&self.hmac_key, &ciphertext);
271
272 let metadata = KeyMetadata::new(key_id.to_string(), key_type);
274
275 self.entries.insert(
277 key_id.to_string(),
278 EncryptedKeyEntry {
279 metadata,
280 ciphertext,
281 hmac: hmac.to_bytes(),
282 },
283 );
284
285 Ok(())
286 }
287
288 pub fn retrieve_key(&mut self, key_id: &str) -> KeyStoreResult<Vec<u8>> {
309 let entry = self
310 .entries
311 .get_mut(key_id)
312 .ok_or_else(|| KeyStoreError::KeyNotFound(key_id.to_string()))?;
313
314 let stored_hmac = HmacTag::from_bytes(&entry.hmac);
316 if !verify_hmac(&self.hmac_key, &entry.ciphertext, &stored_hmac) {
317 return Err(KeyStoreError::IntegrityCheckFailed);
318 }
319
320 if entry.ciphertext.len() < 12 {
322 return Err(KeyStoreError::DecryptionError(
323 "Invalid ciphertext length".to_string(),
324 ));
325 }
326 let (nonce_bytes, encrypted) = entry.ciphertext.split_at(12);
327 let mut nonce = [0u8; 12];
328 nonce.copy_from_slice(nonce_bytes);
329
330 let plaintext = decrypt(encrypted, &self.master_key, &nonce)
332 .map_err(|e| KeyStoreError::DecryptionError(e.to_string()))?;
333
334 entry.metadata.touch();
336
337 Ok(plaintext)
338 }
339
340 pub fn delete_key(&mut self, key_id: &str) -> KeyStoreResult<()> {
358 let mut entry = self
359 .entries
360 .remove(key_id)
361 .ok_or_else(|| KeyStoreError::KeyNotFound(key_id.to_string()))?;
362
363 secure_zero(&mut entry.ciphertext);
365 secure_zero(&mut entry.hmac);
366
367 Ok(())
368 }
369
370 pub fn list_keys(&self) -> Vec<String> {
372 self.entries.keys().cloned().collect()
373 }
374
375 pub fn get_metadata(&self, key_id: &str) -> KeyStoreResult<&KeyMetadata> {
377 let entry = self
378 .entries
379 .get(key_id)
380 .ok_or_else(|| KeyStoreError::KeyNotFound(key_id.to_string()))?;
381 Ok(&entry.metadata)
382 }
383
384 pub fn update_metadata<F>(&mut self, key_id: &str, f: F) -> KeyStoreResult<()>
386 where
387 F: FnOnce(&mut KeyMetadata),
388 {
389 let entry = self
390 .entries
391 .get_mut(key_id)
392 .ok_or_else(|| KeyStoreError::KeyNotFound(key_id.to_string()))?;
393 f(&mut entry.metadata);
394 Ok(())
395 }
396
397 pub fn rotate_key(&mut self, key_id: &str, new_key_data: &[u8]) -> KeyStoreResult<()> {
402 let metadata = {
404 let entry = self
405 .entries
406 .get(key_id)
407 .ok_or_else(|| KeyStoreError::KeyNotFound(key_id.to_string()))?;
408 let mut meta = entry.metadata.clone();
409 meta.version += 1;
410 meta.touch();
411 meta
412 };
413
414 self.delete_key(key_id)?;
416
417 let nonce = generate_nonce();
419
420 let encrypted = encrypt(new_key_data, &self.master_key, &nonce)
422 .map_err(|e| KeyStoreError::EncryptionError(e.to_string()))?;
423
424 let mut ciphertext = Vec::with_capacity(12 + encrypted.len());
426 ciphertext.extend_from_slice(&nonce);
427 ciphertext.extend_from_slice(&encrypted);
428
429 let hmac = compute_hmac(&self.hmac_key, &ciphertext);
431
432 self.entries.insert(
434 key_id.to_string(),
435 EncryptedKeyEntry {
436 metadata,
437 ciphertext,
438 hmac: hmac.to_bytes(),
439 },
440 );
441
442 Ok(())
443 }
444
445 pub fn serialize(&self) -> KeyStoreResult<Vec<u8>> {
449 #[derive(Serialize)]
450 struct KeyStoreData {
451 salt: [u8; 32],
452 entries: HashMap<String, EncryptedKeyEntry>,
453 }
454
455 let data = KeyStoreData {
456 salt: self.salt,
457 entries: self.entries.clone(),
458 };
459
460 crate::codec::encode(&data).map_err(|e| KeyStoreError::SerializationError(e.to_string()))
461 }
462
463 pub fn deserialize(password: &[u8], data: &[u8]) -> KeyStoreResult<Self> {
465 #[derive(Deserialize)]
466 struct KeyStoreData {
467 salt: [u8; 32],
468 entries: HashMap<String, EncryptedKeyEntry>,
469 }
470
471 let stored: KeyStoreData = crate::codec::decode(data)
472 .map_err(|e| KeyStoreError::SerializationError(e.to_string()))?;
473
474 let mut keystore = Self::with_salt(password, stored.salt)?;
475 keystore.entries = stored.entries;
476
477 Ok(keystore)
478 }
479
480 pub fn salt(&self) -> &[u8; 32] {
482 &self.salt
483 }
484
485 pub fn contains_key(&self, key_id: &str) -> bool {
487 self.entries.contains_key(key_id)
488 }
489
490 pub fn len(&self) -> usize {
492 self.entries.len()
493 }
494
495 pub fn is_empty(&self) -> bool {
497 self.entries.is_empty()
498 }
499}
500
501impl Drop for SecureKeyStore {
502 fn drop(&mut self) {
503 secure_zero(&mut self.master_key);
505
506 for entry in self.entries.values_mut() {
508 secure_zero(&mut entry.ciphertext);
509 secure_zero(&mut entry.hmac);
510 }
511 }
512}
513
514#[cfg(test)]
515mod tests {
516 use super::*;
517
518 #[test]
519 fn test_keystore_basic() {
520 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
521
522 keystore
524 .store_key("key1", b"secret-data", KeyType::Generic)
525 .unwrap();
526
527 let retrieved = keystore.retrieve_key("key1").unwrap();
529 assert_eq!(retrieved, b"secret-data");
530 }
531
532 #[test]
533 fn test_multiple_keys() {
534 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
535
536 keystore
537 .store_key("signing", b"sign-key", KeyType::Signing)
538 .unwrap();
539 keystore
540 .store_key("encryption", b"enc-key", KeyType::Encryption)
541 .unwrap();
542 keystore
543 .store_key("hmac", b"hmac-key", KeyType::Authentication)
544 .unwrap();
545
546 assert_eq!(keystore.retrieve_key("signing").unwrap(), b"sign-key");
547 assert_eq!(keystore.retrieve_key("encryption").unwrap(), b"enc-key");
548 assert_eq!(keystore.retrieve_key("hmac").unwrap(), b"hmac-key");
549 }
550
551 #[test]
552 fn test_key_not_found() {
553 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
554
555 let result = keystore.retrieve_key("nonexistent");
556 assert!(matches!(result, Err(KeyStoreError::KeyNotFound(_))));
557 }
558
559 #[test]
560 fn test_duplicate_key() {
561 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
562
563 keystore
564 .store_key("key1", b"data", KeyType::Generic)
565 .unwrap();
566 let result = keystore.store_key("key1", b"other", KeyType::Generic);
567
568 assert!(matches!(result, Err(KeyStoreError::KeyAlreadyExists(_))));
569 }
570
571 #[test]
572 fn test_delete_key() {
573 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
574
575 keystore
576 .store_key("key1", b"data", KeyType::Generic)
577 .unwrap();
578 assert!(keystore.contains_key("key1"));
579
580 keystore.delete_key("key1").unwrap();
581 assert!(!keystore.contains_key("key1"));
582
583 let result = keystore.retrieve_key("key1");
584 assert!(matches!(result, Err(KeyStoreError::KeyNotFound(_))));
585 }
586
587 #[test]
588 fn test_list_keys() {
589 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
590
591 keystore
592 .store_key("key1", b"data1", KeyType::Generic)
593 .unwrap();
594 keystore
595 .store_key("key2", b"data2", KeyType::Signing)
596 .unwrap();
597 keystore
598 .store_key("key3", b"data3", KeyType::Encryption)
599 .unwrap();
600
601 let mut keys = keystore.list_keys();
602 keys.sort();
603
604 assert_eq!(keys, vec!["key1", "key2", "key3"]);
605 }
606
607 #[test]
608 fn test_metadata() {
609 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
610
611 keystore
612 .store_key("key1", b"data", KeyType::Signing)
613 .unwrap();
614
615 let metadata = keystore.get_metadata("key1").unwrap();
616 assert_eq!(metadata.key_id, "key1");
617 assert_eq!(metadata.key_type, KeyType::Signing);
618 assert_eq!(metadata.version, 1);
619 assert!(metadata.active);
620 }
621
622 #[test]
623 fn test_update_metadata() {
624 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
625
626 keystore
627 .store_key("key1", b"data", KeyType::Generic)
628 .unwrap();
629
630 keystore
631 .update_metadata("key1", |meta| {
632 meta.description = Some("Test key".to_string());
633 meta.active = false;
634 })
635 .unwrap();
636
637 let metadata = keystore.get_metadata("key1").unwrap();
638 assert_eq!(metadata.description.as_deref(), Some("Test key"));
639 assert!(!metadata.active);
640 }
641
642 #[test]
643 fn test_key_rotation() {
644 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
645
646 keystore
647 .store_key("key1", b"old-key", KeyType::Signing)
648 .unwrap();
649 assert_eq!(keystore.get_metadata("key1").unwrap().version, 1);
650
651 keystore.rotate_key("key1", b"new-key").unwrap();
652
653 let retrieved = keystore.retrieve_key("key1").unwrap();
654 assert_eq!(retrieved, b"new-key");
655 assert_eq!(keystore.get_metadata("key1").unwrap().version, 2);
656 }
657
658 #[test]
659 fn test_serialization() {
660 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
661
662 keystore
663 .store_key("key1", b"data1", KeyType::Signing)
664 .unwrap();
665 keystore
666 .store_key("key2", b"data2", KeyType::Encryption)
667 .unwrap();
668
669 let serialized = keystore.serialize().unwrap();
671
672 let mut restored = SecureKeyStore::deserialize(b"test-password", &serialized).unwrap();
674
675 assert_eq!(restored.retrieve_key("key1").unwrap(), b"data1");
677 assert_eq!(restored.retrieve_key("key2").unwrap(), b"data2");
678 }
679
680 #[test]
681 fn test_wrong_password() {
682 let mut keystore = SecureKeyStore::new(b"correct-password").unwrap();
683 keystore
684 .store_key("key1", b"data", KeyType::Generic)
685 .unwrap();
686
687 let serialized = keystore.serialize().unwrap();
688
689 let mut wrong_keystore =
691 SecureKeyStore::deserialize(b"wrong-password", &serialized).unwrap();
692
693 let result = wrong_keystore.retrieve_key("key1");
695 assert!(matches!(result, Err(KeyStoreError::IntegrityCheckFailed)));
696 }
697
698 #[test]
699 fn test_keystore_len() {
700 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
701
702 assert_eq!(keystore.len(), 0);
703 assert!(keystore.is_empty());
704
705 keystore
706 .store_key("key1", b"data1", KeyType::Generic)
707 .unwrap();
708 assert_eq!(keystore.len(), 1);
709 assert!(!keystore.is_empty());
710
711 keystore
712 .store_key("key2", b"data2", KeyType::Signing)
713 .unwrap();
714 assert_eq!(keystore.len(), 2);
715
716 keystore.delete_key("key1").unwrap();
717 assert_eq!(keystore.len(), 1);
718 }
719
720 #[test]
721 fn test_different_key_types() {
722 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
723
724 keystore
725 .store_key("sign", b"sign-key", KeyType::Signing)
726 .unwrap();
727 keystore
728 .store_key("enc", b"enc-key", KeyType::Encryption)
729 .unwrap();
730 keystore
731 .store_key("auth", b"auth-key", KeyType::Authentication)
732 .unwrap();
733 keystore
734 .store_key("kex", b"kex-key", KeyType::KeyExchange)
735 .unwrap();
736 keystore
737 .store_key("gen", b"gen-key", KeyType::Generic)
738 .unwrap();
739
740 assert_eq!(
741 keystore.get_metadata("sign").unwrap().key_type,
742 KeyType::Signing
743 );
744 assert_eq!(
745 keystore.get_metadata("enc").unwrap().key_type,
746 KeyType::Encryption
747 );
748 assert_eq!(
749 keystore.get_metadata("auth").unwrap().key_type,
750 KeyType::Authentication
751 );
752 assert_eq!(
753 keystore.get_metadata("kex").unwrap().key_type,
754 KeyType::KeyExchange
755 );
756 assert_eq!(
757 keystore.get_metadata("gen").unwrap().key_type,
758 KeyType::Generic
759 );
760 }
761
762 #[test]
763 fn test_last_accessed_update() {
764 let mut keystore = SecureKeyStore::new(b"test-password").unwrap();
765
766 keystore
767 .store_key("key1", b"data", KeyType::Generic)
768 .unwrap();
769
770 let created_at = keystore.get_metadata("key1").unwrap().created_at;
771 let first_accessed = keystore.get_metadata("key1").unwrap().last_accessed;
772
773 std::thread::sleep(std::time::Duration::from_millis(10));
775
776 keystore.retrieve_key("key1").unwrap();
777
778 let second_accessed = keystore.get_metadata("key1").unwrap().last_accessed;
779
780 assert_eq!(created_at, first_accessed);
781 assert!(second_accessed >= first_accessed);
782 }
783}