Skip to content

Commit

Permalink
[PM-7051] Implement make_register_tde_keys (#685)
Browse files Browse the repository at this point in the history
## Type of change
```
- [ ] Bug fix
- [x] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other
```

## Objective
Add support in the SDK to create the keys necessary for the just in time
user for TDE
  • Loading branch information
dani-garcia authored Mar 28, 2024
1 parent 51a5140 commit 0ae0226
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 1 deletion.
16 changes: 16 additions & 0 deletions crates/bitwarden-uniffi/src/auth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::sync::Arc;

use bitwarden::auth::{
password::MasterPasswordPolicyOptions, AuthRequestResponse, RegisterKeyResponse,
RegisterTdeKeyResponse,
};
use bitwarden_crypto::{AsymmetricEncString, HashPurpose, Kdf, TrustDeviceResponse};

Expand Down Expand Up @@ -78,6 +79,21 @@ impl ClientAuth {
.make_register_keys(email, password, kdf)?)
}

/// Generate keys needed for TDE process
pub async fn make_register_tde_keys(
&self,
org_public_key: String,
remember_device: bool,
) -> Result<RegisterTdeKeyResponse> {
Ok(self
.0
.0
.write()
.await
.auth()
.make_register_tde_keys(org_public_key, remember_device)?)
}

/// Validate the user password
///
/// To retrieve the user's password hash, use [`ClientAuth::hash_password`] with
Expand Down
9 changes: 9 additions & 0 deletions crates/bitwarden/src/auth/client_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{
MasterPasswordPolicyOptions,
},
register::{make_register_keys, register},
tde::{make_register_tde_keys, RegisterTdeKeyResponse},
AuthRequestResponse, RegisterKeyResponse, RegisterRequest,
},
client::Kdf,
Expand Down Expand Up @@ -73,6 +74,14 @@ impl<'a> ClientAuth<'a> {
make_register_keys(email, password, kdf)
}

pub fn make_register_tde_keys(
&mut self,
org_public_key: String,
remember_device: bool,
) -> Result<RegisterTdeKeyResponse> {
make_register_tde_keys(self.client, org_public_key, remember_device)
}

pub async fn register(&mut self, input: &RegisterRequest) -> Result<()> {
register(self.client, input).await
}
Expand Down
4 changes: 4 additions & 0 deletions crates/bitwarden/src/auth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ mod auth_request;
pub use auth_request::AuthRequestResponse;
#[cfg(feature = "mobile")]
pub(crate) use auth_request::{auth_request_decrypt_master_key, auth_request_decrypt_user_key};
#[cfg(feature = "internal")]
mod tde;
#[cfg(feature = "internal")]
pub use tde::RegisterTdeKeyResponse;

#[cfg(feature = "internal")]
use crate::{client::Kdf, error::Result};
Expand Down
51 changes: 51 additions & 0 deletions crates/bitwarden/src/auth/tde.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use base64::{engine::general_purpose::STANDARD, Engine};
use bitwarden_crypto::{
AsymmetricEncString, AsymmetricPublicCryptoKey, DeviceKey, EncString, SymmetricCryptoKey,
TrustDeviceResponse, UserKey,
};

use crate::{error::Result, Client};

/// This function generates a new user key and key pair, initializes the client's crypto with the
/// generated user key, and encrypts the user key with the organization public key for admin
/// password reset. If remember_device is true, it also generates a device key.
pub(super) fn make_register_tde_keys(
client: &mut Client,
org_public_key: String,
remember_device: bool,
) -> Result<RegisterTdeKeyResponse> {
let public_key = AsymmetricPublicCryptoKey::from_der(&STANDARD.decode(org_public_key)?)?;

let mut rng = rand::thread_rng();

let user_key = UserKey::new(SymmetricCryptoKey::generate(&mut rng));
let key_pair = user_key.make_key_pair()?;

let admin_reset =
AsymmetricEncString::encrypt_rsa2048_oaep_sha1(&user_key.0.to_vec(), &public_key)?;

let device_key = if remember_device {
Some(DeviceKey::trust_device(&user_key.0)?)
} else {
None
};

client.initialize_user_crypto_decrypted_key(user_key.0, key_pair.private.clone())?;

Ok(RegisterTdeKeyResponse {
private_key: key_pair.private,
public_key: key_pair.public,

admin_reset,
device_key,
})
}

#[cfg_attr(feature = "mobile", derive(uniffi::Record))]
pub struct RegisterTdeKeyResponse {
pub private_key: EncString,
pub public_key: String,

pub admin_reset: AsymmetricEncString,
pub device_key: Option<TrustDeviceResponse>,
}
2 changes: 1 addition & 1 deletion crates/bitwarden/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ impl Client {
Ok(self.encryption_settings.as_ref().unwrap())
}

#[cfg(feature = "mobile")]
#[cfg(feature = "internal")]
pub(crate) fn initialize_user_crypto_decrypted_key(
&mut self,
user_key: SymmetricCryptoKey,
Expand Down

0 comments on commit 0ae0226

Please sign in to comment.