Commit 2ef13230 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

new seeding stuff as mentioned by Albert Chin

parent 9479ac6d
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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
+32 −1
Original line number Diff line number Diff line
@@ -391,6 +391,36 @@ AC_CHECK_FUNC(gethostname, , AC_CHECK_LIB(ucb, gethostname))
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

+84 −31
Original line number Diff line number Diff line
@@ -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;
    }