diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2013-03-19 03:16:55 +0400 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2013-03-25 21:42:07 +0400 |
commit | cfd0dca9ae0c834e91823c59784f697d0559a63b (patch) | |
tree | e258dd01dcc14eb40517a8b940c4ec14b2651271 | |
parent | 488b74d68bc259c066351dd24adebbdeb53f4d24 (diff) |
crypto: make getCiphers() return non-SSL ciphers
Commit f53441a added crypto.getCiphers() as a function that returns the
names of SSL ciphers.
Commit 14a6c4e then added crypto.getHashes(), which returns the names of
digest algorithms, but that creates a subtle inconsistency: the return
values of crypto.getHashes() are valid arguments to crypto.createHash()
but that is not true for crypto.getCiphers() - the returned values are
only valid for SSL/TLS functions.
Rectify that by adding tls.getCiphers() and making crypto.getCiphers()
return proper cipher names.
-rw-r--r-- | doc/api/crypto.markdown | 2 | ||||
-rw-r--r-- | doc/api/tls.markdown | 10 | ||||
-rw-r--r-- | lib/crypto.js | 16 | ||||
-rw-r--r-- | lib/tls.js | 11 | ||||
-rw-r--r-- | src/node_crypto.cc | 22 | ||||
-rw-r--r-- | test/simple/test-crypto.js | 22 |
6 files changed, 60 insertions, 23 deletions
diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown index 7cc4bdd920e..27b03622e85 100644 --- a/doc/api/crypto.markdown +++ b/doc/api/crypto.markdown @@ -19,7 +19,7 @@ Returns an array with the names of the supported ciphers. Example: var ciphers = crypto.getCiphers(); - console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...] + console.log(ciphers); // ['AES-128-CBC', 'AES-128-CBC-HMAC-SHA1', ...] ## crypto.getHashes() diff --git a/doc/api/tls.markdown b/doc/api/tls.markdown index 28bc05630e6..f89de220596 100644 --- a/doc/api/tls.markdown +++ b/doc/api/tls.markdown @@ -76,6 +76,16 @@ handshake extensions allowing you: certificates. +## tls.getCiphers() + +Returns an array with the names of the supported SSL ciphers. + +Example: + + var ciphers = tls.getCiphers(); + console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...] + + ## tls.createServer(options, [secureConnectionListener]) Creates a new [tls.Server][]. The `connectionListener` argument is diff --git a/lib/crypto.js b/lib/crypto.js index 9c7dd64aed6..94c95695f18 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -576,21 +576,23 @@ exports.prng = pseudoRandomBytes; exports.getCiphers = function() { - return getCiphers.call(null, arguments).sort(); + return filterDuplicates(getCiphers.call(null, arguments)); }; exports.getHashes = function() { - var names = getHashes.call(null, arguments); + return filterDuplicates(getHashes.call(null, arguments)); +}; + + +function filterDuplicates(names) { // Drop all-caps names in favor of their lowercase aliases, // for example, 'sha1' instead of 'SHA1'. var ctx = {}; - names = names.forEach(function(name) { + names.forEach(function(name) { if (/^[0-9A-Z\-]+$/.test(name)) name = name.toLowerCase(); ctx[name] = true; }); - names = Object.getOwnPropertyNames(ctx); - - return names.sort(); -}; + return Object.getOwnPropertyNames(ctx).sort(); +} diff --git a/lib/tls.js b/lib/tls.js index a7908f77fce..df2afec5333 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -40,6 +40,17 @@ exports.CLIENT_RENEG_WINDOW = 600; exports.SLAB_BUFFER_SIZE = 10 * 1024 * 1024; +exports.getCiphers = function() { + var names = process.binding('crypto').getSSLCiphers(); + // Drop all-caps names in favor of their lowercase aliases, + var ctx = {}; + names.forEach(function(name) { + if (/^[0-9A-Z\-]+$/.test(name)) name = name.toLowerCase(); + ctx[name] = true; + }); + return Object.getOwnPropertyNames(ctx).sort(); +}; + var debug; if (process.env.NODE_DEBUG && /tls/.test(process.env.NODE_DEBUG)) { diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 2df45737a5c..c53d2ce7acd 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3948,7 +3948,7 @@ Handle<Value> RandomBytes(const Arguments& args) { } -Handle<Value> GetCiphers(const Arguments& args) { +Handle<Value> GetSSLCiphers(const Arguments& args) { HandleScope scope; SSL_CTX* ctx = SSL_CTX_new(TLSv1_server_method()); @@ -3977,19 +3977,28 @@ Handle<Value> GetCiphers(const Arguments& args) { } -static void add_hash_to_array(const EVP_MD* md, - const char* from, - const char* to, - void* arg) { +template <class TypeName> +static void array_push_back(const TypeName* md, + const char* from, + const char* to, + void* arg) { Local<Array>& arr = *static_cast<Local<Array>*>(arg); arr->Set(arr->Length(), String::New(from)); } +Handle<Value> GetCiphers(const Arguments& args) { + HandleScope scope; + Local<Array> arr = Array::New(); + EVP_CIPHER_do_all_sorted(array_push_back<EVP_CIPHER>, &arr); + return scope.Close(arr); +} + + Handle<Value> GetHashes(const Arguments& args) { HandleScope scope; Local<Array> arr = Array::New(); - EVP_MD_do_all_sorted(add_hash_to_array, &arr); + EVP_MD_do_all_sorted(array_push_back<EVP_MD>, &arr); return scope.Close(arr); } @@ -4033,6 +4042,7 @@ void InitCrypto(Handle<Object> target) { NODE_SET_METHOD(target, "PBKDF2", PBKDF2); NODE_SET_METHOD(target, "randomBytes", RandomBytes<false>); NODE_SET_METHOD(target, "pseudoRandomBytes", RandomBytes<true>); + NODE_SET_METHOD(target, "getSSLCiphers", GetSSLCiphers); NODE_SET_METHOD(target, "getCiphers", GetCiphers); NODE_SET_METHOD(target, "getHashes", GetHashes); diff --git a/test/simple/test-crypto.js b/test/simple/test-crypto.js index 4a7c45681cd..e17f2d5599e 100644 --- a/test/simple/test-crypto.js +++ b/test/simple/test-crypto.js @@ -834,20 +834,24 @@ testPBKDF2('pass\0word', 'sa\0lt', 4096, 16, '\x25\xe0\xc3'); function assertSorted(list) { - for (var i = 0, k = list.length - 1; i < k; ++i) { - var a = list[i + 0]; - var b = list[i + 1]; - assert(a <= b); - } + assert.deepEqual(list, list.sort()); } -// Assume that we have at least AES256-SHA. -assert.notEqual(0, crypto.getCiphers()); -assert.notEqual(-1, crypto.getCiphers().indexOf('AES256-SHA')); +// Assume that we have at least AES-128-CBC. +assert.notEqual(0, crypto.getCiphers().length); +assert.notEqual(-1, crypto.getCiphers().indexOf('aes-128-cbc')); +assert.equal(-1, crypto.getCiphers().indexOf('AES-128-CBC')); assertSorted(crypto.getCiphers()); +// Assume that we have at least AES256-SHA. +var tls = require('tls'); +assert.notEqual(0, tls.getCiphers().length); +assert.notEqual(-1, tls.getCiphers().indexOf('aes256-sha')); +assert.equal(-1, tls.getCiphers().indexOf('AES256-SHA')); +assertSorted(tls.getCiphers()); + // Assert that we have sha and sha1 but not SHA and SHA1. -assert.notEqual(0, crypto.getHashes()); +assert.notEqual(0, crypto.getHashes().length); assert.notEqual(-1, crypto.getHashes().indexOf('sha1')); assert.notEqual(-1, crypto.getHashes().indexOf('sha')); assert.equal(-1, crypto.getHashes().indexOf('SHA1')); |