Skip to content

Commit 9660674

Browse files
committed
tls: accept SecureContext object in server.addContext()
Do not call tls.createSecureContext() if the context provided is already an instance of tls.SecureContext. Fixes: #47408
1 parent a777bbd commit 9660674

File tree

3 files changed

+83
-5
lines changed

3 files changed

+83
-5
lines changed

doc/api/tls.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -728,9 +728,10 @@ added: v0.5.3
728728
-->
729729

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

735736
The `server.addContext()` method adds a secure context that will be used if
736737
the client request's SNI name matches the supplied `hostname` (or wildcard).

lib/_tls_wrap.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -1476,8 +1476,10 @@ Server.prototype.addContext = function(servername, context) {
14761476
RegExpPrototypeSymbolReplace(/([.^$+?\-\\[\]{}])/g, servername, '\\$1'),
14771477
'*', '[^.]*',
14781478
) + '$');
1479-
ArrayPrototypePush(this._contexts,
1480-
[re, tls.createSecureContext(context).context]);
1479+
1480+
const secureContext =
1481+
context instanceof common.SecureContext ? context : tls.createSecureContext(context);
1482+
ArrayPrototypePush(this._contexts, [re, secureContext.context]);
14811483
};
14821484

14831485
Server.prototype[EE.captureRejectionSymbol] = function(

test/parallel/test-tls-add-context.js

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
'use strict';
2+
const common = require('../common');
3+
4+
if (!common.hasCrypto)
5+
common.skip('missing crypto');
6+
7+
const fixtures = require('../common/fixtures');
8+
const assert = require('assert');
9+
const tls = require('tls');
10+
11+
function loadPEM(n) {
12+
return fixtures.readKey(`${n}.pem`);
13+
}
14+
15+
const serverOptions = {
16+
key: loadPEM('agent2-key'),
17+
cert: loadPEM('agent2-cert'),
18+
ca: [ loadPEM('ca2-cert') ],
19+
requestCert: true,
20+
rejectUnauthorized: false,
21+
};
22+
23+
let connections = 0;
24+
25+
const server = tls.createServer(serverOptions, (c) => {
26+
if (++connections === 3) {
27+
server.close();
28+
}
29+
if (c.servername === 'unknowncontext') {
30+
assert.strictEqual(c.authorized, false);
31+
return;
32+
}
33+
assert.strictEqual(c.authorized, true);
34+
});
35+
36+
const secureContext = {
37+
key: loadPEM('agent1-key'),
38+
cert: loadPEM('agent1-cert'),
39+
ca: [ loadPEM('ca1-cert') ],
40+
};
41+
server.addContext('context1', secureContext);
42+
server.addContext('context2', tls.createSecureContext(secureContext));
43+
44+
const clientOptionsBase = {
45+
key: loadPEM('agent1-key'),
46+
cert: loadPEM('agent1-cert'),
47+
ca: [ loadPEM('ca1-cert') ],
48+
rejectUnauthorized: false,
49+
};
50+
51+
server.listen(0, common.mustCall(() => {
52+
const client1 = tls.connect({
53+
...clientOptionsBase,
54+
port: server.address().port,
55+
servername: 'context1',
56+
}, common.mustCall(() => {
57+
client1.end();
58+
}));
59+
60+
const client2 = tls.connect({
61+
...clientOptionsBase,
62+
port: server.address().port,
63+
servername: 'context2',
64+
}, common.mustCall(() => {
65+
client2.end();
66+
}));
67+
68+
const client3 = tls.connect({
69+
...clientOptionsBase,
70+
port: server.address().port,
71+
servername: 'unknowncontext',
72+
}, common.mustCall(() => {
73+
client3.end();
74+
}));
75+
}));

0 commit comments

Comments
 (0)