diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc index d35d601abc70..181cf800da5a 100644 --- a/deps/ncrypto/ncrypto.cc +++ b/deps/ncrypto/ncrypto.cc @@ -4958,8 +4958,10 @@ std::optional SSLPointer::verifyPeerCertificate() const { // Allow no-cert for PSK authentication in TLS1.2 and lower. // In TLS1.3 check that session was reused because TLS1.3 PSK // looks like session resumption. - if (SSL_CIPHER_get_auth_nid(curr_cipher) == NID_auth_psk || - (SSL_SESSION_get_protocol_version(sess) == TLS1_3_VERSION && + if ((curr_cipher != nullptr && + SSL_CIPHER_get_auth_nid(curr_cipher) == NID_auth_psk) || + (sess != nullptr && + SSL_SESSION_get_protocol_version(sess) == TLS1_3_VERSION && SSL_session_reused(get()))) { return X509_V_OK; } diff --git a/test/parallel/test-tls-emit-secure-before-handshake.js b/test/parallel/test-tls-emit-secure-before-handshake.js new file mode 100644 index 000000000000..c8750e7395e2 --- /dev/null +++ b/test/parallel/test-tls-emit-secure-before-handshake.js @@ -0,0 +1,47 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('node:assert'); +const net = require('node:net'); +const tls = require('node:tls'); + +for (const rejectUnauthorized of [false, undefined]) { + const server = net.createServer((socket) => { + socket.resume(); + }); + + server.listen(0, '127.0.0.1', common.mustCall(() => { + const options = { + host: '127.0.0.1', + port: server.address().port, + }; + if (rejectUnauthorized === false) + options.rejectUnauthorized = false; + const socket = tls.connect(options); + + socket.on('connect', common.mustCall(() => { + // A premature secure event must report a missing certificate even when + // neither a cipher nor a session has been established yet. + socket.emit('secure'); + assert.strictEqual(socket.authorized, false); + assert.strictEqual(socket.authorizationError, + 'UNABLE_TO_GET_ISSUER_CERT'); + })); + + if (rejectUnauthorized === false) { + socket.on('error', common.mustNotCall()); + socket.on('secureConnect', common.mustCall(() => socket.destroy())); + } else { + socket.on('secureConnect', common.mustNotCall()); + socket.on('error', common.mustCall((err) => { + assert.strictEqual(err.code, 'UNABLE_TO_GET_ISSUER_CERT'); + })); + } + + socket.on('close', common.mustCall(() => { + server.close(common.mustCall()); + })); + })); +}