Skip to content

fix(ext/node): accept array forms of cert/key/pfx in createSecureContext#34379

Merged
bartlomieju merged 2 commits into
mainfrom
fix/tls-secure-context-array-forms
May 26, 2026
Merged

fix(ext/node): accept array forms of cert/key/pfx in createSecureContext#34379
bartlomieju merged 2 commits into
mainfrom
fix/tls-secure-context-array-forms

Conversation

@bartlomieju

Copy link
Copy Markdown
Member

tls.createSecureContext did not honor the documented array forms of
cert, key and pfx (see
https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions). Array
cert / key values were silently coerced via String(...) to
unusable strings ([object Object] or a comma-joined byte sequence),
so rustls saw no client certificate and TLS proceeded as anonymous. An
empty pfx: [] (as emitted by playwright's
convertClientCertificatesToTLSOptions when only PEM cert/key are
configured) fell into the PFX validator with an empty buffer and threw
"not enough data".

The polyfill now flattens cert/key arrays into a single PEM string,
unwraps the { pem, passphrase } shape, and decrypts
passphrase-protected keys via createPrivateKey so the result is
parseable by rustls_pemfile. The PFX validation loop iterates arrays
(and { buf, passphrase } entries) and treats empty arrays as a
no-op, matching Node.

Fixes #34367
Fixes #34371

`tls.createSecureContext` did not honor the documented array forms of
`cert`, `key` and `pfx`. Array `cert` / `key` values were silently
coerced via `String(...)` to unusable strings (`[object Object]` or a
comma-joined byte sequence), so rustls saw no client certificate. An
empty `pfx: []` (as emitted by playwright's
`convertClientCertificatesToTLSOptions` when only PEM cert/key are
configured) fell into the PFX validator with an empty buffer and threw
"not enough data".

This change adds `normalizeCertPem` and `normalizeKeyPem` helpers that
flatten arrays into single PEM strings, unwrap the `{ pem, passphrase }`
shape, and decrypt passphrase-protected keys via `createPrivateKey` so
the resulting PEM is consumable by `rustls_pemfile`. The PFX validation
loop now iterates arrays (and `{ buf, passphrase }` entries) and skips
empty arrays.

Fixes #34367, #34371.

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

Array handling now matches the Node forms that this path consumes: cert arrays are concatenated before rustls sees them, key array objects keep per-entry passphrases, and pfx arrays are validated entry-by-entry while [] stays a no-op. The regression test covers the empty pfx case, array cert/key, duplicate PEM blocks, and malformed PFX errors.

if (buf == null) continue;
const pfxData = toUint8Array(buf);
const pfxPassphrase = passphrase != null ? String(passphrase) : null;
op_node_validate_pfx(pfxData, pfxPassphrase);

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.

verify_mac in op_node_validate_pfx hardcodes SHA-1 for both PKDF#12 and HMAC. It requires this fix #34342

…t-array-forms

# Conflicts:
#	tests/unit_node/tls_test.ts
@bartlomieju
bartlomieju merged commit 7aadfe8 into main May 26, 2026
136 checks passed
@bartlomieju
bartlomieju deleted the fix/tls-secure-context-array-forms branch May 26, 2026 09:15
littledivy pushed a commit to crowlKats/deno that referenced this pull request Jun 10, 2026
…ext (denoland#34379)

`tls.createSecureContext` did not honor the documented array forms of
`cert`, `key` and `pfx` (see
https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions). Array
`cert` / `key` values were silently coerced via `String(...)` to
unusable strings (`[object Object]` or a comma-joined byte sequence),
so rustls saw no client certificate and TLS proceeded as anonymous. An
empty `pfx: []` (as emitted by playwright's
`convertClientCertificatesToTLSOptions` when only PEM cert/key are
configured) fell into the PFX validator with an empty buffer and threw
"not enough data".

The polyfill now flattens cert/key arrays into a single PEM string,
unwraps the `{ pem, passphrase }` shape, and decrypts
passphrase-protected keys via `createPrivateKey` so the result is
parseable by `rustls_pemfile`. The PFX validation loop iterates arrays
(and `{ buf, passphrase }` entries) and treats empty arrays as a
no-op, matching Node.

Fixes denoland#34367
Fixes denoland#34371
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants