Skip to content

Commit

Permalink
tls: accept SecureContext object in server.addContext()
Browse files Browse the repository at this point in the history
Do not call tls.createSecureContext() if the context provided
is already an instance of tls.SecureContext.

Fixes: #47408
  • Loading branch information
HinataKah0 committed Apr 15, 2023
1 parent 30d92e8 commit 939c576
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 5 deletions.
7 changes: 4 additions & 3 deletions doc/api/tls.md
Original file line number Diff line number Diff line change
Expand Up @@ -728,9 +728,10 @@ added: v0.5.3
-->

* `hostname` {string} A SNI host name or wildcard (e.g. `'*'`)
* `context` {Object} An object containing any of the possible properties
from the [`tls.createSecureContext()`][] `options` arguments (e.g. `key`,
`cert`, `ca`, etc).
* `context` {Object|tls.SecureContext} An object containing any of the possible
properties from the [`tls.createSecureContext()`][] `options` arguments
(e.g. `key`, `cert`, `ca`, etc), or a TLS context object created with
[`tls.createSecureContext()`][] itself.

The `server.addContext()` method adds a secure context that will be used if
the client request's SNI name matches the supplied `hostname` (or wildcard).
Expand Down
6 changes: 4 additions & 2 deletions lib/_tls_wrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -1476,8 +1476,10 @@ Server.prototype.addContext = function(servername, context) {
RegExpPrototypeSymbolReplace(/([.^$+?\-\\[\]{}])/g, servername, '\\$1'),
'*', '[^.]*',
) + '$');
ArrayPrototypePush(this._contexts,
[re, tls.createSecureContext(context).context]);

const secureContext =
context instanceof common.SecureContext ? context : tls.createSecureContext(context);
ArrayPrototypePush(this._contexts, [re, secureContext.context]);
};

Server.prototype[EE.captureRejectionSymbol] = function(
Expand Down
74 changes: 74 additions & 0 deletions test/parallel/test-tls-add-context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
'use strict';
const common = require('../common');

if (!common.hasCrypto)
common.skip('missing crypto');

const fixtures = require('../common/fixtures');
const assert = require('assert');
const tls = require('tls');

function loadPEM(n) {
return fixtures.readKey(`${n}.pem`);
}

const serverOptions = {
key: loadPEM('agent2-key'),
cert: loadPEM('agent2-cert'),
ca: [ loadPEM('ca2-cert') ],
requestCert: true,
rejectUnauthorized: false,
};

const server = tls.createServer(serverOptions, (c) => {
if (c.servername === 'unknowncontext') {
assert.strictEqual(c.authorized, false);
return;
}
assert.strictEqual(c.authorized, true);
});

const secureContext = {
key: loadPEM('agent1-key'),
cert: loadPEM('agent1-cert'),
ca: [ loadPEM('ca1-cert') ],
};
server.addContext('context1', secureContext);
server.addContext('context2', tls.createSecureContext(secureContext));

const clientOptionsBase = {
key: loadPEM('agent1-key'),
cert: loadPEM('agent1-cert'),
ca: [ loadPEM('ca1-cert') ],
rejectUnauthorized: false,
};

server.listen(0, common.mustCall(() => {
const client1 = tls.connect({
...clientOptionsBase,
port: server.address().port,
servername: 'context1',
}, common.mustCall(() => {
client1.end();
}));

const client2 = tls.connect({
...clientOptionsBase,
port: server.address().port,
servername: 'context2',
}, common.mustCall(() => {
client2.end();
}));

const client3 = tls.connect({
...clientOptionsBase,
port: server.address().port,
servername: 'unknowncontext',
}, common.mustCall(() => {
client3.end();
}));

client3.on('close', common.mustCall(() => {
server.close();
}));
}));

0 comments on commit 939c576

Please sign in to comment.