Skip to content

Commit

Permalink
Introduce mutable context
Browse files Browse the repository at this point in the history
  • Loading branch information
dani-garcia committed Oct 4, 2024
1 parent d5f1ede commit 8652d79
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 185 deletions.
135 changes: 0 additions & 135 deletions crates/bitwarden-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,138 +19,3 @@ mod util;

pub use bitwarden_crypto::ZeroizingAllocator;
pub use client::{Client, ClientSettings, DeviceType};

#[allow(warnings)]
#[cfg(test)]
mod testcrypto {

// TEST IMPL OF THE NEW ENCRYPTABLE/DECRYPTABLE TRAITS
// Note that these never touch the keys at all, they just use the context and key references to
// encrypt/decrypt

use bitwarden_crypto::{
key_refs, service::*, AsymmetricCryptoKey, CryptoError, EncString, KeyEncryptable,
SymmetricCryptoKey,
};

key_refs! {
#[symmetric]
pub enum MySymmKeyRef {
User,
Organization(uuid::Uuid),
#[local]
Local(&'static str),
}

#[asymmetric]
pub enum MyAsymmKeyRef {
UserPrivateKey,
#[local]
Local(&'static str),
}
}

#[derive(Clone)]
struct Cipher {
key: Option<EncString>,
name: EncString,
}

#[derive(Clone)]
struct CipherView {
key: Option<EncString>,
name: String,
}

impl UsesKey<MySymmKeyRef> for Cipher {
fn uses_key(&self) -> MySymmKeyRef {
MySymmKeyRef::User
}
}
impl UsesKey<MySymmKeyRef> for CipherView {
fn uses_key(&self) -> MySymmKeyRef {
MySymmKeyRef::User
}
}

const CIPHER_KEY: MySymmKeyRef = MySymmKeyRef::Local("cipher_key");

impl Encryptable<MySymmKeyRef, MyAsymmKeyRef, MySymmKeyRef, Cipher> for CipherView {
fn encrypt(
&self,
ctx: &mut CryptoServiceContext<MySymmKeyRef, MyAsymmKeyRef>,
key: MySymmKeyRef,
) -> Result<Cipher, bitwarden_crypto::CryptoError> {
let cipher_key = match &self.key {
Some(cipher_key) => ctx.decrypt_symmetric_key(key, CIPHER_KEY, cipher_key)?,
None => key,
};

Ok(Cipher {
key: self.key.clone(),
name: self.name.as_str().encrypt(ctx, cipher_key)?,
})
}
}

impl Decryptable<MySymmKeyRef, MyAsymmKeyRef, MySymmKeyRef, CipherView> for Cipher {
fn decrypt(
&self,
ctx: &mut CryptoServiceContext<MySymmKeyRef, MyAsymmKeyRef>,
key: MySymmKeyRef,
) -> Result<CipherView, CryptoError> {
let cipher_key = match &self.key {
Some(cipher_key) => ctx.decrypt_symmetric_key(key, CIPHER_KEY, cipher_key)?,
None => key,
};

Ok(CipherView {
key: self.key.clone(),
name: self.name.decrypt(ctx, cipher_key)?,
})
}
}

#[test]
fn test_cipher() {
let user_key = SymmetricCryptoKey::generate(rand::thread_rng());

let org_id = uuid::Uuid::parse_str("91b000b6-81ce-47f4-9802-3390e0b895ed").unwrap();
let org_key = SymmetricCryptoKey::generate(rand::thread_rng());

let cipher_key = SymmetricCryptoKey::generate(rand::thread_rng());
let cipher_key_user_enc = cipher_key.to_vec().encrypt_with_key(&user_key).unwrap();
let cipher_view = CipherView {
key: Some(cipher_key_user_enc.clone()),
name: "test".to_string(),
};

let service: CryptoService<MySymmKeyRef, MyAsymmKeyRef> = CryptoService::new();
// Ideally we'd decrypt the keys directly into the service, but that's not implemented yet
#[allow(deprecated)]
{
service.insert_symmetric_key(MySymmKeyRef::User, user_key);
service.insert_symmetric_key(MySymmKeyRef::Organization(org_id), org_key);
}

let cipher_enc2 = service.encrypt(cipher_view.clone()).unwrap();

let cipher_view2 = service.decrypt(&cipher_enc2).unwrap();

assert_eq!(cipher_view.name, cipher_view2.name);

// We can also decrypt a value by tagging it with the key
let text = String::from("test!");

let text_enc = service
.encrypt(text.as_str().using_key(MySymmKeyRef::User))
.unwrap();

// And decrypt values in parallel
let mut data = Vec::with_capacity(250);
for _ in 0..data.capacity() {
data.push("hello world, this is an encryption test!".using_key(MySymmKeyRef::User));
}
service.encrypt_list(&data).unwrap();
}
}
4 changes: 3 additions & 1 deletion crates/bitwarden-crypto/benches/new_encryptable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ impl Encryptable<MySymmKeyRef, MyAsymmKeyRef, MySymmKeyRef, Cipher> for CipherVi
key: MySymmKeyRef,
) -> Result<Cipher, bitwarden_crypto::CryptoError> {
let cipher_key = match &self.key {
Some(cipher_key) => ctx.decrypt_symmetric_key(key, CIPHER_KEY, cipher_key)?,
Some(cipher_key) => {
ctx.decrypt_symmetric_key_with_symmetric_key(key, CIPHER_KEY, cipher_key)?
}
None => key,
};

Expand Down
Loading

0 comments on commit 8652d79

Please sign in to comment.