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