Skip to content

Conversation

Hinton
Copy link
Member

@Hinton Hinton commented Aug 22, 2025

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-25121

📔 Objective

Migrates most usages of B64 into the new B64 struct.

⏰ 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

  • 👍 (:+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

.map_err(|_| LoginError::InvalidOrganizationId)?;
let encryption_key = SymmetricCryptoKey::try_from(client_state.encryption_key)?;
let encryption_key =
SymmetricCryptoKey::try_from(client_state.encryption_key.to_string())?;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@quexten I think we want to implement From<B64> for SymmetricCryptoKey?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how many more use-cases there are. If you are b64 encoding your unencrypted key, that to me indicates that the use-case is not supported long-term since keys should not leave the SDK, so we'd be making ergonomic improvements for paths we want to discourage.

Are there other areas we'd want to b64 encode a key in?
(Maybe: Never lock? Biometric unlock?)

Copy link
Contributor

github-actions bot commented Aug 22, 2025

Logo
Checkmarx One – Scan Summary & Details0cbeaa70-7b4a-4c7b-8355-9128022be00a

Great job! No new security vulnerabilities introduced in this pull request

Copy link

codecov bot commented Aug 22, 2025

Codecov Report

❌ Patch coverage is 81.27490% with 47 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.15%. Comparing base (f52e521) to head (1e92aa6).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...es/bitwarden-core/src/platform/get_user_api_key.rs 0.00% 5 Missing ⚠️
crates/bitwarden-core/src/auth/access_token.rs 55.55% 4 Missing ⚠️
...bitwarden-core/src/key_management/crypto_client.rs 0.00% 4 Missing ⚠️
...itwarden-core/src/platform/generate_fingerprint.rs 0.00% 4 Missing ⚠️
...crypto/src/safe/password_protected_key_envelope.rs 0.00% 4 Missing ⚠️
crates/bitwarden-uniffi/src/auth/mod.rs 0.00% 4 Missing ⚠️
crates/bitwarden-core/src/auth/auth_client.rs 0.00% 3 Missing ⚠️
crates/bitwarden-core/src/key_management/crypto.rs 86.95% 3 Missing ⚠️
...tes/bitwarden-crypto/src/keys/signed_public_key.rs 0.00% 3 Missing ⚠️
crates/bitwarden-encoding/src/b64url.rs 83.33% 3 Missing ⚠️
... and 7 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #409      +/-   ##
==========================================
+ Coverage   76.10%   76.15%   +0.04%     
==========================================
  Files         264      264              
  Lines       24045    24070      +25     
==========================================
+ Hits        18299    18330      +31     
+ Misses       5746     5740       -6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Hinton Hinton changed the title Use the new B64 everywhere Use the new B64 in bitwarden-core and bitwarden-crypto Aug 22, 2025
@Hinton Hinton marked this pull request as ready for review August 22, 2025 15:00
@Hinton Hinton requested review from a team as code owners August 22, 2025 15:00
Copy link
Member

@dani-garcia dani-garcia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks pretty good to me, some comments

AccessTokenInvalidError::InvalidBase64Length {
expected: 16,
got: e.len(),
got: encryption_key.as_ref().len(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should implement Deref<[u8]> for B64, then you could remove the as_ref():

        let encryption_key = Zeroizing::new((*encryption_key).try_into().map_err(|_| {
            AccessTokenInvalidError::InvalidBase64Length {
                expected: 16,
                got: encryption_key.len(),
            }
        })?);

Copy link
Member Author

@Hinton Hinton Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe. At the same time I like that we're explicit when we need to go B64 -> slice. In your suggestion there is an ambiguity of what len returns. The length of bytes or length of the b64 encoded string?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but then as_ref is not a particularly descriptive trait either. If we wanted to be unambiguous I feel like we should use an as_slice function.

private_key: STANDARD.encode(key.to_der()?),
public_key: b64,
private_key: key.to_der()?.as_ref().into(),
public_key: spki.as_ref().into(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want a direct B64 -> Bytes and Bytes -> B64 conversion? It should avoid the need to call as_ref as much

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@quexten thoughts?

Copy link
Contributor

@quexten quexten Aug 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that makes sense.

Note, for some instantiations of Bytes such as utf8, (maybe octet stream, pkcs8privatekey) we don't need / want the implementation, so we may add bounds and a marker trait for the variant that we allow the conversion for?

@Hinton Hinton requested a review from dani-garcia August 25, 2025 09:40
Copy link

Copy link

@Hinton Hinton requested a review from quexten August 25, 2025 17:01
Copy link
Contributor

@Thomas-Avery Thomas-Avery left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this makes things easier to follow and understand.

Copy link
Contributor

@quexten quexten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, the marker trait is neat!

@Hinton Hinton merged commit bc66e3d into main Aug 26, 2025
68 of 70 checks passed
@Hinton Hinton deleted the arch/base64-use branch August 26, 2025 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants