豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

fix(ext/node): fix multiple DiffieHellman crypto bugs#32531

Merged
bartlomieju merged 10 commits intodenoland:mainfrom
bartlomieju:fix/crypto-dh-improvements
Mar 9, 2026
Merged

fix(ext/node): fix multiple DiffieHellman crypto bugs#32531
bartlomieju merged 10 commits intodenoland:mainfrom
bartlomieju:fix/crypto-dh-improvements

Conversation

@bartlomieju
Copy link
Copy Markdown
Member

Summary

  • Fix DH group key generation endianness bug (BigUint::from_slice treating big-endian u32 MODULUS words as little-endian limbs)
  • Fix panic when deriving DH public key from private key (implement modular exponentiation g^x mod p)
  • Fix PKCS#8 DH private key and SPKI public key parsing to properly decode DER-encoded INTEGERs
  • Fix PKCS#8/SPKI export to DER-encode keys as ASN.1 INTEGERs
  • Fix ASN.1 prime/generator encoding in key generation paths
  • Fix JS-side DiffieHellman: prime conversion from u32 word arrays, generator encoding, computeSecret zero-padding, generateKeys idempotency, ArrayBufferView prime handling, diffieHellman() input validation
  • Add modp1 and modp2 groups
  • Enable 10 new node_compat DH tests (8 parallel, 2 pummel)

Test plan

  • cargo test --test node_compat "parallel::test-crypto-dh-" — 10/13 pass (3 remaining need verifyError and stateless DH param normalization)
  • cargo test --test node_compat "pummel::test-crypto-dh-" — 2/2 pass

🤖 Generated with Claude Code

bartlomieju and others added 3 commits March 6, 2026 09:58
Upgrades ed448-goldilocks from 0.8.3 to 0.14.0-pre.10 which adds
signing support. Implements Ed448 and X448 key generation, import/export
(PKCS#8, SPKI, JWK), and Ed448 sign/verify for Node.js crypto compat.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add missing modp1 (768-bit) and modp2 (1024-bit) DH groups
- Fix prime conversion: Buffer.from(array) truncated 32-bit words to
  single bytes, now uses writeUInt32BE for correct serialization
- Store generator with minimal byte representation (02 not 00000002)
- Zero-pad computeSecret output to prime length per RFC 4346
- Fix DiffieHellmanGroup constructor identity
- Handle ArrayBufferView prime argument in createDiffieHellman
- Make generateKeys() idempotent when keys already exist, and only
  regenerate public key after setPrivateKey
- Add input validation and callback support to diffieHellman()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… and panic

- Fix BigUint::from_slice treating big-endian u32 MODULUS words as
  little-endian limbs in DH group key generation
- Fix panic when deriving DH public key from private key by implementing
  modular exponentiation (g^x mod p)
- Fix PKCS#8 DH private key parsing to decode DER INTEGER from OCTET STRING
- Fix SPKI DH public key parsing to decode DER INTEGER from BIT STRING
- Fix PKCS#8/SPKI export to DER-encode keys as ASN.1 INTEGERs
- Fix ASN.1 prime encoding in dh_group_generate (was using native endianness)
- Fix generator encoding to use minimal byte representation
- Compare DH params by integer value instead of byte encoding
- Remove dead u32_slice_to_u8_slice function

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@kajukitli kajukitli left a comment

Choose a reason for hiding this comment

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

Solid fix for the DH endianness and ASN.1 encoding issues. Looked through the changes:

Good stuff:

  • The BigUint::from_slicefrom_bytes_be fix in dh.rs is correct. The MODULUS words were big-endian but being treated as little-endian limbs.
  • Zero-padding computeSecret to prime length per RFC 4346 - this was definitely causing interop issues
  • Comparing DH params by integer value instead of byte encoding in op_node_diffie_hellman - handles the leading 0x00 ASN.1 differences correctly
  • Proper DER INTEGER encoding/decoding for PKCS#8 and SPKI keys

One bug:
In keys.rs around line 1080 (ID_ED448 branch), there's:

.map_err(|_| X509PublicKeyError::InvalidEd25519Key)?;

Should be InvalidEd448Key - copy/paste error.

Nit:
In diffiehellman.ts, using op_node_dh_compute_secret to derive the public key when private key is set externally works, but the naming is a bit confusing since "compute_secret" usually implies computing the shared secret. A comment would help clarify this is computing g^privateKey mod p.

Otherwise lgtm

Copy link
Copy Markdown
Contributor

@kajukitli kajukitli left a comment

Choose a reason for hiding this comment

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

Suggested fixes as inline diff:

diff --git a/ext/node_crypto/keys.rs b/ext/node_crypto/keys.rs
--- a/ext/node_crypto/keys.rs
+++ b/ext/node_crypto/keys.rs
@@ -1080,9 +1080,9 @@ impl KeyObjectHandle {
           ID_ED448 => {
             let data = spki.subject_public_key.as_ref();
             let point_bytes: &[u8; 57] = data
-              .try_into()
-              .map_err(|_| X509PublicKeyError::InvalidEd25519Key)?;
+              .try_into()
+              .map_err(|_| X509PublicKeyError::InvalidEd448Key)?;
             let vk = ed448_goldilocks::VerifyingKey::from_bytes(point_bytes)
-              .map_err(|_| X509PublicKeyError::InvalidEd25519Key)?;
+              .map_err(|_| X509PublicKeyError::InvalidEd448Key)?;
             AsymmetricPublicKey::Ed448(vk)
           }

Comment thread ext/node_crypto/keys.rs
Copy link
Copy Markdown
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, with the error variant fix

bartlomieju and others added 4 commits March 9, 2026 16:41
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…vements

# Conflicts:
#	tests/node_compat/config.jsonc
…ation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bartlomieju bartlomieju enabled auto-merge (squash) March 9, 2026 17:12
@bartlomieju bartlomieju merged commit d3e9c91 into denoland:main Mar 9, 2026
112 checks passed
@bartlomieju bartlomieju deleted the fix/crypto-dh-improvements branch March 9, 2026 19:23
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.

3 participants