lib,src: make pseudoRandomBytes alias randomBytes
authorCalvin Metcalf <cmetcalf@appgeo.com>
Thu, 22 Jan 2015 02:30:27 +0000 (21:30 -0500)
committerBen Noordhuis <info@bnoordhuis.nl>
Thu, 22 Jan 2015 22:08:36 +0000 (23:08 +0100)
Previously pseudoRandomBytes worked similarly to randomBytes but in the
event of insufficient entropy would silently return non-secure values.

As of f68a116, the entropy pool blocks if there is insufficient entropy
instead of giving an error so there is now no longer a case where
pseudoRandomBytes would act differently than randomBytes.

Docs are updated to remove pseudoRandomBytes and to clarify that
randomBytes now does block instead of erring when entropy is low.

PR-URL: https://github.com/iojs/io.js/pull/557
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Fedor Indutny <fedor@indutny.com>
doc/api/crypto.markdown
lib/crypto.js
src/node_crypto.cc

index 4753209..84cd27a 100644 (file)
@@ -647,16 +647,10 @@ Generates cryptographically strong pseudo-random data. Usage:
       // most likely, entropy sources are drained
     }
 
-NOTE: Will throw error or invoke callback with error, if there is not enough
-accumulated entropy to generate cryptographically strong data. In other words,
-`crypto.randomBytes` without callback will not block even if all entropy sources
-are drained.
-
-## crypto.pseudoRandomBytes(size[, callback])
-
-Identical to `crypto.randomBytes` except that, instead of throwing an error when
-there is not enough accumulated entropy to generate cryptographically strong
-data, it will silently return **non**-cryptographically strong data.
+NOTE: This will block if there is insufficient entropy, although it should
+normally never take longer than a few milliseconds. The only time when this
+may conceivably block is right after boot, when the whole system is still
+low on entropy.
 
 ## Class: Certificate
 
index e27dad2..8e3a843 100644 (file)
@@ -8,7 +8,6 @@ exports.DEFAULT_ENCODING = 'buffer';
 try {
   var binding = process.binding('crypto');
   var randomBytes = binding.randomBytes;
-  var pseudoRandomBytes = binding.pseudoRandomBytes;
   var getCiphers = binding.getCiphers;
   var getHashes = binding.getHashes;
 } catch (e) {
@@ -636,12 +635,9 @@ exports.setEngine = function setEngine(id, flags) {
   return binding.setEngine(id, flags);
 };
 
-exports.randomBytes = randomBytes;
-exports.pseudoRandomBytes = pseudoRandomBytes;
-
-exports.rng = randomBytes;
-exports.prng = pseudoRandomBytes;
+exports.randomBytes = exports.pseudoRandomBytes = randomBytes;
 
+exports.rng = exports.prng = randomBytes;
 
 exports.getCiphers = function() {
   return filterDuplicates(getCiphers.call(null, arguments));
index 75c832d..b76a1a6 100644 (file)
@@ -4589,25 +4589,18 @@ class RandomBytesRequest : public AsyncWrap {
 };
 
 
-template <bool pseudoRandom>
 void RandomBytesWork(uv_work_t* work_req) {
   RandomBytesRequest* req =
       ContainerOf(&RandomBytesRequest::work_req_, work_req);
-  int r;
 
   // Ensure that OpenSSL's PRNG is properly seeded.
   CheckEntropy();
 
-  if (pseudoRandom == true) {
-    r = RAND_pseudo_bytes(reinterpret_cast<unsigned char*>(req->data()),
-                          req->size());
-  } else {
-    r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data()), req->size());
-  }
+  const int r = RAND_bytes(reinterpret_cast<unsigned char*>(req->data()),
+                           req->size());
 
-  // RAND_bytes() returns 0 on error. RAND_pseudo_bytes() returns 0 when the
-  // result is not cryptographically strong - but that's not an error.
-  if (r == 0 && pseudoRandom == false) {
+  // RAND_bytes() returns 0 on error.
+  if (r == 0) {
     req->set_error(ERR_get_error());
   } else if (r == -1) {
     req->set_error(static_cast<unsigned long>(-1));
@@ -4650,7 +4643,6 @@ void RandomBytesAfter(uv_work_t* work_req, int status) {
 }
 
 
-template <bool pseudoRandom>
 void RandomBytes(const FunctionCallbackInfo<Value>& args) {
   Environment* env = Environment::GetCurrent(args);
 
@@ -4675,12 +4667,12 @@ void RandomBytes(const FunctionCallbackInfo<Value>& args) {
       obj->Set(env->domain_string(), env->domain_array()->Get(0));
     uv_queue_work(env->event_loop(),
                   req->work_req(),
-                  RandomBytesWork<pseudoRandom>,
+                  RandomBytesWork,
                   RandomBytesAfter);
     args.GetReturnValue().Set(obj);
   } else {
     Local<Value> argv[2];
-    RandomBytesWork<pseudoRandom>(req->work_req());
+    RandomBytesWork(req->work_req());
     RandomBytesCheck(req, argv);
     delete req;
 
@@ -5041,8 +5033,7 @@ void InitCrypto(Handle<Object> target,
   env->SetMethod(target, "setEngine", SetEngine);
 #endif  // !OPENSSL_NO_ENGINE
   env->SetMethod(target, "PBKDF2", PBKDF2);
-  env->SetMethod(target, "randomBytes", RandomBytes<false>);
-  env->SetMethod(target, "pseudoRandomBytes", RandomBytes<true>);
+  env->SetMethod(target, "randomBytes", RandomBytes);
   env->SetMethod(target, "getSSLCiphers", GetSSLCiphers);
   env->SetMethod(target, "getCiphers", GetCiphers);
   env->SetMethod(target, "getHashes", GetHashes);