diff --git a/lib/_tls_legacy.js b/lib/_tls_legacy.js index fc2fb6db5d12ae..7b9e34bb847c31 100644 --- a/lib/_tls_legacy.js +++ b/lib/_tls_legacy.js @@ -659,6 +659,10 @@ function onclienthello(hello) { if (err) return self.socket.destroy(err); setImmediate(function() { + // SecurePair might have been destroyed in the time window + // between callback() and this function. + if (!self.ssl) return; + self.ssl.loadSession(session); self.ssl.endParser(); @@ -691,8 +695,9 @@ function onnewsession(key, session) { return; once = true; - if (self.ssl) - self.ssl.newSessionDone(); + // Cycle data + self.cleartext.read(0); + self.encrypted.read(0); } } diff --git a/src/env.h b/src/env.h index e378869b4ccdcb..b47d55d87b3e69 100644 --- a/src/env.h +++ b/src/env.h @@ -216,7 +216,6 @@ class ModuleWrap; V(onheaders_string, "onheaders") \ V(onmessage_string, "onmessage") \ V(onnewsession_string, "onnewsession") \ - V(onnewsessiondone_string, "onnewsessiondone") \ V(onocspresponse_string, "onocspresponse") \ V(ongoawaydata_string, "ongoawaydata") \ V(onorigin_string, "onorigin") \ diff --git a/src/node_crypto.cc b/src/node_crypto.cc index d0e17717d9c2cb..61fefd78b9d970 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -2965,9 +2965,6 @@ void Connection::SetShutdownFlags() { void Connection::NewSessionDoneCb() { - HandleScope scope(env()->isolate()); - - MakeCallback(env()->onnewsessiondone_string(), 0, nullptr); } diff --git a/test/parallel/test-tls-async-cb-after-socket-end-securepair.js b/test/parallel/test-tls-async-cb-after-socket-end-securepair.js new file mode 100644 index 00000000000000..890c2b63ef5c21 --- /dev/null +++ b/test/parallel/test-tls-async-cb-after-socket-end-securepair.js @@ -0,0 +1,80 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const fixtures = require('../common/fixtures'); +const SSL_OP_NO_TICKET = require('crypto').constants.SSL_OP_NO_TICKET; +const assert = require('assert'); +const net = require('net'); +const tls = require('tls'); + +const options = { + secureOptions: SSL_OP_NO_TICKET, + key: fixtures.readSync('test_key.pem'), + cert: fixtures.readSync('test_cert.pem') +}; + +const server = net.createServer(function(socket) { + const sslcontext = tls.createSecureContext(options); + sslcontext.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA'); + + const pair = tls.createSecurePair(sslcontext, true, false, false, { server }); + + assert.ok(pair.encrypted.writable); + assert.ok(pair.cleartext.writable); + + pair.encrypted.pipe(socket); + socket.pipe(pair.encrypted); + + pair.on('error', () => {}); // Expected, client s1 closes connection. +}); + +let sessionCb = null; +let client = null; + +server.on('newSession', common.mustCall(function(key, session, done) { + done(); +})); + +server.on('resumeSession', common.mustCall(function(id, cb) { + sessionCb = cb; + + next(); +})); + +server.listen(0, function() { + const clientOpts = { + port: this.address().port, + rejectUnauthorized: false, + session: false + }; + + const s1 = tls.connect(clientOpts, function() { + clientOpts.session = s1.getSession(); + console.log('1st secure'); + + s1.destroy(); + const s2 = tls.connect(clientOpts, function(s) { + console.log('2nd secure'); + + s2.destroy(); + }).on('connect', function() { + console.log('2nd connected'); + client = s2; + + next(); + }); + }); +}); + +function next() { + if (!client || !sessionCb) + return; + + client.destroy(); + setTimeout(function() { + sessionCb(); + server.close(); + }, 100); +}