diff --git a/src/node_crypto.cc b/src/node_crypto.cc index c5af0924846c0b..8f673ee6e34772 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -5026,6 +5026,7 @@ template void PublicKeyCipher::Cipher(const FunctionCallbackInfo& args) { + MarkPopErrorOnReturn mark_pop_error_on_return; Environment* env = Environment::GetCurrent(args); unsigned int offset = 0; @@ -5056,8 +5057,6 @@ void PublicKeyCipher::Cipher(const FunctionCallbackInfo& args) { AllocatedBuffer out; - ClearErrorOnReturn clear_error_on_return; - bool r = Cipher( env, pkey, diff --git a/test/parallel/test-crypto-private-decrypt-gh32240.js b/test/parallel/test-crypto-private-decrypt-gh32240.js new file mode 100644 index 00000000000000..4b48774145a3f8 --- /dev/null +++ b/test/parallel/test-crypto-private-decrypt-gh32240.js @@ -0,0 +1,38 @@ +'use strict'; + +// Verify that privateDecrypt() does not leave an error on the +// openssl error stack that is visible to subsequent operations. + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { + generateKeyPairSync, + publicEncrypt, + privateDecrypt, +} = require('crypto'); + +const pair = generateKeyPairSync('rsa', { modulusLength: 512 }); + +const expected = Buffer.from('shibboleth'); +const encrypted = publicEncrypt(pair.publicKey, expected); + +const pkey = pair.privateKey.export({ type: 'pkcs1', format: 'pem' }); +const pkeyEncrypted = + pair.privateKey.export({ + type: 'pkcs1', + format: 'pem', + cipher: 'aes128', + passphrase: 'secret', + }); + +function decrypt(key) { + const decrypted = privateDecrypt(key, encrypted); + assert.deepStrictEqual(decrypted, expected); +} + +decrypt(pkey); +assert.throws(() => decrypt(pkeyEncrypted), { code: 'ERR_MISSING_PASSPHRASE' }); +decrypt(pkey); // Should not throw.