From e5e598060eb43faf2142184d523a04f0ca2d95c3 Mon Sep 17 00:00:00 2001 From: Calvin Metcalf Date: Wed, 21 Jan 2015 21:30:27 -0500 Subject: [PATCH] lib,src: make pseudoRandomBytes alias randomBytes 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 Reviewed-By: Fedor Indutny --- doc/api/crypto.markdown | 14 ++++---------- lib/crypto.js | 8 ++------ src/node_crypto.cc | 23 +++++++---------------- 3 files changed, 13 insertions(+), 32 deletions(-) diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown index 4753209..84cd27a 100644 --- a/doc/api/crypto.markdown +++ b/doc/api/crypto.markdown @@ -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 diff --git a/lib/crypto.js b/lib/crypto.js index e27dad2..8e3a843 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -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)); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 75c832d..b76a1a6 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -4589,25 +4589,18 @@ class RandomBytesRequest : public AsyncWrap { }; -template 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(req->data()), - req->size()); - } else { - r = RAND_bytes(reinterpret_cast(req->data()), req->size()); - } + const int r = RAND_bytes(reinterpret_cast(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(-1)); @@ -4650,7 +4643,6 @@ void RandomBytesAfter(uv_work_t* work_req, int status) { } -template void RandomBytes(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -4675,12 +4667,12 @@ void RandomBytes(const FunctionCallbackInfo& args) { obj->Set(env->domain_string(), env->domain_array()->Get(0)); uv_queue_work(env->event_loop(), req->work_req(), - RandomBytesWork, + RandomBytesWork, RandomBytesAfter); args.GetReturnValue().Set(obj); } else { Local argv[2]; - RandomBytesWork(req->work_req()); + RandomBytesWork(req->work_req()); RandomBytesCheck(req, argv); delete req; @@ -5041,8 +5033,7 @@ void InitCrypto(Handle target, env->SetMethod(target, "setEngine", SetEngine); #endif // !OPENSSL_NO_ENGINE env->SetMethod(target, "PBKDF2", PBKDF2); - env->SetMethod(target, "randomBytes", RandomBytes); - env->SetMethod(target, "pseudoRandomBytes", RandomBytes); + env->SetMethod(target, "randomBytes", RandomBytes); env->SetMethod(target, "getSSLCiphers", GetSSLCiphers); env->SetMethod(target, "getCiphers", GetCiphers); env->SetMethod(target, "getHashes", GetHashes); -- 2.7.4