From 70f198ddb1ba464da97799f59ae9233320ecc49d Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 20 Sep 2013 22:01:49 +0200 Subject: [PATCH] src: seed V8's random number generator at startup The default entropy source is /dev/urandom on UNIX platforms, which is okay but we can do better by seeding it from OpenSSL's entropy pool. On Windows we can certainly do better; on that platform, V8 seeds the random number generator using only the current system time. Fixes #6250. NB: This is a back-port of commit 7ac2391 from the master branch that for some reason never got back-ported to the v0.10 branch. The default on UNIX platforms in v0.10 is different and arguably worse than it is with master: if no entropy source is provided, V8 3.14 calls srandom() with a xor of the PID and the current time in microseconds. That means that on systems with a coarse system clock, the initial state of the PRNG may be easily guessable. The situation on Windows is even more dire because there the PRNG is seeded with only the current time... in milliseconds. --- src/node.cc | 6 ++++++ src/node_crypto.cc | 8 ++++++++ src/node_crypto.h | 1 + 3 files changed, 15 insertions(+) diff --git a/src/node.cc b/src/node.cc index ac906f0cd5..958c86dc75 100644 --- a/src/node.cc +++ b/src/node.cc @@ -3057,6 +3057,12 @@ int Start(int argc, char *argv[]) { Init(argc, argv_copy); V8::Initialize(); +#if HAVE_OPENSSL + // V8 on Windows doesn't have a good source of entropy. Seed it from + // OpenSSL's pool. + V8::SetEntropySource(crypto::EntropySource); +#endif + { Locker locker; HandleScope handle_scope; diff --git a/src/node_crypto.cc b/src/node_crypto.cc index e23f1502ce..702a1d13ff 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -157,6 +157,14 @@ Handle ThrowCryptoTypeError(unsigned long err) { } +bool EntropySource(unsigned char* buffer, size_t length) { + // RAND_bytes() can return 0 to indicate that the entropy data is not truly + // random. That's okay, it's still better than V8's stock source of entropy, + // which is /dev/urandom on UNIX platforms and the current time on Windows. + return RAND_bytes(buffer, length) != -1; +} + + void SecureContext::Initialize(Handle target) { HandleScope scope; diff --git a/src/node_crypto.h b/src/node_crypto.h index e4c3cfb392..2b16574142 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -280,6 +280,7 @@ class Connection : ObjectWrap { friend class SecureContext; }; +bool EntropySource(unsigned char* buffer, size_t length); void InitCrypto(v8::Handle target); } // namespace crypto