Skip to content

Commit 9440825

Browse files
committed
Typed encryptable
1 parent b8056c2 commit 9440825

File tree

19 files changed

+150
-126
lines changed

19 files changed

+150
-126
lines changed

bitwarden_license/bitwarden-sm/src/projects/create.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bitwarden_api_api::models::ProjectCreateRequestModel;
22
use bitwarden_core::{key_management::SymmetricKeyId, Client};
3-
use bitwarden_crypto::{ContentFormat, Encryptable};
3+
use bitwarden_crypto::TypedEncryptable;
44
use schemars::JsonSchema;
55
use serde::{Deserialize, Serialize};
66
use uuid::Uuid;
@@ -34,7 +34,7 @@ pub(crate) async fn create_project(
3434
.name
3535
.clone()
3636
.trim()
37-
.encrypt(&mut key_store.context(), key, ContentFormat::Utf8)?
37+
.encrypt(&mut key_store.context(), key)?
3838
.to_string(),
3939
});
4040

bitwarden_license/bitwarden-sm/src/projects/update.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bitwarden_api_api::models::ProjectUpdateRequestModel;
22
use bitwarden_core::{key_management::SymmetricKeyId, Client};
3-
use bitwarden_crypto::{ContentFormat, Encryptable};
3+
use bitwarden_crypto::{Encryptable, TypedEncryptable};
44
use schemars::JsonSchema;
55
use serde::{Deserialize, Serialize};
66
use uuid::Uuid;
@@ -36,7 +36,7 @@ pub(crate) async fn update_project(
3636
.name
3737
.clone()
3838
.trim()
39-
.encrypt(&mut key_store.context(), key, ContentFormat::Utf8)?
39+
.encrypt(&mut key_store.context(), key)?
4040
.to_string(),
4141
});
4242

bitwarden_license/bitwarden-sm/src/secrets/create.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bitwarden_api_api::models::SecretCreateRequestModel;
22
use bitwarden_core::{key_management::SymmetricKeyId, Client};
3-
use bitwarden_crypto::{ContentFormat, Encryptable};
3+
use bitwarden_crypto::{Encryptable, TypedEncryptable};
44
use schemars::JsonSchema;
55
use serde::{Deserialize, Serialize};
66
use uuid::Uuid;
@@ -44,18 +44,18 @@ pub(crate) async fn create_secret(
4444
.key
4545
.clone()
4646
.trim()
47-
.encrypt(&mut ctx, key, ContentFormat::Utf8)?
47+
.encrypt(&mut ctx, key)?
4848
.to_string(),
4949
value: input
5050
.value
5151
.clone()
52-
.encrypt(&mut ctx, key, ContentFormat::Utf8)?
52+
.encrypt(&mut ctx, key)?
5353
.to_string(),
5454
note: input
5555
.note
5656
.clone()
5757
.trim()
58-
.encrypt(&mut ctx, key, ContentFormat::Utf8)?
58+
.encrypt(&mut ctx, key)?
5959
.to_string(),
6060
project_ids: input.project_ids.clone(),
6161
access_policies_requests: None,

bitwarden_license/bitwarden-sm/src/secrets/update.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bitwarden_api_api::models::SecretUpdateRequestModel;
22
use bitwarden_core::{key_management::SymmetricKeyId, Client};
3-
use bitwarden_crypto::{ContentFormat, Encryptable};
3+
use bitwarden_crypto::{Encryptable, TypedEncryptable};
44
use schemars::JsonSchema;
55
use serde::{Deserialize, Serialize};
66
use uuid::Uuid;
@@ -43,18 +43,18 @@ pub(crate) async fn update_secret(
4343
.key
4444
.clone()
4545
.trim()
46-
.encrypt(&mut ctx, key, ContentFormat::Utf8)?
46+
.encrypt(&mut ctx, key)?
4747
.to_string(),
4848
value: input
4949
.value
5050
.clone()
51-
.encrypt(&mut ctx, key, ContentFormat::Utf8)?
51+
.encrypt(&mut ctx, key)?
5252
.to_string(),
5353
note: input
5454
.note
5555
.clone()
5656
.trim()
57-
.encrypt(&mut ctx, key, ContentFormat::Utf8)?
57+
.encrypt(&mut ctx, key)?
5858
.to_string(),
5959
project_ids: input.project_ids.clone(),
6060
access_policies_requests: None,

crates/bitwarden-crypto/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ mod cose;
3434
mod traits;
3535
pub use cose::ContentFormat;
3636
mod xchacha20;
37-
pub use traits::{Decryptable, Encryptable, CompositeEncryptable, IdentifyKey, KeyId, KeyIds};
37+
pub use traits::{Decryptable, Encryptable, CompositeEncryptable, TypedEncryptable, IdentifyKey, KeyId, KeyIds};
3838
pub use zeroizing_alloc::ZeroAlloc as ZeroizingAllocator;
3939

4040
#[cfg(feature = "uniffi")]

crates/bitwarden-crypto/src/store/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,10 @@ impl<Ids: KeyIds> KeyStoreContext<'_, Ids> {
382382
#[allow(deprecated)]
383383
mod tests {
384384
use crate::{
385-
cose::ContentFormat, store::{
385+
store::{
386386
tests::{Data, DataView},
387387
KeyStore,
388-
}, traits::tests::{TestIds, TestSymmKey}, CompositeEncryptable, Decryptable, Encryptable, SymmetricCryptoKey
388+
}, traits::tests::{TestIds, TestSymmKey}, CompositeEncryptable, Decryptable, SymmetricCryptoKey
389389
};
390390

391391
#[test]

crates/bitwarden-crypto/src/store/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ fn batch_chunk_size(len: usize) -> usize {
304304
#[cfg(test)]
305305
pub(crate) mod tests {
306306
use crate::{
307-
store::{KeyStore, KeyStoreContext}, traits::tests::{TestIds, TestSymmKey}, EncString, Encryptable, SymmetricCryptoKey
307+
store::{KeyStore, KeyStoreContext}, traits::tests::{TestIds, TestSymmKey}, EncString, Encryptable, SymmetricCryptoKey, TypedEncryptable
308308
};
309309

310310
pub struct DataView(pub String, pub TestSymmKey);
@@ -328,7 +328,7 @@ pub(crate) mod tests {
328328
ctx: &mut KeyStoreContext<TestIds>,
329329
key: TestSymmKey,
330330
) -> Result<Data, crate::CryptoError> {
331-
Ok(Data(self.0.encrypt(ctx, key, crate::ContentFormat::Utf8)?, key))
331+
Ok(Data(self.0.encrypt(ctx, key)?, key))
332332
}
333333
}
334334

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

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,57 +41,81 @@ impl <Ids: KeyIds, Key: KeyId, T: CompositeEncryptable<Ids, Key, Output>, Output
4141
}
4242
}
4343

44-
/// An encryption operation that takes the input value - a primitive such as `Vec<u8>`, `String` - and encrypts it into the output value.
45-
pub trait Encryptable<Ids: KeyIds, Key: KeyId, Output> {
44+
/// An encryption operation that takes the input value - a primitive such as `String` and encrypts it into the output value.
45+
/// The implementation decides the content format.
46+
pub trait TypedEncryptable<Ids: KeyIds, Key: KeyId, Output> {
4647
fn encrypt(
4748
&self,
4849
ctx: &mut KeyStoreContext<Ids>,
4950
key: Key,
50-
content_format: ContentFormat,
5151
) -> Result<Output, CryptoError>;
5252
}
5353

54-
impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for &[u8] {
54+
impl<Ids: KeyIds, Key: KeyId, T: TypedEncryptable<Ids, Key, Output>, Output>
55+
TypedEncryptable<Ids, Key, Option<Output>> for Option<T>
56+
{
57+
fn encrypt(
58+
&self,
59+
ctx: &mut KeyStoreContext<Ids>,
60+
key: Key,
61+
) -> Result<Option<Output>, CryptoError> {
62+
self.as_ref()
63+
.map(|value| value.encrypt(ctx, key))
64+
.transpose()
65+
}
66+
}
67+
68+
impl<Ids: KeyIds> TypedEncryptable<Ids, Ids::Symmetric, EncString> for &str
69+
{
5570
fn encrypt(
5671
&self,
5772
ctx: &mut KeyStoreContext<Ids>,
5873
key: Ids::Symmetric,
59-
content_format: ContentFormat,
6074
) -> Result<EncString, CryptoError> {
61-
ctx.encrypt_data_with_symmetric_key(key, self, content_format)
75+
self.as_bytes().encrypt(ctx, key, ContentFormat::Utf8)
6276
}
6377
}
6478

65-
impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for Vec<u8> {
79+
impl<Ids: KeyIds> TypedEncryptable<Ids, Ids::Symmetric, EncString> for String
80+
{
6681
fn encrypt(
6782
&self,
6883
ctx: &mut KeyStoreContext<Ids>,
6984
key: Ids::Symmetric,
70-
content_format: ContentFormat,
7185
) -> Result<EncString, CryptoError> {
72-
ctx.encrypt_data_with_symmetric_key(key, self, content_format)
86+
self.as_bytes().encrypt(ctx, key, ContentFormat::Utf8)
7387
}
7488
}
7589

76-
impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for &str {
90+
/// An encryption operation that takes the input value - a primitive such as `Vec<u8>` - and encrypts it into the output value.
91+
pub trait Encryptable<Ids: KeyIds, Key: KeyId, Output> {
92+
fn encrypt(
93+
&self,
94+
ctx: &mut KeyStoreContext<Ids>,
95+
key: Key,
96+
content_format: ContentFormat,
97+
) -> Result<Output, CryptoError>;
98+
}
99+
100+
impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for &[u8] {
77101
fn encrypt(
78102
&self,
79103
ctx: &mut KeyStoreContext<Ids>,
80104
key: Ids::Symmetric,
81105
content_format: ContentFormat,
82106
) -> Result<EncString, CryptoError> {
83-
self.as_bytes().encrypt(ctx, key, content_format)
107+
ctx.encrypt_data_with_symmetric_key(key, self, content_format)
84108
}
85109
}
86110

87-
impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for String {
111+
impl<Ids: KeyIds> Encryptable<Ids, Ids::Symmetric, EncString> for Vec<u8> {
88112
fn encrypt(
89113
&self,
90114
ctx: &mut KeyStoreContext<Ids>,
91115
key: Ids::Symmetric,
92-
content_format: crate::cose::ContentFormat,
116+
content_format: ContentFormat,
93117
) -> Result<EncString, CryptoError> {
94-
self.as_bytes().encrypt(ctx, key, content_format)
118+
ctx.encrypt_data_with_symmetric_key(key, self, content_format)
95119
}
96120
}
97121

@@ -128,7 +152,7 @@ impl<Ids: KeyIds, Key: KeyId, T: Encryptable<Ids, Key, Output>, Output>
128152
#[cfg(test)]
129153
mod tests {
130154
use crate::{
131-
cose::ContentFormat, traits::tests::*, AsymmetricCryptoKey, Decryptable, Encryptable, KeyStore, SymmetricCryptoKey
155+
cose::ContentFormat, traits::tests::*, AsymmetricCryptoKey, Decryptable, Encryptable, KeyStore, SymmetricCryptoKey, TypedEncryptable
132156
};
133157

134158
fn test_store() -> KeyStore<TestIds> {
@@ -184,10 +208,10 @@ mod tests {
184208
let str_data: &str = string_data.as_str();
185209

186210
let string_encrypted = string_data
187-
.encrypt(&mut ctx, key, ContentFormat::OctetStream)
211+
.encrypt(&mut ctx, key)
188212
.unwrap();
189213
let str_encrypted = str_data
190-
.encrypt(&mut ctx, key, ContentFormat::OctetStream)
214+
.encrypt(&mut ctx, key)
191215
.unwrap();
192216

193217
let string_decrypted: String = string_encrypted.decrypt(&mut ctx, key).unwrap();
@@ -206,7 +230,7 @@ mod tests {
206230
let string_data = Some("Hello, World!".to_string());
207231

208232
let string_encrypted = string_data
209-
.encrypt(&mut ctx, key, ContentFormat::OctetStream)
233+
.encrypt(&mut ctx, key)
210234
.unwrap();
211235

212236
let string_decrypted: Option<String> = string_encrypted.decrypt(&mut ctx, key).unwrap();
@@ -222,15 +246,15 @@ mod tests {
222246
let key = TestSymmKey::A(0);
223247
let none_data: Option<String> = None;
224248
let string_encrypted = none_data
225-
.encrypt(&mut ctx, key, ContentFormat::OctetStream)
249+
.encrypt(&mut ctx, key)
226250
.unwrap();
227251
assert_eq!(string_encrypted, None);
228252

229253
// The None implementation will not do any decrypt operations, so it won't fail even if the
230254
// key doesn't exist
231255
let bad_key = TestSymmKey::B((0, 1));
232256
let string_encrypted_bad = none_data
233-
.encrypt(&mut ctx, bad_key, ContentFormat::OctetStream)
257+
.encrypt(&mut ctx, bad_key)
234258
.unwrap();
235259
assert_eq!(string_encrypted_bad, None);
236260
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
mod encryptable;
2-
pub use encryptable::{CompositeEncryptable, Encryptable};
2+
pub use encryptable::{CompositeEncryptable, Encryptable, TypedEncryptable};
33
mod decryptable;
44
pub use decryptable::Decryptable;
55

crates/bitwarden-send/src/send.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use bitwarden_core::{
88
require,
99
};
1010
use bitwarden_crypto::{
11-
generate_random_bytes, CompositeEncryptable, ContentFormat, CryptoError, Decryptable, EncString, Encryptable, IdentifyKey, KeyStoreContext
11+
generate_random_bytes, CompositeEncryptable, ContentFormat, CryptoError, Decryptable, EncString, Encryptable, IdentifyKey, KeyStoreContext, TypedEncryptable
1212
};
1313
use chrono::{DateTime, Utc};
1414
use serde::{Deserialize, Serialize};
@@ -195,7 +195,7 @@ impl CompositeEncryptable<KeyIds, SymmetricKeyId, SendText> for SendTextView {
195195
key: SymmetricKeyId,
196196
) -> Result<SendText, CryptoError> {
197197
Ok(SendText {
198-
text: self.text.encrypt(ctx, key, ContentFormat::Utf8)?,
198+
text: self.text.encrypt(ctx, key)?,
199199
hidden: self.hidden,
200200
})
201201
}
@@ -224,7 +224,7 @@ impl CompositeEncryptable<KeyIds, SymmetricKeyId, SendFile> for SendFileView {
224224
) -> Result<SendFile, CryptoError> {
225225
Ok(SendFile {
226226
id: self.id.clone(),
227-
file_name: self.file_name.encrypt(ctx, key, ContentFormat::Utf8)?,
227+
file_name: self.file_name.encrypt(ctx, key)?,
228228
size: self.size.clone(),
229229
size_name: self.size_name.clone(),
230230
})
@@ -324,8 +324,8 @@ impl CompositeEncryptable<KeyIds, SymmetricKeyId, Send> for SendView {
324324
id: self.id,
325325
access_id: self.access_id.clone(),
326326

327-
name: self.name.encrypt(ctx, send_key, ContentFormat::Utf8)?,
328-
notes: self.notes.encrypt(ctx, send_key, ContentFormat::Utf8)?,
327+
name: self.name.encrypt(ctx, send_key)?,
328+
notes: self.notes.encrypt(ctx, send_key)?,
329329
// In the future, this should support cose key content type
330330
key: k.encrypt(ctx, key, ContentFormat::OctetStream)?,
331331
password: self.new_password.as_ref().map(|password| {

0 commit comments

Comments
 (0)