Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions lib/tls.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,14 @@ exports.checkServerIdentity = function checkServerIdentity(hostname, cert) {
let valid = false;
let reason = 'Unknown reason';

if (net.isIP(hostnameASCIIWithoutFQDN)) {
valid = ips.includes(canonicalizeIP(hostnameASCIIWithoutFQDN));
// An IP literal must not be IDNA-normalized: domainToASCII() returns '' for
// an IPv6 literal (it is not a domain), so matching against the normalized
// host would skip IP-SAN matching for IPv6 entirely. Match IP hosts against
// the original hostname (net.isIP() rejects non-ASCII, so there is no IDNA
// confusion to guard against here); the normalized form is kept for the
// DNS-name path below.
if (net.isIP(hostname)) {
valid = ips.includes(canonicalizeIP(hostname));
if (!valid) {
reason =
`IP: ${hostname} is not in the cert's list: ` + ips.join(', ');
Expand Down
21 changes: 21 additions & 0 deletions test/parallel/test-tls-check-server-identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,27 @@ const tests = [
cert: { subject: { CN: '8.8.8.8' }, subjectaltname: 'IP Address:8.8.8.8' }
},

// An "IP Address:" SAN also matches an IPv6 host. Regression test for the
// IDNA-normalization change: domainToASCII('::1') === '' (an IPv6 literal is
// not a domain), which made the normalized host skip IPv6 IP-SAN matching.
{
host: '::1',
cert: { subject: {}, subjectaltname: 'IP Address:::1' }
},

// IPv6 hosts and SANs are matched canonically.
{
host: '2001:db8::1',
cert: { subject: {}, subjectaltname: 'IP Address:2001:DB8:0:0:0:0:0:1' }
},

// A non-matching IPv6 "IP Address:" SAN is rejected.
{
host: '::1',
cert: { subject: {}, subjectaltname: 'IP Address:::2' },
error: 'IP: ::1 is not in the cert\'s list: ::2'
},

// But not when it's a CIDR.
{
host: '8.8.8.8',
Expand Down