ave_actors_actor/helpers/
encrypted_key.rs1use std::sync::Arc;
2
3use memsecurity::EncryptedMem;
4use zeroize::Zeroizing;
5
6use crate::error::Error;
7
8#[derive(Clone)]
14pub struct EncryptedKey {
15 key: Arc<EncryptedMem>,
16}
17
18impl EncryptedKey {
19 pub fn new(key: &[u8; 32]) -> Result<Self, Error> {
24 let mut encrypted_mem = EncryptedMem::new();
25
26 encrypted_mem.encrypt(key).map_err(|_| {
27 tracing::error!("Key encryption failed");
28 Error::Helper {
29 name: "encryption".to_owned(),
30 reason: "Failed to encrypt key".to_owned(),
31 }
32 })?;
33
34 tracing::debug!("EncryptedKey created");
35 Ok(Self {
36 key: Arc::new(encrypted_mem),
37 })
38 }
39
40 pub fn key(&self) -> Result<Zeroizing<[u8; 32]>, Error> {
46 let decrypted = self.key.decrypt().map_err(|_| {
47 tracing::error!(
48 "Key decryption failed, possible memory corruption"
49 );
50 Error::Helper {
51 name: "decryption".to_owned(),
52 reason: "Failed to decrypt key".to_owned(),
53 }
54 })?;
55
56 let mut key_array = Zeroizing::new([0u8; 32]);
57 key_array.copy_from_slice(decrypted.as_ref());
58
59 tracing::debug!("Key accessed");
60 Ok(key_array)
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn test_encrypted_hash() {
70 let key = [1u8; 32];
71 let eh = EncryptedKey::new(&key).unwrap();
72 let key1 = eh.key().unwrap();
73 let eh_cloned = eh.clone();
74 let key2 = eh_cloned.key().unwrap();
75 assert_eq!(*key1, *key2);
76 }
77
78 #[test]
79 fn test_encrypted_hash_deterministic() {
80 let key = [42u8; 32];
82 let eh1 = EncryptedKey::new(&key).unwrap();
83 let eh2 = EncryptedKey::new(&key).unwrap();
84
85 let key1 = eh1.key().unwrap();
86 let key2 = eh2.key().unwrap();
87
88 assert_eq!(*key1, *key2);
89 }
90
91 #[test]
92 fn test_encrypted_hash_different() {
93 let key1_data = [1u8; 32];
95 let key2_data = [2u8; 32];
96 let eh1 = EncryptedKey::new(&key1_data).unwrap();
97 let eh2 = EncryptedKey::new(&key2_data).unwrap();
98
99 let key1 = eh1.key().unwrap();
100 let key2 = eh2.key().unwrap();
101
102 assert_ne!(*key1, *key2);
103 }
104
105 #[test]
106 fn test_key_access() {
107 let original = [123u8; 32];
108 let eh = EncryptedKey::new(&original).unwrap();
109 let decrypted = eh.key().unwrap();
110
111 assert_eq!(*decrypted, original);
113
114 let decrypted2 = eh.key().unwrap();
116 assert_eq!(*decrypted2, original);
117 }
118
119 #[test]
120 fn test_zeroizing() {
121 let original = [99u8; 32];
122 let eh = EncryptedKey::new(&original).unwrap();
123
124 {
125 let key = eh.key().unwrap();
126 assert_eq!(*key, original);
127 }
129
130 let key2 = eh.key().unwrap();
132 assert_eq!(*key2, original);
133 }
134
135 #[test]
136 fn test_clone_is_cheap() {
137 let original = [77u8; 32];
139 let eh = EncryptedKey::new(&original).unwrap();
140 let eh_clone = eh.clone();
141
142 assert_eq!(Arc::strong_count(&eh.key), 2);
144 assert_eq!(Arc::strong_count(&eh_clone.key), 2);
145
146 let key1 = eh.key().unwrap();
148 let key2 = eh_clone.key().unwrap();
149 assert_eq!(*key1, *key2);
150 }
151}