1use crate::{ContentFormat, CryptoError, EncString, KeySlotId, KeySlotIds, store::KeyStoreContext};
21
22pub trait CompositeEncryptable<Ids: KeySlotIds, Key: KeySlotId, Output> {
27 fn encrypt_composite(
36 &self,
37 ctx: &mut KeyStoreContext<Ids>,
38 key: Key,
39 ) -> Result<Output, CryptoError>;
40}
41
42impl<Ids: KeySlotIds, Key: KeySlotId, T: CompositeEncryptable<Ids, Key, Output>, Output>
43 CompositeEncryptable<Ids, Key, Option<Output>> for Option<T>
44{
45 fn encrypt_composite(
46 &self,
47 ctx: &mut KeyStoreContext<Ids>,
48 key: Key,
49 ) -> Result<Option<Output>, CryptoError> {
50 self.as_ref()
51 .map(|value| value.encrypt_composite(ctx, key))
52 .transpose()
53 }
54}
55
56impl<Ids: KeySlotIds, Key: KeySlotId, T: CompositeEncryptable<Ids, Key, Output>, Output>
57 CompositeEncryptable<Ids, Key, Vec<Output>> for Vec<T>
58{
59 fn encrypt_composite(
60 &self,
61 ctx: &mut KeyStoreContext<Ids>,
62 key: Key,
63 ) -> Result<Vec<Output>, CryptoError> {
64 self.iter()
65 .map(|value| value.encrypt_composite(ctx, key))
66 .collect()
67 }
68}
69
70pub trait PrimitiveEncryptable<Ids: KeySlotIds, Key: KeySlotId, Output> {
73 fn encrypt(&self, ctx: &mut KeyStoreContext<Ids>, key: Key) -> Result<Output, CryptoError>;
79}
80
81impl<Ids: KeySlotIds, Key: KeySlotId, T: PrimitiveEncryptable<Ids, Key, Output>, Output>
82 PrimitiveEncryptable<Ids, Key, Option<Output>> for Option<T>
83{
84 fn encrypt(
85 &self,
86 ctx: &mut KeyStoreContext<Ids>,
87 key: Key,
88 ) -> Result<Option<Output>, CryptoError> {
89 self.as_ref()
90 .map(|value| value.encrypt(ctx, key))
91 .transpose()
92 }
93}
94
95impl<Ids: KeySlotIds> PrimitiveEncryptable<Ids, Ids::Symmetric, EncString> for &str {
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
105impl<Ids: KeySlotIds> PrimitiveEncryptable<Ids, Ids::Symmetric, EncString> for String {
106 fn encrypt(
107 &self,
108 ctx: &mut KeyStoreContext<Ids>,
109 key: Ids::Symmetric,
110 ) -> Result<EncString, CryptoError> {
111 self.as_bytes().encrypt(ctx, key, ContentFormat::Utf8)
112 }
113}
114
115pub(crate) trait PrimitiveEncryptableWithContentType<Ids: KeySlotIds, Key: KeySlotId, Output> {
118 fn encrypt(
124 &self,
125 ctx: &mut KeyStoreContext<Ids>,
126 key: Key,
127 content_format: ContentFormat,
128 ) -> Result<Output, CryptoError>;
129}
130
131impl<Ids: KeySlotIds> PrimitiveEncryptableWithContentType<Ids, Ids::Symmetric, EncString>
132 for &[u8]
133{
134 fn encrypt(
135 &self,
136 ctx: &mut KeyStoreContext<Ids>,
137 key: Ids::Symmetric,
138 content_format: ContentFormat,
139 ) -> Result<EncString, CryptoError> {
140 ctx.encrypt_data_with_symmetric_key(key, self, content_format)
141 }
142}
143
144impl<Ids: KeySlotIds> PrimitiveEncryptableWithContentType<Ids, Ids::Symmetric, EncString>
145 for Vec<u8>
146{
147 fn encrypt(
148 &self,
149 ctx: &mut KeyStoreContext<Ids>,
150 key: Ids::Symmetric,
151 content_format: ContentFormat,
152 ) -> Result<EncString, CryptoError> {
153 ctx.encrypt_data_with_symmetric_key(key, self, content_format)
154 }
155}
156
157impl<
158 Ids: KeySlotIds,
159 Key: KeySlotId,
160 T: PrimitiveEncryptableWithContentType<Ids, Key, Output>,
161 Output,
162> PrimitiveEncryptableWithContentType<Ids, Key, Option<Output>> for Option<T>
163{
164 fn encrypt(
165 &self,
166 ctx: &mut KeyStoreContext<Ids>,
167 key: Key,
168 content_format: crate::ContentFormat,
169 ) -> Result<Option<Output>, CryptoError> {
170 self.as_ref()
171 .map(|value| value.encrypt(ctx, key, content_format))
172 .transpose()
173 }
174}
175
176impl<
177 Ids: KeySlotIds,
178 Key: KeySlotId,
179 T: PrimitiveEncryptableWithContentType<Ids, Key, Output>,
180 Output,
181> PrimitiveEncryptableWithContentType<Ids, Key, Vec<Output>> for Vec<T>
182{
183 fn encrypt(
184 &self,
185 ctx: &mut KeyStoreContext<Ids>,
186 key: Key,
187 content_format: ContentFormat,
188 ) -> Result<Vec<Output>, CryptoError> {
189 self.iter()
190 .map(|value| value.encrypt(ctx, key, content_format))
191 .collect()
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use crate::{
198 ContentFormat, Decryptable, KeyStore, PrimitiveEncryptable, PrivateKey,
199 PublicKeyEncryptionAlgorithm, SymmetricKeyAlgorithm,
200 traits::{encryptable::PrimitiveEncryptableWithContentType, tests::*},
201 };
202
203 fn test_store() -> KeyStore<TestIds> {
204 let store = KeyStore::<TestIds>::default();
205
206 let private_key = PrivateKey::make(PublicKeyEncryptionAlgorithm::RsaOaepSha1);
207
208 let mut ctx = store.context_mut();
209 let local_key_id = ctx.make_symmetric_key(SymmetricKeyAlgorithm::Aes256CbcHmac);
210 ctx.persist_symmetric_key(local_key_id, TestSymmKey::A(0))
211 .unwrap();
212 #[allow(deprecated)]
213 ctx.set_private_key(TestPrivateKey::A(0), private_key.clone())
214 .unwrap();
215 drop(ctx);
216
217 store
218 }
219
220 #[test]
221 fn test_encryptable_bytes() {
222 let store = test_store();
223 let mut ctx = store.context();
224 let key = TestSymmKey::A(0);
225
226 let vec_data = vec![1, 2, 3, 4, 5];
227 let slice_data: &[u8] = &vec_data;
228
229 let vec_encrypted = vec_data
230 .encrypt(&mut ctx, key, ContentFormat::OctetStream)
231 .unwrap();
232 let slice_encrypted = slice_data
233 .encrypt(&mut ctx, key, ContentFormat::OctetStream)
234 .unwrap();
235
236 let vec_decrypted: Vec<u8> = vec_encrypted.decrypt(&mut ctx, key).unwrap();
237 let slice_decrypted: Vec<u8> = slice_encrypted.decrypt(&mut ctx, key).unwrap();
238
239 assert_eq!(vec_data, vec_decrypted);
240 assert_eq!(slice_data, slice_decrypted);
241 }
242
243 #[test]
244 fn test_encryptable_string() {
245 let store = test_store();
246 let mut ctx = store.context();
247 let key = TestSymmKey::A(0);
248
249 let string_data = "Hello, World!".to_string();
250 let str_data: &str = string_data.as_str();
251
252 let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
253 let str_encrypted = str_data.encrypt(&mut ctx, key).unwrap();
254
255 let string_decrypted: String = string_encrypted.decrypt(&mut ctx, key).unwrap();
256 let str_decrypted: String = str_encrypted.decrypt(&mut ctx, key).unwrap();
257
258 assert_eq!(string_data, string_decrypted);
259 assert_eq!(str_data, str_decrypted);
260 }
261
262 #[test]
263 fn test_encryptable_option_some() {
264 let store = test_store();
265 let mut ctx = store.context();
266 let key = TestSymmKey::A(0);
267
268 let string_data = Some("Hello, World!".to_string());
269
270 let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
271
272 let string_decrypted: Option<String> = string_encrypted.decrypt(&mut ctx, key).unwrap();
273
274 assert_eq!(string_data, string_decrypted);
275 }
276
277 #[test]
278 fn test_encryptable_option_none() {
279 let store = test_store();
280 let mut ctx = store.context();
281
282 let key = TestSymmKey::A(0);
283 let none_data: Option<String> = None;
284 let string_encrypted = none_data.encrypt(&mut ctx, key).unwrap();
285 assert_eq!(string_encrypted, None);
286
287 let bad_key = TestSymmKey::B((0, 1));
290 let string_encrypted_bad = none_data.encrypt(&mut ctx, bad_key).unwrap();
291 assert_eq!(string_encrypted_bad, None);
292 }
293}