1pub mod key_management;
13
14#[cfg(feature = "field-encryption")]
15pub mod key_rotation_enhanced;
16
17#[cfg(feature = "tde-enhanced")]
18pub mod column_encryption;
19#[cfg(feature = "tde-enhanced")]
20pub mod dek_buffer;
21#[cfg(feature = "tde-enhanced")]
22pub mod kms_client;
23
24#[cfg(feature = "tde-enhanced")]
25pub use column_encryption::{ColumnCryptoConfig, ColumnEncryptionPolicy};
26#[cfg(feature = "tde-enhanced")]
27pub use dek_buffer::{DekBuffer, EncryptionAlgo};
28#[cfg(feature = "tde-enhanced")]
29pub use kms_client::{
30 CachedKmsClient, DekCache, KmsClient, KmsDegradeManager, KmsError, LocalKmsClient,
31};
32
33use std::collections::HashMap;
34
35use aes_gcm::aead::{Aead, KeyInit};
36use aes_gcm::{Aes256Gcm, Key, Nonce};
37use hmac::{Hmac, Mac};
38use pbkdf2::pbkdf2_hmac;
39use rand::rngs::OsRng;
40use rand::RngCore;
41use sha2::{Digest, Sha256};
42use subtle::ConstantTimeEq;
43
44type HmacSha256 = Hmac<Sha256>;
45
46pub fn sha256(data: &[u8]) -> [u8; 32] {
52 let mut hasher = Sha256::new();
53 hasher.update(data);
54 let result = hasher.finalize();
55 let mut out = [0u8; 32];
56 out.copy_from_slice(&result);
57 out
58}
59
60pub fn sha256_hex(data: &[u8]) -> String {
62 sha256(data).iter().map(|b| format!("{:02x}", b)).collect()
63}
64
65pub fn hmac_sha256(key: &[u8], message: &[u8]) -> [u8; 32] {
67 let mut mac = match <HmacSha256 as Mac>::new_from_slice(key) {
70 Ok(m) => m,
71 Err(_) => {
72 return [0u8; 32];
75 }
76 };
77 mac.update(message);
78 let result = mac.finalize().into_bytes();
79 let mut out = [0u8; 32];
80 out.copy_from_slice(&result);
81 out
82}
83
84pub fn hmac_sha256_hex(key: &[u8], message: &[u8]) -> String {
86 hmac_sha256(key, message)
87 .iter()
88 .map(|b| format!("{:02x}", b))
89 .collect()
90}
91
92fn constant_time_eq(a: &[u8], b: &[u8]) -> bool {
94 a.ct_eq(b).into()
95}
96
97pub trait Crypter: Send + Sync {
102 fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>, CryptoError>;
103 fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError>;
104}
105
106pub struct AesGcmCrypter {
112 cipher: Aes256Gcm,
113}
114
115impl AesGcmCrypter {
116 pub fn new(key: &[u8; 32]) -> Self {
118 let key = Key::<Aes256Gcm>::from_slice(key);
119 Self {
120 cipher: Aes256Gcm::new(key),
121 }
122 }
123
124 pub fn from_key_str(key: &str) -> Self {
126 let hash = sha256(key.as_bytes());
127 Self::new(&hash)
128 }
129
130 fn random_nonce() -> [u8; 12] {
131 let mut nonce = [0u8; 12];
132 OsRng.fill_bytes(&mut nonce);
133 nonce
134 }
135}
136
137impl Crypter for AesGcmCrypter {
138 fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>, CryptoError> {
139 self.encrypt_with_aad(plaintext, &[])
140 }
141
142 fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> {
143 self.decrypt_with_aad(ciphertext, &[])
144 }
145}
146
147impl AesGcmCrypter {
148 pub fn encrypt_with_aad(&self, plaintext: &[u8], aad: &[u8]) -> Result<Vec<u8>, CryptoError> {
155 let nonce_bytes = Self::random_nonce();
156 let nonce = Nonce::from_slice(&nonce_bytes);
157 let payload = aes_gcm::aead::Payload {
158 msg: plaintext,
159 aad,
160 };
161 let ciphertext = self
162 .cipher
163 .encrypt(nonce, payload)
164 .map_err(|e| CryptoError::EncryptionFailed(e.to_string()))?;
165 let mut result = Vec::with_capacity(12 + ciphertext.len());
166 result.extend_from_slice(&nonce_bytes);
167 result.extend_from_slice(&ciphertext);
168 Ok(result)
169 }
170
171 pub fn decrypt_with_aad(&self, ciphertext: &[u8], aad: &[u8]) -> Result<Vec<u8>, CryptoError> {
176 if ciphertext.len() < 12 {
177 return Err(CryptoError::DecryptionFailed(
178 "Ciphertext too short".to_string(),
179 ));
180 }
181 let nonce = Nonce::from_slice(&ciphertext[..12]);
182 let encrypted = &ciphertext[12..];
183 let payload = aes_gcm::aead::Payload {
184 msg: encrypted,
185 aad,
186 };
187 self.cipher
188 .decrypt(nonce, payload)
189 .map_err(|e| CryptoError::DecryptionFailed(e.to_string()))
190 }
191}
192
193pub trait PasswordHasher: Send + Sync {
198 fn hash(&self, password: &str) -> Result<String, CryptoError>;
199 fn verify(&self, password: &str, hash: &str) -> Result<bool, CryptoError>;
200}
201
202pub struct Pbkdf2Hasher {
207 iterations: u32,
208}
209
210impl Pbkdf2Hasher {
211 const DEFAULT_ITERATIONS: u32 = 100_000;
212 const SALT_LEN: usize = 16;
213 const HASH_LEN: usize = 32;
214
215 pub fn new() -> Self {
216 Self {
217 iterations: Self::DEFAULT_ITERATIONS,
218 }
219 }
220
221 pub fn with_iterations(iterations: u32) -> Self {
222 Self {
223 iterations: iterations.max(1),
224 }
225 }
226
227 pub const MIN_ITERATIONS: u32 = 100_000;
233 pub const MAX_ITERATIONS: u32 = 10_000_000;
234
235 fn compute_hash(password: &str, salt: &[u8], iterations: u32) -> [u8; Self::HASH_LEN] {
236 let mut out = [0u8; Self::HASH_LEN];
237 pbkdf2_hmac::<Sha256>(password.as_bytes(), salt, iterations, &mut out);
238 out
239 }
240}
241
242impl Default for Pbkdf2Hasher {
243 fn default() -> Self {
244 Self::new()
245 }
246}
247
248impl PasswordHasher for Pbkdf2Hasher {
249 fn hash(&self, password: &str) -> Result<String, CryptoError> {
250 if password.is_empty() {
251 return Err(CryptoError::InvalidHash(
252 "Password cannot be empty".to_string(),
253 ));
254 }
255 if self.iterations < Self::MIN_ITERATIONS {
258 return Err(CryptoError::InvalidHash(format!(
259 "Iterations below minimum ({} < {})",
260 self.iterations,
261 Self::MIN_ITERATIONS
262 )));
263 }
264 let salt = random_bytes(Self::SALT_LEN);
265 let hash = Self::compute_hash(password, &salt, self.iterations);
266 Ok(format!(
267 "${}${}${}",
268 self.iterations,
269 hex_encode(&salt),
270 hex_encode(&hash)
271 ))
272 }
273
274 fn verify(&self, password: &str, hash: &str) -> Result<bool, CryptoError> {
275 if !hash.starts_with('$') {
276 return Err(CryptoError::InvalidHash("Invalid hash format".to_string()));
277 }
278 let parts: Vec<&str> = hash[1..].splitn(3, '$').collect();
279 if parts.len() != 3 {
280 return Err(CryptoError::InvalidHash("Invalid hash format".to_string()));
281 }
282 let iterations: u32 = parts[0]
283 .parse()
284 .map_err(|_| CryptoError::InvalidHash("Invalid iterations".to_string()))?;
285
286 if iterations < Self::MIN_ITERATIONS {
289 return Err(CryptoError::InvalidHash(format!(
290 "Iterations below minimum ({iterations} < {})",
291 Self::MIN_ITERATIONS
292 )));
293 }
294 if iterations > Self::MAX_ITERATIONS {
295 return Err(CryptoError::InvalidHash(format!(
296 "Iterations above maximum ({iterations} > {})",
297 Self::MAX_ITERATIONS
298 )));
299 }
300
301 let salt = hex_decode(parts[1])
302 .map_err(|_| CryptoError::InvalidHash("Invalid salt hex".to_string()))?;
303 let expected_hash = hex_decode(parts[2])
304 .map_err(|_| CryptoError::InvalidHash("Invalid hash hex".to_string()))?;
305 let computed = Self::compute_hash(password, &salt, iterations);
306 Ok(constant_time_eq(&computed, &expected_hash))
307 }
308}
309
310pub trait ApiSigner: Send + Sync {
315 fn sign(&self, params: &HashMap<String, String>, secret: &str) -> String;
316 fn verify(&self, params: &HashMap<String, String>, secret: &str, signature: &str) -> bool;
317}
318
319pub struct HmacSigner;
333
334impl HmacSigner {
335 pub fn new() -> Self {
336 Self
337 }
338
339 fn percent_encode(s: &str) -> String {
343 let mut out = String::with_capacity(s.len());
344 for b in s.bytes() {
345 match b {
346 b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'.' | b'_' | b'~' => {
347 out.push(b as char)
348 }
349 _ => {
350 out.push('%');
351 out.push(
352 char::from_digit((b >> 4) as u32, 16)
353 .unwrap_or('0')
354 .to_ascii_uppercase(),
355 );
356 out.push(
357 char::from_digit((b & 0x0f) as u32, 16)
358 .unwrap_or('0')
359 .to_ascii_uppercase(),
360 );
361 }
362 }
363 }
364 out
365 }
366
367 fn compute_signature(params: &HashMap<String, String>, secret: &str) -> String {
368 let mut sorted: Vec<_> = params.iter().collect();
369 sorted.sort_by(|a, b| a.0.cmp(b.0));
370
371 let query_string: String = sorted
372 .iter()
373 .map(|(k, v)| format!("{}={}", Self::percent_encode(k), Self::percent_encode(v)))
374 .collect::<Vec<_>>()
375 .join("&");
376
377 hmac_sha256_hex(secret.as_bytes(), query_string.as_bytes())
378 }
379}
380
381impl Default for HmacSigner {
382 fn default() -> Self {
383 Self::new()
384 }
385}
386
387impl ApiSigner for HmacSigner {
388 fn sign(&self, params: &HashMap<String, String>, secret: &str) -> String {
389 Self::compute_signature(params, secret)
390 }
391
392 fn verify(&self, params: &HashMap<String, String>, secret: &str, signature: &str) -> bool {
393 let computed = Self::compute_signature(params, secret);
394 constant_time_eq(computed.as_bytes(), signature.as_bytes())
395 }
396}
397
398use rsa::oaep::Oaep;
403use rsa::{RsaPrivateKey, RsaPublicKey};
404use sha2::Sha256 as RsaSha256;
405
406pub struct RsaOaepCrypter {
412 public_key: RsaPublicKey,
413 private_key: RsaPrivateKey,
414}
415
416impl RsaOaepCrypter {
417 pub fn generate(key_bits: usize) -> Result<Self, CryptoError> {
419 let mut rng = OsRng;
420 let private_key = RsaPrivateKey::new(&mut rng, key_bits)
421 .map_err(|e| CryptoError::InvalidKey(e.to_string()))?;
422 let public_key = RsaPublicKey::from(&private_key);
423 Ok(Self {
424 public_key,
425 private_key,
426 })
427 }
428
429 pub fn from_keys(public_key: RsaPublicKey, private_key: RsaPrivateKey) -> Self {
431 Self {
432 public_key,
433 private_key,
434 }
435 }
436
437 pub fn public_key(&self) -> &RsaPublicKey {
439 &self.public_key
440 }
441
442 pub fn private_key(&self) -> &RsaPrivateKey {
444 &self.private_key
445 }
446
447 pub fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>, CryptoError> {
449 let mut rng = OsRng;
450 let padding = Oaep::new::<RsaSha256>();
451 self.public_key
452 .encrypt(&mut rng, padding, plaintext)
453 .map_err(|e| CryptoError::EncryptionFailed(e.to_string()))
454 }
455
456 pub fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> {
458 let padding = Oaep::new::<RsaSha256>();
459 self.private_key
460 .decrypt(padding, ciphertext)
461 .map_err(|e| CryptoError::DecryptionFailed(e.to_string()))
462 }
463}
464
465impl Crypter for RsaOaepCrypter {
466 fn encrypt(&self, plaintext: &[u8]) -> Result<Vec<u8>, CryptoError> {
467 self.encrypt(plaintext)
468 }
469
470 fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, CryptoError> {
471 self.decrypt(ciphertext)
472 }
473}
474
475pub trait SignatureVerifier: Send + Sync {
481 fn sign(&self, message: &[u8]) -> Vec<u8>;
483 fn verify(&self, message: &[u8], signature: &[u8]) -> bool;
485}
486
487pub struct HmacSignatureVerifier {
492 key: Vec<u8>,
493}
494
495impl HmacSignatureVerifier {
496 pub fn new(key: &[u8]) -> Self {
498 Self { key: key.to_vec() }
499 }
500
501 pub fn from_key_str(key: &str) -> Self {
503 Self::new(key.as_bytes())
504 }
505}
506
507impl SignatureVerifier for HmacSignatureVerifier {
508 fn sign(&self, message: &[u8]) -> Vec<u8> {
509 hmac_sha256(&self.key, message).to_vec()
510 }
511
512 fn verify(&self, message: &[u8], signature: &[u8]) -> bool {
513 let expected = self.sign(message);
514 constant_time_eq(&expected, signature)
515 }
516}
517
518#[derive(Clone)]
524struct KeyVersion {
525 version: u32,
526 key: Vec<u8>,
527 created_at: u64,
528}
529
530pub struct KeyRotationManager {
538 keys: Vec<KeyVersion>,
539 current_version: u32,
540 max_versions: usize,
541}
542
543impl KeyRotationManager {
544 pub fn new(max_versions: usize) -> Self {
546 Self {
547 keys: vec![],
548 current_version: 0,
549 max_versions: max_versions.max(1),
550 }
551 }
552
553 pub fn with_initial_key(key: Vec<u8>) -> Self {
555 let mut mgr = Self::new(3);
556 mgr.rotate_key(key);
557 mgr
558 }
559
560 pub fn rotate_key(&mut self, new_key: Vec<u8>) -> u32 {
562 self.current_version += 1;
563 let now = current_timestamp_secs();
564 self.keys.push(KeyVersion {
565 version: self.current_version,
566 key: new_key,
567 created_at: now,
568 });
569 while self.keys.len() > self.max_versions {
571 self.keys.remove(0);
572 }
573 self.current_version
574 }
575
576 pub fn sign(&self, message: &[u8]) -> (u32, Vec<u8>) {
578 if let Some(kv) = self.keys.last() {
579 let sig = hmac_sha256(&kv.key, message).to_vec();
580 (kv.version, sig)
581 } else {
582 (0, vec![])
583 }
584 }
585
586 pub fn verify(&self, message: &[u8], version: u32, signature: &[u8]) -> bool {
588 for kv in &self.keys {
589 if kv.version == version {
590 let expected = hmac_sha256(&kv.key, message);
591 return constant_time_eq(&expected, signature);
592 }
593 }
594 false
595 }
596
597 pub fn current_version(&self) -> u32 {
599 self.current_version
600 }
601
602 pub fn version_count(&self) -> usize {
604 self.keys.len()
605 }
606
607 pub fn versions(&self) -> Vec<u32> {
609 self.keys.iter().map(|kv| kv.version).collect()
610 }
611
612 pub fn key_created_at(&self, version: u32) -> Option<u64> {
615 self.keys
616 .iter()
617 .find(|kv| kv.version == version)
618 .map(|kv| kv.created_at)
619 }
620}
621
622fn current_timestamp_secs() -> u64 {
623 use std::time::{SystemTime, UNIX_EPOCH};
624 SystemTime::now()
625 .duration_since(UNIX_EPOCH)
626 .unwrap_or_default()
627 .as_secs()
628}
629
630use std::sync::RwLock;
635use std::time::Duration;
636
637const DEFAULT_ROTATION_INTERVAL_SECS: u64 = 90 * 24 * 60 * 60;
639
640#[derive(Debug, Clone)]
642pub struct VersionedKey {
643 pub version: u32,
645 pub key: Vec<u8>,
647 pub created_at: std::time::SystemTime,
649}
650
651pub struct KeyManager {
658 current: RwLock<VersionedKey>,
660 previous: RwLock<Vec<VersionedKey>>,
662 rotation_interval: Duration,
664 last_rotation: RwLock<std::time::SystemTime>,
666}
667
668impl KeyManager {
669 pub fn new(initial_key: Vec<u8>) -> Self {
671 let now = std::time::SystemTime::now();
672 Self {
673 current: RwLock::new(VersionedKey {
674 version: 1,
675 key: initial_key,
676 created_at: now,
677 }),
678 previous: RwLock::new(Vec::new()),
679 rotation_interval: Duration::from_secs(DEFAULT_ROTATION_INTERVAL_SECS),
680 last_rotation: RwLock::new(now),
681 }
682 }
683
684 pub fn with_rotation_interval(mut self, interval: Duration) -> Self {
686 self.rotation_interval = interval;
687 self
688 }
689
690 pub fn rotate(&self, new_key: Vec<u8>) -> Result<(), CryptoError> {
692 let mut current = self.current.write().expect("KeyManager lock poisoned");
693 let mut previous = self.previous.write().expect("KeyManager lock poisoned");
694
695 previous.push(current.clone());
697
698 if previous.len() > 3 {
700 previous.remove(0);
701 }
702
703 *current = VersionedKey {
705 version: current.version + 1,
706 key: new_key,
707 created_at: std::time::SystemTime::now(),
708 };
709
710 *self
711 .last_rotation
712 .write()
713 .expect("KeyManager last_rotation lock poisoned") = std::time::SystemTime::now();
714 Ok(())
715 }
716
717 pub fn needs_rotation(&self) -> bool {
719 let last = *self
720 .last_rotation
721 .read()
722 .expect("KeyManager last_rotation lock poisoned");
723 std::time::SystemTime::now()
724 .duration_since(last)
725 .map(|d| d >= self.rotation_interval)
726 .unwrap_or(false)
727 }
728
729 pub fn current_key(&self) -> VersionedKey {
731 self.current
732 .read()
733 .expect("KeyManager current lock poisoned")
734 .clone()
735 }
736
737 pub fn key_by_version(&self, version: u32) -> Option<VersionedKey> {
739 if self
740 .current
741 .read()
742 .expect("KeyManager current lock poisoned")
743 .version
744 == version
745 {
746 return Some(
747 self.current
748 .read()
749 .expect("KeyManager current lock poisoned")
750 .clone(),
751 );
752 }
753 self.previous
754 .read()
755 .expect("KeyManager previous lock poisoned")
756 .iter()
757 .find(|k| k.version == version)
758 .cloned()
759 }
760
761 pub fn previous_count(&self) -> usize {
763 self.previous
764 .read()
765 .expect("KeyManager previous lock poisoned")
766 .len()
767 }
768}
769
770fn hex_encode(bytes: &[u8]) -> String {
775 bytes.iter().map(|b| format!("{:02x}", b)).collect()
776}
777
778fn hex_decode(hex: &str) -> Result<Vec<u8>, ()> {
779 if !hex.len().is_multiple_of(2) {
780 return Err(());
781 }
782 (0..hex.len())
783 .step_by(2)
784 .map(|i| u8::from_str_radix(&hex[i..i + 2], 16).map_err(|_| ()))
785 .collect()
786}
787
788fn random_bytes(len: usize) -> Vec<u8> {
789 let mut result = vec![0u8; len];
790 OsRng.fill_bytes(&mut result);
791 result
792}
793
794#[derive(Debug)]
799pub enum CryptoError {
800 EncryptionFailed(String),
801 DecryptionFailed(String),
802 InvalidKey(String),
803 InvalidNonce(String),
804 InvalidHash(String),
805 SigningFailed(String),
806}
807
808impl std::fmt::Display for CryptoError {
809 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
810 match self {
811 CryptoError::EncryptionFailed(msg) => write!(f, "Encryption failed: {}", msg),
812 CryptoError::DecryptionFailed(msg) => write!(f, "Decryption failed: {}", msg),
813 CryptoError::InvalidKey(msg) => write!(f, "Invalid key: {}", msg),
814 CryptoError::InvalidNonce(msg) => write!(f, "Invalid nonce: {}", msg),
815 CryptoError::InvalidHash(msg) => write!(f, "Invalid hash: {}", msg),
816 CryptoError::SigningFailed(msg) => write!(f, "Signing failed: {}", msg),
817 }
818 }
819}
820
821impl std::error::Error for CryptoError {}
822
823impl serde::Serialize for CryptoError {
824 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
825 where
826 S: serde::Serializer,
827 {
828 serializer.serialize_str(&self.to_string())
829 }
830}
831
832#[cfg(test)]
837mod tests {
838 use super::*;
839
840 #[test]
843 fn test_sha256_empty() {
844 assert_eq!(
845 sha256_hex(b""),
846 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
847 );
848 }
849
850 #[test]
851 fn test_sha256_abc() {
852 assert_eq!(
853 sha256_hex(b"abc"),
854 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
855 );
856 }
857
858 #[test]
859 fn test_sha256_hello() {
860 assert_eq!(
861 sha256_hex(b"hello"),
862 "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
863 );
864 }
865
866 #[test]
867 fn test_sha256_long_message() {
868 assert_eq!(
869 sha256_hex(b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
870 "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
871 );
872 }
873
874 #[test]
875 fn test_sha256_deterministic() {
876 assert_eq!(sha256_hex(b"test"), sha256_hex(b"test"));
877 assert_ne!(sha256_hex(b"test"), sha256_hex(b"Test"));
878 }
879
880 #[test]
883 fn test_hmac_sha256_rfc4231_case1() {
884 let key = vec![0x0bu8; 20];
885 let result = hmac_sha256_hex(&key, b"Hi There");
886 assert_eq!(
887 result,
888 "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"
889 );
890 }
891
892 #[test]
893 fn test_hmac_sha256_rfc4231_case2() {
894 let result = hmac_sha256_hex(b"Jefe", b"what do ya want for nothing?");
895 assert_eq!(
896 result,
897 "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843"
898 );
899 }
900
901 #[test]
902 fn test_hmac_sha256_long_key() {
903 let key = vec![0xaau8; 130];
904 let result = hmac_sha256_hex(&key, b"test message");
905 assert_eq!(result.len(), 64);
906 let short_key = vec![0xaau8; 32];
907 let result_short = hmac_sha256_hex(&short_key, b"test message");
908 assert_ne!(result, result_short);
909 }
910
911 #[test]
912 fn test_hmac_sha256_different_messages() {
913 let key = b"secret";
914 assert_ne!(hmac_sha256_hex(key, b"msg1"), hmac_sha256_hex(key, b"msg2"));
915 }
916
917 #[test]
920 fn test_aes_gcm_roundtrip() {
921 let key = [0x42u8; 32];
922 let crypter = AesGcmCrypter::new(&key);
923 let plaintext = b"Hello, World!";
924 let encrypted = crypter.encrypt(plaintext).unwrap();
925 let decrypted = crypter.decrypt(&encrypted).unwrap();
926 assert_eq!(decrypted, plaintext);
927 }
928
929 #[test]
930 fn test_aes_gcm_random_nonce_per_encryption() {
931 let key = [0x42u8; 32];
932 let crypter = AesGcmCrypter::new(&key);
933 let plaintext = b"same plaintext";
934 let encrypted1 = crypter.encrypt(plaintext).unwrap();
935 let encrypted2 = crypter.encrypt(plaintext).unwrap();
936 assert_ne!(encrypted1, encrypted2, "随机 nonce 应使密文不同");
937 assert_eq!(crypter.decrypt(&encrypted1).unwrap(), plaintext);
938 assert_eq!(crypter.decrypt(&encrypted2).unwrap(), plaintext);
939 }
940
941 #[test]
942 fn test_aes_gcm_from_key_str() {
943 let crypter = AesGcmCrypter::from_key_str("my-secret-key");
944 let plaintext = b"data to encrypt";
945 let encrypted = crypter.encrypt(plaintext).unwrap();
946 let decrypted = crypter.decrypt(&encrypted).unwrap();
947 assert_eq!(decrypted, plaintext);
948 }
949
950 #[test]
951 fn test_aes_gcm_short_ciphertext() {
952 let key = [0x42u8; 32];
953 let crypter = AesGcmCrypter::new(&key);
954 assert!(crypter.decrypt(&[0u8; 8]).is_err());
955 }
956
957 #[test]
958 fn test_aes_gcm_empty_plaintext() {
959 let key = [0x42u8; 32];
960 let crypter = AesGcmCrypter::new(&key);
961 let encrypted = crypter.encrypt(b"").unwrap();
962 assert_eq!(encrypted.len(), 28);
964 let decrypted = crypter.decrypt(&encrypted).unwrap();
965 assert_eq!(decrypted, b"");
966 }
967
968 #[test]
969 fn test_aes_gcm_tampered_ciphertext() {
970 let key = [0x42u8; 32];
971 let crypter = AesGcmCrypter::new(&key);
972 let encrypted = crypter.encrypt(b"sensitive data").unwrap();
973 let mut tampered = encrypted.clone();
974 tampered[15] ^= 0x01;
975 assert!(crypter.decrypt(&tampered).is_err());
976 }
977
978 #[test]
981 fn test_pbkdf2_hasher_hash_format() {
982 let hasher = Pbkdf2Hasher::new();
983 let hash = hasher.hash("password123").unwrap();
984 assert!(hash.starts_with('$'));
985 let parts: Vec<&str> = hash[1..].splitn(3, '$').collect();
986 assert_eq!(parts.len(), 3);
987 assert_eq!(parts[0].parse::<u32>().unwrap(), 100_000);
988 assert_eq!(parts[1].len(), 32);
990 assert_eq!(parts[2].len(), 64);
992 }
993
994 #[test]
995 fn test_pbkdf2_hasher_verify_correct() {
996 let hasher = Pbkdf2Hasher::new();
997 let hash = hasher.hash("password123").unwrap();
998 assert!(hasher.verify("password123", &hash).unwrap());
999 }
1000
1001 #[test]
1002 fn test_pbkdf2_hasher_verify_wrong() {
1003 let hasher = Pbkdf2Hasher::new();
1004 let hash = hasher.hash("password123").unwrap();
1005 assert!(!hasher.verify("wrongpassword", &hash).unwrap());
1006 }
1007
1008 #[test]
1009 fn test_pbkdf2_hasher_different_passwords_different_hashes() {
1010 let hasher = Pbkdf2Hasher::new();
1011 let h1 = hasher.hash("pass1").unwrap();
1012 let h2 = hasher.hash("pass2").unwrap();
1013 assert_ne!(h1, h2);
1014 }
1015
1016 #[test]
1017 fn test_pbkdf2_hasher_same_password_different_salts() {
1018 let hasher = Pbkdf2Hasher::new();
1019 let h1 = hasher.hash("same").unwrap();
1020 let h2 = hasher.hash("same").unwrap();
1021 assert_ne!(h1, h2);
1022 assert!(hasher.verify("same", &h1).unwrap());
1023 assert!(hasher.verify("same", &h2).unwrap());
1024 }
1025
1026 #[test]
1027 fn test_pbkdf2_hasher_invalid_format() {
1028 let hasher = Pbkdf2Hasher::new();
1029 assert!(hasher.verify("password", "invalid-hash").is_err());
1030 assert!(hasher.verify("password", "$abc").is_err());
1031 assert!(hasher.verify("password", "$abc$def").is_err());
1032 }
1033
1034 #[test]
1035 fn test_pbkdf2_hasher_with_iterations() {
1036 let low = Pbkdf2Hasher::with_iterations(1000);
1038 assert!(low.hash("secret").is_err());
1039
1040 let hasher = Pbkdf2Hasher::with_iterations(100_000);
1041 let hash = hasher.hash("secret").unwrap();
1042 let parts: Vec<&str> = hash[1..].splitn(3, '$').collect();
1043 assert_eq!(parts[0], "100000");
1044 assert!(hasher.verify("secret", &hash).unwrap());
1045 }
1046
1047 #[test]
1048 fn test_pbkdf2_hasher_empty_password() {
1049 let hasher = Pbkdf2Hasher::new();
1050 assert!(hasher.hash("").is_err());
1051 }
1052
1053 #[test]
1056 fn test_hmac_signer_sign_not_empty() {
1057 let signer = HmacSigner::new();
1058 let mut params = HashMap::new();
1059 params.insert("name".to_string(), "test".to_string());
1060 let signature = signer.sign(¶ms, "secret123");
1061 assert_eq!(signature.len(), 64);
1062 }
1063
1064 #[test]
1065 fn test_hmac_signer_verify_correct() {
1066 let signer = HmacSigner::new();
1067 let mut params = HashMap::new();
1068 params.insert("name".to_string(), "test".to_string());
1069 params.insert("age".to_string(), "25".to_string());
1070
1071 let signature = signer.sign(¶ms, "mysecret");
1072 assert!(signer.verify(¶ms, "mysecret", &signature));
1073 }
1074
1075 #[test]
1076 fn test_hmac_signer_verify_wrong_secret() {
1077 let signer = HmacSigner::new();
1078 let mut params = HashMap::new();
1079 params.insert("name".to_string(), "test".to_string());
1080 let signature = signer.sign(¶ms, "correctsecret");
1081 assert!(!signer.verify(¶ms, "wrongsecret", &signature));
1082 }
1083
1084 #[test]
1085 fn test_hmac_signer_verify_wrong_signature() {
1086 let signer = HmacSigner::new();
1087 let mut params = HashMap::new();
1088 params.insert("name".to_string(), "test".to_string());
1089 let valid_sig = signer.sign(¶ms, "secret");
1090 let tampered = if let Some(stripped) = valid_sig.strip_prefix('0') {
1091 format!("1{}", stripped)
1092 } else {
1093 format!("0{}", &valid_sig[1..])
1094 };
1095 assert!(!signer.verify(¶ms, "secret", &tampered));
1096 }
1097
1098 #[test]
1099 fn test_hmac_signer_different_params_different_signatures() {
1100 let signer = HmacSigner::new();
1101 let mut params1 = HashMap::new();
1102 params1.insert("a".to_string(), "1".to_string());
1103
1104 let mut params2 = HashMap::new();
1105 params2.insert("b".to_string(), "2".to_string());
1106
1107 let sig1 = signer.sign(¶ms1, "secret");
1108 let sig2 = signer.sign(¶ms2, "secret");
1109 assert_ne!(sig1, sig2);
1110 }
1111
1112 #[test]
1113 fn test_hmac_signer_param_order_independent() {
1114 let signer = HmacSigner::new();
1115 let mut params1 = HashMap::new();
1116 params1.insert("b".to_string(), "2".to_string());
1117 params1.insert("a".to_string(), "1".to_string());
1118
1119 let mut params2 = HashMap::new();
1120 params2.insert("a".to_string(), "1".to_string());
1121 params2.insert("b".to_string(), "2".to_string());
1122
1123 let sig1 = signer.sign(¶ms1, "secret");
1124 let sig2 = signer.sign(¶ms2, "secret");
1125 assert_eq!(sig1, sig2);
1126 }
1127
1128 #[test]
1129 fn test_hmac_signer_empty_params() {
1130 let signer = HmacSigner::new();
1131 let params = HashMap::new();
1132 let sig = signer.sign(¶ms, "secret");
1133 assert_eq!(sig.len(), 64);
1134 assert!(signer.verify(¶ms, "secret", &sig));
1135 }
1136
1137 #[test]
1140 fn test_random_bytes_length() {
1141 assert_eq!(random_bytes(0).len(), 0);
1142 assert_eq!(random_bytes(16).len(), 16);
1143 assert_eq!(random_bytes(100).len(), 100);
1144 }
1145
1146 #[test]
1147 fn test_random_bytes_random() {
1148 let a = random_bytes(32);
1149 let b = random_bytes(32);
1150 assert_ne!(a, b, "随机字节序列应不同");
1151 }
1152
1153 #[test]
1154 fn test_constant_time_eq() {
1155 assert!(constant_time_eq(b"abc", b"abc"));
1156 assert!(!constant_time_eq(b"abc", b"abd"));
1157 assert!(!constant_time_eq(b"abc", b"ab"));
1158 assert!(!constant_time_eq(b"abc", b"abcd"));
1159 assert!(constant_time_eq(b"", b""));
1160 }
1161
1162 #[test]
1163 fn test_hex_encode_decode_roundtrip() {
1164 let original = vec![0x00, 0xff, 0xab, 0x42];
1165 let encoded = hex_encode(&original);
1166 let decoded = hex_decode(&encoded).unwrap();
1167 assert_eq!(decoded, original);
1168 }
1169
1170 #[test]
1171 fn test_hex_decode_invalid() {
1172 assert!(hex_decode("abc").is_err());
1173 assert!(hex_decode("xy").is_err());
1174 }
1175
1176 #[test]
1179 fn test_aes_gcm_aad_roundtrip() {
1180 let key = [0x42u8; 32];
1181 let crypter = AesGcmCrypter::new(&key);
1182 let plaintext = b"sensitive data";
1183 let aad = b"associated metadata";
1184 let encrypted = crypter.encrypt_with_aad(plaintext, aad).unwrap();
1185 let decrypted = crypter.decrypt_with_aad(&encrypted, aad).unwrap();
1186 assert_eq!(decrypted, plaintext);
1187 }
1188
1189 #[test]
1190 fn test_aes_gcm_aad_wrong_aad_fails() {
1191 let key = [0x42u8; 32];
1192 let crypter = AesGcmCrypter::new(&key);
1193 let plaintext = b"sensitive data";
1194 let aad = b"correct aad";
1195 let encrypted = crypter.encrypt_with_aad(plaintext, aad).unwrap();
1196 let result = crypter.decrypt_with_aad(&encrypted, b"wrong aad");
1198 assert!(result.is_err());
1199 }
1200
1201 #[test]
1202 fn test_aes_gcm_aad_empty_aad_equivalent_to_no_aad() {
1203 let key = [0x42u8; 32];
1204 let crypter = AesGcmCrypter::new(&key);
1205 let plaintext = b"test data";
1206 let encrypted_no_aad = crypter.encrypt(plaintext).unwrap();
1208 let encrypted_empty_aad = crypter.encrypt_with_aad(plaintext, b"").unwrap();
1209 assert_eq!(crypter.decrypt(&encrypted_no_aad).unwrap(), plaintext);
1211 assert_eq!(
1212 crypter.decrypt_with_aad(&encrypted_empty_aad, b"").unwrap(),
1213 plaintext
1214 );
1215 }
1216
1217 #[test]
1218 fn test_aes_gcm_aad_tampered_ciphertext_fails() {
1219 let key = [0x42u8; 32];
1220 let crypter = AesGcmCrypter::new(&key);
1221 let encrypted = crypter.encrypt_with_aad(b"data", b"aad").unwrap();
1222 let mut tampered = encrypted.clone();
1223 tampered[15] ^= 0x01;
1224 assert!(crypter.decrypt_with_aad(&tampered, b"aad").is_err());
1225 }
1226
1227 #[test]
1228 fn test_aes_gcm_aad_empty_plaintext() {
1229 let key = [0x42u8; 32];
1230 let crypter = AesGcmCrypter::new(&key);
1231 let encrypted = crypter.encrypt_with_aad(b"", b"aad").unwrap();
1232 assert_eq!(encrypted.len(), 28);
1234 let decrypted = crypter.decrypt_with_aad(&encrypted, b"aad").unwrap();
1235 assert_eq!(decrypted, b"");
1236 }
1237
1238 #[test]
1241 fn test_rsa_oaep_roundtrip() {
1242 let crypter = RsaOaepCrypter::generate(2048).expect("RSA key generation");
1243 let plaintext = b"Hello, RSA-OAEP!";
1244 let encrypted = crypter.encrypt(plaintext).unwrap();
1245 let decrypted = crypter.decrypt(&encrypted).unwrap();
1246 assert_eq!(decrypted, plaintext);
1247 }
1248
1249 #[test]
1250 fn test_rsa_oaep_different_ciphertexts_same_plaintext() {
1251 let crypter = RsaOaepCrypter::generate(2048).unwrap();
1252 let plaintext = b"same message";
1253 let enc1 = crypter.encrypt(plaintext).unwrap();
1254 let enc2 = crypter.encrypt(plaintext).unwrap();
1255 assert_ne!(enc1, enc2);
1257 assert_eq!(crypter.decrypt(&enc1).unwrap(), plaintext);
1259 assert_eq!(crypter.decrypt(&enc2).unwrap(), plaintext);
1260 }
1261
1262 #[test]
1263 fn test_rsa_oaep_empty_plaintext() {
1264 let crypter = RsaOaepCrypter::generate(2048).unwrap();
1265 let encrypted = crypter.encrypt(b"").unwrap();
1266 let decrypted = crypter.decrypt(&encrypted).unwrap();
1267 assert_eq!(decrypted, b"");
1268 }
1269
1270 #[test]
1271 fn test_rsa_oaep_tampered_ciphertext_fails() {
1272 let crypter = RsaOaepCrypter::generate(2048).unwrap();
1273 let encrypted = crypter.encrypt(b"secret").unwrap();
1274 let mut tampered = encrypted.clone();
1275 tampered[0] ^= 0x01;
1276 assert!(crypter.decrypt(&tampered).is_err());
1277 }
1278
1279 #[test]
1280 fn test_rsa_oaep_max_message_length() {
1281 let crypter = RsaOaepCrypter::generate(2048).unwrap();
1283 let plaintext = vec![0xABu8; 190];
1284 let encrypted = crypter.encrypt(&plaintext).unwrap();
1285 let decrypted = crypter.decrypt(&encrypted).unwrap();
1286 assert_eq!(decrypted, plaintext);
1287 }
1288
1289 #[test]
1290 fn test_rsa_oaep_oversized_message_fails() {
1291 let crypter = RsaOaepCrypter::generate(2048).unwrap();
1292 let plaintext = vec![0xABu8; 191];
1294 assert!(crypter.encrypt(&plaintext).is_err());
1295 }
1296
1297 #[test]
1298 fn test_rsa_oaep_from_keys() {
1299 let crypter1 = RsaOaepCrypter::generate(2048).unwrap();
1300 let crypter2 = RsaOaepCrypter::from_keys(
1301 crypter1.public_key().clone(),
1302 crypter1.private_key().clone(),
1303 );
1304 let plaintext = b"test from_keys";
1305 let encrypted = crypter2.encrypt(plaintext).unwrap();
1306 let decrypted = crypter2.decrypt(&encrypted).unwrap();
1307 assert_eq!(decrypted, plaintext);
1308 }
1309
1310 #[test]
1311 fn test_rsa_oaep_crypter_trait() {
1312 let crypter = RsaOaepCrypter::generate(2048).unwrap();
1313 let plaintext = b"trait test";
1314 let encrypted = Crypter::encrypt(&crypter, plaintext).unwrap();
1315 let decrypted = Crypter::decrypt(&crypter, &encrypted).unwrap();
1316 assert_eq!(decrypted, plaintext);
1317 }
1318
1319 #[test]
1322 fn test_hmac_signature_verifier_sign_verify() {
1323 let verifier = HmacSignatureVerifier::new(b"my-secret-key");
1324 let message = b"important message";
1325 let signature = verifier.sign(message);
1326 assert_eq!(signature.len(), 32);
1327 assert!(verifier.verify(message, &signature));
1328 }
1329
1330 #[test]
1331 fn test_hmac_signature_verifier_wrong_message() {
1332 let verifier = HmacSignatureVerifier::new(b"key");
1333 let signature = verifier.sign(b"message1");
1334 assert!(!verifier.verify(b"message2", &signature));
1335 }
1336
1337 #[test]
1338 fn test_hmac_signature_verifier_wrong_signature() {
1339 let verifier = HmacSignatureVerifier::new(b"key");
1340 let signature = verifier.sign(b"message");
1341 let mut tampered = signature.clone();
1342 tampered[0] ^= 0x01;
1343 assert!(!verifier.verify(b"message", &tampered));
1344 }
1345
1346 #[test]
1347 fn test_hmac_signature_verifier_from_key_str() {
1348 let verifier = HmacSignatureVerifier::from_key_str("string-key");
1349 let message = b"test";
1350 let sig = verifier.sign(message);
1351 assert!(verifier.verify(message, &sig));
1352 }
1353
1354 #[test]
1355 fn test_hmac_signature_verifier_different_keys_different_signatures() {
1356 let v1 = HmacSignatureVerifier::new(b"key1");
1357 let v2 = HmacSignatureVerifier::new(b"key2");
1358 let message = b"same message";
1359 let sig1 = v1.sign(message);
1360 let sig2 = v2.sign(message);
1361 assert_ne!(sig1, sig2);
1362 }
1363
1364 #[test]
1365 fn test_hmac_signature_verifier_empty_message() {
1366 let verifier = HmacSignatureVerifier::new(b"key");
1367 let sig = verifier.sign(b"");
1368 assert_eq!(sig.len(), 32);
1369 assert!(verifier.verify(b"", &sig));
1370 }
1371
1372 #[test]
1373 fn test_hmac_signature_verifier_wrong_length_signature() {
1374 let verifier = HmacSignatureVerifier::new(b"key");
1375 assert!(!verifier.verify(b"message", b"short"));
1377 assert!(!verifier.verify(b"message", &[]));
1378 }
1379
1380 #[test]
1383 fn test_key_rotation_initial_key() {
1384 let mgr = KeyRotationManager::with_initial_key(b"key-v1".to_vec());
1385 assert_eq!(mgr.current_version(), 1);
1386 assert_eq!(mgr.version_count(), 1);
1387 assert_eq!(mgr.versions(), vec![1]);
1388 }
1389
1390 #[test]
1391 fn test_key_rotation_sign_verify_current() {
1392 let mgr = KeyRotationManager::with_initial_key(b"secret-key".to_vec());
1393 let message = b"test message";
1394 let (version, signature) = mgr.sign(message);
1395 assert_eq!(version, 1);
1396 assert!(mgr.verify(message, version, &signature));
1397 }
1398
1399 #[test]
1400 fn test_key_rotation_old_version_still_valid() {
1401 let mut mgr = KeyRotationManager::with_initial_key(b"key-v1".to_vec());
1402 let message = b"persistent message";
1403 let (v1, sig1) = mgr.sign(message);
1404 mgr.rotate_key(b"key-v2".to_vec());
1406 let (v2, sig2) = mgr.sign(message);
1407 assert_eq!(v1, 1);
1408 assert_eq!(v2, 2);
1409 assert!(mgr.verify(message, v1, &sig1));
1411 assert!(mgr.verify(message, v2, &sig2));
1413 }
1414
1415 #[test]
1416 fn test_key_rotation_max_versions_evicts_oldest() {
1417 let mut mgr = KeyRotationManager::new(2);
1418 mgr.rotate_key(b"key-v1".to_vec());
1419 mgr.rotate_key(b"key-v2".to_vec());
1420 assert_eq!(mgr.version_count(), 2);
1421 mgr.rotate_key(b"key-v3".to_vec());
1423 assert_eq!(mgr.version_count(), 2);
1424 assert_eq!(mgr.versions(), vec![2, 3]);
1425 assert!(!mgr.versions().contains(&1));
1426 }
1427
1428 #[test]
1429 fn test_key_rotation_old_version_evicted_fails_verify() {
1430 let mut mgr = KeyRotationManager::new(2);
1431 mgr.rotate_key(b"key-v1".to_vec());
1432 let message = b"test";
1433 let (v1, sig1) = mgr.sign(message);
1434 mgr.rotate_key(b"key-v2".to_vec());
1435 mgr.rotate_key(b"key-v3".to_vec());
1436 assert!(!mgr.verify(message, v1, &sig1));
1438 }
1439
1440 #[test]
1441 fn test_key_rotation_wrong_version_fails() {
1442 let mgr = KeyRotationManager::with_initial_key(b"key".to_vec());
1443 let message = b"test";
1444 let (_, signature) = mgr.sign(message);
1445 assert!(!mgr.verify(message, 999, &signature));
1447 }
1448
1449 #[test]
1450 fn test_key_rotation_multiple_rotations() {
1451 let mut mgr = KeyRotationManager::new(5);
1452 for i in 1..=4 {
1453 let key = format!("key-v{}", i);
1454 let version = mgr.rotate_key(key.as_bytes().to_vec());
1455 assert_eq!(version, i as u32);
1456 }
1457 assert_eq!(mgr.current_version(), 4);
1458 assert_eq!(mgr.version_count(), 4);
1459 assert_eq!(mgr.versions(), vec![1, 2, 3, 4]);
1460 }
1461
1462 #[test]
1463 fn test_key_rotation_empty_manager_sign_returns_zero() {
1464 let mgr = KeyRotationManager::new(3);
1465 let (version, sig) = mgr.sign(b"message");
1466 assert_eq!(version, 0);
1467 assert!(sig.is_empty());
1468 }
1469
1470 #[test]
1471 fn test_key_rotation_verify_with_wrong_signature() {
1472 let mgr = KeyRotationManager::with_initial_key(b"key".to_vec());
1473 let message = b"test";
1474 let (version, _) = mgr.sign(message);
1475 let wrong_sig = vec![0u8; 32];
1476 assert!(!mgr.verify(message, version, &wrong_sig));
1477 }
1478
1479 #[test]
1480 fn test_key_rotation_max_versions_min_one() {
1481 let mut mgr = KeyRotationManager::new(0);
1483 mgr.rotate_key(b"k1".to_vec());
1484 mgr.rotate_key(b"k2".to_vec());
1485 assert_eq!(mgr.version_count(), 1);
1486 assert_eq!(mgr.versions(), vec![2]);
1487 }
1488
1489 #[test]
1492 fn test_key_manager_initial_key() {
1493 let mgr = KeyManager::new(b"initial-key".to_vec());
1494 let current = mgr.current_key();
1495 assert_eq!(current.version, 1);
1496 assert_eq!(current.key, b"initial-key");
1497 assert_eq!(mgr.previous_count(), 0);
1498 }
1499
1500 #[test]
1501 fn test_key_manager_rotate_increments_version() {
1502 let mgr = KeyManager::new(b"v1".to_vec());
1503 assert!(mgr.rotate(b"v2".to_vec()).is_ok());
1504 let current = mgr.current_key();
1505 assert_eq!(current.version, 2);
1506 assert_eq!(current.key, b"v2");
1507 assert_eq!(mgr.previous_count(), 1);
1508 }
1509
1510 #[test]
1511 fn test_key_manager_key_by_version_current() {
1512 let mgr = KeyManager::new(b"v1".to_vec());
1513 let found = mgr.key_by_version(1).expect("v1 should exist");
1514 assert_eq!(found.key, b"v1");
1515 }
1516
1517 #[test]
1518 fn test_key_manager_key_by_version_previous() {
1519 let mgr = KeyManager::new(b"v1".to_vec());
1520 mgr.rotate(b"v2".to_vec()).unwrap();
1521 let old = mgr.key_by_version(1).expect("v1 should still be retained");
1523 assert_eq!(old.key, b"v1");
1524 let new = mgr.key_by_version(2).expect("v2 should exist");
1526 assert_eq!(new.key, b"v2");
1527 }
1528
1529 #[test]
1530 fn test_key_manager_key_by_version_not_found() {
1531 let mgr = KeyManager::new(b"v1".to_vec());
1532 assert!(mgr.key_by_version(999).is_none());
1533 }
1534
1535 #[test]
1536 fn test_key_manager_retains_at_most_three_previous() {
1537 let mgr = KeyManager::new(b"v1".to_vec());
1538 mgr.rotate(b"v2".to_vec()).unwrap();
1539 mgr.rotate(b"v3".to_vec()).unwrap();
1540 mgr.rotate(b"v4".to_vec()).unwrap();
1541 assert_eq!(mgr.previous_count(), 3);
1543 mgr.rotate(b"v5".to_vec()).unwrap();
1544 assert_eq!(mgr.previous_count(), 3);
1545 assert!(mgr.key_by_version(1).is_none());
1547 assert!(mgr.key_by_version(2).is_some());
1549 assert_eq!(mgr.current_key().version, 5);
1551 }
1552
1553 #[test]
1554 fn test_key_manager_needs_rotation_false_initially() {
1555 let mgr = KeyManager::new(b"k".to_vec());
1556 assert!(!mgr.needs_rotation());
1558 }
1559
1560 #[test]
1561 fn test_key_manager_needs_rotation_true_after_interval() {
1562 let mgr = KeyManager::new(b"k".to_vec()).with_rotation_interval(Duration::from_millis(0));
1563 std::thread::sleep(Duration::from_millis(1));
1565 assert!(mgr.needs_rotation());
1566 }
1567
1568 #[test]
1569 fn test_key_manager_with_rotation_interval() {
1570 let mgr = KeyManager::new(b"k".to_vec()).with_rotation_interval(Duration::from_secs(60));
1571 assert!(!mgr.needs_rotation());
1572 }
1573
1574 #[test]
1575 fn test_key_manager_rotate_resets_last_rotation() {
1576 let mgr = KeyManager::new(b"k".to_vec()).with_rotation_interval(Duration::from_millis(1));
1577 std::thread::sleep(Duration::from_millis(5));
1578 assert!(mgr.needs_rotation());
1579 mgr.rotate(b"k2".to_vec()).unwrap();
1580 assert!(!mgr.needs_rotation());
1582 }
1583
1584 #[test]
1585 fn test_key_manager_concurrent_access() {
1586 use std::sync::Arc;
1587 use std::thread;
1588 let mgr = Arc::new(KeyManager::new(b"base".to_vec()));
1589 let mut handles = vec![];
1590 for _ in 0..4 {
1592 let m = mgr.clone();
1593 handles.push(thread::spawn(move || {
1594 let _ = m.current_key();
1595 let _ = m.previous_count();
1596 }));
1597 }
1598 for h in handles {
1599 h.join().expect("thread panicked");
1600 }
1601 assert_eq!(mgr.current_key().version, 1);
1603 }
1604}