Skip to content

Commit

Permalink
Asymmetric encstring rebased
Browse files Browse the repository at this point in the history
  • Loading branch information
dani-garcia committed Sep 8, 2023
1 parent 7196a66 commit 29bf596
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 102 deletions.
4 changes: 2 additions & 2 deletions crates/bitwarden/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use {
TwoFactorEmailRequest,
},
client::auth_settings::AuthSettings,
crypto::EncString,
crypto::{AsymmetricEncString, EncString},
platform::{
generate_fingerprint, get_user_api_key, sync, FingerprintRequest, FingerprintResponse,
SecretVerificationRequest, SyncRequest, SyncResponse, UserApiKeyResponse,
Expand Down Expand Up @@ -244,7 +244,7 @@ impl Client {
#[cfg(feature = "internal")]
pub(crate) fn initialize_org_crypto(
&mut self,
org_keys: Vec<(Uuid, EncString)>,
org_keys: Vec<(Uuid, AsymmetricEncString)>,
) -> Result<&EncryptionSettings> {
let enc = self
.encryption_settings
Expand Down
60 changes: 43 additions & 17 deletions crates/bitwarden/src/client/encryption_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@ use std::collections::HashMap;
use rsa::RsaPrivateKey;
use uuid::Uuid;
#[cfg(feature = "internal")]
use {
crate::client::auth_settings::AuthSettings,
rsa::{pkcs8::DecodePrivateKey, Oaep},
};
use {crate::client::auth_settings::AuthSettings, rsa::pkcs8::DecodePrivateKey};

use crate::{
crypto::{encrypt_aes256_hmac, EncString, SymmetricCryptoKey},
crypto::{encrypt_aes256_hmac, AsymmetricEncString, EncString, SymmetricCryptoKey},
error::{CryptoError, Result},
};

Expand Down Expand Up @@ -65,23 +62,15 @@ impl EncryptionSettings {
#[cfg(feature = "internal")]
pub(crate) fn set_org_keys(
&mut self,
org_enc_keys: Vec<(Uuid, EncString)>,
org_enc_keys: Vec<(Uuid, AsymmetricEncString)>,
) -> Result<&mut Self> {
use crate::error::Error;

let private_key = self.private_key.as_ref().ok_or(Error::VaultLocked)?;

// Decrypt the org keys with the private key
for (org_id, org_enc_key) in org_enc_keys {
let data = match org_enc_key {
EncString::Rsa2048_OaepSha1_B64 { data } => data,
_ => return Err(CryptoError::InvalidKey.into()),
};

let dec = private_key
.decrypt(Oaep::new::<sha1::Sha1>(), &data)
.map_err(|_| CryptoError::KeyDecrypt)?;

let dec: Vec<u8> = org_enc_key.decrypt_with_key(private_key)?;
let org_key = SymmetricCryptoKey::try_from(dec.as_slice())?;

self.org_keys.insert(org_id, org_key);
Expand Down Expand Up @@ -122,20 +111,57 @@ impl EncryptionSettings {
let dec = encrypt_aes256_hmac(data, key.mac_key.ok_or(CryptoError::InvalidMac)?, key.key)?;
Ok(dec)
}

fn get_asymmetric_key(&self, org_id: &Option<Uuid>) -> Option<&rsa::RsaPrivateKey> {
// TODO: Add key selection here
self.private_key.as_ref()
}

pub(crate) fn decrypt_bytes_asymmetric(
&self,
cipher: &AsymmetricEncString,
org_id: &Option<Uuid>,
) -> Result<Vec<u8>> {
let key = self
.get_asymmetric_key(org_id)
.ok_or(CryptoError::NoKeyForOrg)?;
cipher.decrypt_with_key(key)
}

pub(crate) fn decrypt_asymmetric(
&self,
cipher: &AsymmetricEncString,
org_id: &Option<Uuid>,
) -> Result<String> {
let dec = self.decrypt_bytes_asymmetric(cipher, org_id)?;
String::from_utf8(dec).map_err(|_| CryptoError::InvalidUtf8String.into())
}

pub(crate) fn encrypt_asymmetric(
&self,
data: &[u8],
org_id: &Option<Uuid>,
) -> Result<AsymmetricEncString> {
let key = self
.get_asymmetric_key(org_id)
.ok_or(CryptoError::NoKeyForOrg)?;

todo!()
}
}

#[cfg(test)]
mod tests {
use super::{EncryptionSettings, SymmetricCryptoKey};
use crate::crypto::{Decryptable, Encryptable};
use crate::crypto::{Decryptable, EncString, Encryptable};

#[test]
fn test_encryption_settings() {
let key = SymmetricCryptoKey::generate("test");
let settings = EncryptionSettings::new_single_key(key);

let test_string = "encrypted_test_string".to_string();
let cipher = test_string.clone().encrypt(&settings, &None).unwrap();
let cipher: EncString = test_string.clone().encrypt(&settings, &None).unwrap();

let decrypted_str = cipher.decrypt(&settings, &None).unwrap();
assert_eq!(decrypted_str, test_string);
Expand Down
6 changes: 4 additions & 2 deletions crates/bitwarden/src/crypto/aes_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use crate::{
error::{CryptoError, Result},
};

use super::EncStringVariants;

pub fn decrypt_aes256(iv: &[u8; 16], data: Vec<u8>, key: GenericArray<u8, U32>) -> Result<Vec<u8>> {
// Decrypt data
let iv = GenericArray::from_slice(iv);
Expand Down Expand Up @@ -42,7 +44,7 @@ pub fn decrypt_aes256_hmac(
pub fn encrypt_aes256(data_dec: &[u8], key: GenericArray<u8, U32>) -> Result<EncString> {
let (iv, data) = encrypt_aes256_internal(data_dec, key);

Ok(EncString::AesCbc256_B64 { iv, data })
Ok(EncStringVariants::AesCbc256_B64 { iv, data }.into())
}

pub fn encrypt_aes256_hmac(
Expand All @@ -53,7 +55,7 @@ pub fn encrypt_aes256_hmac(
let (iv, data) = encrypt_aes256_internal(data_dec, key);
let mac = validate_mac(&mac_key, &iv, &data)?;

Ok(EncString::AesCbc256_HmacSha256_B64 { iv, mac, data })
Ok(EncStringVariants::AesCbc256_HmacSha256_B64 { iv, mac, data }.into())
}

fn encrypt_aes256_internal(data_dec: &[u8], key: GenericArray<u8, U32>) -> ([u8; 16], Vec<u8>) {
Expand Down
Loading

0 comments on commit 29bf596

Please sign in to comment.