From 5d91d5a9358d3f36f3a5cd555e8f49e9429a0acc Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 19 May 2016 20:25:05 -0400 Subject: [PATCH 1/3] tls: catch `certCbDone` exceptions Catch and emit `certCbDone` exceptions instead of throwing them as `uncaughtException` and crashing the whole process. Fix: https://github.com/nodejs/node/issues/6822 --- lib/_tls_wrap.js | 6 ++- test/parallel/test-tls-empty-sni-context.js | 42 +++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-tls-empty-sni-context.js diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 029d9ac26fe6bd..cdb5817fa6f223 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -171,7 +171,11 @@ function oncertcb(info) { if (!self._handle) return self.destroy(new Error('Socket is closed')); - self._handle.certCbDone(); + try { + self._handle.certCbDone(); + } catch (e) { + self.destroy(e); + } }); }); } diff --git a/test/parallel/test-tls-empty-sni-context.js b/test/parallel/test-tls-empty-sni-context.js new file mode 100644 index 00000000000000..4e90f7aea30579 --- /dev/null +++ b/test/parallel/test-tls-empty-sni-context.js @@ -0,0 +1,42 @@ +'use strict'; + +if (!process.features.tls_sni) { + console.log('1..0 # Skipped: node compiled without OpenSSL or ' + + 'with old OpenSSL version.'); + return; +} + +const common = require('../common'); +const assert = require('assert'); + +if (!common.hasCrypto) { + console.log('1..0 # Skipped: missing crypto'); + return; +} + +const tls = require('tls'); + +const options = { + SNICallback: (name, callback) => { + callback(null, tls.createSecureContext()); + } +}; + +const server = tls.createServer(options, (c) => { + assert(false, 'Should not be called'); +}).on('tlsClientError', common.mustCall((err, c) => { + assert(/SSL_use_certificate:passed a null parameter/i.test(err.message)); + server.close(); +})).listen(common.PORT, common.mustCall(() => { + const c = tls.connect({ + port: common.PORT, + rejectUnauthorized: false, + servername: 'any.name' + }, () => { + assert(false, 'Should not be called'); + }); + + c.on('error', common.mustCall((err) => { + assert(err); + })); +})); From f522ddeac50ec10577c0eb0239d6696aa7272770 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 20 May 2016 15:36:34 -0400 Subject: [PATCH 2/3] fix --- test/parallel/test-tls-empty-sni-context.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/parallel/test-tls-empty-sni-context.js b/test/parallel/test-tls-empty-sni-context.js index 4e90f7aea30579..0aa111cf26bbc7 100644 --- a/test/parallel/test-tls-empty-sni-context.js +++ b/test/parallel/test-tls-empty-sni-context.js @@ -23,7 +23,7 @@ const options = { }; const server = tls.createServer(options, (c) => { - assert(false, 'Should not be called'); + assert.fail(null, null, 'Should not be called'); }).on('tlsClientError', common.mustCall((err, c) => { assert(/SSL_use_certificate:passed a null parameter/i.test(err.message)); server.close(); @@ -33,10 +33,10 @@ const server = tls.createServer(options, (c) => { rejectUnauthorized: false, servername: 'any.name' }, () => { - assert(false, 'Should not be called'); + assert.fail(null, null, 'Should not be called'); }); c.on('error', common.mustCall((err) => { - assert(err); + assert(/socket hang up/.test(err.message)); })); })); From 542a70db8f7be745921136f50eb43951a8b66711 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 20 May 2016 15:36:57 -0400 Subject: [PATCH 3/3] fix --- test/parallel/test-tls-empty-sni-context.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-tls-empty-sni-context.js b/test/parallel/test-tls-empty-sni-context.js index 0aa111cf26bbc7..a3089b9de3a05b 100644 --- a/test/parallel/test-tls-empty-sni-context.js +++ b/test/parallel/test-tls-empty-sni-context.js @@ -23,7 +23,7 @@ const options = { }; const server = tls.createServer(options, (c) => { - assert.fail(null, null, 'Should not be called'); + common.fail('Should not be called'); }).on('tlsClientError', common.mustCall((err, c) => { assert(/SSL_use_certificate:passed a null parameter/i.test(err.message)); server.close(); @@ -33,7 +33,7 @@ const server = tls.createServer(options, (c) => { rejectUnauthorized: false, servername: 'any.name' }, () => { - assert.fail(null, null, 'Should not be called'); + common.fail('Should not be called'); }); c.on('error', common.mustCall((err) => {