summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordmitrykos <dmitrykos@neutroncode.com>2017-06-27 20:56:12 +0300
committerDaniel Stenberg <daniel@haxx.se>2017-06-30 09:21:03 +0200
commit192877058e3c50181f3cdc349c17c13b6f9465b9 (patch)
tree51f2829eb5c8d672c6ac37d7ec87ed26c9e05c65
parentf8f040e6596fa22b68198adf42dc6adcedfa57f0 (diff)
downloadcurl-192877058e3c50181f3cdc349c17c13b6f9465b9.tar.gz
openssl: improve fallback seed of PRNG with a time based hash
Fixes #1620
-rw-r--r--lib/vtls/openssl.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 11419f488..a77e4330e 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -236,7 +236,6 @@ 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;
- int nread=0;
char fname[256];
if(ssl_seeded)
@@ -256,12 +255,12 @@ static CURLcode Curl_ossl_seed(struct Curl_easy *data)
#endif
{
/* let the option override the define */
- nread += RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
- data->set.str[STRING_SSL_RANDOM_FILE]:
- RANDOM_FILE),
- RAND_LOAD_LENGTH);
+ RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
+ data->set.str[STRING_SSL_RANDOM_FILE]:
+ RANDOM_FILE),
+ RAND_LOAD_LENGTH);
if(rand_enough())
- return nread;
+ return CURLE_OK;
}
#if defined(HAVE_RAND_EGD)
@@ -279,21 +278,30 @@ static CURLcode Curl_ossl_seed(struct Curl_easy *data)
int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
if(-1 != ret) {
- nread += ret;
if(rand_enough())
- return nread;
+ return CURLE_OK;
}
}
#endif
- /* If we get here, it means we need to seed the PRNG using a "silly"
- approach! */
+ /* fallback to a custom seeding of the PRNG using a hash based on a current
+ time */
do {
unsigned char randb[64];
- int len = sizeof(randb);
- if(!RAND_bytes(randb, len))
- break;
- RAND_add(randb, len, (len >> 1));
+ size_t len = sizeof(randb);
+ size_t i, i_max;
+ for(i = 0, i_max = len / sizeof(struct timeval); i < i_max; ++i) {
+ struct timeval tv = curlx_tvnow();
+ Curl_wait_ms(1);
+ tv.tv_sec *= i + 1;
+ tv.tv_usec *= i + 2;
+ tv.tv_sec ^= ((curlx_tvnow().tv_sec + curlx_tvnow().tv_usec) *
+ (i + 3)) << 8;
+ tv.tv_usec ^= ((curlx_tvnow().tv_sec + curlx_tvnow().tv_usec) *
+ (i + 4)) << 16;
+ memcpy(&randb[i * sizeof(struct timeval)], &tv, sizeof(struct timeval));
+ }
+ RAND_add(randb, (int)len, (double)len/2);
} while(!rand_enough());
/* generates a default path for the random seed file */
@@ -301,13 +309,14 @@ static CURLcode Curl_ossl_seed(struct Curl_easy *data)
RAND_file_name(fname, sizeof(fname));
if(fname[0]) {
/* we got a file name to try */
- nread += RAND_load_file(fname, RAND_LOAD_LENGTH);
+ RAND_load_file(fname, RAND_LOAD_LENGTH);
if(rand_enough())
- return nread;
+ return CURLE_OK;
}
infof(data, "libcurl is now using a weak random seed!\n");
- return CURLE_SSL_CONNECT_ERROR; /* confusing error code */
+ return (rand_enough() ? CURLE_OK :
+ CURLE_SSL_CONNECT_ERROR /* confusing error code */);
}
#ifndef SSL_FILETYPE_ENGINE