From 32e45b20da0b9a17f4d27d81e86997e800c9ac3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Thu, 3 Jan 2019 18:59:34 +0100 Subject: [PATCH] crypto: fix key object wrapping in sync keygen PR-URL: https://github.com/nodejs/node/pull/25326 Fixes: https://github.com/nodejs/node/issues/25322 Reviewed-By: Ben Noordhuis Reviewed-By: Colin Ihrig Reviewed-By: Sam Roberts Reviewed-By: James M Snell --- doc/api/crypto.md | 23 +++++++++-------------- lib/internal/crypto/keygen.js | 6 +++++- test/parallel/test-crypto-keygen.js | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index bc842062d06257..95b1e9114ab536 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1951,18 +1951,8 @@ changes: - `publicExponent`: {number} Public exponent (RSA). **Default:** `0x10001`. - `divisorLength`: {number} Size of `q` in bits (DSA). - `namedCurve`: {string} Name of the curve to use (EC). - - `publicKeyEncoding`: {Object} - - `type`: {string} Must be one of `'pkcs1'` (RSA only) or `'spki'`. - - `format`: {string} Must be `'pem'` or `'der'`. - - `privateKeyEncoding`: {Object} - - `type`: {string} Must be one of `'pkcs1'` (RSA only), `'pkcs8'` or - `'sec1'` (EC only). - - `format`: {string} Must be `'pem'` or `'der'`. - - `cipher`: {string} If specified, the private key will be encrypted with - the given `cipher` and `passphrase` using PKCS#5 v2.0 password based - encryption. - - `passphrase`: {string | Buffer} The passphrase to use for encryption, see - `cipher`. + - `publicKeyEncoding`: {Object} See [`keyObject.export()`][]. + - `privateKeyEncoding`: {Object} See [`keyObject.export()`][]. * Returns: {Object} - `publicKey`: {string | Buffer | KeyObject} - `privateKey`: {string | Buffer | KeyObject} @@ -1970,8 +1960,13 @@ changes: Generates a new asymmetric key pair of the given `type`. Only RSA, DSA and EC are currently supported. -It is recommended to encode public keys as `'spki'` and private keys as -`'pkcs8'` with encryption: +If a `publicKeyEncoding` or `privateKeyEncoding` was specified, this function +behaves as if [`keyObject.export()`][] had been called on its result. Otherwise, +the respective part of the key is returned as a [`KeyObject`]. + +When encoding public keys, it is recommended to use `'spki'`. When encoding +private keys, it is recommended to use `'pks8'` with a strong passphrase, and to +keep the passphrase confidential. ```js const { generateKeyPairSync } = require('crypto'); diff --git a/lib/internal/crypto/keygen.js b/lib/internal/crypto/keygen.js index 7c0c4110439860..21dbf5ff8a136e 100644 --- a/lib/internal/crypto/keygen.js +++ b/lib/internal/crypto/keygen.js @@ -74,7 +74,11 @@ function handleError(impl, wrap) { if (err !== undefined) throw err; - return { publicKey, privateKey }; + // If no encoding was chosen, return key objects instead. + return { + publicKey: wrapKey(publicKey, PublicKeyObject), + privateKey: wrapKey(privateKey, PrivateKeyObject) + }; } function parseKeyEncoding(keyType, options) { diff --git a/test/parallel/test-crypto-keygen.js b/test/parallel/test-crypto-keygen.js index 43319c38599ebf..aabd92e369a3c0 100644 --- a/test/parallel/test-crypto-keygen.js +++ b/test/parallel/test-crypto-keygen.js @@ -95,6 +95,21 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); testSignVerify(publicKey, privateKey); } +{ + // Test sync key generation with key objects. + const { publicKey, privateKey } = generateKeyPairSync('rsa', { + modulusLength: 512 + }); + + assert.strictEqual(typeof publicKey, 'object'); + assert.strictEqual(publicKey.type, 'public'); + assert.strictEqual(publicKey.asymmetricKeyType, 'rsa'); + + assert.strictEqual(typeof privateKey, 'object'); + assert.strictEqual(privateKey.type, 'private'); + assert.strictEqual(privateKey.asymmetricKeyType, 'rsa'); +} + { const publicKeyEncoding = { type: 'pkcs1',