Skip to content

crypto: add crypto.parsePKCS12() - #65627

Open
bmuenzenmeyer wants to merge 1 commit into
nodejs:mainfrom
bmuenzenmeyer:pkcs12
Open

crypto: add crypto.parsePKCS12()#65627
bmuenzenmeyer wants to merge 1 commit into
nodejs:mainfrom
bmuenzenmeyer:pkcs12

Conversation

@bmuenzenmeyer

Copy link
Copy Markdown
Contributor

Return the private key, end-entity certificate, and CA 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.

SecureContext::LoadPKCS12 has backed tls's pfx option for years, but its results are loaded straight into an SSL_CTX and never reach JavaScript. The capability is in the runtime already; it just isn't reachable. This exposes it.

const { key, cert, ca } = crypto.parsePKCS12(
  readFileSync('bundle.p12'),
  { passphrase: 'secret' },
);

Returns { key: KeyObject|null, cert: X509Certificate|null, ca: X509Certificate[] }.

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.


Return the private key, end-entity certificate, and CA 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.

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 `ca`. A bundle
containing no private key reports `cert` as null and returns its
certificates through `ca`.

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>
@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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lib / src Issues and PRs involving general changes in the lib/ or src/ directories. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants