1use crate::{EventData, EventualiError, Result};
2use base64::{Engine as _, engine::general_purpose};
3use serde::{Deserialize, Serialize};
4use sha2::{Digest, Sha256};
5use std::collections::HashMap;
6
7pub struct EventEncryption {
9 key_manager: KeyManager,
10}
11
12#[derive(Debug, Clone)]
14pub struct KeyManager {
15 keys: HashMap<String, EncryptionKey>,
16 default_key_id: String,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct EncryptionKey {
22 pub id: String,
23 pub key_data: Vec<u8>, pub created_at: chrono::DateTime<chrono::Utc>,
25 pub algorithm: EncryptionAlgorithm,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
30pub enum EncryptionAlgorithm {
31 Aes256Gcm,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
36pub struct EncryptedEventData {
37 pub algorithm: EncryptionAlgorithm,
38 pub key_id: String,
39 pub iv: Vec<u8>,
40 pub encrypted_data: Vec<u8>,
41 pub tag: Vec<u8>,
42}
43
44impl EventEncryption {
45 pub fn new(key_manager: KeyManager) -> Self {
47 Self { key_manager }
48 }
49
50 pub fn with_key(key_id: String, key_data: Vec<u8>) -> Result<Self> {
52 let mut keys = HashMap::new();
53 let encryption_key = EncryptionKey {
54 id: key_id.clone(),
55 key_data,
56 created_at: chrono::Utc::now(),
57 algorithm: EncryptionAlgorithm::Aes256Gcm,
58 };
59 keys.insert(key_id.clone(), encryption_key);
60
61 let key_manager = KeyManager {
62 keys,
63 default_key_id: key_id,
64 };
65
66 Ok(Self::new(key_manager))
67 }
68
69 pub fn encrypt_event_data(&self, data: &EventData) -> Result<EncryptedEventData> {
71 self.encrypt_event_data_with_key(data, &self.key_manager.default_key_id)
72 }
73
74 pub fn encrypt_event_data_with_key(&self, data: &EventData, key_id: &str) -> Result<EncryptedEventData> {
76 let key = self.key_manager.get_key(key_id)?;
77 let plaintext = self.serialize_event_data(data)?;
78
79 let iv = self.generate_iv()?;
81
82 let (encrypted_data, tag) = self.encrypt_aes_256_gcm(&plaintext, &key.key_data, &iv)?;
84
85 Ok(EncryptedEventData {
86 algorithm: EncryptionAlgorithm::Aes256Gcm,
87 key_id: key_id.to_string(),
88 iv,
89 encrypted_data,
90 tag,
91 })
92 }
93
94 pub fn decrypt_event_data(&self, encrypted_data: &EncryptedEventData) -> Result<EventData> {
96 let key = self.key_manager.get_key(&encrypted_data.key_id)?;
97
98 match encrypted_data.algorithm {
99 EncryptionAlgorithm::Aes256Gcm => {
100 let plaintext = self.decrypt_aes_256_gcm(
101 &encrypted_data.encrypted_data,
102 &key.key_data,
103 &encrypted_data.iv,
104 &encrypted_data.tag,
105 )?;
106 self.deserialize_event_data(&plaintext)
107 }
108 }
109 }
110
111 fn serialize_event_data(&self, data: &EventData) -> Result<Vec<u8>> {
113 match data {
114 EventData::Json(value) => {
115 let json_string = serde_json::to_string(value)?;
116 Ok(json_string.into_bytes())
117 }
118 EventData::Protobuf(bytes) => Ok(bytes.clone()),
119 }
120 }
121
122 fn deserialize_event_data(&self, bytes: &[u8]) -> Result<EventData> {
124 if let Ok(json_str) = std::str::from_utf8(bytes) {
126 if let Ok(json_value) = serde_json::from_str(json_str) {
127 return Ok(EventData::Json(json_value));
128 }
129 }
130 Ok(EventData::Protobuf(bytes.to_vec()))
132 }
133
134 fn generate_iv(&self) -> Result<Vec<u8>> {
136 use std::time::{SystemTime, UNIX_EPOCH};
137
138 let timestamp = SystemTime::now()
140 .duration_since(UNIX_EPOCH)
141 .map_err(|e| EventualiError::Encryption(format!("Time error: {e}")))?
142 .as_nanos() as u64;
143
144 let mut iv = Vec::with_capacity(12);
145 iv.extend_from_slice(×tamp.to_be_bytes());
146
147 let random_seed = (timestamp.wrapping_mul(1103515245).wrapping_add(12345)) % (1u64 << 31);
149 iv.extend_from_slice(&(random_seed as u32).to_be_bytes());
150
151 Ok(iv)
152 }
153
154 fn encrypt_aes_256_gcm(&self, plaintext: &[u8], key: &[u8], iv: &[u8]) -> Result<(Vec<u8>, Vec<u8>)> {
156 use aes_gcm::{Aes256Gcm, KeyInit, Nonce};
157 use aes_gcm::aead::{Aead, generic_array::GenericArray};
158
159 let cipher = Aes256Gcm::new(GenericArray::from_slice(key));
160 let nonce = Nonce::from_slice(iv);
161
162 let ciphertext = cipher
163 .encrypt(nonce, plaintext)
164 .map_err(|e| EventualiError::Encryption(format!("AES-256-GCM encryption failed: {e}")))?;
165
166 let tag_start = ciphertext.len() - 16;
168 let encrypted_data = ciphertext[..tag_start].to_vec();
169 let tag = ciphertext[tag_start..].to_vec();
170
171 Ok((encrypted_data, tag))
172 }
173
174 fn decrypt_aes_256_gcm(&self, ciphertext: &[u8], key: &[u8], iv: &[u8], tag: &[u8]) -> Result<Vec<u8>> {
176 use aes_gcm::{Aes256Gcm, KeyInit, Nonce};
177 use aes_gcm::aead::{Aead, generic_array::GenericArray};
178
179 let cipher = Aes256Gcm::new(GenericArray::from_slice(key));
180 let nonce = Nonce::from_slice(iv);
181
182 let mut full_ciphertext = ciphertext.to_vec();
184 full_ciphertext.extend_from_slice(tag);
185
186 let plaintext = cipher
187 .decrypt(nonce, full_ciphertext.as_ref())
188 .map_err(|e| EventualiError::Encryption(format!("AES-256-GCM decryption failed: {e}")))?;
189
190 Ok(plaintext)
191 }
192}
193
194impl KeyManager {
195 pub fn new() -> Self {
197 Self {
198 keys: HashMap::new(),
199 default_key_id: String::new(),
200 }
201 }
202
203 pub fn add_key(&mut self, key: EncryptionKey) -> Result<()> {
205 if key.key_data.len() != 32 {
206 return Err(EventualiError::Encryption(
207 "AES-256 requires 32-byte keys".to_string()
208 ));
209 }
210
211 if self.keys.is_empty() {
212 self.default_key_id = key.id.clone();
213 }
214
215 self.keys.insert(key.id.clone(), key);
216 Ok(())
217 }
218
219 pub fn generate_key(id: String) -> Result<EncryptionKey> {
221 let key_data = Self::generate_random_key()?;
222 Ok(EncryptionKey {
223 id,
224 key_data,
225 created_at: chrono::Utc::now(),
226 algorithm: EncryptionAlgorithm::Aes256Gcm,
227 })
228 }
229
230 pub fn derive_key_from_password(id: String, password: &str, salt: &[u8]) -> Result<EncryptionKey> {
232 use pbkdf2::{pbkdf2_hmac};
233 use sha2::Sha256;
234
235 let mut key_data = [0u8; 32];
236 pbkdf2_hmac::<Sha256>(password.as_bytes(), salt, 100_000, &mut key_data);
237
238 Ok(EncryptionKey {
239 id,
240 key_data: key_data.to_vec(),
241 created_at: chrono::Utc::now(),
242 algorithm: EncryptionAlgorithm::Aes256Gcm,
243 })
244 }
245
246 pub fn get_key(&self, key_id: &str) -> Result<&EncryptionKey> {
248 self.keys.get(key_id).ok_or_else(|| {
249 EventualiError::Encryption(format!("Key not found: {key_id}"))
250 })
251 }
252
253 pub fn set_default_key(&mut self, key_id: &str) -> Result<()> {
255 if !self.keys.contains_key(key_id) {
256 return Err(EventualiError::Encryption(
257 format!("Key not found: {key_id}")
258 ));
259 }
260 self.default_key_id = key_id.to_string();
261 Ok(())
262 }
263
264 fn generate_random_key() -> Result<Vec<u8>> {
266 use std::time::{SystemTime, UNIX_EPOCH};
267
268 let timestamp = SystemTime::now()
270 .duration_since(UNIX_EPOCH)
271 .map_err(|e| EventualiError::Encryption(format!("Time error: {e}")))?
272 .as_nanos();
273
274 let mut hasher = Sha256::new();
276 hasher.update(timestamp.to_be_bytes());
277 hasher.update(b"eventuali-encryption-key");
278
279 let pid = std::process::id();
281 hasher.update(pid.to_be_bytes());
282
283 let stack_var: u64 = 42;
285 let stack_addr = &stack_var as *const u64 as usize;
286 hasher.update(stack_addr.to_be_bytes());
287
288 let key_hash = hasher.finalize();
289 Ok(key_hash.to_vec())
290 }
291}
292
293impl Default for KeyManager {
294 fn default() -> Self {
295 Self::new()
296 }
297}
298
299impl EncryptedEventData {
301 pub fn to_base64(&self) -> String {
303 let serialized = serde_json::to_vec(self).unwrap_or_default();
304 general_purpose::STANDARD.encode(serialized)
305 }
306
307 pub fn from_base64(data: &str) -> Result<Self> {
309 let bytes = general_purpose::STANDARD
310 .decode(data)
311 .map_err(|e| EventualiError::Encryption(format!("Base64 decode error: {e}")))?;
312
313 serde_json::from_slice(&bytes)
314 .map_err(EventualiError::from)
315 }
316}
317
318#[cfg(test)]
319mod tests {
320 use super::*;
321 use serde_json::json;
322
323 #[test]
324 fn test_key_generation() {
325 let key = KeyManager::generate_key("test-key".to_string()).unwrap();
326 assert_eq!(key.key_data.len(), 32);
327 assert_eq!(key.id, "test-key");
328 assert_eq!(key.algorithm, EncryptionAlgorithm::Aes256Gcm);
329 }
330
331 #[test]
332 fn test_password_key_derivation() {
333 let salt = b"test-salt";
334 let key = KeyManager::derive_key_from_password(
335 "test-key".to_string(),
336 "test-password",
337 salt
338 ).unwrap();
339
340 assert_eq!(key.key_data.len(), 32);
341
342 let key2 = KeyManager::derive_key_from_password(
344 "test-key-2".to_string(),
345 "test-password",
346 salt
347 ).unwrap();
348
349 assert_eq!(key.key_data, key2.key_data);
350 }
351
352 #[test]
353 fn test_json_encryption_decryption() {
354 let key = KeyManager::generate_key("test-key".to_string()).unwrap();
355 let encryption = EventEncryption::with_key("test-key".to_string(), key.key_data).unwrap();
356
357 let original_data = EventData::Json(json!({
358 "user_id": "user123",
359 "action": "create_order",
360 "amount": 100.50
361 }));
362
363 let encrypted = encryption.encrypt_event_data(&original_data).unwrap();
364 assert_eq!(encrypted.algorithm, EncryptionAlgorithm::Aes256Gcm);
365 assert_eq!(encrypted.key_id, "test-key");
366 assert_eq!(encrypted.iv.len(), 12);
367 assert!(!encrypted.encrypted_data.is_empty());
368 assert_eq!(encrypted.tag.len(), 16);
369
370 let decrypted = encryption.decrypt_event_data(&encrypted).unwrap();
371 assert_eq!(original_data, decrypted);
372 }
373
374 #[test]
375 fn test_protobuf_encryption_decryption() {
376 let key = KeyManager::generate_key("test-key".to_string()).unwrap();
377 let encryption = EventEncryption::with_key("test-key".to_string(), key.key_data).unwrap();
378
379 let original_data = EventData::Protobuf(vec![0x08, 0x96, 0x01, 0x12, 0x04, 0x74, 0x65, 0x73, 0x74]);
380
381 let encrypted = encryption.encrypt_event_data(&original_data).unwrap();
382 let decrypted = encryption.decrypt_event_data(&encrypted).unwrap();
383
384 assert_eq!(original_data, decrypted);
385 }
386
387 #[test]
388 fn test_multiple_keys() {
389 let mut key_manager = KeyManager::new();
390
391 let key1 = KeyManager::generate_key("key1".to_string()).unwrap();
392 let key2 = KeyManager::generate_key("key2".to_string()).unwrap();
393
394 key_manager.add_key(key1.clone()).unwrap();
395 key_manager.add_key(key2.clone()).unwrap();
396
397 let encryption = EventEncryption::new(key_manager);
398 let data = EventData::Json(json!({"test": "data"}));
399
400 let encrypted1 = encryption.encrypt_event_data_with_key(&data, "key1").unwrap();
401 let encrypted2 = encryption.encrypt_event_data_with_key(&data, "key2").unwrap();
402
403 assert_eq!(encrypted1.key_id, "key1");
404 assert_eq!(encrypted2.key_id, "key2");
405
406 let decrypted1 = encryption.decrypt_event_data(&encrypted1).unwrap();
407 let decrypted2 = encryption.decrypt_event_data(&encrypted2).unwrap();
408
409 assert_eq!(data, decrypted1);
410 assert_eq!(data, decrypted2);
411 }
412
413 #[test]
414 fn test_base64_serialization() {
415 let key = KeyManager::generate_key("test-key".to_string()).unwrap();
416 let encryption = EventEncryption::with_key("test-key".to_string(), key.key_data).unwrap();
417
418 let data = EventData::Json(json!({"test": "data"}));
419 let encrypted = encryption.encrypt_event_data(&data).unwrap();
420
421 let base64_str = encrypted.to_base64();
422 assert!(!base64_str.is_empty());
423
424 let deserialized = EncryptedEventData::from_base64(&base64_str).unwrap();
425 assert_eq!(encrypted, deserialized);
426
427 let decrypted = encryption.decrypt_event_data(&deserialized).unwrap();
428 assert_eq!(data, decrypted);
429 }
430}