tls: allow empty subject even with altNames defined

Behavior described in https://github.com/nodejs/node/issues/11771
is still true even though the issue is closed.

This PR is to allow DNS and URI names, even when there is not a subject.

Refs: https://github.com/nodejs/node/issues/11771

PR-URL: https://github.com/nodejs/node/pull/22906
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Jason Macgowan authored and Anna Henningsen committed 2019-11-29 02:13:41 +01:00
1 parent 3e79c004fd
commit ff48009fef
2 files changed
+28 -10

No files matched your search

+14 -10
View File
@@ -248,19 +248,28 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) {
let valid = false;
let reason = 'Unknown reason';
const hasAltNames =
dnsNames.length > 0 || ips.length > 0 || uriNames.length > 0;
hostname = unfqdn(hostname); // Remove trailing dot for error messages.
if (net.isIP(hostname)) {
valid = ips.includes(canonicalizeIP(hostname));
if (!valid)
reason = `IP: ${hostname} is not in the cert's list: ${ips.join(', ')}`;
// TODO(bnoordhuis) Also check URI SANs that are IP addresses.
} else if (subject) {
hostname = unfqdn(hostname); // Remove trailing dot for error messages.
} else if (hasAltNames || subject) {
const hostParts = splitHost(hostname);
const wildcard = (pattern) => check(hostParts, pattern, true);
const noWildcard = (pattern) => check(hostParts, pattern, false);
// Match against Common Name only if no supported identifiers are present.
if (dnsNames.length === 0 && ips.length === 0 && uriNames.length === 0) {
if (hasAltNames) {
const noWildcard = (pattern) => check(hostParts, pattern, false);
valid = dnsNames.some(wildcard) || uriNames.some(noWildcard);
if (!valid)
reason =
`Host: ${hostname}. is not in the cert's altnames: ${altNames}`;
} else {
// Match against Common Name only if no supported identifiers exist.
const cn = subject.CN;
if (ArrayIsArray(cn))
@@ -270,11 +279,6 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) {
if (!valid)
reason = `Host: ${hostname}. is not cert's CN: ${cn}`;
} else {
valid = dnsNames.some(wildcard) || uriNames.some(noWildcard);
if (!valid)
reason =
`Host: ${hostname}. is not in the cert's altnames: ${altNames}`;
}
} else {
reason = 'Cert is empty';
@@ -143,6 +143,20 @@ const tests = [
error: 'Cert is empty'
},
// Empty Subject w/DNS name
{
host: 'a.com', cert: {
subjectaltname: 'DNS:a.com',
}
},
// Empty Subject w/URI name
{
host: 'a.b.a.com', cert: {
subjectaltname: 'URI:http://a.b.a.com/',
}
},
// Multiple CN fields
{
host: 'foo.com', cert: {