From 8dfd22089cac13f718815eb60581ad392b7f106e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 3 Jun 2014 20:04:46 +0200 Subject: vtls: make the random function mandatory in the TLS backend To force each backend implementation to really attempt to provide proper random. If a proper random function is missing, then we can explicitly make use of the default one we use when TLS support is missing. This commit makes sure it works for darwinssl, gnutls, nss and openssl. --- lib/vtls/curl_darwinssl.c | 7 +++---- lib/vtls/curl_darwinssl.h | 10 ++++------ lib/vtls/gtls.c | 13 ++++++++----- lib/vtls/gtls.h | 11 ++++------- lib/vtls/nss.c | 11 +++++++---- lib/vtls/nssg.h | 9 ++++----- lib/vtls/openssl.c | 11 +++++++---- lib/vtls/openssl.h | 9 ++++----- lib/vtls/vtls.c | 20 +++++++++++++------- lib/vtls/vtls.h | 8 ++++---- 10 files changed, 58 insertions(+), 51 deletions(-) (limited to 'lib/vtls') diff --git a/lib/vtls/curl_darwinssl.c b/lib/vtls/curl_darwinssl.c index 1ff5c2494..480e06e6b 100644 --- a/lib/vtls/curl_darwinssl.c +++ b/lib/vtls/curl_darwinssl.c @@ -2267,9 +2267,8 @@ bool Curl_darwinssl_data_pending(const struct connectdata *conn, return false; } -void Curl_darwinssl_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length) +int Curl_darwinssl_random(unsigned char *entropy, + size_t length) { /* arc4random_buf() isn't available on cats older than Lion, so let's do this manually for the benefit of the older cats. */ @@ -2283,7 +2282,7 @@ void Curl_darwinssl_random(struct SessionHandle *data, random_number >>= 8; } i = random_number = 0; - (void)data; + return 0; } void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */ diff --git a/lib/vtls/curl_darwinssl.h b/lib/vtls/curl_darwinssl.h index 432d3d7ce..25ad3d419 100644 --- a/lib/vtls/curl_darwinssl.h +++ b/lib/vtls/curl_darwinssl.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2013, Nick Zitzmann, . + * Copyright (C) 2012 - 2014, Nick Zitzmann, . * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -44,16 +44,14 @@ int Curl_darwinssl_check_cxn(struct connectdata *conn); bool Curl_darwinssl_data_pending(const struct connectdata *conn, int connindex); -void Curl_darwinssl_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length); +int Curl_darwinssl_random(unsigned char *entropy, + size_t length); void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */ size_t tmplen, unsigned char *md5sum, /* output */ size_t md5len); /* this backend provides these functions: */ -#define have_curlssl_random 1 #define have_curlssl_md5sum 1 /* API setup for SecureTransport */ @@ -71,7 +69,7 @@ void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */ #define curlssl_version Curl_darwinssl_version #define curlssl_check_cxn Curl_darwinssl_check_cxn #define curlssl_data_pending(x,y) Curl_darwinssl_data_pending(x, y) -#define curlssl_random(x,y,z) Curl_darwinssl_random(x,y,z) +#define curlssl_random(x,y,z) Curl_darwinssl_random(y,z) #define curlssl_md5sum(a,b,c,d) Curl_darwinssl_md5sum(a,b,c,d) #endif /* USE_DARWINSSL */ diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index e9f60b5e2..0f9bf7b35 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -1261,7 +1261,7 @@ size_t Curl_gtls_version(char *buffer, size_t size) return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL)); } -int Curl_gtls_seed(struct SessionHandle *data) +static int Curl_gtls_seed(struct SessionHandle *data) { /* we have the "SSL is seeded" boolean static to prevent multiple time-consuming seedings in vain */ @@ -1285,17 +1285,20 @@ int Curl_gtls_seed(struct SessionHandle *data) return 0; } -void Curl_gtls_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length) +/* data might be NULL! */ +int Curl_gtls_random(struct SessionHandle *data, + unsigned char *entropy, + size_t length) { #if defined(USE_GNUTLS_NETTLE) (void)data; gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length); #elif defined(USE_GNUTLS) - Curl_gtls_seed(data); /* Initiate the seed if not already done */ + if(data) + Curl_gtls_seed(data); /* Initiate the seed if not already done */ gcry_randomize(entropy, length, GCRY_STRONG_RANDOM); #endif + return 0; } void Curl_gtls_md5sum(unsigned char *tmp, /* input */ diff --git a/lib/vtls/gtls.h b/lib/vtls/gtls.h index 453542e1e..9f99042cf 100644 --- a/lib/vtls/gtls.h +++ b/lib/vtls/gtls.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -45,18 +45,15 @@ void Curl_gtls_close(struct connectdata *conn, int sockindex); void Curl_gtls_session_free(void *ptr); size_t Curl_gtls_version(char *buffer, size_t size); int Curl_gtls_shutdown(struct connectdata *conn, int sockindex); -int Curl_gtls_seed(struct SessionHandle *data); - -void Curl_gtls_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length); +int Curl_gtls_random(struct SessionHandle *data, + unsigned char *entropy, + size_t length); void Curl_gtls_md5sum(unsigned char *tmp, /* input */ size_t tmplen, unsigned char *md5sum, /* output */ size_t md5len); /* this backend provides these functions: */ -#define have_curlssl_random 1 #define have_curlssl_md5sum 1 /* API setup for GnuTLS */ diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c index b2d7f6f9f..83b3e3237 100644 --- a/lib/vtls/nss.c +++ b/lib/vtls/nss.c @@ -1913,16 +1913,19 @@ int Curl_nss_seed(struct SessionHandle *data) return !!Curl_nss_force_init(data); } -void Curl_nss_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length) +/* data might be NULL */ +int Curl_nss_random(struct SessionHandle *data, + unsigned char *entropy, + size_t length) { - Curl_nss_seed(data); /* Initiate the seed if not already done */ + if(data) + Curl_nss_seed(data); /* Initiate the seed if not already done */ if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length))) { /* no way to signal a failure from here, we have to abort */ failf(data, "PK11_GenerateRandom() failed, calling abort()..."); abort(); } + return 0; } void Curl_nss_md5sum(unsigned char *tmp, /* input */ diff --git a/lib/vtls/nssg.h b/lib/vtls/nssg.h index 21e96ce4b..d441de9d9 100644 --- a/lib/vtls/nssg.h +++ b/lib/vtls/nssg.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -51,9 +51,9 @@ int Curl_nss_seed(struct SessionHandle *data); /* initialize NSS library if not already */ CURLcode Curl_nss_force_init(struct SessionHandle *data); -void Curl_nss_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length); +int Curl_nss_random(struct SessionHandle *data, + unsigned char *entropy, + size_t length); void Curl_nss_md5sum(unsigned char *tmp, /* input */ size_t tmplen, @@ -61,7 +61,6 @@ void Curl_nss_md5sum(unsigned char *tmp, /* input */ size_t md5len); /* this backend provides these functions: */ -#define have_curlssl_random 1 #define have_curlssl_md5sum 1 /* API setup for NSS */ diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index c4896008c..844b6e113 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -259,7 +259,7 @@ static int ossl_seed(struct SessionHandle *data) return nread; } -int Curl_ossl_seed(struct SessionHandle *data) +static int Curl_ossl_seed(struct SessionHandle *data) { /* we have the "SSL is seeded" boolean static to prevent multiple time-consuming seedings in vain */ @@ -2865,11 +2865,14 @@ size_t Curl_ossl_version(char *buffer, size_t size) #endif /* YASSL_VERSION */ } -void Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy, - size_t length) +/* can be called with data == NULL */ +int Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy, + size_t length) { - Curl_ossl_seed(data); /* Initiate the seed if not already done */ + if(data) + Curl_ossl_seed(data); /* Initiate the seed if not already done */ RAND_bytes(entropy, curlx_uztosi(length)); + return 0; /* 0 as in no problem */ } void Curl_ossl_md5sum(unsigned char *tmp, /* input */ diff --git a/lib/vtls/openssl.h b/lib/vtls/openssl.h index 07448b50b..fecad7f54 100644 --- a/lib/vtls/openssl.h +++ b/lib/vtls/openssl.h @@ -61,20 +61,19 @@ void Curl_ossl_cleanup(void); size_t Curl_ossl_version(char *buffer, size_t size); int Curl_ossl_check_cxn(struct connectdata *cxn); -int Curl_ossl_seed(struct SessionHandle *data); - int Curl_ossl_shutdown(struct connectdata *conn, int sockindex); bool Curl_ossl_data_pending(const struct connectdata *conn, int connindex); -void Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy, - size_t length); + +/* return 0 if a find random is filled in */ +int Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy, + size_t length); void Curl_ossl_md5sum(unsigned char *tmp, /* input */ size_t tmplen, unsigned char *md5sum /* output */, size_t unused); /* this backend provides these functions: */ -#define have_curlssl_random 1 #define have_curlssl_md5sum 1 /* API setup for OpenSSL */ diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c index 6c2295a45..3c7bc9865 100644 --- a/lib/vtls/vtls.c +++ b/lib/vtls/vtls.c @@ -213,14 +213,12 @@ unsigned int Curl_rand(struct SessionHandle *data) } #endif -#ifndef have_curlssl_random - (void)data; -#else - if(data) { - curlssl_random(data, (unsigned char *)&r, sizeof(r)); + /* data may be NULL! */ + if(!Curl_ssl_random(data, (unsigned char *)&r, sizeof(r))) return r; - } -#endif + + /* If Curl_ssl_random() returns non-zero it couldn't offer randomness and we + instead perform a "best effort" */ #ifdef RANDOM_FILE if(!seeded) { @@ -238,6 +236,7 @@ unsigned int Curl_rand(struct SessionHandle *data) if(!seeded) { struct timeval now = curlx_tvnow(); + infof(data, "WARNING: Using weak random seed\n"); randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec; randseed = randseed * 1103515245 + 12345; randseed = randseed * 1103515245 + 12345; @@ -681,6 +680,13 @@ CURLcode Curl_ssl_push_certinfo(struct SessionHandle *data, return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen); } +int Curl_ssl_random(struct SessionHandle *data, + unsigned char *entropy, + size_t length) +{ + return curlssl_random(data, entropy, length); +} + #ifdef have_curlssl_md5sum void Curl_ssl_md5sum(unsigned char *tmp, /* input */ size_t tmplen, diff --git a/lib/vtls/vtls.h b/lib/vtls/vtls.h index d309da6e4..5f58cbd98 100644 --- a/lib/vtls/vtls.h +++ b/lib/vtls/vtls.h @@ -88,7 +88,10 @@ void Curl_ssl_kill_session(struct curl_ssl_session *session); /* delete a session from the cache */ void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid); -/* get N random bytes into the buffer */ +/* get N random bytes into the buffer, return 0 if a find random is filled + in */ +int Curl_ssl_random(struct SessionHandle *data, unsigned char *buffer, + size_t length); void Curl_ssl_md5sum(unsigned char *tmp, /* input */ size_t tmplen, unsigned char *md5sum, /* output */ @@ -96,9 +99,6 @@ void Curl_ssl_md5sum(unsigned char *tmp, /* input */ #define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */ -#ifdef have_curlssl_random -#define HAVE_CURL_SSL_RANDOM -#endif #ifdef have_curlssl_md5sum #define HAVE_CURL_SSL_MD5SUM #endif -- cgit v1.2.3