]> granicus.if.org Git - curl/commitdiff
openssl: make sure to fail in the unlikely event that PRNG seeding fails
authorDaniel Stenberg <daniel@haxx.se>
Fri, 11 Nov 2016 13:16:17 +0000 (14:16 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 11 Nov 2016 13:16:31 +0000 (14:16 +0100)
lib/vtls/openssl.c

index fa128fa46a658cf54b0b4020a7bdf9b78555f1c9..8874632aa6a8169320926743295dbce3bc96ea6e 100644 (file)
@@ -183,13 +183,22 @@ static bool rand_enough(void)
   return (0 != RAND_status()) ? TRUE : FALSE;
 }
 
-static int ossl_seed(struct Curl_easy *data)
+static CURLcode Curl_ossl_seed(struct Curl_easy *data)
 {
+  /* we have the "SSL is seeded" boolean static to prevent multiple
+     time-consuming seedings in vain */
+  static bool ssl_seeded = FALSE;
   char *buf = data->state.buffer; /* point to the big buffer */
   int nread=0;
 
-  if(rand_enough())
-    return 1;
+  if(ssl_seeded)
+    return CURLE_OK;
+
+  if(rand_enough()) {
+    /* OpenSSL 1.1.0+ will return here */
+    ssl_seeded = TRUE;
+    return CURLE_OK;
+  }
 
 #ifndef RANDOM_FILE
   /* if RANDOM_FILE isn't defined, we only perform this if an option tells
@@ -234,9 +243,10 @@ static int ossl_seed(struct Curl_easy *data)
   do {
     unsigned char randb[64];
     int len = sizeof(randb);
-    RAND_bytes(randb, len);
+    if(!RAND_bytes(randb, len))
+      break;
     RAND_add(randb, len, (len >> 1));
-  } while(!RAND_status());
+  } while(!rand_enough());
 
   /* generates a default path for the random seed file */
   buf[0]=0; /* blank it first */
@@ -249,20 +259,7 @@ static int ossl_seed(struct Curl_easy *data)
   }
 
   infof(data, "libcurl is now using a weak random seed!\n");
-  return nread;
-}
-
-static void Curl_ossl_seed(struct Curl_easy *data)
-{
-  /* we have the "SSL is seeded" boolean static to prevent multiple
-     time-consuming seedings in vain */
-  static bool ssl_seeded = FALSE;
-
-  if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
-     data->set.str[STRING_SSL_EGDSOCKET]) {
-    ossl_seed(data);
-    ssl_seeded = TRUE;
-  }
+  return CURLE_SSL_CONNECT_ERROR; /* confusing error code */
 }
 
 #ifndef SSL_FILETYPE_ENGINE
@@ -1710,7 +1707,9 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
   DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
 
   /* Make funny stuff to get random input */
-  Curl_ossl_seed(data);
+  result = Curl_ossl_seed(data);
+  if(result)
+    return result;
 
   data->set.ssl.certverifyresult = !X509_V_OK;
 
@@ -3237,7 +3236,12 @@ int Curl_ossl_random(struct Curl_easy *data, unsigned char *entropy,
                      size_t length)
 {
   if(data) {
-    Curl_ossl_seed(data); /* Initiate the seed if not already done */
+    if(Curl_ossl_seed(data)) /* Initiate the seed if not already done */
+      return 1; /* couldn't seed for some reason */
+  }
+  else {
+    if(!rand_enough())
+      return 1;
   }
   RAND_bytes(entropy, curlx_uztosi(length));
   return 0; /* 0 as in no problem */