Skip to content

[PM-20361] Signature keys #207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 155 commits into from
Jun 16, 2025
Merged

[PM-20361] Signature keys #207

merged 155 commits into from
Jun 16, 2025

Conversation

quexten
Copy link
Contributor

@quexten quexten commented Apr 5, 2025

🎟️ Tracking

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

📔 Objective

Signing operations

This PR adds signing/verifying operations, and keys, including serialization to COSE for both the keys, and for the signatures. We enforce strong domain separation by adding a namespace. This ensures not having to worry about cross-protocol attacks / swapping messages between contexts.

Two signing operations are provided; sign and sign detached. The former signs an object and returns a signedobject, containing the payload. To get the payload, the signature must be verified (guaranteed by the interface). The latter returns signature and serialized message. This is useful when multiple signatures are needed for one message; in this case a countersignature can be created, so that we can have multiple signatures for the same object, in case a trust relationship needs to be proven in multiple directions.

Signing is implemented in 3 layers documented at the top of sign.rs.

The high level layer accepts a struct that is serializable and namespace, and returns a signature and the serialized representation, or the signedobject. The serialization may not be canonical, so the consumer should store the serialized representation instead of their input struct. The reverse operation - verify / getverifiedpayload - returns the deserialized struct.

The middle layer accepts byte array plus namespace.

The low layer is the direct implementation of the signature, and accepts byte array (no namespace). This ensures that implementing a new signature scheme only requires implementing this low level operation.

The one implemented algorithm type is ed25519.

Keys are represented as enums such that it is easy to add other signing key types (ML-DSA for post-quantum crypto, PoC here: #216) later on.

The signature is represented as a Cose Sign1 message (https://www.rfc-editor.org/rfc/rfc9052.html#name-signing-with-one-signer).

The namespace is separated by setting the protected header. Since this is included in the signed data, and since this is validated on verifying the signature, and since the values are unique, domain separation is enforced. We only ever want to expose the safe function outside of the crate (if we even expose it out of the crate).

SignedPublicKey

Public encryption keys should have their owner identity verified. Thus, a new SignedPublicKey that is a signed object containing the public key is created. Consumers must verify the signature before being able to access the public encryption key.

Public key changes

Public keys are hardcoded at the moment to expect DER encoding and RSA-OAEP encryption. This is not the case long-term, and the signature format above makes this clear by including format types.

This PR also includes some prep-work, applying the same per-encryption-time enum variant split in the asymmetric encryption keys. Follow-up work can further clean this up, and clean up the folder structure / file split.

⏰ 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

Copy link
Contributor

github-actions bot commented Apr 5, 2025

Logo
Checkmarx One – Scan Summary & Detailscffc44d2-1073-425c-ba85-efc489ec78d6

Great job, no security vulnerabilities found in this Pull Request

Copy link

codecov bot commented Apr 5, 2025

Codecov Report

Attention: Patch coverage is 85.86859% with 157 lines in your changes missing coverage. Please review.

Project coverage is 71.40%. Comparing base (b0335ef) to head (9fc8fc9).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...tes/bitwarden-crypto/src/keys/signed_public_key.rs 57.33% 32 Missing ⚠️
crates/bitwarden-core/src/key_management/crypto.rs 32.60% 31 Missing ⚠️
crates/bitwarden-crypto/src/store/context.rs 79.80% 21 Missing ⚠️
crates/bitwarden-crypto/src/uniffi_support.rs 0.00% 8 Missing ⚠️
crates/bitwarden-core/src/auth/tde.rs 0.00% 7 Missing ⚠️
crates/bitwarden-crypto/src/signing/cose.rs 92.78% 7 Missing ⚠️
crates/bitwarden-crypto/src/signing/signing_key.rs 91.13% 7 Missing ⚠️
crates/bitwarden-core/src/auth/login/api_key.rs 0.00% 6 Missing ⚠️
crates/bitwarden-core/src/auth/login/password.rs 0.00% 6 Missing ⚠️
...bitwarden-core/src/key_management/crypto_client.rs 0.00% 5 Missing ⚠️
... and 12 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #207      +/-   ##
==========================================
+ Coverage   70.46%   71.40%   +0.93%     
==========================================
  Files         215      224       +9     
  Lines       17084    18081     +997     
==========================================
+ Hits        12038    12910     +872     
- Misses       5046     5171     +125     

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

@quexten quexten changed the title Km/cose signatures [PM-20361] Signature keys Apr 17, 2025
@quexten quexten requested review from Hinton and MGibson1 April 17, 2025 17:22
@quexten
Copy link
Contributor Author

quexten commented Apr 17, 2025

Adding both @MGibson1 and @Hinton to the reviews here. This is a completely new (w.r.t. bitwarden) type of cryptographic object, operation and key.

@quexten quexten marked this pull request as ready for review April 17, 2025 17:38
@quexten quexten requested a review from a team as a code owner April 17, 2025 17:38
@quexten quexten requested a review from addisonbeck April 17, 2025 17:38
@quexten quexten marked this pull request as draft April 30, 2025 11:15
Base automatically changed from km/cose to main May 6, 2025 15:13
@quexten quexten force-pushed the km/cose-signatures branch from f8044bd to c9b80df Compare May 6, 2025 17:27
@quexten quexten marked this pull request as ready for review May 6, 2025 17:50
@quexten quexten requested review from dani-garcia and removed request for addisonbeck May 19, 2025 11:26
@Hinton
Copy link
Member

Hinton commented May 19, 2025

Since there is no consumer I've only looked at the code from an idiomatic rust perspective. I would prefer if we have a working implementation done before merging this since we otherwise won't get a full perspective review.

Hinton
Hinton previously approved these changes Jun 12, 2025
Copy link
Member

@Hinton Hinton left a comment

Choose a reason for hiding this comment

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

Looks good to me, thanks for iterating on this!

@quexten
Copy link
Contributor Author

quexten commented Jun 12, 2025

Brought up-to-date with the wasm client + mobile client merging changes.

Hinton
Hinton previously approved these changes Jun 12, 2025
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.

Looks pretty good to me, some minor nits and questions

Copy link

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.

LGTM, thanks!

@quexten quexten merged commit e147b4d into main Jun 16, 2025
44 checks passed
@quexten quexten deleted the km/cose-signatures branch June 16, 2025 13:37
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