tls: fix handling of asterisk in SNI context
authorFedor Indutny <fedor.indutny@gmail.com>
Thu, 5 Dec 2013 15:16:01 +0000 (19:16 +0400)
committerTimothy J Fontaine <tjfontaine@gmail.com>
Fri, 6 Dec 2013 03:45:19 +0000 (19:45 -0800)
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

lib/_tls_wrap.js
test/simple/test-tls-sni-server-client.js

index dbf55ce..ac47895 100644 (file)
@@ -612,7 +612,7 @@ Server.prototype.addContext = function(servername, credentials) {
 
   var re = new RegExp('^' +
                       servername.replace(/([\.^$+?\-\\[\]{}])/g, '\\$1')
-                                .replace(/\*/g, '.*') +
+                                .replace(/\*/g, '[^\.]*') +
                       '$');
   this._contexts.push([re, crypto.createCredentials(credentials).context]);
 };
index 8de57e2..31fc419 100644 (file)
@@ -66,14 +66,21 @@ var clientsOptions = [{
   ca: [loadPEM('ca1-cert')],
   servername: 'a.example.com',
   rejectUnauthorized: false
-},{
+}, {
   port: serverPort,
   key: loadPEM('agent2-key'),
   cert: loadPEM('agent2-cert'),
   ca: [loadPEM('ca2-cert')],
   servername: 'b.test.com',
   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,
   key: loadPEM('agent3-key'),
   cert: loadPEM('agent3-cert'),
@@ -95,28 +102,29 @@ server.addContext('*.test.com', SNIContexts['asterisk.test.com']);
 server.listen(serverPort, 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() {
       clientResults.push(
         client.authorizationError &&
         /Hostname\/IP doesn't/.test(client.authorizationError));
       client.destroy();
 
-      callback();
+      // Continue
+      start();
     });
   };
 
-  connectClient(clientsOptions[0], function() {
-    connectClient(clientsOptions[1], function() {
-      connectClient(clientsOptions[2], function() {
-        server.close();
-      });
-    });
-  });
+  start();
 }
 
 process.on('exit', function() {
   assert.deepEqual(serverResults, ['a.example.com', 'b.test.com',
-                                   'c.wrong.com']);
-  assert.deepEqual(clientResults, [true, true, false]);
+                                   'a.b.test.com', 'c.wrong.com']);
+  assert.deepEqual(clientResults, [true, true, false, false]);
 });