Skip to content

Commit

Permalink
tls: compare san against ip in correct format
Browse files Browse the repository at this point in the history
When comparing IP addresses against addresses in the subjectAltName
field of a certificate, format the address correctly before
doing the string comparison.

Fixes: nodejs#14736
  • Loading branch information
mattiasholmlund committed Oct 10, 2017
1 parent 0d19c20 commit 31b5eda
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
30 changes: 29 additions & 1 deletion lib/tls.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,33 @@ function check(hostParts, pattern, wildcards) {
return true;
}

exports._canonicalIp = function(address) {
// Convert the ip address into the same format
// stored in certificates
if (net.isIPv6(address)) {
const b = ['0', '0', '0', '0', '0', '0', '0', '0'];

const s = address.split('::');
if (s.length === 2) {
const s1 = s[0].split(':');
for (var n = 0; n < s1.length; n++) {
if (s1[n]) {
b[n] = s1[n].replace(/^0+(\d+)$/, '$1');
}
}
const s2 = s[1].split(':');
for (n = 0; n < s2.length; n++) {
if (s2[n]) {
b[8 - s2.length + n] = s2[n].replace(/^0+(\d+)$/, '$1');
}
}
}

return b.join(':');
} else
return address.replace(/\b0+(\d)/g, '$1'); // Delete leading zeroes
};

exports.checkServerIdentity = function checkServerIdentity(host, cert) {
const subject = cert.subject;
const altNames = cert.subjectaltname;
Expand All @@ -190,7 +217,8 @@ exports.checkServerIdentity = function checkServerIdentity(host, cert) {
let reason = 'Unknown reason';

if (net.isIP(host)) {
valid = ips.includes(host);
const canonicalIp = exports._canonicalIp(host);
valid = ips.includes(canonicalIp);
if (!valid)
reason = `IP: ${host} is not in the cert's list: ${ips.join(', ')}`;
// TODO(bnoordhuis) Also check URI SANs that are IP addresses.
Expand Down
18 changes: 18 additions & 0 deletions test/internet/test-tls-canonical-ip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';
require('../common');

// Test conversion of IP addresses to the format returned
// for addresses in Subject Alternative Name section
// of a TLS certificate

const assert = require('assert');
const tls = require('tls');

assert.strictEqual(tls._canonicalIp('127.0.0.1'), '127.0.0.1');
assert.strictEqual(tls._canonicalIp('010.001.0.1'), '10.1.0.1');
assert.strictEqual(tls._canonicalIp('::1'), '0:0:0:0:0:0:0:1');
assert.strictEqual(tls._canonicalIp('fe80::1'), 'fe80:0:0:0:0:0:0:1');
assert.strictEqual(tls._canonicalIp('fe80::'), 'fe80:0:0:0:0:0:0:0');
assert.strictEqual(
tls._canonicalIp('fe80::0000:0010:0001'),
'fe80:0:0:0:0:0:10:1');

0 comments on commit 31b5eda

Please sign in to comment.