From fd60847014115d5652ceeafeb0f9ac6b31ba2ed5 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Fri, 21 Nov 2025 18:26:18 +0100 Subject: [PATCH 1/3] Add rsa extract public key --- .../src/enc_string/symmetric.rs | 21 +++++++++++++++++++ .../src/pure_crypto.rs | 15 +++++++++++++ 2 files changed, 36 insertions(+) diff --git a/crates/bitwarden-crypto/src/enc_string/symmetric.rs b/crates/bitwarden-crypto/src/enc_string/symmetric.rs index 72557bdb0..12d47d4da 100644 --- a/crates/bitwarden-crypto/src/enc_string/symmetric.rs +++ b/crates/bitwarden-crypto/src/enc_string/symmetric.rs @@ -3,6 +3,8 @@ use std::{borrow::Cow, str::FromStr}; use bitwarden_encoding::{B64, FromStrVisitor}; use coset::{CborSerializable, iana::KeyOperation}; use serde::Deserialize; +#[cfg(feature = "wasm")] +use wasm_bindgen::convert::FromWasmAbi; use super::{check_length, from_b64, from_b64_vec, split_enc_string}; use crate::{ @@ -75,6 +77,25 @@ pub enum EncString { }, } +#[cfg(feature = "wasm")] +impl wasm_bindgen::describe::WasmDescribe for EncString { + fn describe() { + ::describe(); + } +} + +#[cfg(feature = "wasm")] +impl FromWasmAbi for EncString { + type Abi = ::Abi; + + unsafe fn from_abi(abi: Self::Abi) -> Self { + use wasm_bindgen::UnwrapThrowExt; + + let s = unsafe { String::from_abi(abi) }; + Self::from_str(&s).unwrap_throw() + } +} + /// Deserializes an [EncString] from a string. impl FromStr for EncString { type Err = CryptoError; diff --git a/crates/bitwarden-wasm-internal/src/pure_crypto.rs b/crates/bitwarden-wasm-internal/src/pure_crypto.rs index 9bbe13633..e7646db76 100644 --- a/crates/bitwarden-wasm-internal/src/pure_crypto.rs +++ b/crates/bitwarden-wasm-internal/src/pure_crypto.rs @@ -318,6 +318,21 @@ impl PureCrypto { .map_err(|_| CryptoError::InvalidKey)?; Ok(result.to_encoded().to_vec()) } + + pub fn rsa_extract_public_key( + encrypted_private_key: EncString, + wrapping_key: Vec, + ) -> Result, CryptoError> { + let wrapping_key = SymmetricCryptoKey::try_from( + &BitwardenLegacyKeyBytes::from(wrapping_key), + )?; + let decrypted_private_key: Vec = encrypted_private_key.decrypt_with_key(&wrapping_key)?; + let private_key = AsymmetricCryptoKey::from_der(&Pkcs8PrivateKeyBytes::from( + decrypted_private_key, + ))?; + let public_key = private_key.to_public_key(); + Ok(public_key.to_der()?.to_vec()) + } } #[cfg(test)] From 76d0ef39dd30ca0d62363367e3ca7b3705f885b1 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 24 Nov 2025 10:09:49 +0100 Subject: [PATCH 2/3] Cargo fmt --- crates/bitwarden-wasm-internal/src/pure_crypto.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/crates/bitwarden-wasm-internal/src/pure_crypto.rs b/crates/bitwarden-wasm-internal/src/pure_crypto.rs index e7646db76..90af04064 100644 --- a/crates/bitwarden-wasm-internal/src/pure_crypto.rs +++ b/crates/bitwarden-wasm-internal/src/pure_crypto.rs @@ -323,13 +323,12 @@ impl PureCrypto { encrypted_private_key: EncString, wrapping_key: Vec, ) -> Result, CryptoError> { - let wrapping_key = SymmetricCryptoKey::try_from( - &BitwardenLegacyKeyBytes::from(wrapping_key), - )?; - let decrypted_private_key: Vec = encrypted_private_key.decrypt_with_key(&wrapping_key)?; - let private_key = AsymmetricCryptoKey::from_der(&Pkcs8PrivateKeyBytes::from( - decrypted_private_key, - ))?; + let wrapping_key = + SymmetricCryptoKey::try_from(&BitwardenLegacyKeyBytes::from(wrapping_key))?; + let decrypted_private_key: Vec = + encrypted_private_key.decrypt_with_key(&wrapping_key)?; + let private_key = + AsymmetricCryptoKey::from_der(&Pkcs8PrivateKeyBytes::from(decrypted_private_key))?; let public_key = private_key.to_public_key(); Ok(public_key.to_der()?.to_vec()) } From 4f7bd1ab0671b4bb7998570429f26be8b1b89c47 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 24 Nov 2025 10:14:17 +0100 Subject: [PATCH 3/3] Add comment --- crates/bitwarden-wasm-internal/src/pure_crypto.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/bitwarden-wasm-internal/src/pure_crypto.rs b/crates/bitwarden-wasm-internal/src/pure_crypto.rs index 90af04064..bbf215a63 100644 --- a/crates/bitwarden-wasm-internal/src/pure_crypto.rs +++ b/crates/bitwarden-wasm-internal/src/pure_crypto.rs @@ -319,6 +319,8 @@ impl PureCrypto { Ok(result.to_encoded().to_vec()) } + /// Given an encrypted private RSA key and the symmetric key it is wrapped with, this returns + /// the corresponding public RSA key in DER format. pub fn rsa_extract_public_key( encrypted_private_key: EncString, wrapping_key: Vec,