1#![warn(missing_docs)]
2pub mod aes_gcm;
33pub mod chacha20;
34pub mod traits;
35
36mod envelope;
37
38pub use aes_gcm::AesGcmEncryptor;
39pub use chacha20::ChaCha20Encryptor;
40pub use traits::{Algorithm, Encryptor};
41
42pub fn new_encryptor(key: &[u8], algorithm: Algorithm) -> Box<dyn Encryptor> {
61 match algorithm {
62 Algorithm::AesGcm => Box::new(AesGcmEncryptor::new(key)),
63 Algorithm::ChaCha20Poly1305 => Box::new(ChaCha20Encryptor::new(key)),
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn test_factory_aes_gcm() {
73 let encryptor = new_encryptor(b"secret-key", Algorithm::AesGcm);
74 assert_eq!(encryptor.algorithm(), Algorithm::AesGcm);
75
76 let plaintext = b"test";
77 let ciphertext = encryptor.encrypt(plaintext).unwrap();
78 let decrypted = encryptor.decrypt(&ciphertext).unwrap();
79 assert_eq!(decrypted, plaintext);
80 }
81
82 #[test]
83 fn test_factory_chacha20() {
84 let encryptor = new_encryptor(b"secret-key", Algorithm::ChaCha20Poly1305);
85 assert_eq!(encryptor.algorithm(), Algorithm::ChaCha20Poly1305);
86
87 let plaintext = b"test";
88 let ciphertext = encryptor.encrypt(plaintext).unwrap();
89 let decrypted = encryptor.decrypt(&ciphertext).unwrap();
90 assert_eq!(decrypted, plaintext);
91 }
92
93 #[test]
94 fn malformed_versioned_envelopes_are_rejected() {
95 use base64::{Engine, engine::general_purpose::STANDARD};
96
97 let encryptor = new_encryptor(b"secret-key", Algorithm::AesGcm);
98 let too_short = STANDARD.encode([1_u8, 1, 2, 3]);
99 let err = encryptor.decrypt(&too_short).unwrap_err();
100 assert_eq!(err.code(), rskit_errors::ErrorCode::InvalidFormat);
101
102 let mut bad_version = vec![0_u8, 1];
103 bad_version.extend_from_slice(&[0_u8; 44]);
104 let err = encryptor
105 .decrypt(&STANDARD.encode(bad_version))
106 .unwrap_err();
107 assert_eq!(err.code(), rskit_errors::ErrorCode::InvalidFormat);
108
109 let mut bad_algorithm = vec![1_u8, 99];
110 bad_algorithm.extend_from_slice(&[0_u8; 44]);
111 let err = encryptor
112 .decrypt(&STANDARD.encode(bad_algorithm))
113 .unwrap_err();
114 assert_eq!(err.code(), rskit_errors::ErrorCode::InvalidFormat);
115 }
116}