Skip to content

Commit

Permalink
tls,crypto: update default cipher list version numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien Gilli committed Jul 16, 2015
1 parent 9783a82 commit bd74d90
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 55 deletions.
26 changes: 13 additions & 13 deletions doc/api/tls.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -135,41 +135,41 @@ absolutely necessary.

It is possible for the built-in default cipher suite to change from one release
of Node.js to another. For instance, v0.10.39 uses a different default than
v0.10.38. Such changes can cause issues with applications written to assume
v0.10.40. Such changes can cause issues with applications written to assume
certain specific defaults. To help buffer applications against such changes,
the `--enable-legacy-cipher-list` command line switch or `NODE_LEGACY_CIPHER_LIST`
environment variable can be set to specify a specific preset default:

# Use the v0.10.38 defaults
node --enable-legacy-cipher-list=v0.10.38
# Use the v0.10.40 defaults
node --enable-legacy-cipher-list=v0.10.40
// or
NODE_LEGACY_CIPHER_LIST=v0.10.38
NODE_LEGACY_CIPHER_LIST=v0.10.40

Currently, the values supported for the `enable-legacy-cipher-list` switch and
`NODE_LEGACY_CIPHER_LIST` environment variable include:

v0.10.38 - To enable the default cipher suite used in v0.10.38
v0.10.40 - To enable the default cipher suite used in v0.10.40

ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH

These legacy cipher suites are also made available for use via the
`getLegacyCiphers()` method:

var tls = require('tls');
console.log(tls.getLegacyCiphers('v0.10.38'));
console.log(tls.getLegacyCiphers('v0.10.40'));

CAUTION: Changes to the default cipher suite are typically made in order to
strengthen the default security for applications running within Node.js.
Reverting back to the defaults used by older releases can weaken the security
of your applications. The legacy cipher suites should only be used if absolutely
necessary.

NOTE: Due to an error in Node.js v0.10.38, the default cipher list only applied
NOTE: Due to an error in Node.js v0.10.40, the default cipher list only applied
to servers using TLS. The default cipher list would _not_ be used by clients.
This behavior has been changed in v0.10.39 and the default cipher list is now
used by both the server and client when using TLS. However, when using
`--enable-legacy-cipher-list=v0.10.38`, Node.js is reverted back to the
v0.10.38 behavior of only using the default cipher list on the server.
`--enable-legacy-cipher-list=v0.10.40`, Node.js is reverted back to the
v0.10.40 behavior of only using the default cipher list on the server.

### Cipher List Precedence

Expand All @@ -184,11 +184,11 @@ will override the environment variables. If both happen to be specified, the
right-most (second one specified) will take precedence. For instance, in the
example:

node --cipher-list=ABC --enable-legacy-cipher-list=v0.10.38
node --cipher-list=ABC --enable-legacy-cipher-list=v0.10.40

The v0.10.38 default cipher list will be used.
The v0.10.40 default cipher list will be used.

node --enable-legacy-cipher-list=v0.10.38 --cipher-list=ABC
node --enable-legacy-cipher-list=v0.10.40 --cipher-list=ABC

The custom cipher list will be used.

Expand All @@ -206,7 +206,7 @@ Example:

Returns a default cipher list used in a previous version of Node.js. The
version parameter must be a string whose value identifies previous Node.js
release version. The only value currently supported is `v0.10.38`.
release version. The only value currently supported is `v0.10.40`.

A TypeError will be thrown if: (a) the `version` is any type other than a
string, (b) the `version` parameter is not specified, or (c) additional
Expand Down
4 changes: 2 additions & 2 deletions lib/crypto.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ exports.createCredentials = function(options, context) {

if (options.ciphers) {
c.context.setCiphers(options.ciphers);
} else if (!(process._usingV1038Ciphers() && options.ciphers === undefined)) {
} else if (!(process._usingV1040Ciphers() && options.ciphers === undefined)) {
// Set the ciphers to the default ciphers list unless
// --enable-legacy-cipher-list=v0.10.38 was passed on the command line and
// --enable-legacy-cipher-list=v0.10.40 was passed on the command line and
// no ciphers value was passed explicitly. In that case, we want to
// preserve the previous buggy behavior that existed in v0.10.x until
// v0.10.39, otherwise, a lot of client code might be broken. Server
Expand Down
8 changes: 4 additions & 4 deletions lib/tls.js
Original file line number Diff line number Diff line change
Expand Up @@ -1338,14 +1338,14 @@ exports.connect = function(/* [port, host], options, cb */) {
var defaults = {
rejectUnauthorized: '0' !== process.env.NODE_TLS_REJECT_UNAUTHORIZED
};
if (!process._usingV1038Ciphers()) {
if (!process._usingV1040Ciphers()) {
// only set the default ciphers if we are _not_ using the
// v0.10.38 legacy cipher list. Node v0.10.38 had a bug
// v0.10.40 legacy cipher list. Node v0.10.40 had a bug
// that failed to set the default ciphers on the default
// options. This has been fixed in v0.10.39 and above.
// However, when the user explicitly tells node to revert
// back to using the v0.10.38 cipher list, node should
// revert back to the original v0.10.38 behavior.
// back to using the v0.10.40 cipher list, node should
// revert back to the original v0.10.40 behavior.
defaults.ciphers = DEFAULT_CIPHERS;
}
options = util._extend(defaults, options || {});
Expand Down
4 changes: 2 additions & 2 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2567,7 +2567,7 @@ static void PrintHelp() {
" --enable-ssl2 enable ssl2\n"
" --enable-ssl3 enable ssl3\n"
" --cipher-list=val specify the default TLS cipher list\n"
" --enable-legacy-cipher-list=v0.10.38 \n"
" --enable-legacy-cipher-list=v0.10.40 \n"
"\n"
"Environment variables:\n"
#ifdef _WIN32
Expand All @@ -2580,7 +2580,7 @@ static void PrintHelp() {
" global contexts.\n"
"NODE_DISABLE_COLORS Set to 1 to disable colors in the REPL\n"
"NODE_CIPHER_LIST Override the default TLS cipher list\n"
"NODE_LEGACY_CIPHER_LIST=v0.10.38\n"
"NODE_LEGACY_CIPHER_LIST=v0.10.40\n"
"\n"
"Documentation can be found at http://nodejs.org/\n");
}
Expand Down
10 changes: 5 additions & 5 deletions src/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,17 @@
};

startup.setupLegacyCiphers = function setupLegacyCiphers() {
process._usingV1038Ciphers = function _usingV1038Ciphers() {
process._usingV1040Ciphers = function _usingV1040Ciphers() {
// Returns true if the --enable-legacy-cipher-list command line
// switch, or the NODE_LEGACY_CIPHER_LIST environment variable
// are set to v0.10.38 and the DEFAULT_CIPHERS equal the v0.10.38
// are set to v0.10.40 and the DEFAULT_CIPHERS equal the v0.10.40
// list.
var crypto = process.binding('crypto');

var argv = process.execArgv;
if ((argv.indexOf('--enable-legacy-cipher-list=v0.10.38') > -1 ||
process.env.NODE_LEGACY_CIPHER_LIST === 'v0.10.38') &&
crypto.DEFAULT_CIPHER_LIST === crypto.getLegacyCiphers('v0.10.38')) {
if ((argv.indexOf('--enable-legacy-cipher-list=v0.10.40') > -1 ||
process.env.NODE_LEGACY_CIPHER_LIST === 'v0.10.40') &&
crypto.DEFAULT_CIPHER_LIST === crypto.getLegacyCiphers('v0.10.40')) {
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
| XN_FLAG_SEP_MULTILINE
| XN_FLAG_FN_SN;

#define DEFAULT_CIPHER_LIST_V10_38 "ECDHE-RSA-AES128-SHA256:" \
#define DEFAULT_CIPHER_LIST_V10_40 "ECDHE-RSA-AES128-SHA256:" \
"AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH"

#define DEFAULT_CIPHER_LIST_HEAD "ECDHE-RSA-AES128-SHA256:" \
Expand Down Expand Up @@ -4207,8 +4207,8 @@ const char* LegacyCipherList(const char * ver) {
if (ver == NULL) {
return NULL;
}
if (strncmp(ver, "v0.10.38", 8) == 0) {
return DEFAULT_CIPHER_LIST_V10_38;
if (strncmp(ver, "v0.10.40", 8) == 0) {
return DEFAULT_CIPHER_LIST_V10_40;
} else {
return NULL;
}
Expand Down
14 changes: 7 additions & 7 deletions test/external/ssl-options/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var RC4_MD5_CIPHER = 'RC4-MD5';
//
// This specific cipher is used to test that it can be used with current
// versions of Node.js *only* when both ends explicitly specify RC4-SHA
// as the cipher they want to use, or if --enable-legacy-cipher-list=v0.10.38
// as the cipher they want to use, or if --enable-legacy-cipher-list=v0.10.40
// is passed at least to the client or the server.
//
// Note also that RC4-SHA is a SSLv3 cipher, not a SSLv2 cipher contrary to
Expand All @@ -37,7 +37,7 @@ var CMD_LINE_OPTIONS = [
null,
"--enable-ssl2",
"--enable-ssl3",
"--enable-legacy-cipher-list=v0.10.38"
"--enable-legacy-cipher-list=v0.10.40"
];

var SERVER_SSL_PROTOCOLS = [
Expand Down Expand Up @@ -188,13 +188,13 @@ function testSSLv2Setups(serverSetup, clientSetup) {

// It is also the case if the server passes explicitly RC4-MD%
// but the client doesn't pass any cipher and passes
// --enable-legacy-cipher-list=v0.10.38 on the command line. This basically
// --enable-legacy-cipher-list=v0.10.40 on the command line. This basically
// keeps the buggy be behavior of clients not using the default ciphers
// list when not explicitly passing any cipher, and as a result
// allowing RC4 and MD5 to be used.
if (serverSetup.ciphers === RC4_MD5_CIPHER &&
clientSetup.ciphers === undefined &&
clientSetup.cmdLine === '--enable-legacy-cipher-list=v0.10.38')
clientSetup.cmdLine === '--enable-legacy-cipher-list=v0.10.40')
return true;

// In all other cases, when using SSLv2 on both sides,
Expand Down Expand Up @@ -222,7 +222,7 @@ function testRC4LegacyCiphers(serverSetup, clientSetup) {
// To be able to use a RC4 cipher suite, either both ends specify it (like
// for the test using RC4-MD5), or one end pass it explicitly and the other
// uses the default ciphers list while passing the
// --enable-legacy-cipher-list=v0.10.38 command line option
// --enable-legacy-cipher-list=v0.10.40 command line option
// We're using RC4-SHA as our test cipher suite, because SHA is allowed by
// default and not RC4, so we know that we're only testing disabling/enabling
// RC4.
Expand All @@ -236,12 +236,12 @@ function testRC4LegacyCiphers(serverSetup, clientSetup) {

if (serverSetup.ciphers === RC4_SHA_CIPHER &&
usesDefaultCiphers(clientSetup) &&
clientSetup.cmdLine === '--enable-legacy-cipher-list=v0.10.38')
clientSetup.cmdLine === '--enable-legacy-cipher-list=v0.10.40')
return true;

if (clientSetup.ciphers === RC4_SHA_CIPHER &&
usesDefaultCiphers(serverSetup) &&
serverSetup.cmdLine === '--enable-legacy-cipher-list=v0.10.38')
serverSetup.cmdLine === '--enable-legacy-cipher-list=v0.10.40')
return true;

// Otherwise, if only one end passes a RC4 cipher suite explicitly,
Expand Down
38 changes: 19 additions & 19 deletions test/simple/test-tls-cipher-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var crypto = process.binding('crypto');
var common = require('../common');
var fs = require('fs');

var V1038Ciphers = tls.getLegacyCiphers('v0.10.38');
var V1038Ciphers = tls.getLegacyCiphers('v0.10.40');

function doTest(checklist, additional_args, env) {
var options;
Expand Down Expand Up @@ -54,53 +54,53 @@ function doTestPrecedence() {
// test that --enable-legacy-cipher-list takes precedence
// over NODE_CIPHER_LIST
doTest(V1038Ciphers,
['--enable-legacy-cipher-list=v0.10.38'],
['--enable-legacy-cipher-list=v0.10.40'],
{'NODE_CIPHER_LIST': 'XYZ'});

// test that --cipher-list takes precedence over NODE_LEGACY_CIPHER_LIST
doTest('ABC',
['--cipher-list=ABC'],
{'NODE_LEGACY_CIPHER_LIST': 'v0.10.38'});
{'NODE_LEGACY_CIPHER_LIST': 'v0.10.40'});

// test that --enable-legacy-cipher-list takes precence over both envars
// note: in this release, there's only one legal value for the legacy
// switch so this test is largely a non-op. When multiple values
// are supported, this test should be changed to test that the
// command line switch actually does override
doTest(V1038Ciphers,
['--enable-legacy-cipher-list=v0.10.38'],
['--enable-legacy-cipher-list=v0.10.40'],
{
'NODE_LEGACY_CIPHER_LIST': 'v0.10.38',
'NODE_LEGACY_CIPHER_LIST': 'v0.10.40',
'NODE_CIPHER_LIST': 'XYZ'
});

// test the right-most command line option takes precedence
doTest(V1038Ciphers,
[
'--cipher-list=XYZ',
'--enable-legacy-cipher-list=v0.10.38'
'--enable-legacy-cipher-list=v0.10.40'
]);

// test the right-most command line option takes precedence
doTest('XYZ',
[
'--enable-legacy-cipher-list=v0.10.38',
'--enable-legacy-cipher-list=v0.10.40',
'--cipher-list=XYZ'
]);

// test the right-most command line option takes precedence
doTest('XYZ',
[
'--cipher-list=ABC',
'--enable-legacy-cipher-list=v0.10.38',
'--enable-legacy-cipher-list=v0.10.40',
'--cipher-list=XYZ'
]);

// test that NODE_LEGACY_CIPHER_LIST takes precedence over
// NODE_CIPHER_LIST
doTest(V1038Ciphers, [],
{
'NODE_LEGACY_CIPHER_LIST': 'v0.10.38',
'NODE_LEGACY_CIPHER_LIST': 'v0.10.40',
'NODE_CIPHER_LIST': 'ABC'
});
}
Expand All @@ -115,7 +115,7 @@ doTest('ABC', [], {'NODE_CIPHER_LIST':'ABC'});
doTest('ABC', ['--cipher-list=ABC']);

// Test the --enable-legacy-cipher-list and NODE_LEGACY_CIPHER_LIST envar
['v0.10.38'].forEach(function(arg) {
['v0.10.40'].forEach(function(arg) {
var checklist = tls.getLegacyCiphers(arg);
// command line switch
doTest(checklist, ['--enable-legacy-cipher-list=' + arg]);
Expand All @@ -136,11 +136,11 @@ assert.throws(function() {tls.getLegacyCiphers(1);}, TypeError);
// too many parameters
assert.throws(function() {tls.getLegacyCiphers('abc', 'extra');}, TypeError);
// ah, just right
assert.doesNotThrow(function() {tls.getLegacyCiphers('v0.10.38');});
assert.doesNotThrow(function() {tls.getLegacyCiphers('v0.10.40');});

// Test to ensure default ciphers are not set when v0.10.38 legacy cipher
// Test to ensure default ciphers are not set when v0.10.40 legacy cipher
// switch is used. This is a bit involved... we need to first set up the
// TLS server, then spawn a second node instance using the v0.10.38 cipher,
// TLS server, then spawn a second node instance using the v0.10.40 cipher,
// then connect and check to make sure the options are correct. Since there
// is no direct way of testing it, an alternate createCredentials shim is
// created that intercepts the call to createCredentials and checks the
Expand All @@ -159,7 +159,7 @@ var fail_if_default_ciphers_set = (
require('crypto').createCredentials = function(options) {
used_monkey_patch = true;
// since node was started with the --enable-legacy-cipher-list
// switch equal to v0.10.38, the options.ciphers should be
// switch equal to v0.10.40, the options.ciphers should be
// undefined. If it's not undefined, we have a problem and
// the test fails
if (options.ciphers !== undefined) {
Expand Down Expand Up @@ -253,19 +253,19 @@ var server = tls.Server(options, function(socket) {
server.listen(common.PORT, function() {
// checks to make sure the default ciphers are *not* set
// because the --enable-legacy-cipher-list switch is set to
// v0.10.38
// v0.10.40
doDefaultCipherTest(fail_if_default_ciphers_set,
['--enable-legacy-cipher-list=v0.10.38']);
['--enable-legacy-cipher-list=v0.10.40']);

// checks to make sure the default ciphers are *not* set
// because the NODE_LEGACY_CIPHER_LIST envar is set to v0.10.38
// because the NODE_LEGACY_CIPHER_LIST envar is set to v0.10.40
doDefaultCipherTest(fail_if_default_ciphers_set,
[], {'NODE_LEGACY_CIPHER_LIST': 'v0.10.38'});
[], {'NODE_LEGACY_CIPHER_LIST': 'v0.10.40'});

// this variant checks to ensure that the default cipher list IS set
doDefaultCipherTest(fail_if_default_ciphers_not_set, [], {});

// test that setting the cipher list explicitly to the v0.10.38
// test that setting the cipher list explicitly to the v0.10.40
// string without using the legacy cipher switch causes the
// default ciphers to be set.
doDefaultCipherTest(fail_if_default_ciphers_not_set,
Expand Down

0 comments on commit bd74d90

Please sign in to comment.