Skip to content

Commit 5795e83

Browse files
committed
tls: emit errors on close whilst async action
When loading session, OCSP response, SNI, always check that the `self._handle` is present. If it is not - the socket was closed - and we should emit the error instead of throwing an uncaught exception. Fix: nodejs/node-v0.x-archive#8780 Fix: #1696 PR-URL: #1702 Reviewed-By: Trevor Norris <trev.norris@gmail.com>
1 parent 6d95f4f commit 5795e83

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

lib/_tls_wrap.js

+15
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ function loadSession(self, hello, cb) {
6161
if (err)
6262
return cb(err);
6363

64+
if (!self._handle)
65+
return cb(new Error('Socket is closed'));
66+
6467
// NOTE: That we have disabled OpenSSL's internal session storage in
6568
// `node_crypto.cc` and hence its safe to rely on getting servername only
6669
// from clienthello or this place.
@@ -91,6 +94,9 @@ function loadSNI(self, servername, cb) {
9194
if (err)
9295
return cb(err);
9396

97+
if (!self._handle)
98+
return cb(new Error('Socket is closed'));
99+
94100
// TODO(indutny): eventually disallow raw `SecureContext`
95101
if (context)
96102
self._handle.sni_context = context.context || context;
@@ -127,6 +133,9 @@ function requestOCSP(self, hello, ctx, cb) {
127133
if (err)
128134
return cb(err);
129135

136+
if (!self._handle)
137+
return cb(new Error('Socket is closed'));
138+
130139
if (response)
131140
self._handle.setOCSPResponse(response);
132141
cb(null);
@@ -157,6 +166,9 @@ function oncertcb(info) {
157166
if (err)
158167
return self.destroy(err);
159168

169+
if (!self._handle)
170+
return cb(new Error('Socket is closed'));
171+
160172
self._handle.certCbDone();
161173
});
162174
});
@@ -179,6 +191,9 @@ function onnewsession(key, session) {
179191
return;
180192
once = true;
181193

194+
if (!self._handle)
195+
return cb(new Error('Socket is closed'));
196+
182197
self._handle.newSessionDone();
183198

184199
self._newSessionPending = false;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
'use strict';
2+
3+
var common = require('../common');
4+
5+
var assert = require('assert');
6+
var path = require('path');
7+
var fs = require('fs');
8+
var constants = require('constants');
9+
10+
if (!common.hasCrypto) {
11+
console.log('1..0 # Skipped: missing crypto');
12+
process.exit();
13+
}
14+
15+
var tls = require('tls');
16+
17+
var options = {
18+
secureOptions: constants.SSL_OP_NO_TICKET,
19+
key: fs.readFileSync(path.join(common.fixturesDir, 'test_key.pem')),
20+
cert: fs.readFileSync(path.join(common.fixturesDir, 'test_cert.pem'))
21+
};
22+
23+
var server = tls.createServer(options, function(c) {
24+
});
25+
26+
var sessionCb = null;
27+
var client = null;
28+
29+
server.on('newSession', function(key, session, done) {
30+
done();
31+
});
32+
33+
server.on('resumeSession', function(id, cb) {
34+
sessionCb = cb;
35+
36+
next();
37+
});
38+
39+
server.listen(1443, function() {
40+
var clientOpts = {
41+
port: 1443,
42+
rejectUnauthorized: false,
43+
session: false
44+
};
45+
46+
var s1 = tls.connect(clientOpts, function() {
47+
clientOpts.session = s1.getSession();
48+
console.log('1st secure');
49+
50+
s1.destroy();
51+
var s2 = tls.connect(clientOpts, function(s) {
52+
console.log('2nd secure');
53+
54+
s2.destroy();
55+
}).on('connect', function() {
56+
console.log('2nd connected');
57+
client = s2;
58+
59+
next();
60+
});
61+
});
62+
});
63+
64+
function next() {
65+
if (!client || !sessionCb)
66+
return;
67+
68+
client.destroy();
69+
setTimeout(function() {
70+
sessionCb();
71+
server.close();
72+
}, 100);
73+
}

0 commit comments

Comments
 (0)