diff --git a/src/crypto/crypto_common.cc b/src/crypto/crypto_common.cc index 759353f08f03..630606b3c7ae 100644 --- a/src/crypto/crypto_common.cc +++ b/src/crypto/crypto_common.cc @@ -30,6 +30,7 @@ namespace node { using ncrypto::ClearErrorOnReturn; using ncrypto::EVPKeyPointer; using ncrypto::KeyAlgorithm; +using ncrypto::MarkPopErrorOnReturn; using ncrypto::SSLPointer; using ncrypto::SSLSessionPointer; using ncrypto::StackOfX509; @@ -49,6 +50,7 @@ using v8::Value; namespace crypto { SSLSessionPointer GetTLSSession(const unsigned char* buf, size_t length) { + MarkPopErrorOnReturn mark_pop_error_on_return; return SSLSessionPointer(d2i_SSL_SESSION(nullptr, &buf, length)); } diff --git a/test/parallel/test-tls-socket-invalid-session.js b/test/parallel/test-tls-socket-invalid-session.js new file mode 100644 index 000000000000..09685ef745a2 --- /dev/null +++ b/test/parallel/test-tls-socket-invalid-session.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); +const tls = require('tls'); + +// A session that fails to deserialize must not leave an error on the OpenSSL +// error queue for the next unrelated crypto operation to pick up. + +const badKey = '-----BEGIN PRIVATE KEY-----\nAAAA\n-----END PRIVATE KEY-----'; + +function keyErrorCode() { + try { + crypto.createPrivateKey(badKey); + } catch (err) { + return err.code; + } + assert.fail('createPrivateKey() should have thrown'); +} + +const expected = keyErrorCode(); +new tls.TLSSocket(null, { session: Buffer.from('invalid session') }); +assert.strictEqual(keyErrorCode(), expected);