From 614d646767ec37de23d5db25e103540230beafbb Mon Sep 17 00:00:00 2001 From: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> Date: Sun, 30 Oct 2022 04:23:16 +0800 Subject: [PATCH] src: fix `crypto.privateEncrypt` fails first time `crypto.privateEncrypt` fails for the first time after `crypto.generateKeyPairSync` with certain parameters because the error stack is not cleaned up when `crypto.generateKeyPairSync` exits. Fixes: https://github.com/nodejs/node/issues/40814 PR-URL: https://github.com/nodejs/node/pull/42793 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Filip Skokan --- src/crypto/crypto_keys.cc | 1 + ...t-crypto-publicDecrypt-fails-first-time.js | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/parallel/test-crypto-publicDecrypt-fails-first-time.js diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index d52ffeb9d44430..d1ea8f8f2cde7e 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -319,6 +319,7 @@ MaybeLocal WritePrivateKey( } } + MarkPopErrorOnReturn mark_pop_error_on_return; bool err; PKEncodingType encoding_type = config.type_.ToChecked(); diff --git a/test/parallel/test-crypto-publicDecrypt-fails-first-time.js b/test/parallel/test-crypto-publicDecrypt-fails-first-time.js new file mode 100644 index 00000000000000..a60b87dbf65229 --- /dev/null +++ b/test/parallel/test-crypto-publicDecrypt-fails-first-time.js @@ -0,0 +1,41 @@ +'use strict'; +const common = require('../common'); + +// Test for https://github.com/nodejs/node/issues/40814 + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.hasOpenSSL3) + common.skip('only openssl3'); // https://github.com/nodejs/node/pull/42793#issuecomment-1107491901 + +const assert = require('assert'); +const crypto = require('crypto'); + +const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', { + modulusLength: 2048, + publicKeyEncoding: { + type: 'spki', + format: 'pem' + }, + privateKeyEncoding: { + type: 'pkcs8', + format: 'pem', + cipher: 'aes-128-ecb', + passphrase: 'abcdef' + } +}); +assert.notStrictEqual(privateKey.toString(), ''); + +const msg = 'The quick brown fox jumps over the lazy dog'; + +const encryptedString = crypto.privateEncrypt({ + key: privateKey, + passphrase: 'abcdef' +}, Buffer.from(msg)).toString('base64'); +const decryptedString = crypto.publicDecrypt(publicKey, Buffer.from(encryptedString, 'base64')).toString(); +console.log(`Encrypted: ${encryptedString}`); +console.log(`Decrypted: ${decryptedString}`); + +assert.notStrictEqual(encryptedString, ''); +assert.strictEqual(decryptedString, msg);