summaryrefslogtreecommitdiff
path: root/lib/internal/crypto/keygen.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/internal/crypto/keygen.js')
-rw-r--r--lib/internal/crypto/keygen.js135
1 files changed, 46 insertions, 89 deletions
diff --git a/lib/internal/crypto/keygen.js b/lib/internal/crypto/keygen.js
index 7222d301f0..7c0c411043 100644
--- a/lib/internal/crypto/keygen.js
+++ b/lib/internal/crypto/keygen.js
@@ -6,24 +6,32 @@ const {
generateKeyPairDSA,
generateKeyPairEC,
OPENSSL_EC_NAMED_CURVE,
- OPENSSL_EC_EXPLICIT_CURVE,
- PK_ENCODING_PKCS1,
- PK_ENCODING_PKCS8,
- PK_ENCODING_SPKI,
- PK_ENCODING_SEC1,
- PK_FORMAT_DER,
- PK_FORMAT_PEM
+ OPENSSL_EC_EXPLICIT_CURVE
} = internalBinding('crypto');
+const {
+ parsePublicKeyEncoding,
+ parsePrivateKeyEncoding,
+
+ PublicKeyObject,
+ PrivateKeyObject
+} = require('internal/crypto/keys');
const { customPromisifyArgs } = require('internal/util');
const { isUint32, validateString } = require('internal/validators');
const {
- ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS,
ERR_INVALID_ARG_TYPE,
ERR_INVALID_ARG_VALUE,
ERR_INVALID_CALLBACK,
ERR_INVALID_OPT_VALUE
} = require('internal/errors').codes;
+const { isArrayBufferView } = require('internal/util/types');
+
+function wrapKey(key, ctor) {
+ if (typeof key === 'string' || isArrayBufferView(key))
+ return key;
+ return new ctor(key);
+}
+
function generateKeyPair(type, options, callback) {
if (typeof options === 'function') {
callback = options;
@@ -38,6 +46,9 @@ function generateKeyPair(type, options, callback) {
const wrap = new AsyncWrap(Providers.KEYPAIRGENREQUEST);
wrap.ondone = (ex, pubkey, privkey) => {
if (ex) return callback.call(wrap, ex);
+ // If no encoding was chosen, return key objects instead.
+ pubkey = wrapKey(pubkey, PublicKeyObject);
+ privkey = wrapKey(privkey, PrivateKeyObject);
callback.call(wrap, null, pubkey, privkey);
};
@@ -69,86 +80,32 @@ function handleError(impl, wrap) {
function parseKeyEncoding(keyType, options) {
const { publicKeyEncoding, privateKeyEncoding } = options;
- if (publicKeyEncoding == null || typeof publicKeyEncoding !== 'object')
- throw new ERR_INVALID_OPT_VALUE('publicKeyEncoding', publicKeyEncoding);
-
- const { format: strPublicFormat, type: strPublicType } = publicKeyEncoding;
-
- let publicType;
- if (strPublicType === 'pkcs1') {
- if (keyType !== 'rsa') {
- throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS(
- strPublicType, 'can only be used for RSA keys');
- }
- publicType = PK_ENCODING_PKCS1;
- } else if (strPublicType === 'spki') {
- publicType = PK_ENCODING_SPKI;
+ let publicFormat, publicType;
+ if (publicKeyEncoding == null) {
+ publicFormat = publicType = undefined;
+ } else if (typeof publicKeyEncoding === 'object') {
+ ({
+ format: publicFormat,
+ type: publicType
+ } = parsePublicKeyEncoding(publicKeyEncoding, keyType,
+ 'publicKeyEncoding'));
} else {
- throw new ERR_INVALID_OPT_VALUE('publicKeyEncoding.type', strPublicType);
+ throw new ERR_INVALID_OPT_VALUE('publicKeyEncoding', publicKeyEncoding);
}
- let publicFormat;
- if (strPublicFormat === 'der') {
- publicFormat = PK_FORMAT_DER;
- } else if (strPublicFormat === 'pem') {
- publicFormat = PK_FORMAT_PEM;
+ let privateFormat, privateType, cipher, passphrase;
+ if (privateKeyEncoding == null) {
+ privateFormat = privateType = undefined;
+ } else if (typeof privateKeyEncoding === 'object') {
+ ({
+ format: privateFormat,
+ type: privateType,
+ cipher,
+ passphrase
+ } = parsePrivateKeyEncoding(privateKeyEncoding, keyType,
+ 'privateKeyEncoding'));
} else {
- throw new ERR_INVALID_OPT_VALUE('publicKeyEncoding.format',
- strPublicFormat);
- }
-
- if (privateKeyEncoding == null || typeof privateKeyEncoding !== 'object')
throw new ERR_INVALID_OPT_VALUE('privateKeyEncoding', privateKeyEncoding);
-
- const {
- cipher,
- passphrase,
- format: strPrivateFormat,
- type: strPrivateType
- } = privateKeyEncoding;
-
- let privateType;
- if (strPrivateType === 'pkcs1') {
- if (keyType !== 'rsa') {
- throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS(
- strPrivateType, 'can only be used for RSA keys');
- }
- privateType = PK_ENCODING_PKCS1;
- } else if (strPrivateType === 'pkcs8') {
- privateType = PK_ENCODING_PKCS8;
- } else if (strPrivateType === 'sec1') {
- if (keyType !== 'ec') {
- throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS(
- strPrivateType, 'can only be used for EC keys');
- }
- privateType = PK_ENCODING_SEC1;
- } else {
- throw new ERR_INVALID_OPT_VALUE('privateKeyEncoding.type', strPrivateType);
- }
-
- let privateFormat;
- if (strPrivateFormat === 'der') {
- privateFormat = PK_FORMAT_DER;
- } else if (strPrivateFormat === 'pem') {
- privateFormat = PK_FORMAT_PEM;
- } else {
- throw new ERR_INVALID_OPT_VALUE('privateKeyEncoding.format',
- strPrivateFormat);
- }
-
- if (cipher != null) {
- if (typeof cipher !== 'string')
- throw new ERR_INVALID_OPT_VALUE('privateKeyEncoding.cipher', cipher);
- if (privateFormat === PK_FORMAT_DER &&
- (privateType === PK_ENCODING_PKCS1 ||
- privateType === PK_ENCODING_SEC1)) {
- throw new ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS(
- strPrivateType, 'does not support encryption');
- }
- if (typeof passphrase !== 'string') {
- throw new ERR_INVALID_OPT_VALUE('privateKeyEncoding.passphrase',
- passphrase);
- }
}
return {
@@ -181,8 +138,8 @@ function check(type, options, callback) {
}
impl = (wrap) => generateKeyPairRSA(modulusLength, publicExponent,
- publicType, publicFormat,
- privateType, privateFormat,
+ publicFormat, publicType,
+ privateFormat, privateType,
cipher, passphrase, wrap);
}
break;
@@ -200,8 +157,8 @@ function check(type, options, callback) {
}
impl = (wrap) => generateKeyPairDSA(modulusLength, divisorLength,
- publicType, publicFormat,
- privateType, privateFormat,
+ publicFormat, publicType,
+ privateFormat, privateType,
cipher, passphrase, wrap);
}
break;
@@ -219,8 +176,8 @@ function check(type, options, callback) {
throw new ERR_INVALID_OPT_VALUE('paramEncoding', paramEncoding);
impl = (wrap) => generateKeyPairEC(namedCurve, paramEncoding,
- publicType, publicFormat,
- privateType, privateFormat,
+ publicFormat, publicType,
+ privateFormat, privateType,
cipher, passphrase, wrap);
}
break;