Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
eb5e85a
Remove nested EncStrings on decrypted CipherViews
nikwithak Aug 3, 2026
4dda207
Store fido2_credentials fully decrypted in LoginView
nikwithak Aug 5, 2026
7dbed79
Throw error when failing to decrypt Fido2 credentials
nikwithak Aug 6, 2026
7107c81
Keep value in AttachmentView on decrypt failures
nikwithak Aug 6, 2026
365ae1a
Remove obsolete comment
nikwithak Aug 6, 2026
9abf0c9
Rename reencrypt_cipher_keys -> validate_attachment_keys to reflect n…
nikwithak Aug 6, 2026
a4eaf60
Drop unused _ctx and _key_store parameters
nikwithak Aug 6, 2026
b7af535
Update comments
nikwithak Aug 6, 2026
a5a508c
Clean up totp tests
nikwithak Aug 6, 2026
58d7116
Remove stale comment
nikwithak Aug 6, 2026
68872e8
Use ctx.add_local_symmetric_key instead of attachment function
nikwithak Aug 6, 2026
492dee1
Merge branch 'main' of https://github.com/bitwarden/sdk-internal into…
nikwithak Aug 6, 2026
a2dab8f
Change decrypted keys from b64 String to SymmetricCryptoKey
nikwithak Aug 7, 2026
3dfb3ec
Clean up deprecated functions
nikwithak Aug 7, 2026
4ed2a03
Change attachment keys to be SymmetricCryptoKey type
nikwithak Aug 7, 2026
e611061
Fix lint errors: Removed no longer needed attributes from TotpClient
nikwithak Aug 7, 2026
6d33e06
Remove key from CipherListView
nikwithak Aug 10, 2026
fea9886
Rename wrapping_key to cipher_key in seal_cipher functions
nikwithak Aug 10, 2026
70b2793
Convert CipherEditREquest::key to SymmetricCryptoKey instead of raw s…
nikwithak Aug 10, 2026
5e13848
clippy: Remove no longer needed key_store and ctx variables
nikwithak Aug 10, 2026
3b12971
Fix clippy errors
nikwithak Aug 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/bitwarden-exporters/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub fn encrypt_import(
if let Some(passkey) = passkey {
let passkeys = passkey.into_iter().map(|p| p.into()).collect();

view.set_new_fido2_credentials(ctx, passkeys)?;
view.set_new_fido2_credentials(passkeys)?;
}

// Select the encryption format based on the account's current security state, matching how
Expand Down
11 changes: 8 additions & 3 deletions crates/bitwarden-exporters/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl From<PasswordHistoryView> for crate::PasswordHistory {
/// Convert a `LoginView` into a `crate::Login`.
fn from_login(
view: &CipherView,
key_store: &KeyStore<KeySlotIds>,
Comment thread
quexten marked this conversation as resolved.
_key_store: &KeyStore<KeySlotIds>,
) -> Result<crate::Login, MissingFieldError> {
let l = require!(view.login.clone());

Expand All @@ -110,11 +110,16 @@ fn from_login(
.collect(),
totp: l.totp,
fido2_credentials: l.fido2_credentials.as_ref().and_then(|_| {
let credentials = view.get_fido2_credentials(&mut key_store.context()).ok()?;
let credentials = view.get_fido2_credentials();
if credentials.is_empty() {
None
} else {
Some(credentials.into_iter().map(|c| c.into()).collect())
Some(
credentials
.into_iter()
.map(|c| Fido2CredentialFullView::from(c).into())
.collect(),
)
}
}),
})
Expand Down
49 changes: 18 additions & 31 deletions crates/bitwarden-fido/src/authenticator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,16 +326,14 @@ impl<'a> Fido2Authenticator<'a> {
pub(super) fn get_selected_credential(
&self,
) -> Result<SelectedCredential, GetSelectedCredentialError> {
let key_store = self.client.internal.get_key_store();

let cipher = self
.selected_cipher
.lock()
.expect("Mutex is not poisoned")
.clone()
.ok_or(GetSelectedCredentialError::NoSelectedCredential)?;

let creds = cipher.decrypt_fido2_credentials(&mut key_store.context())?;
let creds = cipher.get_fido2_credentials();

let credential = creds
.first()
Expand Down Expand Up @@ -480,9 +478,7 @@ impl passkey::authenticator::CredentialStore for CredentialStoreImpl<'_> {
.clone()
.ok_or(InnerError::NoSelectedCredential)?;

let key_store = this.authenticator.client.internal.get_key_store();

selected.set_new_fido2_credentials(&mut key_store.context(), vec![cred])?;
selected.set_new_fido2_credentials(vec![cred])?;

// Store the updated credential for later use
this.authenticator
Expand Down Expand Up @@ -554,10 +550,8 @@ impl passkey::authenticator::CredentialStore for CredentialStoreImpl<'_> {

let cred = fill_with_credential(&selected.credential, cred)?;

let key_store = this.authenticator.client.internal.get_key_store();

let mut selected = selected.cipher;
selected.set_new_fido2_credentials(&mut key_store.context(), vec![cred])?;
selected.set_new_fido2_credentials(vec![cred])?;

// Store the updated credential for later use
this.authenticator
Expand Down Expand Up @@ -681,15 +675,12 @@ fn map_ui_hint(hint: UiHint<'_, CipherViewContainer>) -> UiHint<'_, CipherView>
#[cfg(test)]
mod tests {
use async_trait::async_trait;
use bitwarden_core::{
Client,
key_management::{KeySlotIds, SymmetricKeySlotId},
};
use bitwarden_crypto::{KeyStoreContext, PrimitiveEncryptable, SymmetricCryptoKey};
use bitwarden_core::{Client, key_management::SymmetricKeySlotId};
use bitwarden_crypto::SymmetricCryptoKey;
use bitwarden_encoding::B64Url;
use bitwarden_vault::{
CipherListView, CipherRepromptType, CipherType, CipherView, EncryptionContext,
Fido2Credential, Fido2CredentialNewView, LoginView,
Fido2CredentialNewView, Fido2CredentialView, LoginView,
};
use passkey::authenticator::UiHint;

Expand Down Expand Up @@ -783,23 +774,22 @@ mod tests {
0x84, 0x05, 0x71,
];

fn create_test_cipher(ctx: &mut KeyStoreContext<KeySlotIds>) -> CipherView {
let key = SymmetricKeySlotId::User;
fn create_test_cipher() -> CipherView {
let key_value = B64Url::from(TEST_FIDO_P256_KEY).to_string();

let fido2_credential = Fido2Credential {
credential_id: TEST_FIDO_CREDENTIAL_ID.encrypt(ctx, key).unwrap(),
key_type: "public-key".to_string().encrypt(ctx, key).unwrap(),
key_algorithm: "ECDSA".to_string().encrypt(ctx, key).unwrap(),
key_curve: "P-256".to_string().encrypt(ctx, key).unwrap(),
key_value: key_value.encrypt(ctx, key).unwrap(),
rp_id: TEST_FIDO_RP_ID.encrypt(ctx, key).unwrap(),
user_handle: Some(TEST_FIDO_USER_HANDLE.encrypt(ctx, key).unwrap()),
let fido2_credential = Fido2CredentialView {
credential_id: TEST_FIDO_CREDENTIAL_ID.to_string(),
key_type: "public-key".to_string(),
key_algorithm: "ECDSA".to_string(),
key_curve: "P-256".to_string(),
key_value,
rp_id: TEST_FIDO_RP_ID.to_string(),
user_handle: Some(TEST_FIDO_USER_HANDLE.to_string()),
user_name: None,
counter: "0".to_string().encrypt(ctx, key).unwrap(),
counter: "0".to_string(),
rp_name: None,
user_display_name: None,
discoverable: "true".to_string().encrypt(ctx, key).unwrap(),
discoverable: "true".to_string(),
creation_date: "2024-06-07T14:12:36.150Z".parse().unwrap(),
};

Expand Down Expand Up @@ -867,10 +857,7 @@ mod tests {
.set_symmetric_key(SymmetricKeySlotId::User, user_key)
.unwrap();

let cipher = {
let mut ctx = client.internal.get_key_store().context();
create_test_cipher(&mut ctx)
};
let cipher = create_test_cipher();

let user_interface = MockUserInterface;
let credential_store = MockCredentialStore { cipher };
Expand Down
11 changes: 9 additions & 2 deletions crates/bitwarden-fido/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,15 @@ pub(crate) struct CipherViewContainer {
}

impl CipherViewContainer {
fn new(cipher: CipherView, ctx: &mut KeyStoreContext<KeySlotIds>) -> Result<Self, CipherError> {
let fido2_credentials = cipher.get_fido2_credentials(ctx)?;
fn new(
cipher: CipherView,
_ctx: &mut KeyStoreContext<KeySlotIds>,
) -> Result<Self, CipherError> {
let fido2_credentials = cipher
.get_fido2_credentials()
.into_iter()
.map(Fido2CredentialFullView::from)
.collect();
Ok(Self {
cipher,
fido2_credentials,
Expand Down
4 changes: 2 additions & 2 deletions crates/bitwarden-fido/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ impl Fido2CredentialAutofillView {
#[allow(missing_docs)]
pub fn from_cipher_view(
cipher: &CipherView,
ctx: &mut KeyStoreContext<KeySlotIds>,
_ctx: &mut KeyStoreContext<KeySlotIds>,
) -> Result<Vec<Fido2CredentialAutofillView>, Fido2CredentialAutofillViewError> {
let credentials = cipher.decrypt_fido2_credentials(ctx)?;
let credentials = cipher.get_fido2_credentials();

credentials
.iter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ mod tests {

// A legacy cipher that already carries a per-item cipher key
let mut cipher = make_cipher_view();
cipher.generate_cipher_key(&mut ctx, user_key_old).unwrap();
cipher.generate_cipher_key(&mut ctx).unwrap();
let encrypted = EncryptMode::Legacy(cipher.clone())
.encrypt_composite(&mut ctx, user_key_old)
.unwrap();
Expand Down
Loading
Loading