Skip to content

Conversation

@quexten
Copy link
Contributor

@quexten quexten commented Oct 28, 2025

🎟️ Tracking

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

Fixes:
bitwarden/clients#17028
bitwarden/clients#14076

📔 Objective

Updates the bitwarden-ssh dependencies to rc releases from RustCrypto. This allows us to:

  • Drop our PKCS5 patch crate
  • Fix import of putty keys
  • Fix import of various other broken keys (linewidth issues and others)

It also replaces the RSA crate that has a vulnerability (timing attack) - though, it is unlikely that this actually affects import / was abusable.

RSA key generation test vectors are broken because the underlying RSA generation algorithm changed with rustcrypto's massive re-implementation of RSA, hence new test keys are provided.

Note: This pins the dependencies to be different from the workspace crates, as those are not yet ready to be updated. Eventually we will update those bit-by-bit too and then drop the dependency pinning.

⏰ 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

@github-actions
Copy link
Contributor

github-actions bot commented Oct 28, 2025

Logo
Checkmarx One – Scan Summary & Details6119c753-9f33-4ba7-bdc1-33e27427ed53

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

@quexten quexten marked this pull request as ready for review October 29, 2025 18:41
@quexten quexten requested a review from a team as a code owner October 29, 2025 18:41
@quexten quexten requested a review from addisonbeck October 29, 2025 18:41
@quexten quexten changed the title [BEEEP] Update ssh dependencies and fix imports of various SSH keys [BEEEP] Update bitwarden-ssh RustCrypto dependencies, fixing imports of various SSH keys Oct 29, 2025
@claude
Copy link

claude bot commented Oct 29, 2025

Claude finished @quexten's task —— View job


Comprehensive Code Review

I've completed a thorough review of PR #536, which updates bitwarden-ssh RustCrypto dependencies to RC releases.


Summary of Changes

This PR upgrades the bitwarden-ssh crate to use release candidate (RC) versions of RustCrypto dependencies, specifically:

  • ssh-key: 0.6.x → 0.7.0-rc.3
  • ed25519/ed25519-dalek: 2.x → 3.0.0-rc.1/pre.1
  • rsa: 0.9.x → 0.10.0-rc.9
  • pkcs8: 0.10.x → 0.11.0-rc.7
  • pem-rfc7468: 0.7.0 → 1.0.0-rc.3
  • Various other crypto dependencies bumped to RC versions

Key improvements:

  • Removes the custom PKCS5 patch crate (no longer needed)
  • Fixes PuTTY key import issues
  • Fixes regression in issue #17028 (line width issues)
  • Addresses RSA timing attack vulnerability (though low risk in import context)

Critical Issues

None identified. The changes are well-structured and the updated dependencies address legitimate security and functionality issues.


Security Implications

✅ Positive:

  1. RSA timing attack mitigation: The new rsa crate (0.10.0-rc.9) addresses a timing attack vulnerability in the previous version. While unlikely to be exploitable during key import operations, this is good defense-in-depth.

  2. No secrets in logs: Verified that no new logging of sensitive data was introduced. The code properly maintains separation between key material and error messages.

  3. Backward compatibility maintained: The import/export functions maintain the same API surface and OpenSSH format output, ensuring existing encrypted data remains decryptable.

⚠️ Considerations:

RC dependency pinning strategy (click to expand)

The PR pins dependencies to specific RC versions (using = instead of version ranges), which deviates from workspace conventions. From the PR description:

"This pins the dependencies to be different from the workspace crates, as those are not yet ready to be updated."

Implications:

  • bitwarden-ssh now uses ed25519-dalek = "=3.0.0-pre.1" while bitwarden-crypto uses workspace version ed25519-dalek = ">=2.1.1, <=2.2.0"
  • This creates two separate dependency trees in the same workspace
  • Need to track when workspace dependencies can be updated to avoid long-term divergence

Recommendation: Add a tracking issue or TODO comment in the code noting this temporary divergence and when it should be reconciled.


Suggested Improvements

📝 Documentation & Tracking

  1. crates/bitwarden-ssh/Cargo.toml:30-37 - Consider adding a comment explaining the temporary RC dependency pinning:
# TEMPORARY: These dependencies use RC versions ahead of the workspace.
# When workspace dependencies are ready to upgrade, unpin these and use
# workspace versions. See: [link to tracking issue if one exists]
block-padding = { version = "=0.4.0-rc.4" }
ed25519 = { version = "3.0.0-rc.1", features = ["pkcs8"] }
# ... etc

🎨 Code Quality

  1. crates/bitwarden-ssh/src/import.rs:24-25 - The generic type parameters on PEM_LABEL constants are unusual:
pkcs8::PrivateKeyInfo::<(), (), ()>::PEM_LABEL => import_pkcs8_key(encoded_key, None),
pkcs8::EncryptedPrivateKeyInfo::<()>::PEM_LABEL => import_pkcs8_key(

This appears to be a requirement from the updated pkcs8 crate API. The turbofish syntax with unit types is correct but visually noisy. Consider adding a brief comment explaining why this is necessary if it's non-obvious from the pkcs8 docs.

  1. crates/bitwarden-ssh/src/generator.rs:30 - Good update from rand::thread_rng() to rand::rng(), which follows the newer rand 0.9 API conventions.

  2. crates/bitwarden-ssh/src/export.rs:28-38 - The RSA keypair conversion now properly uses TryFrom trait:

let rk: RsaPrivateKey = keypair
    .try_into()
    .map_err(|_| SshKeyExportError::KeyConversion)?;

This removes the previous manual convert_rsa_keypair workaround. Excellent - the upstream fix in RustCrypto made this possible.

🧪 Testing

  1. Test coverage is comprehensive - New test cases cover the fixed scenarios:

    • import_key_ed25519_putty() - now expects success instead of parsing error
    • import_key_rsa_openssh_putty() - now expects success instead of parsing error
    • import_ed25519_key_regression_17028() - regression test for issue #17028
  2. RSA test vector changes - The PR correctly regenerates RSA test vectors since the underlying RSA generation algorithm changed in RustCrypto. The new keys in resources/generator/rsa3072_key and resources/generator/rsa4096_key reflect this algorithm change.

⚠️ Minor Concerns

  1. crates/bitwarden-ssh/Cargo.toml:22 - The getrandom/wasm_js feature was added to WASM support. This is correct, but worth verifying this is actually needed or if it was added preemptively. The corresponding change in build.sh suggests it's necessary.

Good Practices Observed

  • Proper error handling with specific error types
  • Comprehensive test coverage with regression tests
  • Removed technical debt (custom PKCS5 patch)
  • Clear commit messages and PR description
  • Updated test vectors appropriately

Action Items for Author

  1. Consider adding tracking issue/comment for RC dependency pinning divergence from workspace
  2. Verify WASM build passes with the new getrandom/wasm_js feature requirement
  3. Plan workspace-wide upgrade path for when RustCrypto stable releases are available
  4. Optional: Add inline comment explaining the generic type parameters on PEM_LABEL constants if non-obvious

Overall Assessment

This is a well-executed dependency upgrade that addresses real issues (PuTTY import bugs, security vulnerability) while maintaining backward compatibility. The code quality is high, tests are comprehensive, and the changes follow Rust best practices. The temporary dependency pinning is pragmatic given the workspace constraints.

Recommendation: Approve after addressing tracking issue for dependency pinning.

@codecov
Copy link

codecov bot commented Oct 30, 2025

Codecov Report

❌ Patch coverage is 96.55172% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 78.66%. Comparing base (8ef7951) to head (47325ab).

Files with missing lines Patch % Lines
crates/bitwarden-ssh/src/generator.rs 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #536      +/-   ##
==========================================
- Coverage   78.70%   78.66%   -0.04%     
==========================================
  Files         296      296              
  Lines       30500    30504       +4     
==========================================
- Hits        24005    23997       -8     
- Misses       6495     6507      +12     

☔ 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.

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.

2 participants