Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] tls: fix legacy SecurePair clienthello race window #26452

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 7 additions & 2 deletions lib/_tls_legacy.js
Expand Up @@ -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();

Expand Down Expand Up @@ -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);
}
}

Expand Down
1 change: 0 additions & 1 deletion src/env.h
Expand Up @@ -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") \
Expand Down
3 changes: 0 additions & 3 deletions src/node_crypto.cc
Expand Up @@ -2965,9 +2965,6 @@ void Connection::SetShutdownFlags() {


void Connection::NewSessionDoneCb() {
HandleScope scope(env()->isolate());

MakeCallback(env()->onnewsessiondone_string(), 0, nullptr);
}


Expand Down
80 changes: 80 additions & 0 deletions 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need common.platformTimeout() ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not used in test-tls-async-cb-after-socket-end.js either so I'm inclined to say it's not.

}
Copy link
Member Author

@bnoordhuis bnoordhuis Mar 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apropos the somewhat uncommon style in this file, it's a mashup of two (fairly old and crufty) tests: test-tls-async-cb-after-socket-end.js and test-tls-securepair-server.js. I didn't want to deviate too much from the style used in those files.