Skip to content
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

fix(ext/crypto): support cross-curve ECDSA sign and verify #28574

Merged
merged 9 commits into from
Mar 22, 2025

Conversation

gopoto
Copy link
Contributor

@gopoto gopoto commented Mar 21, 2025

Fixes: #20198

Overview

The Web Crypto implementation has been artificially limiting ECDSA to only the “recommended” curve/hash pairs (P‑256/SHA‑256 and P‑384/SHA‑384). The underlying ring APIs enforced those pairs, so any attempt to verify signatures produced with different digests (e.g. P‑384 with SHA‑256) failed with a “Not implemented” error.

This PR rewires the ECDSA sign/verify path to use RustCrypto’s ecdsa crate instead of ring, computes digests separately, and uses the prehash signing/verifying API so that any sha1, sha256, sha384 or sha512 can be used with either curve. The JS SubtleCrypto bindings were updated to drop the hard coded checks, and a new unit test exercises P‑384 + SHA‑256 to ensure non‑matching combos now round trip.

Changes

  • ext/crypto/lib.rs: switch ECDSA sign/verify to use ecdsa prehash interfaces; parse signatures as raw r||s; generate raw r||s output.
  • ext/crypto/Cargo.toml: bring in ecdsa and signature crates and enable relevant features.
  • ext/crypto/00_crypto.js: remove curve/hash guards from ECDSA sign/verify.
  • tests/unit/webcrypto_test.ts: add ECDSA cross‑hash test.
  • Build and check passes (cargo build -p deno --offline). Warnings about unused ring imports remain but can be cleaned up separately.

Testing

Run the unit suite and observe the new test case:

cargo build -p deno --offline
./target/debug/deno test --allow-all tests/unit/webcrypto_test.ts

The new testEcdsaCrossHashAlgorithms uses the existing P‑384 test vectors to sign with SHA‑256 and verifies correctly. All existing tests continue to pass.

Notes

This change broadens ECDSA compatibility without affecting RSA, HMAC or EdDSA. Further cleanups (removing unused ring imports, adding P‑521, etc.) could be tackled separately.


Please let me know if any further adjustments are needed.


This PR was generated by an AI system in collaboration with maintainers: @dsherret

Signed-off-by: Gene Parmesan Thomas <201852096+gopoto@users.noreply.github.com>
@ry ry requested a review from littledivy March 21, 2025 05:27
Copy link
Member

@littledivy littledivy left a comment

Choose a reason for hiding this comment

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

lgtm

.ok_or_else(JsErrorBox::not_supported)?;
match named_curve {
CryptoNamedCurve::P256 => {
use p256::ecdsa::{Signature as P256Signature, VerifyingKey};
Copy link
Member

Choose a reason for hiding this comment

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

nit: move these to top level. makes refactors easier.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call; moved the nested use for SigningKey, Signature, and VerifyingKey out of the match arms into top-level imports (with appropriate aliases), and imported PrehashSigner/PrehashVerifier at the top of the module. This makes the code cleaner and easier to refactor.

Signed-off-by: gopoto <201852096+gopoto@users.noreply.github.com>
@littledivy littledivy marked this pull request as ready for review March 21, 2025 07:55
@littledivy

This comment was marked as resolved.

@littledivy littledivy changed the title feat(crypto): support cross-curve ECDSA sign and verify fix(ext/crypto): support cross-curve ECDSA sign and verify Mar 22, 2025
@littledivy littledivy enabled auto-merge (squash) March 22, 2025 17:16
@littledivy littledivy merged commit 5b5e93f into denoland:main Mar 22, 2025
17 checks passed
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