From ddefc056b68e0eb8912080b6817d17f1a8ad406f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 11 Nov 2016 14:16:17 +0100 Subject: [PATCH] openssl: make sure to fail in the unlikely event that PRNG seeding fails --- lib/vtls/openssl.c | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index fa128fa46..8874632aa 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -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 */