Browse Source

tls: follow RFC6125 more stricly

* Allow wildcards only in left-most part of hostname identifier.
* Do not match CN if altnames are present
v0.8.18-release
Fedor Indutny 12 years ago
parent
commit
31583be042
  1. 23
      lib/tls.js
  2. 13
      test/simple/test-tls-check-server-identity.js

23
lib/tls.js

@ -91,7 +91,14 @@ function checkServerIdentity(host, cert) {
// The same applies to hostname with more than one wildcard, // The same applies to hostname with more than one wildcard,
// if hostname has wildcard when wildcards are not allowed, // if hostname has wildcard when wildcards are not allowed,
// or if there are less than two dots after wildcard (i.e. *.com or *d.com) // or if there are less than two dots after wildcard (i.e. *.com or *d.com)
if (/\*.*\*/.test(host) || !wildcards && /\*/.test(host) || //
// also
//
// "The client SHOULD NOT attempt to match a presented identifier in
// which the wildcard character comprises a label other than the
// left-most label (e.g., do not match bar.*.example.net)."
// RFC6125
if (!wildcards && /\*/.test(host) || /[\.\*].*\*/.test(host) ||
/\*/.test(host) && !/\*.*\..+\..+/.test(host)) { /\*/.test(host) && !/\*.*\..+\..+/.test(host)) {
return /$./; return /$./;
} }
@ -112,6 +119,7 @@ function checkServerIdentity(host, cert) {
var dnsNames = [], var dnsNames = [],
uriNames = [], uriNames = [],
ips = [], ips = [],
matchCN = true,
valid = false; valid = false;
// There're several names to perform check against: // There're several names to perform check against:
@ -120,6 +128,7 @@ function checkServerIdentity(host, cert) {
// //
// Walk through altnames and generate lists of those names // Walk through altnames and generate lists of those names
if (cert.subjectaltname) { if (cert.subjectaltname) {
matchCN = false;
cert.subjectaltname.split(/, /g).forEach(function(altname) { cert.subjectaltname.split(/, /g).forEach(function(altname) {
if (/^DNS:/.test(altname)) { if (/^DNS:/.test(altname)) {
dnsNames.push(altname.slice(4)); dnsNames.push(altname.slice(4));
@ -155,7 +164,16 @@ function checkServerIdentity(host, cert) {
dnsNames = dnsNames.concat(uriNames); dnsNames = dnsNames.concat(uriNames);
// And only after check if hostname matches CN if (dnsNames.length > 0) matchCN = false;
// Match against Common Name (CN) only if altnames are not present.
//
// "As noted, a client MUST NOT seek a match for a reference identifier
// of CN-ID if the presented identifiers include a DNS-ID, SRV-ID,
// URI-ID, or any application-specific identifier types supported by the
// client."
// RFC6125
if (matchCN) {
var commonNames = cert.subject.CN; var commonNames = cert.subject.CN;
if (Array.isArray(commonNames)) { if (Array.isArray(commonNames)) {
for (var i = 0, k = commonNames.length; i < k; ++i) { for (var i = 0, k = commonNames.length; i < k; ++i) {
@ -164,6 +182,7 @@ function checkServerIdentity(host, cert) {
} else { } else {
dnsNames.push(regexpify(commonNames, true)); dnsNames.push(regexpify(commonNames, true));
} }
}
valid = dnsNames.some(function(re) { valid = dnsNames.some(function(re) {
return re.test(host); return re.test(host);

13
test/simple/test-tls-check-server-identity.js

@ -31,8 +31,13 @@ var tests = [
{ host: 'a.com', cert: { subject: { CN: 'b.com' } }, result: false }, { host: 'a.com', cert: { subject: { CN: 'b.com' } }, result: false },
{ host: 'a.com', cert: { subject: { CN: 'a.com.' } }, result: true }, { host: 'a.com', cert: { subject: { CN: 'a.com.' } }, result: true },
// No wildcards in CN // Wildcards in CN
{ host: 'b.a.com', cert: { subject: { CN: '*.a.com' } }, result: false }, { host: 'b.a.com', cert: { subject: { CN: '*.a.com' } }, result: true },
{ host: 'b.a.com', cert: {
subjectaltname: 'DNS:omg.com',
subject: { CN: '*.a.com' } },
result: false
},
// Multiple CN fields // Multiple CN fields
{ {
@ -69,7 +74,7 @@ var tests = [
subjectaltname: 'DNS:*.a.com', subjectaltname: 'DNS:*.a.com',
subject: { CN: 'a.com' } subject: { CN: 'a.com' }
}, },
result: true result: false
}, },
{ {
host: 'a.com', cert: { host: 'a.com', cert: {
@ -193,7 +198,7 @@ var tests = [
subjectaltname: 'DNS:a.com', subjectaltname: 'DNS:a.com',
subject: { CN: 'localhost' } subject: { CN: 'localhost' }
}, },
result: true result: false
}, },
]; ];

Loading…
Cancel
Save