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