1use crate::{store::KeyStoreContext, ContentFormat, CryptoError, EncString, KeyId, KeyIds};
21
22pub trait CompositeEncryptable<Ids: KeyIds, Key: KeyId, Output> {
27 fn encrypt_composite(
30 &self,
31 ctx: &mut KeyStoreContext<Ids>,
32 key: Key,
33 ) -> Result<Output, CryptoError>;
34}
35
36impl<Ids: KeyIds, Key: KeyId, T: CompositeEncryptable<Ids, Key, Output>, Output>
37 CompositeEncryptable<Ids, Key, Option<Output>> for Option<T>
38{
39 fn encrypt_composite(
40 &self,
41 ctx: &mut KeyStoreContext<Ids>,
42 key: Key,
43 ) -> Result<Option<Output>, CryptoError> {
44 self.as_ref()
45 .map(|value| value.encrypt_composite(ctx, key))
46 .transpose()
47 }
48}
49
50impl<Ids: KeyIds, Key: KeyId, T: CompositeEncryptable<Ids, Key, Output>, Output>
51 CompositeEncryptable<Ids, Key, Vec<Output>> for Vec<T>
52{
53 fn encrypt_composite(
54 &self,
55 ctx: &mut KeyStoreContext<Ids>,
56 key: Key,
57 ) -> Result<Vec<Output>, CryptoError> {
58 self.iter()
59 .map(|value| value.encrypt_composite(ctx, key))
60 .collect()
61 }
62}
63
64pub trait PrimitiveEncryptable<Ids: KeyIds, Key: KeyId, Output> {
67 fn encrypt(&self, ctx: &mut KeyStoreContext<Ids>, key: Key) -> Result<Output, CryptoError>;
69}
70
71impl<Ids: KeyIds, Key: KeyId, T: PrimitiveEncryptable<Ids, Key, Output>, Output>
72 PrimitiveEncryptable<Ids, Key, Option<Output>> for Option<T>
73{
74 fn encrypt(
75 &self,
76 ctx: &mut KeyStoreContext<Ids>,
77 key: Key,
78 ) -> Result<Option<Output>, CryptoError> {
79 self.as_ref()
80 .map(|value| value.encrypt(ctx, key))
81 .transpose()
82 }
83}
84
85impl<Ids: KeyIds> PrimitiveEncryptable<Ids, Ids::Symmetric, EncString> for &str {
86 fn encrypt(
87 &self,
88 ctx: &mut KeyStoreContext<Ids>,
89 key: Ids::Symmetric,
90 ) -> Result<EncString, CryptoError> {
91 self.as_bytes().encrypt(ctx, key, ContentFormat::Utf8)
92 }
93}
94
95impl<Ids: KeyIds> PrimitiveEncryptable<Ids, Ids::Symmetric, EncString> for String {
96 fn encrypt(
97 &self,
98 ctx: &mut KeyStoreContext<Ids>,
99 key: Ids::Symmetric,
100 ) -> Result<EncString, CryptoError> {
101 self.as_bytes().encrypt(ctx, key, ContentFormat::Utf8)
102 }
103}
104
105pub(crate) trait PrimitiveEncryptableWithContentType<Ids: KeyIds, Key: KeyId, Output> {
108 fn encrypt(
110 &self,
111 ctx: &mut KeyStoreContext<Ids>,
112 key: Key,
113 content_format: ContentFormat,
114 ) -> Result<Output, CryptoError>;
115}
116
117impl<Ids: KeyIds> PrimitiveEncryptableWithContentType<Ids, Ids::Symmetric, EncString> for &[u8] {
118 fn encrypt(
119 &self,
120 ctx: &mut KeyStoreContext<Ids>,
121 key: Ids::Symmetric,
122 content_format: ContentFormat,
123 ) -> Result<EncString, CryptoError> {
124 ctx.encrypt_data_with_symmetric_key(key, self, content_format)
125 }
126}
127
128impl<Ids: KeyIds> PrimitiveEncryptableWithContentType<Ids, Ids::Symmetric, EncString> for Vec<u8> {
129 fn encrypt(
130 &self,
131 ctx: &mut KeyStoreContext<Ids>,
132 key: Ids::Symmetric,
133 content_format: ContentFormat,
134 ) -> Result<EncString, CryptoError> {
135 ctx.encrypt_data_with_symmetric_key(key, self, content_format)
136 }
137}
138
139impl<Ids: KeyIds, Key: KeyId, T: PrimitiveEncryptableWithContentType<Ids, Key, Output>, Output>
140 PrimitiveEncryptableWithContentType<Ids, Key, Option<Output>> for Option<T>
141{
142 fn encrypt(
143 &self,
144 ctx: &mut KeyStoreContext<Ids>,
145 key: Key,
146 content_format: crate::ContentFormat,
147 ) -> Result<Option<Output>, CryptoError> {
148 self.as_ref()
149 .map(|value| value.encrypt(ctx, key, content_format))
150 .transpose()
151 }
152}
153
154impl<Ids: KeyIds, Key: KeyId, T: PrimitiveEncryptableWithContentType<Ids, Key, Output>, Output>
155 PrimitiveEncryptableWithContentType<Ids, Key, Vec<Output>> for Vec<T>
156{
157 fn encrypt(
158 &self,
159 ctx: &mut KeyStoreContext<Ids>,
160 key: Key,
161 content_format: ContentFormat,
162 ) -> Result<Vec<Output>, CryptoError> {
163 self.iter()
164 .map(|value| value.encrypt(ctx, key, content_format))
165 .collect()
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use crate::{
172 traits::{encryptable::PrimitiveEncryptableWithContentType, tests::*},
173 AsymmetricCryptoKey, ContentFormat, Decryptable, KeyStore, PrimitiveEncryptable,
174 PublicKeyEncryptionAlgorithm, SymmetricCryptoKey,
175 };
176
177 fn test_store() -> KeyStore<TestIds> {
178 let store = KeyStore::<TestIds>::default();
179
180 let symm_key = SymmetricCryptoKey::make_aes256_cbc_hmac_key();
181 let asymm_key = AsymmetricCryptoKey::make(PublicKeyEncryptionAlgorithm::RsaOaepSha1);
182
183 #[allow(deprecated)]
184 store
185 .context_mut()
186 .set_symmetric_key(TestSymmKey::A(0), symm_key.clone())
187 .unwrap();
188 #[allow(deprecated)]
189 store
190 .context_mut()
191 .set_asymmetric_key(TestAsymmKey::A(0), asymm_key.clone())
192 .unwrap();
193
194 store
195 }
196
197 #[test]
198 fn test_encryptable_bytes() {
199 let store = test_store();
200 let mut ctx = store.context();
201 let key = TestSymmKey::A(0);
202
203 let vec_data = vec![1, 2, 3, 4, 5];
204 let slice_data: &[u8] = &vec_data;
205
206 let vec_encrypted = vec_data
207 .encrypt(&mut ctx, key, ContentFormat::OctetStream)
208 .unwrap();
209 let slice_encrypted = slice_data
210 .encrypt(&mut ctx, key, ContentFormat::OctetStream)
211 .unwrap();
212
213 let vec_decrypted: Vec<u8> = vec_encrypted.decrypt(&mut ctx, key).unwrap();
214 let slice_decrypted: Vec<u8> = slice_encrypted.decrypt(&mut ctx, key).unwrap();
215
216 assert_eq!(vec_data, vec_decrypted);
217 assert_eq!(slice_data, slice_decrypted);
218 }
219
220 #[test]
221 fn test_encryptable_string() {
222 let store = test_store();
223 let mut ctx = store.context();
224 let key = TestSymmKey::A(0);
225
226 let string_data = "Hello, World!".to_string();
227 let str_data: &str = string_data.as_str();
228
229 let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
230 let str_encrypted = str_data.encrypt(&mut ctx, key).unwrap();
231
232 let string_decrypted: String = string_encrypted.decrypt(&mut ctx, key).unwrap();
233 let str_decrypted: String = str_encrypted.decrypt(&mut ctx, key).unwrap();
234
235 assert_eq!(string_data, string_decrypted);
236 assert_eq!(str_data, str_decrypted);
237 }
238
239 #[test]
240 fn test_encryptable_option_some() {
241 let store = test_store();
242 let mut ctx = store.context();
243 let key = TestSymmKey::A(0);
244
245 let string_data = Some("Hello, World!".to_string());
246
247 let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
248
249 let string_decrypted: Option<String> = string_encrypted.decrypt(&mut ctx, key).unwrap();
250
251 assert_eq!(string_data, string_decrypted);
252 }
253
254 #[test]
255 fn test_encryptable_option_none() {
256 let store = test_store();
257 let mut ctx = store.context();
258
259 let key = TestSymmKey::A(0);
260 let none_data: Option<String> = None;
261 let string_encrypted = none_data.encrypt(&mut ctx, key).unwrap();
262 assert_eq!(string_encrypted, None);
263
264 let bad_key = TestSymmKey::B((0, 1));
267 let string_encrypted_bad = none_data.encrypt(&mut ctx, bad_key).unwrap();
268 assert_eq!(string_encrypted_bad, None);
269 }
270}