-
-
Notifications
You must be signed in to change notification settings - Fork 36.6k
crypto: add crypto.parsePKCS12() #65627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
9e8f05c
9e94a9a
42bc331
e24d894
44b14a4
2d6065c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| 'use strict'; | ||
|
|
||
| const { | ||
| ArrayPrototypeMap, | ||
| ArrayPrototypeSlice, | ||
| ObjectDefineProperties, | ||
| ObjectPrototypeHasOwnProperty, | ||
|
|
@@ -35,6 +36,7 @@ const { | |
| kKeyEncodingPKCS8, | ||
| kKeyEncodingSPKI, | ||
| kKeyEncodingSEC1, | ||
| parsePKCS12: _parsePKCS12, | ||
|
panva marked this conversation as resolved.
|
||
| } = internalBinding('crypto'); | ||
|
|
||
| const { | ||
|
|
@@ -77,6 +79,8 @@ const { | |
| isArrayBufferView, | ||
| } = require('internal/util/types'); | ||
|
|
||
| const { Buffer } = require('buffer'); | ||
|
|
||
| const { | ||
| fileURLToPath, | ||
| getURLHref, | ||
|
|
@@ -739,6 +743,55 @@ function createPublicKey(key) { | |
| return new PublicKeyObject(handle); | ||
| } | ||
|
|
||
| /** | ||
| * Parses a PKCS#12 (.p12 / .pfx) bundle. Returns an object holding the first | ||
| * private key as `key`, the certificate associated with it as `cert`, and any | ||
| * remaining certificates as an array in `ca`; `key` and `cert` are null when | ||
| * the bundle contains none. | ||
| * @param {ArrayBuffer|Buffer|TypedArray|DataView} bundle | ||
| * @param {object} [options] | ||
| * @returns {object} | ||
| */ | ||
| function parsePKCS12(bundle, options = kEmptyObject) { | ||
| if (!isArrayBufferView(bundle) && !isAnyArrayBuffer(bundle)) { | ||
| throw new ERR_INVALID_ARG_TYPE( | ||
| 'bundle', | ||
| ['ArrayBuffer', 'TypedArray', 'DataView', 'Buffer'], | ||
| bundle); | ||
| } | ||
|
|
||
| validateObject(options, 'options'); | ||
| const { passphrase } = options; | ||
|
|
||
| // Absent and empty passphrases are distinct at the OpenSSL level and are | ||
| // kept distinct here. `undefined` means no passphrase; '' means a | ||
| // zero-length one. | ||
| let passBuf; | ||
| if (passphrase !== undefined) { | ||
| passBuf = getArrayBufferOrView(passphrase, 'options.passphrase', 'utf8'); | ||
| // The binding reads the passphrase as a view; wrap a bare ArrayBuffer. | ||
| if (isAnyArrayBuffer(passBuf)) passBuf = Buffer.from(passBuf); | ||
| } | ||
|
|
||
| // Likewise, the binding reads the bundle as a view. | ||
| const bundleBuf = isAnyArrayBuffer(bundle) ? Buffer.from(bundle) : bundle; | ||
|
|
||
| const { | ||
| 0: keyHandle, | ||
| 1: certHandle, | ||
| 2: caHandles, | ||
| } = _parsePKCS12(bundleBuf, passBuf); | ||
|
|
||
| // Required lazily: internal/crypto/x509 depends on this module. | ||
| const { InternalX509Certificate } = require('internal/crypto/x509'); | ||
|
|
||
| return { | ||
| key: keyHandle === null ? null : new PrivateKeyObject(keyHandle), | ||
| cert: certHandle === null ? null : new InternalX509Certificate(certHandle), | ||
| ca: ArrayPrototypeMap(caHandles, (h) => new InternalX509Certificate(h)), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| }; | ||
| } | ||
|
|
||
| /** | ||
| * Converts a secret KeyObjectHandle to a CryptoKey by dispatching to the | ||
| * algorithm-specific Web Crypto import path. | ||
|
|
@@ -1333,6 +1386,7 @@ module.exports = { | |
| createSecretKey, | ||
| createPublicKey, | ||
| createPrivateKey, | ||
| parsePKCS12, | ||
| KeyObject, | ||
| CryptoKey, | ||
| InternalCryptoKey, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not the behavior exposed by
PKCS12_parse(). When given eithernullptror"", OpenSSL tries both PKCS#12 password encodings and uses whichever verifies the MAC. The tests already open the sameec.pfxonce with""and once with omission.