aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--acconfig.h5
-rw-r--r--configure.in33
-rw-r--r--lib/ssluse.c115
3 files changed, 121 insertions, 32 deletions
diff --git a/acconfig.h b/acconfig.h
index 1ec870a78..8f39d3c36 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -43,3 +43,8 @@
/* Define this to 'int' if ssize_t is not an available typedefed type */
#undef ssize_t
+/* Define this as a suitable file to read random data from */
+#undef RANDOM_FILE
+
+/* Define this to your Entropy Gathering Daemon socket pathname */
+#undef EGD_SOCKET
diff --git a/configure.in b/configure.in
index 5feb45ff7..d48efb18e 100644
--- a/configure.in
+++ b/configure.in
@@ -392,6 +392,36 @@ dnl dl lib?
AC_CHECK_FUNC(dlopen, , AC_CHECK_LIB(dl, dlopen))
dnl **********************************************************************
+dnl Check for the random seed preferences
+dnl **********************************************************************
+
+AC_ARG_WITH(egd-socket,
+ [ --with-egd-socket=FILE Entropy Gathering Daemon socket pathname],
+ [ EGD_SOCKET="$withval" ]
+)
+if test -n "$EGD_SOCKET" ; then
+ AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET")
+fi
+
+dnl Check for user-specified random device
+AC_ARG_WITH(random,
+ [ --with-random=FILE read randomness from FILE (default=/dev/urandom)],
+ [ RANDOM_FILE="$withval" ],
+ [
+ dnl Check for random device
+ AC_CHECK_FILE("/dev/urandom",
+ [
+ RANDOM_FILE="/dev/urandom";
+ ]
+ )
+ ]
+)
+if test -n "$RANDOM_FILE" ; then
+ AC_SUBST(RANDOM_FILE)
+ AC_DEFINE_UNQUOTED(RANDOM_FILE, "$RANDOM_FILE")
+fi
+
+dnl **********************************************************************
dnl Check for the presence of Kerberos4 libraries and headers
dnl **********************************************************************
@@ -545,7 +575,8 @@ else
dnl these can only exist if openssl exists
AC_CHECK_FUNCS( RAND_status \
- RAND_screen )
+ RAND_screen \
+ RAND_egd )
fi
diff --git a/lib/ssluse.c b/lib/ssluse.c
index 789175735..8e43dd565 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -58,16 +58,92 @@ static int passwd_callback(char *buf, int num, int verify
return 0;
}
-/* This function is *highly* inspired by (and parts are directly stolen
- * from) source from the SSLeay package written by Eric Young
- * (eay@cryptsoft.com). */
+static
+bool seed_enough(struct connectdata *conn, /* unused for now */
+ int nread)
+{
+#ifdef HAVE_RAND_STATUS
+ /* only available in OpenSSL 0.9.5a and later */
+ if(RAND_status())
+ return TRUE;
+#else
+ if(nread > 500)
+ /* this is a very silly decision to make */
+ return TRUE;
+#endif
+ return FALSE; /* not enough */
+}
+
+static
+int random_the_seed(struct connectdata *conn)
+{
+ char *buf = conn->data->buffer; /* point to the big buffer */
+ int ret;
+ int nread=0;
+
+ /* Q: should we add support for a random file name as a libcurl option?
+ A: Yes */
+#if 0
+ /* something like this */
+ nread += RAND_load_file(filename, number_of_bytes);
+#endif
+ /* generates a default path for the random seed file */
+ buf[0]=0; /* blank it first */
+ RAND_file_name(buf, BUFSIZE);
+ if ( buf[0] ) {
+ /* we got a file name to try */
+ nread += RAND_load_file(buf, 16384);
+ if(seed_enough(conn, nread))
+ return nread;
+ }
+
+#ifdef RANDOM_FILE
+ nread += RAND_load_file(RANDOM_FILE, 16384);
+ if(seed_enough(conn, nread))
+ return nread;
+#endif
+
+#if defined(HAVE_RAND_EGD) && defined(EGD_SOCKET)
+ /* only available in OpenSSL 0.9.5 and later */
+ /* EGD_SOCKET is set at configure time */
+ ret = RAND_egd(EGD_SOCKET);
+ if(-1 != ret) {
+ nread += ret;
+ if(seed_enough(conn, nread))
+ return nread;
+ }
+#endif
+
+ /* If we get here, it means we need to seed the PRNG using a "silly"
+ approach! */
+#ifdef HAVE_RAND_SCREEN
+ /* This one gets a random value by reading the currently shown screen */
+ RAND_screen();
+ nread = 100; /* just a value */
+#else
+ {
+ int len;
+ char *area = Curl_FormBoundary();
+ if(!area)
+ return 3; /* out of memory */
+
+ len = strlen(area);
+ RAND_seed(area, len);
+
+ free(area); /* now remove the random junk */
+#endif
+ }
+
+ infof(conn->data, "Your connection is using a weak random seed!\n");
+ return nread;
+}
static
-int cert_stuff(struct UrlData *data,
- struct connectdata *conn,
+int cert_stuff(struct connectdata *conn,
char *cert_file,
char *key_file)
{
+ struct UrlData *data = conn->data;
if (cert_file != NULL) {
SSL *ssl;
X509 *x509;
@@ -123,9 +199,6 @@ int cert_stuff(struct UrlData *data,
return(1);
}
-#endif
-
-#ifdef USE_SSLEAY
static
int cert_verify_callback(int ok, X509_STORE_CTX *ctx)
{
@@ -156,28 +229,8 @@ Curl_SSLConnect(struct connectdata *conn)
/* Lets get nice error messages */
SSL_load_error_strings();
-#ifdef HAVE_RAND_STATUS
- /* RAND_status() was introduced in OpenSSL 0.9.5 */
- if(0 == RAND_status())
-#endif
- {
- /* We need to seed the PRNG properly! */
-#ifdef HAVE_RAND_SCREEN
- /* This one gets a random value by reading the currently shown screen */
- RAND_screen();
-#else
- int len;
- char *area = Curl_FormBoundary();
- if(!area)
- return 3; /* out of memory */
-
- len = strlen(area);
-
- RAND_seed(area, len);
-
- free(area); /* now remove the random junk */
-#endif
- }
+ /* Make funny stuff to get random input */
+ random_the_seed(conn);
/* Setup all the global SSL stuff */
SSLeay_add_ssl_algorithms();
@@ -202,7 +255,7 @@ Curl_SSLConnect(struct connectdata *conn)
}
if(data->cert) {
- if (!cert_stuff(data, conn, data->cert, data->cert)) {
+ if (!cert_stuff(conn, data->cert, data->cert)) {
failf(data, "couldn't use certificate!\n");
return 2;
}