Skip to content

Commit 939c576

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 30d92e8 commit 939c576

File tree

3 files changed

+82
-5
lines changed

3 files changed

+82
-5
lines changed

doc/api/tls.md

Lines changed: 4 additions & 3 deletions
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

Lines changed: 4 additions & 2 deletions
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

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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+
const server = tls.createServer(serverOptions, (c) => {
24+
if (c.servername === 'unknowncontext') {
25+
assert.strictEqual(c.authorized, false);
26+
return;
27+
}
28+
assert.strictEqual(c.authorized, true);
29+
});
30+
31+
const secureContext = {
32+
key: loadPEM('agent1-key'),
33+
cert: loadPEM('agent1-cert'),
34+
ca: [ loadPEM('ca1-cert') ],
35+
};
36+
server.addContext('context1', secureContext);
37+
server.addContext('context2', tls.createSecureContext(secureContext));
38+
39+
const clientOptionsBase = {
40+
key: loadPEM('agent1-key'),
41+
cert: loadPEM('agent1-cert'),
42+
ca: [ loadPEM('ca1-cert') ],
43+
rejectUnauthorized: false,
44+
};
45+
46+
server.listen(0, common.mustCall(() => {
47+
const client1 = tls.connect({
48+
...clientOptionsBase,
49+
port: server.address().port,
50+
servername: 'context1',
51+
}, common.mustCall(() => {
52+
client1.end();
53+
}));
54+
55+
const client2 = tls.connect({
56+
...clientOptionsBase,
57+
port: server.address().port,
58+
servername: 'context2',
59+
}, common.mustCall(() => {
60+
client2.end();
61+
}));
62+
63+
const client3 = tls.connect({
64+
...clientOptionsBase,
65+
port: server.address().port,
66+
servername: 'unknowncontext',
67+
}, common.mustCall(() => {
68+
client3.end();
69+
}));
70+
71+
client3.on('close', common.mustCall(() => {
72+
server.close();
73+
}));
74+
}));

0 commit comments

Comments
 (0)