summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Gilli <julien.gilli@joyent.com>2015-06-11 14:32:48 -0700
committerJulien Gilli <julien.gilli@joyent.com>2015-06-18 22:37:10 -0700
commitdcb7ef2e4024bbb984c5d40b692fb5ec6aefa008 (patch)
tree4cf466d35d576cab25dfe18f9657614f38efd8db
parent9463cfae333a5c249e26aef4e5607cbe1d84dea5 (diff)
downloadnode-dcb7ef2e4024bbb984c5d40b692fb5ec6aefa008.tar.gz
tls: revert disable RC4 and cipher lists changes
This reverts commit 67d9a56251c4491beacb666ba5833574d0cf0d12. This commit actually reverts both 67d9a56251c4491beacb666ba5833574d0cf0d12 and 02a549ed2b2afe85d8ff0335b6684ad54023afb7 (both related to ciphers list changes). It does it in one commit because reverting 02a549ed2b2afe85d8ff0335b6684ad54023afb7 results in an empty commit. These changes are not yet ready to be released, and before they are we want to be able to publish new releases. We're reverting them so that we can submit a new PR that will contain all these changes plus what's necessary to be able to land them properly. Conflicts: src/node.cc PR: #25511 PR-URL: https://github.com/joyent/node/pull/25511 Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
-rw-r--r--doc/api/tls.markdown66
-rw-r--r--lib/tls.js14
-rw-r--r--src/node.cc39
-rw-r--r--src/node_crypto.cc25
-rw-r--r--src/node_crypto.h20
-rw-r--r--test/simple/test-tls-cipher-list.js70
-rw-r--r--test/simple/test-tls-getcipher.js2
7 files changed, 12 insertions, 224 deletions
diff --git a/doc/api/tls.markdown b/doc/api/tls.markdown
index 49b37106e..fbd97e88a 100644
--- a/doc/api/tls.markdown
+++ b/doc/api/tls.markdown
@@ -109,60 +109,6 @@ handshake extensions allowing you:
* SNI - to use one TLS server for multiple hostnames with different SSL
certificates.
-## Modifying the Default Cipher Suite
-
-Node.js is built with a default suite of enabled and disabled ciphers.
-Currently, the default cipher suite is:
-
- ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:HIGH:!RC4:!MD5:!aNULL:!EDH
-
-This default can be overridden entirely using the `--cipher-list` command line
-switch or `NODE_CIPHER_LIST` environment variable. For instance:
-
- node --cipher-list=ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384
-
-Setting the environment variable would have the same effect:
-
- NODE_CIPHER_LIST=ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384
-
-CAUTION: The default cipher suite has been carefully selected to reflect current
-security best practices and risk mitigation. Changing the default cipher suite
-can have a significant impact on the security of an application. The
-`--cipher-list` and `NODE_CIPHER_LIST` options should only be used if
-absolutely necessary.
-
-### Using Legacy Default Cipher Suite ###
-
-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
-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
- // or
- NODE_LEGACY_CIPHER_LIST=v0.10.38
-
-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
-
- 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'));
-
-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.
## tls.getCiphers()
@@ -205,13 +151,13 @@ automatically set as a listener for the [secureConnection][] event. The
conjunction with the `honorCipherOrder` option described below to
prioritize the non-CBC cipher.
- Defaults to `ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:HIGH:!RC4:!MD5:!aNULL:!EDH`.
+ Defaults to `AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH`.
Consult the [OpenSSL cipher list format documentation] for details on the
format. ECDH (Elliptic Curve Diffie-Hellman) ciphers are not yet supported.
`AES128-GCM-SHA256` is used when node.js is linked against OpenSSL 1.0.1
- or newer and the client speaks TLS 1.2.
+ or newer and the client speaks TLS 1.2, RC4 is used as a secure fallback.
**NOTE**: Previous revisions of this section suggested `AES256-SHA` as an
acceptable cipher. Unfortunately, `AES256-SHA` is a CBC cipher and therefore
@@ -387,7 +333,7 @@ Here is an example of a client of echo server as described previously:
// These are necessary only if using the client certificate authentication
key: fs.readFileSync('client-key.pem'),
cert: fs.readFileSync('client-cert.pem'),
-
+
// This is necessary only if the server uses the self-signed certificate
ca: [ fs.readFileSync('server-cert.pem') ]
};
@@ -579,7 +525,7 @@ A ClearTextStream is the `clear` member of a SecurePair object.
### Event: 'secureConnect'
-This event is emitted after a new connection has been successfully handshaked.
+This event is emitted after a new connection has been successfully handshaked.
The listener will be called no matter if the server's certificate was
authorized or not. It is up to the user to test `cleartextStream.authorized`
to see if the server certificate was signed by one of the specified CAs.
@@ -604,14 +550,14 @@ some properties corresponding to the field of the certificate.
Example:
- { subject:
+ { subject:
{ C: 'UK',
ST: 'Acknack Ltd',
L: 'Rhys Jones',
O: 'node.js',
OU: 'Test TLS Certificate',
CN: 'localhost' },
- issuer:
+ issuer:
{ C: 'UK',
ST: 'Acknack Ltd',
L: 'Rhys Jones',
diff --git a/lib/tls.js b/lib/tls.js
index 9f53ad82a..e3b908322 100644
--- a/lib/tls.js
+++ b/lib/tls.js
@@ -19,8 +19,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-var _crypto = process.binding('crypto');
-
var crypto = require('crypto');
var util = require('util');
var net = require('net');
@@ -33,9 +31,8 @@ var constants = require('constants');
var Timer = process.binding('timer_wrap').Timer;
-var DEFAULT_CIPHERS = _crypto.DEFAULT_CIPHER_LIST;
-
-exports.getLegacyCiphers = _crypto.getLegacyCiphers;
+var DEFAULT_CIPHERS = 'ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:' + // TLS 1.2
+ 'RC4:HIGH:!MD5:!aNULL:!EDH'; // TLS 1.0
// Allow {CLIENT_RENEG_LIMIT} client-initiated session renegotiations
// every {CLIENT_RENEG_WINDOW} seconds. An error event is emitted if more
@@ -47,7 +44,7 @@ exports.CLIENT_RENEG_WINDOW = 600;
exports.SLAB_BUFFER_SIZE = 10 * 1024 * 1024;
exports.getCiphers = function() {
- var names = _crypto.getSSLCiphers();
+ var names = process.binding('crypto').getSSLCiphers();
// Drop all-caps names in favor of their lowercase aliases,
var ctx = {};
names.forEach(function(name) {
@@ -68,7 +65,7 @@ if (process.env.NODE_DEBUG && /tls/.test(process.env.NODE_DEBUG)) {
var Connection = null;
try {
- Connection = _crypto.Connection;
+ Connection = process.binding('crypto').Connection;
} catch (e) {
throw new Error('node.js not compiled with openssl crypto support.');
}
@@ -1338,9 +1335,6 @@ exports.connect = function(/* [port, host], options, cb */) {
var defaults = {
rejectUnauthorized: '0' !== process.env.NODE_TLS_REJECT_UNAUTHORIZED
};
- if (DEFAULT_CIPHERS != _crypto.getLegacyCiphers('v0.10.38')) {
- defaults.ciphers = DEFAULT_CIPHERS;
- }
options = util._extend(defaults, options || {});
options.secureOptions = crypto._getSecureOptions(options.secureProtocol,
diff --git a/src/node.cc b/src/node.cc
index 81e123e57..e80c1a573 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -2566,8 +2566,6 @@ static void PrintHelp() {
" --max-stack-size=val set max v8 stack size (bytes)\n"
" --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"
"\n"
"Environment variables:\n"
#ifdef _WIN32
@@ -2579,8 +2577,6 @@ static void PrintHelp() {
"NODE_MODULE_CONTEXTS Set to 1 to load modules in their own\n"
" 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"
"\n"
"Documentation can be found at http://nodejs.org/\n");
}
@@ -2588,7 +2584,6 @@ static void PrintHelp() {
// Parse node command line arguments.
static void ParseArgs(int argc, char **argv) {
int i;
- bool using_legacy_cipher_list = false;
// TODO use parse opts
for (i = 1; i < argc; i++) {
@@ -2657,21 +2652,6 @@ static void ParseArgs(int argc, char **argv) {
} else if (strcmp(arg, "--throw-deprecation") == 0) {
argv[i] = const_cast<char*>("");
throw_deprecation = true;
- } else if (strncmp(arg, "--cipher-list=", 14) == 0) {
- if (!using_legacy_cipher_list) {
- DEFAULT_CIPHER_LIST = arg + 14;
- }
- argv[i] = const_cast<char*>("");
- } else if (strncmp(arg, "--enable-legacy-cipher-list=", 28) == 0) {
- const char * legacy_list = legacy_cipher_list(arg+28);
- if (legacy_list != NULL) {
- using_legacy_cipher_list = true;
- DEFAULT_CIPHER_LIST = legacy_list;
- } else {
- fprintf(stderr, "Error: An unknown legacy cipher list was specified\n");
- exit(9);
- }
- argv[i] = const_cast<char*>("");
} else if (argv[i][0] != '-') {
break;
}
@@ -2966,25 +2946,6 @@ char** Init(int argc, char *argv[]) {
v8argv[option_end_index + 1] = const_cast<char*>("v8debug");
}
- const char * cipher_list = getenv("NODE_CIPHER_LIST");
- if (cipher_list != NULL) {
- DEFAULT_CIPHER_LIST = cipher_list;
- }
- // Allow the NODE_LEGACY_CIPHER_LIST envar to override the other
- // cipher list options. NODE_LEGACY_CIPHER_LIST=v0.10.38 will use
- // the cipher list from v0.10.38
- const char * leg_cipher_id = getenv("NODE_LEGACY_CIPHER_LIST");
- if (leg_cipher_id != NULL) {
- const char * leg_cipher_list =
- legacy_cipher_list(leg_cipher_id);
- if (leg_cipher_list != NULL) {
- DEFAULT_CIPHER_LIST = leg_cipher_list;
- } else {
- fprintf(stderr, "Error: An unknown legacy cipher list was specified\n");
- exit(9);
- }
- }
-
// For the normal stack which moves from high to low addresses when frames
// are pushed, we can compute the limit as stack_size bytes below the
// the address of a stack variable (e.g. &stack_var) as an approximation
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index c1e943fef..7a3922a79 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -71,7 +71,6 @@ const char* root_certs[] = {
bool SSL2_ENABLE = false;
bool SSL3_ENABLE = false;
-const char * DEFAULT_CIPHER_LIST = DEFAULT_CIPHER_LIST_HEAD;
namespace crypto {
@@ -803,7 +802,7 @@ size_t ClientHelloParser::Write(const uint8_t* data, size_t len) {
HandleScope scope;
assert(state_ != kEnded);
-
+
// Just accumulate data, everything will be pushed to BIO later
if (state_ == kPaused) return 0;
@@ -4191,21 +4190,6 @@ static void array_push_back(const TypeName* md,
arr->Set(arr->Length(), String::New(from));
}
-// borrowed from v8
-// (see http://v8.googlecode.com/svn/trunk/samples/shell.cc)
-const char* ToCString(const node::Utf8Value& value) {
- return *value ? *value : "<string conversion failed>";
-}
-
-Handle<Value> DefaultCiphers(const Arguments& args) {
- HandleScope scope;
- node::Utf8Value key(args[0]);
- const char * list = legacy_cipher_list(ToCString(key));
- if (list == NULL) {
- list = DEFAULT_CIPHER_LIST_HEAD;
- }
- return scope.Close(v8::String::New(list));
-}
Handle<Value> GetCiphers(const Arguments& args) {
HandleScope scope;
@@ -4280,13 +4264,6 @@ void InitCrypto(Handle<Object> target) {
NODE_DEFINE_CONSTANT(target, SSL3_ENABLE);
NODE_DEFINE_CONSTANT(target, SSL2_ENABLE);
-
- (target)->ForceSet(
- v8::String::New("DEFAULT_CIPHER_LIST"),
- v8::String::New(DEFAULT_CIPHER_LIST),
- static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
-
- NODE_SET_METHOD(target, "getLegacyCiphers", DefaultCiphers);
}
} // namespace crypto
diff --git a/src/node_crypto.h b/src/node_crypto.h
index 0b360cfa3..54b9b88e4 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -27,7 +27,6 @@
#include "node_object_wrap.h"
#include "v8.h"
-#include <string.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/evp.h>
@@ -44,29 +43,10 @@
#define EVP_F_EVP_DECRYPTFINAL 101
-#define DEFAULT_CIPHER_LIST_V10_38 "ECDHE-RSA-AES128-SHA256:" \
- "AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH"
-
-#define DEFAULT_CIPHER_LIST_HEAD "ECDHE-RSA-AES128-SHA256:" \
- "AES128-GCM-SHA256:HIGH:!RC4:!MD5:!aNULL:!EDH"
-
-static inline const char * legacy_cipher_list(const char * ver) {
- if (ver == NULL) {
- return NULL;
- }
- if (strncmp(ver, "v0.10.38", 8) == 0) {
- return DEFAULT_CIPHER_LIST_V10_38;
- } else {
- return NULL;
- }
-}
-
-
namespace node {
extern bool SSL2_ENABLE;
extern bool SSL3_ENABLE;
-extern const char * DEFAULT_CIPHER_LIST;
namespace crypto {
diff --git a/test/simple/test-tls-cipher-list.js b/test/simple/test-tls-cipher-list.js
deleted file mode 100644
index ac2169537..000000000
--- a/test/simple/test-tls-cipher-list.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var spawn = require('child_process').spawn;
-var assert = require('assert');
-var tls = require('tls');
-var crypto = process.binding('crypto');
-
-function doTest(checklist, env, useswitch) {
- var options;
- if (env && useswitch === 1) {
- options = {env:env};
- }
- var args = ['-e', 'console.log(process.binding(\'crypto\').DEFAULT_CIPHER_LIST)'];
-
- switch(useswitch) {
- case 1:
- // Test --cipher-test
- args.unshift('--cipher-list=' + env);
- break;
- case 2:
- // Test --enable-legacy-cipher-list
- args.unshift('--enable-legacy-cipher-list=' + env);
- break;
- case 3:
- // Test NODE_LEGACY_CIPHER_LIST
- if (env) options = {env:{"NODE_LEGACY_CIPHER_LIST": env}};
- break;
- default:
- // Test NODE_CIPHER_LIST
- if (env) options = {env:env};
- }
-
- var out = '';
- spawn(process.execPath, args, options).
- stdout.
- on('data', function(data) {
- out += data;
- }).
- on('end', function() {
- assert.equal(out.trim(), checklist);
- });
-}
-
-doTest(crypto.DEFAULT_CIPHER_LIST); // test the default
-doTest('ABC', {'NODE_CIPHER_LIST':'ABC'}); // test the envar
-doTest('ABC', 'ABC', 1); // test the --cipher-list switch
-
-['v0.10.38'].forEach(function(ver) {
- doTest(tls.getLegacyCiphers(ver), ver, 2);
- doTest(tls.getLegacyCiphers(ver), ver, 3);
-});
diff --git a/test/simple/test-tls-getcipher.js b/test/simple/test-tls-getcipher.js
index 8fb9d5287..22a280e58 100644
--- a/test/simple/test-tls-getcipher.js
+++ b/test/simple/test-tls-getcipher.js
@@ -49,7 +49,7 @@ server.listen(common.PORT, '127.0.0.1', function() {
rejectUnauthorized: false
}, function() {
var cipher = client.getCipher();
- assert.equal(cipher.name, cipher_list[1]);
+ assert.equal(cipher.name, cipher_list[0]);
assert(cipher_version_pattern.test(cipher.version));
client.end();
server.close();