1use crate::{ContentFormat, CryptoError, EncString, KeySlotId, KeySlotIds, store::KeyStoreContext};
36
37pub trait CompositeEncryptable<Ids: KeySlotIds, Key: KeySlotId, Output> {
42 fn encrypt_composite(
61 &self,
62 ctx: &mut KeyStoreContext<Ids>,
63 key: Key,
64 ) -> Result<Output, CryptoError>;
65}
66
67impl<Ids: KeySlotIds, Key: KeySlotId, T: CompositeEncryptable<Ids, Key, Output>, Output>
68 CompositeEncryptable<Ids, Key, Option<Output>> for Option<T>
69{
70 fn encrypt_composite(
71 &self,
72 ctx: &mut KeyStoreContext<Ids>,
73 key: Key,
74 ) -> Result<Option<Output>, CryptoError> {
75 self.as_ref()
76 .map(|value| value.encrypt_composite(ctx, key))
77 .transpose()
78 }
79}
80
81impl<Ids: KeySlotIds, Key: KeySlotId, T: CompositeEncryptable<Ids, Key, Output>, Output>
82 CompositeEncryptable<Ids, Key, Vec<Output>> for Vec<T>
83{
84 fn encrypt_composite(
85 &self,
86 ctx: &mut KeyStoreContext<Ids>,
87 key: Key,
88 ) -> Result<Vec<Output>, CryptoError> {
89 self.iter()
90 .map(|value| value.encrypt_composite(ctx, key))
91 .collect()
92 }
93}
94
95pub trait PrimitiveEncryptable<Ids: KeySlotIds, Key: KeySlotId, Output> {
98 fn encrypt(&self, ctx: &mut KeyStoreContext<Ids>, key: Key) -> Result<Output, CryptoError>;
111}
112
113impl<Ids: KeySlotIds, Key: KeySlotId, T: PrimitiveEncryptable<Ids, Key, Output>, Output>
114 PrimitiveEncryptable<Ids, Key, Option<Output>> for Option<T>
115{
116 fn encrypt(
117 &self,
118 ctx: &mut KeyStoreContext<Ids>,
119 key: Key,
120 ) -> Result<Option<Output>, CryptoError> {
121 self.as_ref()
122 .map(|value| value.encrypt(ctx, key))
123 .transpose()
124 }
125}
126
127impl<Ids: KeySlotIds> PrimitiveEncryptable<Ids, Ids::Symmetric, EncString> for &str {
128 fn encrypt(
129 &self,
130 ctx: &mut KeyStoreContext<Ids>,
131 key: Ids::Symmetric,
132 ) -> Result<EncString, CryptoError> {
133 self.as_bytes().encrypt(ctx, key, ContentFormat::Utf8)
134 }
135}
136
137impl<Ids: KeySlotIds> PrimitiveEncryptable<Ids, Ids::Symmetric, EncString> for String {
138 fn encrypt(
139 &self,
140 ctx: &mut KeyStoreContext<Ids>,
141 key: Ids::Symmetric,
142 ) -> Result<EncString, CryptoError> {
143 self.as_bytes().encrypt(ctx, key, ContentFormat::Utf8)
144 }
145}
146
147pub(crate) trait PrimitiveEncryptableWithContentType<Ids: KeySlotIds, Key: KeySlotId, Output> {
150 fn encrypt(
156 &self,
157 ctx: &mut KeyStoreContext<Ids>,
158 key: Key,
159 content_format: ContentFormat,
160 ) -> Result<Output, CryptoError>;
161}
162
163impl<Ids: KeySlotIds> PrimitiveEncryptableWithContentType<Ids, Ids::Symmetric, EncString>
164 for &[u8]
165{
166 fn encrypt(
167 &self,
168 ctx: &mut KeyStoreContext<Ids>,
169 key: Ids::Symmetric,
170 content_format: ContentFormat,
171 ) -> Result<EncString, CryptoError> {
172 ctx.encrypt_data_with_symmetric_key(key, self, content_format)
173 }
174}
175
176impl<Ids: KeySlotIds> PrimitiveEncryptableWithContentType<Ids, Ids::Symmetric, EncString>
177 for Vec<u8>
178{
179 fn encrypt(
180 &self,
181 ctx: &mut KeyStoreContext<Ids>,
182 key: Ids::Symmetric,
183 content_format: ContentFormat,
184 ) -> Result<EncString, CryptoError> {
185 ctx.encrypt_data_with_symmetric_key(key, self, content_format)
186 }
187}
188
189impl<
190 Ids: KeySlotIds,
191 Key: KeySlotId,
192 T: PrimitiveEncryptableWithContentType<Ids, Key, Output>,
193 Output,
194> PrimitiveEncryptableWithContentType<Ids, Key, Option<Output>> for Option<T>
195{
196 fn encrypt(
197 &self,
198 ctx: &mut KeyStoreContext<Ids>,
199 key: Key,
200 content_format: crate::ContentFormat,
201 ) -> Result<Option<Output>, CryptoError> {
202 self.as_ref()
203 .map(|value| value.encrypt(ctx, key, content_format))
204 .transpose()
205 }
206}
207
208impl<
209 Ids: KeySlotIds,
210 Key: KeySlotId,
211 T: PrimitiveEncryptableWithContentType<Ids, Key, Output>,
212 Output,
213> PrimitiveEncryptableWithContentType<Ids, Key, Vec<Output>> for Vec<T>
214{
215 fn encrypt(
216 &self,
217 ctx: &mut KeyStoreContext<Ids>,
218 key: Key,
219 content_format: ContentFormat,
220 ) -> Result<Vec<Output>, CryptoError> {
221 self.iter()
222 .map(|value| value.encrypt(ctx, key, content_format))
223 .collect()
224 }
225}
226
227#[cfg(test)]
228mod tests {
229 use crate::{
230 ContentFormat, Decryptable, KeyStore, PrimitiveEncryptable, PrivateKey,
231 PublicKeyEncryptionAlgorithm, SymmetricKeyAlgorithm,
232 traits::{encryptable::PrimitiveEncryptableWithContentType, tests::*},
233 };
234
235 fn test_store() -> KeyStore<TestIds> {
236 let store = KeyStore::<TestIds>::default();
237
238 let private_key = PrivateKey::make(PublicKeyEncryptionAlgorithm::RsaOaepSha1);
239
240 let mut ctx = store.context_mut();
241 let local_key_id = ctx.make_symmetric_key(SymmetricKeyAlgorithm::Aes256CbcHmac);
242 ctx.persist_symmetric_key(local_key_id, TestSymmKey::A(0))
243 .unwrap();
244 #[allow(deprecated)]
245 ctx.set_private_key(TestPrivateKey::A(0), private_key.clone())
246 .unwrap();
247 drop(ctx);
248
249 store
250 }
251
252 #[test]
253 fn test_encryptable_bytes() {
254 let store = test_store();
255 let mut ctx = store.context();
256 let key = TestSymmKey::A(0);
257
258 let vec_data = vec![1, 2, 3, 4, 5];
259 let slice_data: &[u8] = &vec_data;
260
261 let vec_encrypted = vec_data
262 .encrypt(&mut ctx, key, ContentFormat::OctetStream)
263 .unwrap();
264 let slice_encrypted = slice_data
265 .encrypt(&mut ctx, key, ContentFormat::OctetStream)
266 .unwrap();
267
268 let vec_decrypted: Vec<u8> = vec_encrypted.decrypt(&mut ctx, key).unwrap();
269 let slice_decrypted: Vec<u8> = slice_encrypted.decrypt(&mut ctx, key).unwrap();
270
271 assert_eq!(vec_data, vec_decrypted);
272 assert_eq!(slice_data, slice_decrypted);
273 }
274
275 #[test]
276 fn test_encryptable_string() {
277 let store = test_store();
278 let mut ctx = store.context();
279 let key = TestSymmKey::A(0);
280
281 let string_data = "Hello, World!".to_string();
282 let str_data: &str = string_data.as_str();
283
284 let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
285 let str_encrypted = str_data.encrypt(&mut ctx, key).unwrap();
286
287 let string_decrypted: String = string_encrypted.decrypt(&mut ctx, key).unwrap();
288 let str_decrypted: String = str_encrypted.decrypt(&mut ctx, key).unwrap();
289
290 assert_eq!(string_data, string_decrypted);
291 assert_eq!(str_data, str_decrypted);
292 }
293
294 #[test]
295 fn test_encryptable_option_some() {
296 let store = test_store();
297 let mut ctx = store.context();
298 let key = TestSymmKey::A(0);
299
300 let string_data = Some("Hello, World!".to_string());
301
302 let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
303
304 let string_decrypted: Option<String> = string_encrypted.decrypt(&mut ctx, key).unwrap();
305
306 assert_eq!(string_data, string_decrypted);
307 }
308
309 #[test]
310 fn test_encryptable_option_none() {
311 let store = test_store();
312 let mut ctx = store.context();
313
314 let key = TestSymmKey::A(0);
315 let none_data: Option<String> = None;
316 let string_encrypted = none_data.encrypt(&mut ctx, key).unwrap();
317 assert_eq!(string_encrypted, None);
318
319 let bad_key = TestSymmKey::B((0, 1));
322 let string_encrypted_bad = none_data.encrypt(&mut ctx, bad_key).unwrap();
323 assert_eq!(string_encrypted_bad, None);
324 }
325}