Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8e7ac25
http, tls: better support for IPv6 addresses
mattiasholmlund Aug 10, 2017
e021fb7
doc,test: mention Duplex support for TLS
addaleax Dec 11, 2017
4879038
tools: add number-isnan rule
maclover7 Dec 11, 2017
969c39e
lib: enable dot-notation eslint rule
apapirovski Jan 5, 2018
16ef24b
test: use smaller input file for test-zlib.js
Trott Jan 5, 2018
17c88c4
doc: examples for fast-tracking regression fixes
refack Nov 26, 2017
37071b8
path: fix path.normalize for relative paths
starkwang Jan 4, 2018
838f7bd
doc: be less tentative about undefined behavior
Trott Jan 10, 2018
1505b71
doc: add Leko to collaborators
Leko Jan 11, 2018
8f9362d
doc: add documentation for deprecation properties
maclover7 Oct 26, 2017
2004efd
test: improve to use template string
sreepurnajasti Jan 10, 2018
eaa30e4
test: simplify loadDHParam in TLS test
tniessen Jan 11, 2018
df038ad
fs: fix options.end of fs.ReadStream()
Jan 12, 2018
2c21421
doc: simplify sentences that use "considered"
Trott Jan 11, 2018
2e76df5
doc: warn users about non-ASCII paths on build
Nov 4, 2017
b83b104
doc: add builtin module in building.md
Suixinlei Dec 16, 2017
46e4311
doc: V8 branch used in 8.x not active anymore
fhinkel Jan 15, 2018
1e8d120
doc: Add example of null to assert.ifError
Leko Jan 18, 2018
27107b9
test: use countdown timer
daxlab Nov 26, 2017
7fc5c69
doc: use PBKDF2 in text
tniessen Jan 21, 2018
bb2d292
test: change assert message to default
ryanmahan Jan 19, 2018
d333ba5
doc: add vdeturckheim as collaborator
vdeturckheim Jan 29, 2018
fdf73b1
test: preserve env in test cases
BethGriggs Aug 14, 2017
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
Next Next commit
http, tls: better support for IPv6 addresses
- Properly handle IPv6 in Host header when setting servername.
- When comparing IP addresses against addresses in the subjectAltName
  field of a certificate, format the address correctly before
  doing the string comparison.

PR-URL: #14772
Fixes: #14736
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
mattiasholmlund authored and MylesBorins committed Feb 27, 2018
commit 8e7ac25aa6e5aec345c13f4a4e26ade49a1de66a
41 changes: 27 additions & 14 deletions lib/_http_agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,8 @@ Agent.prototype.addRequest = function(req, options) {
options = util._extend({}, options);
options = util._extend(options, this.options);

if (!options.servername) {
options.servername = options.host;
const hostHeader = req.getHeader('host');
if (hostHeader) {
options.servername = hostHeader.replace(/:.*$/, '');
}
}
if (!options.servername)
options.servername = calculateServerName(options, req);

var name = this.getName(options);
if (!this.sockets[name]) {
Expand Down Expand Up @@ -178,13 +173,8 @@ Agent.prototype.createSocket = function(req, options, cb) {
options = util._extend({}, options);
options = util._extend(options, self.options);

if (!options.servername) {
options.servername = options.host;
const hostHeader = req.getHeader('host');
if (hostHeader) {
options.servername = hostHeader.replace(/:.*$/, '');
}
}
if (!options.servername)
options.servername = calculateServerName(options, req);

var name = self.getName(options);
options._agentKey = name;
Expand All @@ -211,6 +201,29 @@ Agent.prototype.createSocket = function(req, options, cb) {
}
};

function calculateServerName(options, req) {
let servername = options.host;
const hostHeader = req.getHeader('host');
if (hostHeader) {
// abc => abc
// abc:123 => abc
// [::1] => ::1
// [::1]:123 => ::1
if (hostHeader.startsWith('[')) {
const index = hostHeader.indexOf(']');
if (index === -1) {
// Leading '[', but no ']'. Need to do something...
servername = hostHeader;
} else {
servername = hostHeader.substr(1, index - 1);
}
} else {
servername = hostHeader.split(':', 1)[0];
}
}
return servername;
}

function installListeners(agent, s, options) {
function onFree() {
debug('CLIENT socket onFree');
Expand Down
5 changes: 3 additions & 2 deletions lib/tls.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const net = require('net');
const url = require('url');
const binding = process.binding('crypto');
const Buffer = require('buffer').Buffer;
const canonicalizeIP = process.binding('cares_wrap').canonicalizeIP;

// Allow {CLIENT_RENEG_LIMIT} client-initiated session renegotiations
// every {CLIENT_RENEG_WINDOW} seconds. An error event is emitted if more
Expand Down Expand Up @@ -156,7 +157,7 @@ exports.checkServerIdentity = function checkServerIdentity(host, cert) {
const uri = url.parse(name.slice(4));
uriNames.push(uri.hostname); // TODO(bnoordhuis) Also use scheme.
} else if (name.startsWith('IP Address:')) {
ips.push(name.slice(11));
ips.push(canonicalizeIP(name.slice(11)));
}
}
}
Expand All @@ -165,7 +166,7 @@ exports.checkServerIdentity = function checkServerIdentity(host, cert) {
let reason = 'Unknown reason';

if (net.isIP(host)) {
valid = ips.includes(host);
valid = ips.includes(canonicalizeIP(host));
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
23 changes: 23 additions & 0 deletions src/cares_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,28 @@ static void IsIPv6(const FunctionCallbackInfo<Value>& args) {
}
}


void CanonicalizeIP(const FunctionCallbackInfo<Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
node::Utf8Value ip(isolate, args[0]);
char address_buffer[sizeof(struct in6_addr)];
char canonical_ip[INET6_ADDRSTRLEN];

int af;
if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0)
af = AF_INET;
else if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0)
af = AF_INET6;
else
return;

int err = uv_inet_ntop(af, address_buffer, canonical_ip,
sizeof(canonical_ip));
CHECK_EQ(err, 0);

args.GetReturnValue().Set(String::NewFromUtf8(isolate, canonical_ip));
}

static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);

Expand Down Expand Up @@ -1514,6 +1536,7 @@ static void Initialize(Local<Object> target,
env->SetMethod(target, "isIP", IsIP);
env->SetMethod(target, "isIPv4", IsIPv4);
env->SetMethod(target, "isIPv6", IsIPv6);
env->SetMethod(target, "canonicalizeIP", CanonicalizeIP);

env->SetMethod(target, "strerror", StrError);
env->SetMethod(target, "getServers", GetServers);
Expand Down
31 changes: 31 additions & 0 deletions test/parallel/test-tls-canonical-ip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'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 { canonicalizeIP } = process.binding('cares_wrap');

assert.strictEqual(canonicalizeIP('127.0.0.1'), '127.0.0.1');
assert.strictEqual(canonicalizeIP('10.1.0.1'), '10.1.0.1');
assert.strictEqual(canonicalizeIP('::1'), '::1');
assert.strictEqual(canonicalizeIP('fe80:0:0:0:0:0:0:1'), 'fe80::1');
assert.strictEqual(canonicalizeIP('fe80:0:0:0:0:0:0:0'), 'fe80::');
assert.strictEqual(canonicalizeIP('fe80::0000:0010:0001'), 'fe80::10:1');
assert.strictEqual(canonicalizeIP('0001:2222:3333:4444:5555:6666:7777:0088'),
'1:2222:3333:4444:5555:6666:7777:88');

assert.strictEqual(canonicalizeIP('0001:2222:3333:4444:5555:6666::'),
'1:2222:3333:4444:5555:6666::');

assert.strictEqual(canonicalizeIP('a002:B12:00Ba:4444:5555:6666:0:0'),
'a002:b12:ba:4444:5555:6666::');

// IPv4 address represented in IPv6
assert.strictEqual(canonicalizeIP('0:0:0:0:0:ffff:c0a8:101'),
'::ffff:192.168.1.1');

assert.strictEqual(canonicalizeIP('::ffff:192.168.1.1'),
'::ffff:192.168.1.1');