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: nodejs#47408
PR-URL: nodejs#47570
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
HinataKah0 authored and yjl9903 committed Apr 29, 2023
1 parent 1ad41cd commit 9fc9c85
Show file tree
Hide file tree
Showing 3 changed files with 83 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
75 changes: 75 additions & 0 deletions test/parallel/test-tls-add-context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'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,
};

let connections = 0;

const server = tls.createServer(serverOptions, (c) => {
if (++connections === 3) {
server.close();
}
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();
}));
}));

0 comments on commit 9fc9c85

Please sign in to comment.