Browse Source

tls: fix handling of asterisk in SNI context

Wildcard server names should not match subdomains.

Quote from RFC2818:

   ...Names may contain the wildcard
   character * which is considered to match any single domain name
   component or component fragment. E.g., *.a.com matches foo.a.com but
   not bar.foo.a.com. f*.com matches foo.com but not bar.com.

fix #6610
v0.11.10-release
Fedor Indutny 11 years ago
committed by Timothy J Fontaine
parent
commit
f572b91c3e
  1. 2
      lib/_tls_wrap.js
  2. 34
      test/simple/test-tls-sni-server-client.js

2
lib/_tls_wrap.js

@ -612,7 +612,7 @@ Server.prototype.addContext = function(servername, credentials) {
var re = new RegExp('^' + var re = new RegExp('^' +
servername.replace(/([\.^$+?\-\\[\]{}])/g, '\\$1') servername.replace(/([\.^$+?\-\\[\]{}])/g, '\\$1')
.replace(/\*/g, '.*') + .replace(/\*/g, '[^\.]*') +
'$'); '$');
this._contexts.push([re, crypto.createCredentials(credentials).context]); this._contexts.push([re, crypto.createCredentials(credentials).context]);
}; };

34
test/simple/test-tls-sni-server-client.js

@ -66,14 +66,21 @@ var clientsOptions = [{
ca: [loadPEM('ca1-cert')], ca: [loadPEM('ca1-cert')],
servername: 'a.example.com', servername: 'a.example.com',
rejectUnauthorized: false rejectUnauthorized: false
},{ }, {
port: serverPort, port: serverPort,
key: loadPEM('agent2-key'), key: loadPEM('agent2-key'),
cert: loadPEM('agent2-cert'), cert: loadPEM('agent2-cert'),
ca: [loadPEM('ca2-cert')], ca: [loadPEM('ca2-cert')],
servername: 'b.test.com', servername: 'b.test.com',
rejectUnauthorized: false rejectUnauthorized: false
},{ }, {
port: serverPort,
key: loadPEM('agent2-key'),
cert: loadPEM('agent2-cert'),
ca: [loadPEM('ca2-cert')],
servername: 'a.b.test.com',
rejectUnauthorized: false
}, {
port: serverPort, port: serverPort,
key: loadPEM('agent3-key'), key: loadPEM('agent3-key'),
cert: loadPEM('agent3-cert'), cert: loadPEM('agent3-cert'),
@ -95,28 +102,29 @@ server.addContext('*.test.com', SNIContexts['asterisk.test.com']);
server.listen(serverPort, startTest); server.listen(serverPort, startTest);
function startTest() { function startTest() {
function connectClient(options, callback) { var i = 0;
function start() {
// No options left
if (i === clientsOptions.length)
return server.close();
var options = clientsOptions[i++];
var client = tls.connect(options, function() { var client = tls.connect(options, function() {
clientResults.push( clientResults.push(
client.authorizationError && client.authorizationError &&
/Hostname\/IP doesn't/.test(client.authorizationError)); /Hostname\/IP doesn't/.test(client.authorizationError));
client.destroy(); client.destroy();
callback(); // Continue
start();
}); });
}; };
connectClient(clientsOptions[0], function() { start();
connectClient(clientsOptions[1], function() {
connectClient(clientsOptions[2], function() {
server.close();
});
});
});
} }
process.on('exit', function() { process.on('exit', function() {
assert.deepEqual(serverResults, ['a.example.com', 'b.test.com', assert.deepEqual(serverResults, ['a.example.com', 'b.test.com',
'c.wrong.com']); 'a.b.test.com', 'c.wrong.com']);
assert.deepEqual(clientResults, [true, true, false]); assert.deepEqual(clientResults, [true, true, false, false]);
}); });

Loading…
Cancel
Save