src: seed V8's random number generator at startup
authorBen Noordhuis <info@bnoordhuis.nl>
Fri, 20 Sep 2013 20:01:49 +0000 (22:01 +0200)
committerBen Noordhuis <info@bnoordhuis.nl>
Fri, 20 Sep 2013 20:11:42 +0000 (22:11 +0200)
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.

src/node.cc
src/node_crypto.cc
src/node_crypto.h

index b4ce91f..0f630c5 100644 (file)
@@ -3224,6 +3224,12 @@ int Start(int argc, char** argv) {
   Init(&argc, const_cast<const char**>(argv), &exec_argc, &exec_argv);
 
   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(node_isolate);
     Environment* env =
index e4b983b..ee1b7db 100644 (file)
@@ -185,6 +185,14 @@ void 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(Environment* env, Handle<Object> target) {
   Local<FunctionTemplate> t = FunctionTemplate::New(SecureContext::New);
   t->InstanceTemplate()->SetInternalFieldCount(1);
index c37285b..b6eb882 100644 (file)
@@ -509,6 +509,7 @@ class DiffieHellman : public ObjectWrap {
   DH* dh;
 };
 
+bool EntropySource(unsigned char* buffer, size_t length);
 void InitCrypto(v8::Handle<v8::Object> target);
 
 }  // namespace crypto