Skip to content

fix(ext/node): support PKCS#8 encrypted private key PEM export via PBES2#33758

Merged
bartlomieju merged 3 commits into
denoland:mainfrom
divybot:claude/test-crypto-keygen-async-named-elliptic-curve-encrypted-p256
May 1, 2026
Merged

fix(ext/node): support PKCS#8 encrypted private key PEM export via PBES2#33758
bartlomieju merged 3 commits into
denoland:mainfrom
divybot:claude/test-crypto-keygen-async-named-elliptic-curve-encrypted-p256

Conversation

@divybot

@divybot divybot commented May 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Enables test-crypto-keygen-async-named-elliptic-curve-encrypted-p256 in node_compat suite.

Test plan

  • cargo test --test node_compat -- test-crypto-keygen-async-named-elliptic-curve-encrypted-p256

Enables tests/node_compat/runner/suite/test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted-p256.js

Co-authored-by: Divy Srivastava <[email protected]>
@divybot divybot changed the title duplicate of #32805 fix(ext/node): support PKCS#8 encrypted private key PEM export via PBES2 May 1, 2026
The test-crypto-keygen-async-named-elliptic-curve-encrypted-p256 node
compatibility test asserts the exact OpenSSL 3 error string when
attempting to use an encrypted PKCS#8 key without a passphrase. Update
the AsymmetricPrivateKeyError variant message to match.

Also wrap an over-length .map_err line in encrypt_pkcs8_der so the
formatter is satisfied.

Co-authored-by: Divy Srivastava <[email protected]>

@fibibot fibibot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. Verified: (1) the new error string error:07880109:common libcrypto routines::interrupted or cancelled at keys.rs:632 matches Node's own assertion in test/parallel/test-crypto-keygen-async-named-elliptic-curve-encrypted-p256.js for the hasOpenSSL3 branch — faithful Node-parity, not a random OpenSSL string. (2) The crypto_key_test.ts assertion flip from BEGIN PRIVATE KEY to BEGIN ENCRYPTED PRIVATE KEY is correct — that test already passes cipher: "aes-256-cbc" + passphrase, so the prior assertion was hiding a bug where the cipher was silently dropped. CI 133/136 success, 2 skip, 1 cla pending.

One non-blocking smell inline on the parse-error mapping in encrypt_pkcs8_der. Worth a follow-up; doesn't gate this.

Comment thread ext/node_crypto/keys.rs
fn encrypt_pkcs8_der(
data: &[u8],
cipher: &str,
passphrase: &[u8],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Minor: PrivateKeyInfo::try_from(data).map_err(|err| ExportPrivateKeyPemError::UnsupportedCipher(err.to_string())) mislabels a DER parse failure as an unsupported-cipher error. If data is malformed PKCS#8 DER (corrupted upstream), the user sees "Unsupported cipher: ..." which sends them debugging the wrong thing.

Not a blocker — the upstream call sites pass DER bytes that just came out of op_node_export_private_key_pem's own encoder so they're well-formed in practice. But worth a follow-up to add an InvalidPkcs8Der variant (or reuse an existing parse-error variant) so the diagnostic matches the actual failure.

Address review feedback: when encrypt_pkcs8_der is called with malformed
DER bytes, surface "invalid PKCS#8 DER: ..." via a dedicated
InvalidPkcs8Der variant instead of mislabeling it as UnsupportedCipher,
which would send users debugging the wrong thing.

Co-authored-by: Divy Srivastava <[email protected]>
divybot added a commit to divybot/deno that referenced this pull request May 1, 2026
…ariant

The previous variant fired from both the PEM-import call site and the new
encrypted-PKCS#8 DER call site, but Node emits different errors at those
sites: a JS-side ERR_MISSING_PASSPHRASE for the encrypted-DER-no-passphrase
case, and an OpenSSL3 surface message for the encrypted-PEM path. Add a
distinct EncryptedPkcs8DerRequiresPassphrase variant for the DER site so
each path can carry its own message and code without conflicting with
work in denoland#33758.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@bartlomieju
bartlomieju merged commit 0f570e2 into denoland:main May 1, 2026
136 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.

3 participants