Skip to content

Commit efed963

Browse files
authored
Add rsa extract public key (#572)
## 🎟️ Tracking <!-- Paste the link to the Jira or GitHub issue or otherwise describe / point to where this change is coming from. --> ## 📔 Objective <!-- Describe what the purpose of this PR is, for example what bug you're fixing or new feature you're adding. --> Webcrypto provides non-useful errors when private keys are corrupt (invalid content on undecryptable wrapping decryption). This PR introduces a temporary function to immediately replace the derive_public_key function in `clients` so that the error logs become useful. ## 🚨 Breaking Changes <!-- Does this PR introduce any breaking changes? If so, please describe the impact and migration path for clients. If you're unsure, the automated TypeScript compatibility check will run when you open/update this PR and provide feedback. For breaking changes: 1. Describe what changed in the client interface 2. Explain why the change was necessary 3. Provide migration steps for client developers 4. Link to any paired client PRs if needed Otherwise, you can remove this section. --> ## ⏰ Reminders before review - Contributor guidelines followed - All formatters and local linters executed and passed - Written new unit and / or integration tests where applicable - Protected functional changes with optionality (feature flags) - Used internationalization (i18n) for all UI strings - CI builds passed - Communicated to DevOps any deployment requirements - Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team ## 🦮 Reviewer guidelines <!-- Suggested interactions but feel free to use (or not) as you desire! --> - 👍 (`:+1:`) or similar for great changes - 📝 (`:memo:`) or ℹ️ (`:information_source:`) for notes or general info - ❓ (`:question:`) for questions - 🤔 (`:thinking:`) or 💭 (`:thought_balloon:`) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion - 🎨 (`:art:`) for suggestions / improvements - ❌ (`:x:`) or ⚠️ (`:warning:`) for more significant problems or concerns needing attention - 🌱 (`:seedling:`) or ♻️ (`:recycle:`) for future improvements or indications of technical debt - ⛏ (`:pick:`) for minor or nitpick changes
1 parent f75a58c commit efed963

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

crates/bitwarden-crypto/src/enc_string/symmetric.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use std::{borrow::Cow, str::FromStr};
33
use bitwarden_encoding::{B64, FromStrVisitor};
44
use coset::{CborSerializable, iana::KeyOperation};
55
use serde::Deserialize;
6+
#[cfg(feature = "wasm")]
7+
use wasm_bindgen::convert::FromWasmAbi;
68

79
use super::{check_length, from_b64, from_b64_vec, split_enc_string};
810
use crate::{
@@ -75,6 +77,25 @@ pub enum EncString {
7577
},
7678
}
7779

80+
#[cfg(feature = "wasm")]
81+
impl wasm_bindgen::describe::WasmDescribe for EncString {
82+
fn describe() {
83+
<String as wasm_bindgen::describe::WasmDescribe>::describe();
84+
}
85+
}
86+
87+
#[cfg(feature = "wasm")]
88+
impl FromWasmAbi for EncString {
89+
type Abi = <String as FromWasmAbi>::Abi;
90+
91+
unsafe fn from_abi(abi: Self::Abi) -> Self {
92+
use wasm_bindgen::UnwrapThrowExt;
93+
94+
let s = unsafe { String::from_abi(abi) };
95+
Self::from_str(&s).unwrap_throw()
96+
}
97+
}
98+
7899
/// Deserializes an [EncString] from a string.
79100
impl FromStr for EncString {
80101
type Err = CryptoError;

crates/bitwarden-wasm-internal/src/pure_crypto.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,22 @@ impl PureCrypto {
318318
.map_err(|_| CryptoError::InvalidKey)?;
319319
Ok(result.to_encoded().to_vec())
320320
}
321+
322+
/// Given an encrypted private RSA key and the symmetric key it is wrapped with, this returns
323+
/// the corresponding public RSA key in DER format.
324+
pub fn rsa_extract_public_key(
325+
encrypted_private_key: EncString,
326+
wrapping_key: Vec<u8>,
327+
) -> Result<Vec<u8>, CryptoError> {
328+
let wrapping_key =
329+
SymmetricCryptoKey::try_from(&BitwardenLegacyKeyBytes::from(wrapping_key))?;
330+
let decrypted_private_key: Vec<u8> =
331+
encrypted_private_key.decrypt_with_key(&wrapping_key)?;
332+
let private_key =
333+
AsymmetricCryptoKey::from_der(&Pkcs8PrivateKeyBytes::from(decrypted_private_key))?;
334+
let public_key = private_key.to_public_key();
335+
Ok(public_key.to_der()?.to_vec())
336+
}
321337
}
322338

323339
#[cfg(test)]

0 commit comments

Comments
 (0)