From 2a168917cb479630ccd1974c8c2d629100526ed6 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Mon, 9 Jan 2017 08:38:31 -0500 Subject: [PATCH] tls: do not crash on STARTTLS when OCSP requested `TLSSocket` should not have a hard dependency on `tls.Server`, since it may be running without it in cases like `STARTTLS`. Fix: #10704 PR-URL: https://github.com/nodejs/node/pull/10706 Reviewed-By: James M Snell Reviewed-By: Sam Roberts Reviewed-By: Ben Noordhuis --- lib/_tls_wrap.js | 7 +++ test/parallel/test-tls-starttls-server.js | 53 +++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 test/parallel/test-tls-starttls-server.js diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index cf40618aa32b3d..2a135b14a06f95 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -114,6 +114,13 @@ function requestOCSP(self, hello, ctx, cb) { if (!ctx) ctx = self.server._sharedCreds; + + // TLS socket is using a `net.Server` instead of a tls.TLSServer. + // Some TLS properties like `server._sharedCreds` will not be present + if (!ctx) + return cb(null); + + // TODO(indutny): eventually disallow raw `SecureContext` if (ctx.context) ctx = ctx.context; diff --git a/test/parallel/test-tls-starttls-server.js b/test/parallel/test-tls-starttls-server.js new file mode 100644 index 00000000000000..ca6a00b25ddc03 --- /dev/null +++ b/test/parallel/test-tls-starttls-server.js @@ -0,0 +1,53 @@ +'use strict'; + +// Test asynchronous SNI+OCSP on TLSSocket created with `server` set to +// `net.Server` instead of `tls.Server` + +const common = require('../common'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} + +const assert = require('assert'); +const fs = require('fs'); +const net = require('net'); +const tls = require('tls'); + +const key = fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'); +const cert = fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem'); + +const server = net.createServer(common.mustCall((s) => { + const tlsSocket = new tls.TLSSocket(s, { + isServer: true, + server: server, + + secureContext: tls.createSecureContext({ + key: key, + cert: cert + }), + + SNICallback: common.mustCall((hostname, callback) => { + assert.strictEqual(hostname, 'test.test'); + + callback(null, null); + }) + }); + + tlsSocket.on('secure', common.mustCall(() => { + tlsSocket.end(); + server.close(); + })); +})).listen(0, () => { + const opts = { + servername: 'test.test', + port: server.address().port, + rejectUnauthorized: false, + requestOCSP: true + }; + + tls.connect(opts, function() { + this.end(); + }); +});