Skip to content

[v24.x backport] crypto, WebCrypto, and WebIDL updates#63563

Open
panva wants to merge 27 commits into
nodejs:v24.x-stagingfrom
panva:backport-crypto-24
Open

[v24.x backport] crypto, WebCrypto, and WebIDL updates#63563
panva wants to merge 27 commits into
nodejs:v24.x-stagingfrom
panva:backport-crypto-24

Conversation

@panva
Copy link
Copy Markdown
Member

@panva panva commented May 25, 2026

PR-URL: nodejs#62389
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
@panva panva added the commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. label May 25, 2026
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/crypto
  • @nodejs/gyp
  • @nodejs/performance
  • @nodejs/security-wg

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. v24.x Issues that can be reproduced on v24.x or PRs targeting the v24.x-staging branch. labels May 25, 2026
@panva panva marked this pull request as draft May 25, 2026 16:40
panva added 8 commits May 25, 2026 18:41
Consolidate all asymmetric key import paths (DER/PEM, JWK, raw) into
a single KeyObjectHandle::Init() entry point with a uniform signature.

Remove the per-type C++ init methods (InitECRaw, InitEDRaw, InitPqcRaw,
InitJwk, InitECPrivateRaw) and their JS-side callers, replacing them
with shared C++ and JS helpers.

createPublicKey, createPrivateKey, sign, verify, and other operations
that accept key material now handle JWK and raw formats directly in
C++, removing redundant JS-to-C++ key handle round-trips.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62499
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62527
Reviewed-By: James M Snell <jasnell@gmail.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62527
Reviewed-By: James M Snell <jasnell@gmail.com>
Refs: https://hackerone.com/reports/3655230

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62626
Refs: https://hackerone.com/reports/3655230
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62706
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62905
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62883
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
@panva panva force-pushed the backport-crypto-24 branch from c28512b to b58348e Compare May 25, 2026 16:50
@panva panva marked this pull request as ready for review May 25, 2026 16:56
@panva panva changed the title [v24.x backport] crypto, WebCrypto, and PQC updates [v24.x backport] webidl, crypto, WebCrypto, and PQC updates May 25, 2026
@nodejs-github-bot

This comment was marked as outdated.

@panva panva force-pushed the backport-crypto-24 branch from b58348e to 8c19add Compare May 25, 2026 18:07
@panva panva changed the title [v24.x backport] webidl, crypto, WebCrypto, and PQC updates [v24.x backport] crypto, WebCrypto, and WebIDL updates May 25, 2026
@nodejs-github-bot

This comment was marked as outdated.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 25, 2026

Codecov Report

❌ Patch coverage is 91.28164% with 434 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.91%. Comparing base (b881658) to head (061a021).
⚠️ Report is 66 commits behind head on v24.x-staging.

Files with missing lines Patch % Lines
src/crypto/crypto_keys.cc 75.30% 45 Missing and 77 partials ⚠️
src/crypto/crypto_turboshake.cc 83.05% 34 Missing and 26 partials ⚠️
src/crypto/crypto_util.h 50.98% 33 Missing and 17 partials ⚠️
lib/internal/crypto/keys.js 97.05% 16 Missing and 1 partial ⚠️
src/crypto/crypto_keygen.h 78.87% 2 Missing and 13 partials ⚠️
src/crypto/crypto_pqc.cc 87.71% 2 Missing and 12 partials ⚠️
src/crypto/crypto_ec.cc 83.09% 3 Missing and 9 partials ⚠️
lib/internal/crypto/webcrypto.js 97.78% 6 Missing and 4 partials ⚠️
lib/internal/crypto/webcrypto_util.js 93.10% 9 Missing and 1 partial ⚠️
src/crypto/crypto_util.cc 75.60% 3 Missing and 7 partials ⚠️
... and 26 more
Additional details and impacted files
@@                Coverage Diff                @@
##           v24.x-staging   #63563      +/-   ##
=================================================
- Coverage          89.92%   89.91%   -0.01%     
=================================================
  Files                686      689       +3     
  Lines             208389   210582    +2193     
  Branches           40077    40396     +319     
=================================================
+ Hits              187387   189340    +1953     
- Misses             13238    13422     +184     
- Partials            7764     7820      +56     
Files with missing lines Coverage Δ
lib/internal/blob.js 99.44% <100.00%> (+0.18%) ⬆️
lib/internal/crypto/aes.js 92.61% <100.00%> (+4.19%) ⬆️
lib/internal/crypto/argon2.js 98.70% <100.00%> (+2.82%) ⬆️
lib/internal/crypto/chacha20_poly1305.js 98.47% <100.00%> (+5.74%) ⬆️
lib/internal/crypto/cipher.js 98.27% <100.00%> (+<0.01%) ⬆️
lib/internal/crypto/hash.js 98.68% <100.00%> (+0.09%) ⬆️
lib/internal/crypto/hkdf.js 98.84% <100.00%> (+2.86%) ⬆️
lib/internal/crypto/kem.js 95.68% <100.00%> (+0.15%) ⬆️
lib/internal/crypto/keygen.js 98.13% <100.00%> (ø)
lib/internal/crypto/mac.js 99.02% <100.00%> (+7.93%) ⬆️
... and 54 more

... and 32 files with indirect coverage changes

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

panva added 3 commits May 26, 2026 09:20
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62924
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Move KeyObject type and handle storage behind NativeKeyObject and
expose it to JS through a module-private slot reader, mirroring the
CryptoKey hardening. Cache the native slot tuple in a private field
and lazily derive secret and asymmetric metadata from the cached
KeyObjectHandle.

Update internal crypto, QUIC, and comparison callers to use private
helpers instead of public KeyObject accessors. Keep getKeyObjectSlots
restricted to internal/crypto/keys with an ESLint guard.

Add regression coverage for brand checks, hidden slots, clone and
transfer behavior, own-property reflection, and post-clone crypto
operations. Extend the CryptoKey brand test to assert getSlots is not
reachable through the public constructor or prototype chain.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63111
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Clone CryptoKey algorithm dictionaries into null-prototype objects
before storing or caching them internally. Copy nested hash dictionaries
and publicExponent bytes so internal consumers and transferred keys do
not observe user-mutable input objects or polluted Object.prototype
fields.

Keep public algorithm and inspect output as ordinary objects. Make the
clone path check only own hash and publicExponent properties.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63111
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
@panva panva force-pushed the backport-crypto-24 branch from 8c19add to ed231b8 Compare May 26, 2026 07:23
panva added 3 commits May 26, 2026 09:28
Add ESLint rules that reject public KeyObject and CryptoKey accessor
reads after internal brand checks. Internal code must use the private
key helpers so it reads native-backed slots instead of user-replaceable
properties.

Add a separate rule that rejects instanceof checks against KeyObject
and CryptoKey constructors, including the global CryptoKey constructor.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63111
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
BoringSSL declares EVP_CIPHER_do_all_sorted and
EVP_MD_do_all_sorted, but stock no-decrepit builds do not provide
those symbols. Add a Node build flag that keeps ncrypto and its
dependents on a local BoringSSL fallback list when libdecrepit is
absent.

Keep embedders that provide the EVP enumeration symbols on the normal
OpenSSL-compatible path, matching Electron's patched BoringSSL build.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63206
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Add OPENSSL_WITH_* feature macros for crypto capabilities that vary by
OpenSSL version and use those instead of repeating version checks.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63255
Refs: electron/electron#36256
Refs: electron/electron#41720
Refs: electron/electron#51127
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
panva and others added 10 commits May 26, 2026 09:28
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63255
Refs: electron/electron#36256
Refs: electron/electron#41720
Refs: electron/electron#51127
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63255
Refs: electron/electron#36256
Refs: electron/electron#41720
Refs: electron/electron#51127
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63255
Refs: electron/electron#36256
Refs: electron/electron#41720
Refs: electron/electron#51127
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Add a WebCrypto-specific CryptoJob mode that returns a promise from
run() and resolves it when native work is finished.

Encode job output directly as Web Crypto values, including CryptoKey
instances and CryptoKeyPair dictionaries. Convert operation-specific
setup failures from AdditionalConfig into OperationError rejections.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63363
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
Remove async function wrappers from SubtleCrypto methods while keeping
their public promise-returning behaviour.

Route method entry points through a shared helper that converts
synchronous validation errors into rejected promises. Let the internal
implementations return native job promises directly.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63363
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
Pass CryptoKey handles directly into KDF jobs instead of exporting
secret bytes in lib.

Normalize HKDF, PBKDF2, and Argon2 around the same job construction
pattern so WebCrypto derivation paths avoid extra key material copies
and keep operation failures in native job handling.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63363
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
Avoid re-wrapping native WebCrypto promises with PromiseResolve(),
since resolving a promise can read its user-mutated constructor.

Add a helper for chaining internal WebCrypto job promises without
consulting Promise species state, and use it for intermediate job
results.

Also align JWK wrapping and unwrapping with the spec's fresh-global
JSON handling by detaching internal JWK values from user prototypes.
Use the internal UTF-8 encoder/decoder bindings instead of shared
TextEncoder/TextDecoder prototype methods.

Expand the WebCrypto prototype pollution regression test to cover
SubtleCrypto methods, export formats, zero-length KDF results, JWK
toJSON/kty pollution, and encoder/decoder prototype poisoning.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63363
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
PR-URL: nodejs#63417
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Rework lib/internal/webidl.js into a documented shared converter module
that follows the Web IDL conversion algorithms more closely.

Improvements:
- Add documented converters and helper factories for primitive values,
  dictionaries, enums, sequences, interfaces, required arguments,
  integers, `Uint8Array`, and `BufferSource`.
- Move WebCrypto onto the shared converters, while keeping compatibility
  wrappers for its existing `BufferSource` and `BigInteger` behavior.
- Use shared converters from Blob, Performance, Web Locks, and
  structured clone option handling.
- Add benchmarks for `ConvertToInt` and WebCrypto Web IDL converter hot
  paths.
- Add focused tests for core converters, WebCrypto converters, integer
  conversion, and buffer source behavior.

Fixes:
- Make the shared `BufferSource` and `Uint8Array` converters reject
  resizable `ArrayBuffer` and growable `SharedArrayBuffer` backing
  stores unless explicitly allowed. WebCrypto preserves its legacy
  resizable backing-store behavior through compatibility wrappers until
  a semver-major follow-up can opt in to the stricter behavior.
- Use Web IDL `ToNumber` and `ToString` behavior for BigInt, Symbol, and
  object primitive conversion.
- Use exact BigInt modulo for 64-bit `ConvertToInt` wrapping and
  document the final Number approximation behavior.
- Normalize mathematical modulo results to `+0` where Web IDL requires
  it.
- Process inherited dictionaries in least-derived to most-derived order,
  sorting members only within each dictionary level.
- Use `IteratorComplete` truthiness for sequence conversion.
- Cover detached buffers, resizable-backed views, growable-backed views,
  cross-realm buffer sources, mutation-after-call behavior, inherited
  dictionary member order, and sequence iterator completion behavior.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62979
Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Instead of first discarding the top 24 bits of the argument and then
checking that the low 8 bits are within the expected range, first check
that the original 32-bit integer is within the expected range and then
discard the top 24 bits.

PR-URL: nodejs#62763
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Xuguang Mei <meixuguang@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
@panva panva force-pushed the backport-crypto-24 branch from ed231b8 to 51e937e Compare May 26, 2026 07:31
@nodejs-github-bot

This comment was marked as outdated.

Comment thread test/parallel/test-crypto-dh-stateless-async.js Outdated
@nodejs-github-bot

This comment was marked as outdated.

panva added 2 commits May 26, 2026 17:13
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#62645
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Signed-off-by: Filip Skokan <panva.ip@gmail.com>
PR-URL: nodejs#63161
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
@panva panva force-pushed the backport-crypto-24 branch from ca8c11d to 061a021 Compare May 26, 2026 15:13
@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commit-queue-rebase Add this label to allow the Commit Queue to land a PR in several commits. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. v24.x Issues that can be reproduced on v24.x or PRs targeting the v24.x-staging branch.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants