Skip to content

crypto: add crypto.parsePKCS12() - #65627

Merged
nodejs-github-bot merged 1 commit into
nodejs:mainfrom
bmuenzenmeyer:pkcs12
Sep 12, 2026
Merged

crypto: add crypto.parsePKCS12()#65627
nodejs-github-bot merged 1 commit into
nodejs:mainfrom
bmuenzenmeyer:pkcs12

Conversation

@bmuenzenmeyer

@bmuenzenmeyer bmuenzenmeyer commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Return the private key, end-entity certificate, and other certificates from a PKCS#12 (.p12/.pfx) bundle as a KeyObject and X509Certificate instances.


Reading a .p12 / .pfx bundle from JavaScript today means shelling out to the openssl pkcs12 CLI or taking a userland dependency such as node-forge. In talking to a colleague about this unfortunate missing method in core, I (with Claude) noticed Node.js already parses this internally.

This PR exposes those internals to end users. Our use case is loading identity files supplied by our environment, to be forwarded during MCP tool calls. This allows us to use real identity instead of service account.

Note

This is my first significant contribution to core that touches the internals. I am still getting my bearings with regard to the module mechanics, bindings, and c++. I'm committed to shaping this, but learning.

SecureContext::LoadPKCS12 has backed tls's pfx option for years, but its results are loaded straight into an SSL_CTX and never reach JavaScript.

const { privateKey, certificate } = parsePKCS12(
  readFileSync('bundle.p12'),
  { passphrase: 'secret' },
);

Returns { privateKey: KeyObject|null, certificate: X509Certificate|null, additionalCertificates: X509Certificate[] }.


Assisted-by: Claude Opus


@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/crypto
  • @nodejs/gyp

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs involving general changes in the lib/ or src/ directories. needs-ci PRs that need a full CI run. labels Aug 28, 2026
@panva
panva self-requested a review August 28, 2026 20:57

@panva panva left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The direction looks alright. I noted a few issues to work through.

Comment thread lib/internal/crypto/keys.js Outdated
Comment thread src/crypto/crypto_pkcs12.cc
Comment thread doc/api/crypto.md Outdated
Comment thread test/parallel/test-crypto-pkcs12.js Outdated
Comment thread lib/internal/crypto/keys.js
Comment thread src/crypto/crypto_pkcs12.cc Outdated
Comment thread doc/api/crypto.md
Comment thread doc/api/crypto.md Outdated
@codecov

codecov Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.86957% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.16%. Comparing base (c143041) to head (c4391ee).
⚠️ Report is 20 commits behind head on main.

Files with missing lines Patch % Lines
src/crypto/crypto_pkcs12.cc 77.65% 7 Missing and 14 partials ⚠️
src/crypto/crypto_context.cc 79.16% 2 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65627      +/-   ##
==========================================
- Coverage   90.18%   90.16%   -0.03%     
==========================================
  Files         771      772       +1     
  Lines      265487   265635     +148     
  Branches    50461    50497      +36     
==========================================
+ Hits       239437   239517      +80     
- Misses      17006    17063      +57     
- Partials     9044     9055      +11     
Files with missing lines Coverage Δ
lib/crypto.js 93.71% <100.00%> (+0.03%) ⬆️
lib/internal/crypto/keys.js 98.30% <100.00%> (+0.07%) ⬆️
src/node_crypto.cc 81.81% <ø> (ø)
src/crypto/crypto_context.cc 71.39% <79.16%> (-0.28%) ⬇️
src/crypto/crypto_pkcs12.cc 77.65% <77.65%> (ø)

... 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 panva added the commit-queue-squash PRs the Commit Queue should land as one squashed commit. label Aug 29, 2026
@panva
panva requested a review from pimterry September 4, 2026 10:45
@bmuenzenmeyer

This comment was marked as outdated.

@bmuenzenmeyer
bmuenzenmeyer marked this pull request as draft September 4, 2026 10:48
@bmuenzenmeyer
bmuenzenmeyer force-pushed the pkcs12 branch 3 times, most recently from dc7a151 to dbcba0a Compare September 4, 2026 13:01
@bmuenzenmeyer
bmuenzenmeyer marked this pull request as ready for review September 4, 2026 13:11
@bmuenzenmeyer
bmuenzenmeyer force-pushed the pkcs12 branch 2 times, most recently from 3a8e383 to 06b6a3b Compare September 4, 2026 15:23
Comment thread src/crypto/crypto_pkcs12.cc
@panva panva removed the commit-queue-squash PRs the Commit Queue should land as one squashed commit. label Sep 4, 2026
Comment thread doc/api/crypto.md Outdated
Comment thread doc/api/crypto.md Outdated
Comment thread doc/api/crypto.md Outdated
Comment thread doc/api/crypto.md Outdated
@bmuenzenmeyer bmuenzenmeyer added the commit-queue-squash PRs the Commit Queue should land as one squashed commit. label Sep 11, 2026
@bmuenzenmeyer bmuenzenmeyer removed the commit-queue-squash PRs the Commit Queue should land as one squashed commit. label Sep 11, 2026
Return the private key, end-entity certificate, and any other
non-matching certificates from a PKCS#12 (.p12/.pfx) bundle as a
KeyObject and X509Certificate instances.

Node.js already parses PKCS#12 in SecureContext::LoadPKCS12, which backs
tls's `pfx` option, but the results are consumed directly into an
SSL_CTX and never reach JavaScript. Callers who need the key or the
certificates for anything other than an immediate TLS connection have to
shell out to `openssl pkcs12` or take a userland dependency.
SecureContext::LoadPKCS12 now uses this same parsing logic.

The binding wraps d2i_PKCS12_bio() and PKCS12_parse() and follows their
semantics, matching the existing TLS path: the first private key is
returned, the end-entity certificate is the one associated with that
key, and any remaining certificates are returned through
`additionalCertificates`. A bundle containing no private key reports
`certificate` as null and returns its certificates through
`additionalCertificates`.

Absent and empty passphrases are kept distinct, since OpenSSL treats
them differently. Bundles that require OpenSSL's legacy provider throw
ERR_CRYPTO_UNSUPPORTED_OPERATION, reusing the error added for the TLS
path.

Signed-off-by: bmuenzenmeyer <brian.muenzenmeyer@gmail.com>
Co-authored-by: Filip Skokan <panva.ip@gmail.com>

@jasnell jasnell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM but would like @panva to also take a look

@panva panva left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@panva panva added author ready PRs with CI started, the required approvals, and no outstanding review comments. request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. labels Sep 11, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. label Sep 11, 2026
@nodejs-github-bot

This comment has been minimized.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@panva panva added semver-minor PRs that contain new features and should be released in the next minor version. commit-queue PRs queued for automated landing through the Commit Queue. labels Sep 12, 2026
@nodejs-github-bot
nodejs-github-bot merged commit 6fc8826 into nodejs:main Sep 12, 2026
82 checks passed
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Landed in 6fc8826

@nodejs-github-bot nodejs-github-bot removed the commit-queue PRs queued for automated landing through the Commit Queue. label Sep 12, 2026
@bmuenzenmeyer
bmuenzenmeyer deleted the pkcs12 branch September 12, 2026 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs with CI started, the required approvals, and no outstanding review comments. lib / src Issues and PRs involving general changes in the lib/ or src/ directories. needs-ci PRs that need a full CI run. semver-minor PRs that contain new features and should be released in the next minor version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants