1use crate::{store::KeyStoreContext, CryptoError, EncString, KeyId, KeyIds};
2
3pub trait Encryptable<Ids: KeyIds, Key: KeyId, Output> {
7 fn encrypt(&self, ctx: &mut KeyStoreContext<Ids>, key: Key) -> Result<Output, CryptoError>;
8}
9
10impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for &[u8] {
11 fn encrypt(
12 &self,
13 ctx: &mut KeyStoreContext<Ids>,
14 key: Ids::Symmetric,
15 ) -> Result<EncString, CryptoError> {
16 ctx.encrypt_data_with_symmetric_key(key, self)
17 }
18}
19
20impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for Vec<u8> {
21 fn encrypt(
22 &self,
23 ctx: &mut KeyStoreContext<Ids>,
24 key: Ids::Symmetric,
25 ) -> Result<EncString, CryptoError> {
26 ctx.encrypt_data_with_symmetric_key(key, self)
27 }
28}
29
30impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for &str {
31 fn encrypt(
32 &self,
33 ctx: &mut KeyStoreContext<Ids>,
34 key: Ids::Symmetric,
35 ) -> Result<EncString, CryptoError> {
36 self.as_bytes().encrypt(ctx, key)
37 }
38}
39
40impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for String {
41 fn encrypt(
42 &self,
43 ctx: &mut KeyStoreContext<Ids>,
44 key: Ids::Symmetric,
45 ) -> Result<EncString, CryptoError> {
46 self.as_bytes().encrypt(ctx, key)
47 }
48}
49
50impl<Ids: KeyIds, Key: KeyId, T: Encryptable<Ids, Key, Output>, Output>
51 Encryptable<Ids, Key, Option<Output>> for Option<T>
52{
53 fn encrypt(
54 &self,
55 ctx: &mut KeyStoreContext<Ids>,
56 key: Key,
57 ) -> Result<Option<Output>, CryptoError> {
58 self.as_ref()
59 .map(|value| value.encrypt(ctx, key))
60 .transpose()
61 }
62}
63
64impl<Ids: KeyIds, Key: KeyId, T: Encryptable<Ids, Key, Output>, Output>
65 Encryptable<Ids, Key, Vec<Output>> for Vec<T>
66{
67 fn encrypt(
68 &self,
69 ctx: &mut KeyStoreContext<Ids>,
70 key: Key,
71 ) -> Result<Vec<Output>, CryptoError> {
72 self.iter().map(|value| value.encrypt(ctx, key)).collect()
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use crate::{
79 traits::tests::*, AsymmetricCryptoKey, Decryptable, Encryptable, KeyStore,
80 SymmetricCryptoKey,
81 };
82
83 fn test_store() -> KeyStore<TestIds> {
84 let store = KeyStore::<TestIds>::default();
85
86 let symm_key = SymmetricCryptoKey::make_aes256_cbc_hmac_key();
87 let asymm_key = AsymmetricCryptoKey::generate(&mut rand::thread_rng());
88
89 #[allow(deprecated)]
90 store
91 .context_mut()
92 .set_symmetric_key(TestSymmKey::A(0), symm_key.clone())
93 .unwrap();
94 #[allow(deprecated)]
95 store
96 .context_mut()
97 .set_asymmetric_key(TestAsymmKey::A(0), asymm_key.clone())
98 .unwrap();
99
100 store
101 }
102
103 #[test]
104 fn test_encryptable_bytes() {
105 let store = test_store();
106 let mut ctx = store.context();
107 let key = TestSymmKey::A(0);
108
109 let vec_data = vec![1, 2, 3, 4, 5];
110 let slice_data: &[u8] = &vec_data;
111
112 let vec_encrypted = vec_data.encrypt(&mut ctx, key).unwrap();
113 let slice_encrypted = slice_data.encrypt(&mut ctx, key).unwrap();
114
115 let vec_decrypted: Vec<u8> = vec_encrypted.decrypt(&mut ctx, key).unwrap();
116 let slice_decrypted: Vec<u8> = slice_encrypted.decrypt(&mut ctx, key).unwrap();
117
118 assert_eq!(vec_data, vec_decrypted);
119 assert_eq!(slice_data, slice_decrypted);
120 }
121
122 #[test]
123 fn test_encryptable_string() {
124 let store = test_store();
125 let mut ctx = store.context();
126 let key = TestSymmKey::A(0);
127
128 let string_data = "Hello, World!".to_string();
129 let str_data: &str = string_data.as_str();
130
131 let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
132 let str_encrypted = str_data.encrypt(&mut ctx, key).unwrap();
133
134 let string_decrypted: String = string_encrypted.decrypt(&mut ctx, key).unwrap();
135 let str_decrypted: String = str_encrypted.decrypt(&mut ctx, key).unwrap();
136
137 assert_eq!(string_data, string_decrypted);
138 assert_eq!(str_data, str_decrypted);
139 }
140
141 #[test]
142 fn test_encryptable_option_some() {
143 let store = test_store();
144 let mut ctx = store.context();
145 let key = TestSymmKey::A(0);
146
147 let string_data = Some("Hello, World!".to_string());
148
149 let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
150
151 let string_decrypted: Option<String> = string_encrypted.decrypt(&mut ctx, key).unwrap();
152
153 assert_eq!(string_data, string_decrypted);
154 }
155
156 #[test]
157 fn test_encryptable_option_none() {
158 let store = test_store();
159 let mut ctx = store.context();
160
161 let key = TestSymmKey::A(0);
162 let none_data: Option<String> = None;
163 let string_encrypted = none_data.encrypt(&mut ctx, key).unwrap();
164 assert_eq!(string_encrypted, None);
165
166 let bad_key = TestSymmKey::B((0, 1));
169 let string_encrypted_bad = none_data.encrypt(&mut ctx, bad_key).unwrap();
170 assert_eq!(string_encrypted_bad, None);
171 }
172}