From 3ac3cf66442f1c79c18be793c3101b019eadcbb7 Mon Sep 17 00:00:00 2001 From: Thomas Avery Date: Wed, 13 Nov 2024 17:34:37 -0600 Subject: [PATCH] Swap to not requiring crypto initialization --- .../src/mobile/client_crypto.rs | 6 +-- crates/bitwarden-core/src/mobile/crypto.rs | 54 ++++++++----------- crates/bitwarden-wasm-internal/src/crypto.rs | 12 ++--- 3 files changed, 32 insertions(+), 40 deletions(-) diff --git a/crates/bitwarden-core/src/mobile/client_crypto.rs b/crates/bitwarden-core/src/mobile/client_crypto.rs index 75a50f3a..f4ac3cd6 100644 --- a/crates/bitwarden-core/src/mobile/client_crypto.rs +++ b/crates/bitwarden-core/src/mobile/client_crypto.rs @@ -60,15 +60,15 @@ impl<'a> ClientCrypto<'a> { derive_key_connector(request) } - pub fn make_key_pair(&self) -> Result { - make_key_pair(self.client) + pub fn make_key_pair(&self, user_key: String) -> Result { + make_key_pair(user_key) } pub fn verify_asymmetric_keys( &self, request: VerifyAsymmetricKeysRequest, ) -> Result { - verify_asymmetric_keys(self.client, request) + verify_asymmetric_keys(request) } } diff --git a/crates/bitwarden-core/src/mobile/crypto.rs b/crates/bitwarden-core/src/mobile/crypto.rs index af8d6001..934c640f 100644 --- a/crates/bitwarden-core/src/mobile/crypto.rs +++ b/crates/bitwarden-core/src/mobile/crypto.rs @@ -362,9 +362,8 @@ pub struct MakeKeyPairResponse { user_key_encrypted_private_key: EncString, } -pub fn make_key_pair(client: &Client) -> Result { - let enc = client.internal.get_encryption_settings()?; - let user_key = UserKey::new(enc.get_key(&None)?.clone()); +pub fn make_key_pair(user_key: String) -> Result { + let user_key = UserKey::new(SymmetricCryptoKey::try_from(user_key)?); let key_pair = user_key.make_key_pair()?; @@ -379,9 +378,10 @@ pub fn make_key_pair(client: &Client) -> Result { #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] #[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))] pub struct VerifyAsymmetricKeysRequest { + /// The user's user key + user_key: String, /// The user's public key user_public_key: String, - /// User's private key, encrypted with the user key user_key_encrypted_private_key: EncString, } @@ -398,7 +398,6 @@ pub struct VerifyAsymmetricKeysResponse { } pub fn verify_asymmetric_keys( - client: &Client, request: VerifyAsymmetricKeysRequest, ) -> Result { #[derive(Debug, thiserror::Error)] @@ -437,10 +436,9 @@ pub fn verify_asymmetric_keys( Ok(()) } - let enc = client.internal.get_encryption_settings()?; - let user_key = enc.get_key(&None)?; + let user_key = SymmetricCryptoKey::try_from(request.user_key.clone())?; - Ok(match verify_inner(user_key, &request) { + Ok(match verify_inner(&user_key, &request) { Ok(_) => VerifyAsymmetricKeysResponse { private_key_decryptable: true, valid_private_key: true, @@ -694,9 +692,7 @@ mod tests { assert_eq!(result, "ySXq1RVLKEaV1eoQE/ui9aFKIvXTl9PAXwp1MljfF50="); } - fn setup_asymmetric_keys_test() -> (Client, UserKey, RsaKeyPair) { - let client = Client::new(None); - + fn setup_asymmetric_keys_test() -> (UserKey, RsaKeyPair) { let master_key = MasterKey::derive( "asdfasdfasdf", "test@bitwarden.com", @@ -705,25 +701,17 @@ mod tests { }, ) .unwrap(); - let (user_key, encrypted_user_key) = master_key.make_user_key().unwrap(); + let user_key = (master_key.make_user_key().unwrap()).0; let key_pair = user_key.make_key_pair().unwrap(); - client - .internal - .initialize_user_crypto_master_key( - master_key, - encrypted_user_key, - key_pair.private.clone(), - ) - .unwrap(); - (client, user_key, key_pair) + (user_key, key_pair) } #[test] fn test_make_key_pair() { - let (client, user_key, _) = setup_asymmetric_keys_test(); + let (user_key, _) = setup_asymmetric_keys_test(); - let response = make_key_pair(&client).unwrap(); + let response = make_key_pair(user_key.0.to_base64()).unwrap(); assert!(!response.user_public_key.is_empty()); let encrypted_private_key = response.user_key_encrypted_private_key; @@ -733,13 +721,14 @@ mod tests { #[test] fn test_verify_asymmetric_keys_success() { - let (client, _, key_pair) = setup_asymmetric_keys_test(); + let (user_key, key_pair) = setup_asymmetric_keys_test(); let request = VerifyAsymmetricKeysRequest { + user_key: user_key.0.to_base64(), user_public_key: key_pair.public, user_key_encrypted_private_key: key_pair.private, }; - let response = client.crypto().verify_asymmetric_keys(request).unwrap(); + let response = verify_asymmetric_keys(request).unwrap(); assert!(response.private_key_decryptable); assert!(response.valid_private_key); @@ -747,14 +736,15 @@ mod tests { #[test] fn test_verify_asymmetric_keys_decrypt_failed() { - let (client, _, key_pair) = setup_asymmetric_keys_test(); + let (user_key, key_pair) = setup_asymmetric_keys_test(); let undecryptable_private_key = "2.cqD39M4erPZ3tWaz2Fng9w==|+Bsp/xvM30oo+HThKN12qirK0A63EjMadcwethCX7kEgfL5nEXgAFsSgRBMpByc1djgpGDMXzUTLOE+FejXRsrEHH/ICZ7jPMgSR+lV64Mlvw3fgvDPQdJ6w3MCmjPueGQtrlPj1K78BkRomN3vQwwRBFUIJhLAnLshTOIFrSghoyG78na7McqVMMD0gmC0zmRaSs2YWu/46ES+2Rp8V5OC4qdeeoJM9MQfaOtmaqv7NRVDeDM3DwoyTJAOcon8eovMKE4jbFPUboiXjNQBkBgjvLhco3lVJnFcQuYgmjqrwuUQRsfAtZjxFXg/RQSH2D+SI5uRaTNQwkL4iJqIw7BIKtI0gxDz6eCVdq/+DLhpImgCV/aaIhF/jkpGqLCceFsYMbuqdULMM1VYKgV+IAuyC65R+wxOaKS+1IevvPnNp7tgKAvT5+shFg8piusj+rQ49daX2SmV2OImwdWMmmX93bcVV0xJ/WYB1yrqmyRUcTwyvX3RQF25P5okIIzFasRp8jXFZe8C6f93yzkn1TPQbp95zF4OsWjfPFVH4hzca07ACt2HjbAB75JakWbFA5MbCF8aOIwIfeLVhVlquQXCldOHCsl22U/f3HTGLB9OS8F83CDAy7qZqpKha9Im8RUhHoyf+lXrky0gyd6un7Ky8NSkVOGd8CEG7bvZfutxv/qtAjEM9/lV78fh8TQIy9GNgioMzplpuzPIJOgMaY/ZFZj6a8H9OMPneN5Je0H/DwHEglSyWy7CMgwcbQgXYGXc8rXTTxL71GUAFHzDr4bAJvf40YnjndoL9tf+oBw8vVNUccoD4cjyOT5w8h7M3Liaxk9/0O8JR98PKxxpv1Xw6XjFCSEHeG2y9FgDUASFR4ZwG1qQBiiLMnJ7e9kvxsdnmasBux9H0tOdhDhAM16Afk3NPPKA8eztJVHJBAfQiaNiUA4LIJ48d8EpUAe2Tvz0WW/gQThplUINDTpvPf+FojLwc5lFwNIPb4CVN1Ui8jOJI5nsOw4BSWJvLzJLxawHxX/sBuK96iXza+4aMH+FqYKt/twpTJtiVXo26sPtHe6xXtp7uO4b+bL9yYUcaAci69L0W8aNdu8iF0lVX6kFn2lOL8dBLRleGvixX9gYEVEsiI7BQBjxEBHW/YMr5F4M4smqCpleZIAxkse1r2fQ33BSOJVQKInt4zzgdKwrxDzuVR7RyiIUuNXHsprKtRHNJrSc4x5kWFUeivahed2hON+Ir/ZvrxYN6nJJPeYYH4uEm1Nn4osUzzfWILlqpmDPK1yYy365T38W8wT0cbdcJrI87ycS37HeB8bzpFJZSY/Dzv48Yy19mDZJHLJLCRqyxNeIlBPsVC8fvxQhzr+ZyS3Wi8Dsa2Sgjt/wd0xPULLCJlb37s+1aWgYYylr9QR1uhXheYfkXFED+saGWwY1jlYL5e2Oo9n3sviBYwJxIZ+RTKFgwlXV5S+Jx/MbDpgnVHP1KaoU6vvzdWYwMChdHV/6PhZVbeT2txq7Qt+zQN59IGrOWf6vlMkHxfUzMTD58CE+xAaz/D05ljHMesLj9hb3MSrymw0PcwoFGWUMIzIQE73pUVYNE7fVHa8HqUOdoxZ5dRZqXRVox1xd9siIPE3e6CuVQIMabTp1YLno=|Y38qtTuCwNLDqFnzJ3Cgbjm1SE15OnhDm9iAMABaQBA=".parse().unwrap(); let request = VerifyAsymmetricKeysRequest { + user_key: user_key.0.to_base64(), user_public_key: key_pair.public, user_key_encrypted_private_key: undecryptable_private_key, }; - let response = client.crypto().verify_asymmetric_keys(request).unwrap(); + let response = verify_asymmetric_keys(request).unwrap(); assert!(!response.private_key_decryptable); assert!(!response.valid_private_key); @@ -762,7 +752,7 @@ mod tests { #[test] fn test_verify_asymmetric_keys_parse_failed() { - let (client, user_key, key_pair) = setup_asymmetric_keys_test(); + let (user_key, key_pair) = setup_asymmetric_keys_test(); let invalid_private_key = "bad_key" .to_string() @@ -771,10 +761,11 @@ mod tests { .unwrap(); let request = VerifyAsymmetricKeysRequest { + user_key: user_key.0.to_base64(), user_public_key: key_pair.public, user_key_encrypted_private_key: invalid_private_key, }; - let response = client.crypto().verify_asymmetric_keys(request).unwrap(); + let response = verify_asymmetric_keys(request).unwrap(); assert!(response.private_key_decryptable); assert!(!response.valid_private_key); @@ -782,14 +773,15 @@ mod tests { #[test] fn test_verify_asymmetric_keys_key_mismatch() { - let (client, user_key, key_pair) = setup_asymmetric_keys_test(); + let (user_key, key_pair) = setup_asymmetric_keys_test(); let new_key_pair = user_key.make_key_pair().unwrap(); let request = VerifyAsymmetricKeysRequest { + user_key: user_key.0.to_base64(), user_public_key: key_pair.public, user_key_encrypted_private_key: new_key_pair.private, }; - let response = client.crypto().verify_asymmetric_keys(request).unwrap(); + let response = verify_asymmetric_keys(request).unwrap(); assert!(response.private_key_decryptable); assert!(!response.valid_private_key); diff --git a/crates/bitwarden-wasm-internal/src/crypto.rs b/crates/bitwarden-wasm-internal/src/crypto.rs index 56d47d7a..9b89ffa7 100644 --- a/crates/bitwarden-wasm-internal/src/crypto.rs +++ b/crates/bitwarden-wasm-internal/src/crypto.rs @@ -34,15 +34,15 @@ impl ClientCrypto { Ok(self.0.crypto().initialize_org_crypto(req).await?) } - /// Generates a new key pair and encrypts the private key with the initialized user key. - /// Needs to be called after `initialize_user_crypto`. - pub fn make_key_pair(&self) -> Result { - Ok(self.0.crypto().make_key_pair()?) + /// Generates a new key pair and encrypts the private key with the provided user key. + /// Crypto initialization not required. + pub fn make_key_pair(&self, user_key: String) -> Result { + Ok(self.0.crypto().make_key_pair(user_key)?) } - /// Verifies a user's asymmetric keys by decrypting the private key with the initialized user + /// Verifies a user's asymmetric keys by decrypting the private key with the provided user /// key. Returns if the private key is decryptable and if it is a valid matching key. - /// Needs to be called after `initialize_user_crypto`. + /// Crypto initialization not required. pub fn verify_asymmetric_keys( &self, request: VerifyAsymmetricKeysRequest,