Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
tls: add minDHSize option to tls.connect()
Add a new option to specifiy a minimum size of an ephemeral DH
parameter to accept a tls connection. Default is 1024 bit.
  • Loading branch information
Shigeki Ohtsu committed Aug 27, 2015
commit a351777b82b1b8158653d3db024c602176e7cc84
5 changes: 5 additions & 0 deletions doc/api/tls.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,11 @@ Creates a new client connection to the given `port` and `host` (old API) or

- `session`: A `Buffer` instance, containing TLS session.

- `minDHSize`: Minimum size of DH parameter in bits to accept a TLS
connection. When a server offers DH parameter with a size less
than this, the TLS connection is destroyed and throws an
error. Default: 1024.

The `callback` parameter will be added as a listener for the
['secureConnect'][] event.

Expand Down
19 changes: 18 additions & 1 deletion lib/_tls_wrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -945,14 +945,20 @@ exports.connect = function(/* [port, host], options, cb */) {
var defaults = {
rejectUnauthorized: '0' !== process.env.NODE_TLS_REJECT_UNAUTHORIZED,
ciphers: tls.DEFAULT_CIPHERS,
checkServerIdentity: tls.checkServerIdentity
checkServerIdentity: tls.checkServerIdentity,
minDHSize: 1024
};

options = util._extend(defaults, options || {});
if (!options.keepAlive)
options.singleUse = true;

assert(typeof options.checkServerIdentity === 'function');
assert(typeof options.minDHSize === 'number',
'options.minDHSize is not a number: ' + options.minDHSize);
assert(options.minDHSize > 0,
'options.minDHSize is not a posivie number: ' +
options.minDHSize);

var hostname = options.servername ||
options.host ||
Expand Down Expand Up @@ -1004,6 +1010,17 @@ exports.connect = function(/* [port, host], options, cb */) {
socket._start();

socket.on('secure', function() {
// Check the size of DHE parameter above minimum requirement
// specified in options.
var ekeyinfo = socket.getEphemeralKeyInfo();
if (ekeyinfo.type === 'DH' && ekeyinfo.size < options.minDHSize) {
var err = new Error('DH parameter size ' + ekeyinfo.size +
' is less than ' + options.minDHSize);
socket.emit('error', err);
socket.destroy();
return;
}

var verifyError = socket._handle.verifyError();

// Verify that server's identity matches it's certificate's names
Expand Down
81 changes: 81 additions & 0 deletions test/parallel/test-tls-client-mindhsize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'use strict';
var common = require('../common');
var assert = require('assert');

if (!common.hasCrypto) {
console.log('1..0 # Skipped: missing crypto');
process.exit();
}
var tls = require('tls');

var fs = require('fs');
var key = fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem');
var cert = fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem');

var nsuccess = 0;
var nerror = 0;

function loadDHParam(n) {
var path = common.fixturesDir;
if (n !== 'error') path += '/keys';
return fs.readFileSync(path + '/dh' + n + '.pem');
}

function test(size, err, next) {
var options = {
key: key,
cert: cert,
dhparam: loadDHParam(size),
ciphers: 'DHE-RSA-AES128-GCM-SHA256'
};

var server = tls.createServer(options, function(conn) {
conn.end();
});

server.on('close', function(isException) {
assert(!isException);
if (next) next();
});

server.listen(common.PORT, '127.0.0.1', function() {
// client set minimum DH parameter size to 2048 bits so that
// it fails when it make a connection to the tls server where
// dhparams is 1024 bits
var client = tls.connect({
minDHSize: 2048,
port: common.PORT,
rejectUnauthorized: false
}, function() {
nsuccess++;
server.close();
});
if (err) {
client.on('error', function(e) {
nerror++;
assert.strictEqual(e.message, 'DH parameter size 1024 is less'
+ ' than 2048');
server.close();
});
}
});
}

// A client connection fails with an error when a client has an
// 2048 bits minDHSize option and a server has 1024 bits dhparam
function testDHE1024() {
test(1024, true, testDHE2048);
}

// A client connection successes when a client has an
// 2048 bits minDHSize option and a server has 2048 bits dhparam
function testDHE2048() {
test(2048, false, null);
}

testDHE1024();

process.on('exit', function() {
assert.equal(nsuccess, 1);
assert.equal(nerror, 1);
});