diff --git a/src/crypto/crypto_scrypt.cc b/src/crypto/crypto_scrypt.cc index 24ba2f3e3c5e..8e1cd2e43a4a 100644 --- a/src/crypto/crypto_scrypt.cc +++ b/src/crypto/crypto_scrypt.cc @@ -85,6 +85,7 @@ Maybe ScryptTraits::AdditionalConfig( params->length = args[offset + 6].As()->Value(); CHECK_GE(params->length, 0); + ncrypto::MarkPopErrorOnReturn mark_pop_error_on_return; if (!ncrypto::checkScryptParams( params->N, params->r, params->p, params->maxmem)) { // Do not use CryptoErrorStore or ThrowCryptoError here in order to maintain diff --git a/test/parallel/test-crypto-scrypt.js b/test/parallel/test-crypto-scrypt.js index e4a4a071558a..03198a9a42bf 100644 --- a/test/parallel/test-crypto-scrypt.js +++ b/test/parallel/test-crypto-scrypt.js @@ -5,6 +5,7 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); +const fixtures = require('../common/fixtures'); const { hasFIPS, isBoringSSL } = require('../common/crypto'); const isFips = hasFIPS(3); @@ -196,6 +197,19 @@ for (const options of toobig) { expected); } +// A failed parameter check must not leave an error on the OpenSSL error queue +// for the next unrelated crypto operation to pick up. +{ + const key = fixtures.readKey('ec_p256_private.pem'); + const options = { N: 2 ** 10, p: 1, r: 8, maxmem: 2 ** 20 }; + const expected = { code: 'ERR_CRYPTO_INVALID_SCRYPT_PARAMS' }; + assert.throws(() => crypto.scryptSync('pass', 'salt', 1, options), expected); + crypto.createPrivateKey(key); + assert.throws(() => crypto.scrypt('pass', 'salt', 1, options, () => {}), + expected); + crypto.createPrivateKey(key); +} + if (!isFips) { const expected = '4cac4540'; const actual = crypto.scryptSync('pass', 'salt', 4);