crypto: add getCurves() to get supported ECs
authorBrian White <mscdex@mscdex.net>
Mon, 8 Jun 2015 16:26:16 +0000 (12:26 -0400)
committerBrian White <mscdex@mscdex.net>
Mon, 8 Jun 2015 16:35:41 +0000 (12:35 -0400)
PR-URL: https://github.com/nodejs/io.js/pull/1914
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
doc/api/crypto.markdown
lib/crypto.js
src/node_crypto.cc
test/parallel/test-crypto.js

index df5f28e..6e2e1ef 100644 (file)
@@ -42,7 +42,7 @@ Returns an array with the names of the supported ciphers.
 Example:
 
     var ciphers = crypto.getCiphers();
-    console.log(ciphers); // ['AES-128-CBC', 'AES-128-CBC-HMAC-SHA1', ...]
+    console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...]
 
 
 ## crypto.getHashes()
@@ -55,6 +55,16 @@ Example:
     console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]
 
 
+## crypto.getCurves()
+
+Returns an array with the names of the supported elliptic curves.
+
+Example:
+
+    var curves = crypto.getCurves();
+    console.log(curves); // ['secp256k1', 'secp384r1', ...]
+
+
 ## crypto.createCredentials(details)
 
     Stability: 0 - Deprecated. Use [tls.createSecureContext][] instead.
index 7ce8948..d0ecef4 100644 (file)
@@ -10,6 +10,7 @@ try {
   var randomBytes = binding.randomBytes;
   var getCiphers = binding.getCiphers;
   var getHashes = binding.getHashes;
+  var getCurves = binding.getCurves;
 } catch (e) {
   throw new Error('node.js not compiled with openssl crypto support.');
 }
@@ -652,13 +653,17 @@ exports.randomBytes = exports.pseudoRandomBytes = randomBytes;
 exports.rng = exports.prng = randomBytes;
 
 exports.getCiphers = function() {
-  return filterDuplicates(getCiphers.call(null, arguments));
+  return filterDuplicates(getCiphers());
 };
 
 
 exports.getHashes = function() {
-  return filterDuplicates(getHashes.call(null, arguments));
+  return filterDuplicates(getHashes());
+};
+
 
+exports.getCurves = function() {
+  return filterDuplicates(getCurves());
 };
 
 
index e2c478a..51914b8 100644 (file)
@@ -4878,6 +4878,32 @@ void GetHashes(const FunctionCallbackInfo<Value>& args) {
 }
 
 
+void GetCurves(const FunctionCallbackInfo<Value>& args) {
+  Environment* env = Environment::GetCurrent(args);
+  const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
+  Local<Array> arr = Array::New(env->isolate(), num_curves);
+  EC_builtin_curve* curves;
+  size_t alloc_size;
+
+  if (num_curves) {
+    alloc_size = sizeof(*curves) * num_curves;
+    curves = static_cast<EC_builtin_curve*>(malloc(alloc_size));
+
+    CHECK_NE(curves, nullptr);
+
+    if (EC_get_builtin_curves(curves, num_curves)) {
+      for (size_t i = 0; i < num_curves; i++) {
+        arr->Set(i, OneByteString(env->isolate(), OBJ_nid2sn(curves[i].nid)));
+      }
+    }
+
+    free(curves);
+  }
+
+  args.GetReturnValue().Set(arr);
+}
+
+
 void Certificate::Initialize(Environment* env, Handle<Object> target) {
   HandleScope scope(env->isolate());
 
@@ -5160,6 +5186,7 @@ void InitCrypto(Handle<Object> target,
   env->SetMethod(target, "getSSLCiphers", GetSSLCiphers);
   env->SetMethod(target, "getCiphers", GetCiphers);
   env->SetMethod(target, "getHashes", GetHashes);
+  env->SetMethod(target, "getCurves", GetCurves);
   env->SetMethod(target, "publicEncrypt",
                  PublicKeyCipher::Cipher<PublicKeyCipher::kPublic,
                                          EVP_PKEY_encrypt_init,
index e355794..2555cf4 100644 (file)
@@ -96,6 +96,12 @@ assert.notEqual(-1, crypto.getHashes().indexOf('RSA-SHA1'));
 assert.equal(-1, crypto.getHashes().indexOf('rsa-sha1'));
 assertSorted(crypto.getHashes());
 
+// Assume that we have at least secp384r1.
+assert.notEqual(0, crypto.getCurves().length);
+assert.notEqual(-1, crypto.getCurves().indexOf('secp384r1'));
+assert.equal(-1, crypto.getCurves().indexOf('SECP384R1'));
+assertSorted(crypto.getCurves());
+
 // Regression tests for #5725: hex input that's not a power of two should
 // throw, not assert in C++ land.
 assert.throws(function() {