diff options
author | Daniel Stenberg <daniel@haxx.se> | 2016-11-11 14:16:17 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2016-11-11 14:16:31 +0100 |
commit | ddefc056b68e0eb8912080b6817d17f1a8ad406f (patch) | |
tree | 323d3fff34d9bd87c743aca13c47f79e6e9cc29a /lib | |
parent | 942c952db6d81c4ea52ea40daf8470a0d3e3e420 (diff) |
openssl: make sure to fail in the unlikely event that PRNG seeding fails
Diffstat (limited to 'lib')
-rw-r--r-- | lib/vtls/openssl.c | 46 |
1 files 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 */ |