Skip to content

Commit cc1c27e

Browse files
committed
Add decryptable/encryptable tests
1 parent 4e6b707 commit cc1c27e

File tree

2 files changed

+227
-0
lines changed

2 files changed

+227
-0
lines changed

crates/bitwarden-crypto/src/traits/decryptable.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,75 @@ impl<Ids: KeyIds, Key: KeyId, T: Decryptable<Ids, Key, Output>, Output>
7474
self.iter().map(|value| value.decrypt(ctx, key)).collect()
7575
}
7676
}
77+
78+
#[cfg(test)]
79+
mod tests {
80+
use crate::{traits::tests::*, Decryptable, EncString, KeyStore, SymmetricCryptoKey};
81+
82+
fn test_store() -> KeyStore<TestIds> {
83+
let store = KeyStore::<TestIds>::default();
84+
85+
let key = SymmetricCryptoKey::try_from("sJnO8rVi0dTwND43n0T9x7665s8mVUYNAaJ4nm7gx1iia1I7947URL60nwfIHaf9QJePO4VkNN0oT9jh4iC6aA==".to_string()).unwrap();
86+
87+
#[allow(deprecated)]
88+
store
89+
.context_mut()
90+
.set_symmetric_key(TestSymmKey::A(0), key.clone())
91+
.unwrap();
92+
93+
store
94+
}
95+
96+
#[test]
97+
fn test_decryptable_bytes() {
98+
let store = test_store();
99+
let mut ctx = store.context();
100+
let key = TestSymmKey::A(0);
101+
102+
let data_encrypted: EncString = "2.kTtIypq9OLzd5iMMbU11pQ==|J4i3hTtGVdg7EZ+AQv/ujg==|QJpSpotQVpIW8j8dR/8l015WJzAIxBaOmrz4Uj/V1JA=".parse().unwrap();
103+
104+
let data_decrypted: Vec<u8> = data_encrypted.decrypt(&mut ctx, key).unwrap();
105+
assert_eq!(data_decrypted, &[1, 2, 3, 4, 5]);
106+
}
107+
108+
#[test]
109+
fn test_decryptable_string() {
110+
let store = test_store();
111+
let mut ctx = store.context();
112+
let key = TestSymmKey::A(0);
113+
114+
let data_encrypted: EncString = "2.fkvl0+sL1lwtiOn1eewsvQ==|dT0TynLl8YERZ8x7dxC+DQ==|cWhiRSYHOi/AA2LiV/JBJWbO9C7pbUpOM6TMAcV47hE=".parse().unwrap();
115+
116+
let data_decrypted: String = data_encrypted.decrypt(&mut ctx, key).unwrap();
117+
assert_eq!(data_decrypted, "Hello, World!");
118+
}
119+
120+
#[test]
121+
fn test_decryptable_option_some() {
122+
let store = test_store();
123+
let mut ctx = store.context();
124+
let key = TestSymmKey::A(0);
125+
126+
let data_encrypted: EncString = "2.fkvl0+sL1lwtiOn1eewsvQ==|dT0TynLl8YERZ8x7dxC+DQ==|cWhiRSYHOi/AA2LiV/JBJWbO9C7pbUpOM6TMAcV47hE=".parse().unwrap();
127+
let data_encrypted_some = Some(data_encrypted);
128+
129+
let string_decrypted: Option<String> = data_encrypted_some.decrypt(&mut ctx, key).unwrap();
130+
assert_eq!(string_decrypted, Some("Hello, World!".to_string()));
131+
}
132+
133+
#[test]
134+
fn test_decryptable_option_none() {
135+
let store = test_store();
136+
let mut ctx = store.context();
137+
138+
let key = TestSymmKey::A(0);
139+
let none_data: Option<EncString> = None;
140+
let string_decrypted: Option<String> = none_data.decrypt(&mut ctx, key).unwrap();
141+
assert_eq!(string_decrypted, None);
142+
143+
// The None implementation will not do any decrypt operations, so it won't fail even if the key doesn't exist
144+
let bad_key = TestSymmKey::B((0, 1));
145+
let string_decrypted_bad: Option<String> = none_data.decrypt(&mut ctx, bad_key).unwrap();
146+
assert_eq!(string_decrypted_bad, None);
147+
}
148+
}

crates/bitwarden-crypto/src/traits/encryptable.rs

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,26 @@ impl<Ids: KeyIds> Encryptable<Ids, Ids::Asymmetric, AsymmetricEncString> for &[u
2727
}
2828
}
2929

30+
impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for Vec<u8> {
31+
fn encrypt(
32+
&self,
33+
ctx: &mut KeyStoreContext<Ids>,
34+
key: Ids::Symmetric,
35+
) -> Result<EncString, CryptoError> {
36+
ctx.encrypt_data_with_symmetric_key(key, self)
37+
}
38+
}
39+
40+
impl<Ids: KeyIds> Encryptable<Ids, Ids::Asymmetric, AsymmetricEncString> for Vec<u8> {
41+
fn encrypt(
42+
&self,
43+
ctx: &mut KeyStoreContext<Ids>,
44+
key: Ids::Asymmetric,
45+
) -> Result<AsymmetricEncString, CryptoError> {
46+
ctx.encrypt_data_with_asymmetric_key(key, self)
47+
}
48+
}
49+
3050
impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for &str {
3151
fn encrypt(
3252
&self,
@@ -92,3 +112,138 @@ impl<Ids: KeyIds, Key: KeyId, T: Encryptable<Ids, Key, Output>, Output>
92112
self.iter().map(|value| value.encrypt(ctx, key)).collect()
93113
}
94114
}
115+
116+
#[cfg(test)]
117+
mod tests {
118+
use crate::{
119+
traits::tests::*, AsymmetricCryptoKey, Decryptable, Encryptable, KeyStore,
120+
SymmetricCryptoKey,
121+
};
122+
123+
fn test_store() -> KeyStore<TestIds> {
124+
let store = KeyStore::<TestIds>::default();
125+
126+
let symm_key = SymmetricCryptoKey::generate(rand::thread_rng());
127+
let asymm_key = AsymmetricCryptoKey::generate(&mut rand::thread_rng());
128+
129+
#[allow(deprecated)]
130+
store
131+
.context_mut()
132+
.set_symmetric_key(TestSymmKey::A(0), symm_key.clone())
133+
.unwrap();
134+
#[allow(deprecated)]
135+
store
136+
.context_mut()
137+
.set_asymmetric_key(TestAsymmKey::A(0), asymm_key.clone())
138+
.unwrap();
139+
140+
store
141+
}
142+
143+
#[test]
144+
fn test_encryptable_bytes() {
145+
let store = test_store();
146+
let mut ctx = store.context();
147+
let key = TestSymmKey::A(0);
148+
149+
let vec_data = vec![1, 2, 3, 4, 5];
150+
let slice_data: &[u8] = &vec_data;
151+
152+
let vec_encrypted = vec_data.encrypt(&mut ctx, key).unwrap();
153+
let slice_encrypted = slice_data.encrypt(&mut ctx, key).unwrap();
154+
155+
let vec_decrypted: Vec<u8> = vec_encrypted.decrypt(&mut ctx, key).unwrap();
156+
let slice_decrypted: Vec<u8> = slice_encrypted.decrypt(&mut ctx, key).unwrap();
157+
158+
assert_eq!(vec_data, vec_decrypted);
159+
assert_eq!(slice_data, slice_decrypted);
160+
}
161+
162+
#[test]
163+
fn test_encryptable_string() {
164+
let store = test_store();
165+
let mut ctx = store.context();
166+
let key = TestSymmKey::A(0);
167+
168+
let string_data = "Hello, World!".to_string();
169+
let str_data: &str = string_data.as_str();
170+
171+
let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
172+
let str_encrypted = str_data.encrypt(&mut ctx, key).unwrap();
173+
174+
let string_decrypted: String = string_encrypted.decrypt(&mut ctx, key).unwrap();
175+
let str_decrypted: String = str_encrypted.decrypt(&mut ctx, key).unwrap();
176+
177+
assert_eq!(string_data, string_decrypted);
178+
assert_eq!(str_data, str_decrypted);
179+
}
180+
181+
#[test]
182+
fn test_encryptable_bytes_asymmetric() {
183+
let store = test_store();
184+
let mut ctx = store.context();
185+
let key = TestAsymmKey::A(0);
186+
187+
let vec_data = vec![1, 2, 3, 4, 5];
188+
let slice_data: &[u8] = &vec_data;
189+
190+
let vec_encrypted = vec_data.encrypt(&mut ctx, key).unwrap();
191+
let slice_encrypted = slice_data.encrypt(&mut ctx, key).unwrap();
192+
193+
let vec_decrypted: Vec<u8> = vec_encrypted.decrypt(&mut ctx, key).unwrap();
194+
let slice_decrypted: Vec<u8> = slice_encrypted.decrypt(&mut ctx, key).unwrap();
195+
196+
assert_eq!(vec_data, vec_decrypted);
197+
assert_eq!(slice_data, slice_decrypted);
198+
}
199+
200+
#[test]
201+
fn test_encryptable_string_asymmetric() {
202+
let store = test_store();
203+
let mut ctx = store.context();
204+
let key = TestAsymmKey::A(0);
205+
206+
let string_data = "Hello, World!".to_string();
207+
let str_data: &str = string_data.as_str();
208+
209+
let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
210+
let str_encrypted = str_data.encrypt(&mut ctx, key).unwrap();
211+
212+
let string_decrypted: String = string_encrypted.decrypt(&mut ctx, key).unwrap();
213+
let str_decrypted: String = str_encrypted.decrypt(&mut ctx, key).unwrap();
214+
215+
assert_eq!(string_data, string_decrypted);
216+
assert_eq!(str_data, str_decrypted);
217+
}
218+
219+
#[test]
220+
fn test_encryptable_option_some() {
221+
let store = test_store();
222+
let mut ctx = store.context();
223+
let key = TestSymmKey::A(0);
224+
225+
let string_data = Some("Hello, World!".to_string());
226+
227+
let string_encrypted = string_data.encrypt(&mut ctx, key).unwrap();
228+
229+
let string_decrypted: Option<String> = string_encrypted.decrypt(&mut ctx, key).unwrap();
230+
231+
assert_eq!(string_data, string_decrypted);
232+
}
233+
234+
#[test]
235+
fn test_encryptable_option_none() {
236+
let store = test_store();
237+
let mut ctx = store.context();
238+
239+
let key = TestSymmKey::A(0);
240+
let none_data: Option<String> = None;
241+
let string_encrypted = none_data.encrypt(&mut ctx, key).unwrap();
242+
assert_eq!(string_encrypted, None);
243+
244+
// The None implementation will not do any decrypt operations, so it won't fail even if the key doesn't exist
245+
let bad_key = TestSymmKey::B((0, 1));
246+
let string_encrypted_bad = none_data.encrypt(&mut ctx, bad_key).unwrap();
247+
assert_eq!(string_encrypted_bad, None);
248+
}
249+
}

0 commit comments

Comments
 (0)