diff --git a/CHANGES b/CHANGES
index 2c212fd284080a2d2220e30c92ea36c2605fb2df..579707a241db24edf15457fa3b2e901fdfdcba19 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,12 @@
Changes between 0.9.4 and 0.9.5 [xx XXX 2000]
+ *) Support EGD . New functions
+ RAND_egd() and RAND_status(). In the command line application,
+ the EGD socket can be specified like a seed file using RANDFILE
+ or -rand.
+ [Ulf Möller]
+
*) Allow the string CERTIFICATE to be tolerated in PKCS#7 structures.
Some CAs (e.g. Verisign) distribute certificates in this form.
[Steve Henson]
diff --git a/apps/app_rand.c b/apps/app_rand.c
index b94c85323a4ca7780cd5223d3173d9daa4c6042b..ea35bf9b1d712ae5687b51314e774379c671efd6 100644
--- a/apps/app_rand.c
+++ b/apps/app_rand.c
@@ -115,6 +115,7 @@
static int seeded = 0;
+static int egdsocket = 0;
int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn)
{
@@ -130,12 +131,19 @@ int app_RAND_load_file(const char *file, BIO *bio_e, int dont_warn)
if (file == NULL)
file = RAND_file_name(buffer, sizeof buffer);
+ else if (RAND_egd(file) > 0)
+ {
+ /* we try if the given filename is an EGD socket.
+ if it is, we don't write anything back to the file. */
+ egdsocket = 1;
+ return 1;
+ }
if (file == NULL || !RAND_load_file(file, -1))
{
- if (!dont_warn)
+ if (RAND_status() == 0 && !dont_warn)
{
BIO_printf(bio_e,"unable to load 'random state'\n");
- BIO_printf(bio_e,"What this means is that the random number generator has not been seeded\n");
+ BIO_printf(bio_e,"This means that the random number generator has not been seeded\n");
BIO_printf(bio_e,"with much random data.\n");
if (consider_randfile) /* explanation does not apply when a file is explicitly named */
{
@@ -165,6 +173,7 @@ long app_RAND_load_files(char *name)
name=p+1;
if (*n == '\0') break;
+ tot+=RAND_egd(n);
tot+=RAND_load_file(n,1024L*1024L);
if (last) break;
}
@@ -177,7 +186,7 @@ int app_RAND_write_file(const char *file, BIO *bio_e)
{
char buffer[200];
- if (!seeded)
+ if (egdsocket || !seeded)
/* If we did not manage to read the seed file,
* we should not write a low-entropy seed file back --
* it would suppress a crucial warning the next time
diff --git a/crypto/rand/Makefile.ssl b/crypto/rand/Makefile.ssl
index 8195bf090b332c2e295a774f30d7f879e6109951..68ef887902fa438822c5fc8b1be8029f3f607218 100644
--- a/crypto/rand/Makefile.ssl
+++ b/crypto/rand/Makefile.ssl
@@ -22,8 +22,8 @@ TEST= randtest.c
APPS=
LIB=$(TOP)/libcrypto.a
-LIBSRC=md_rand.c randfile.c rand_lib.c rand_err.c
-LIBOBJ=md_rand.o randfile.o rand_lib.o rand_err.o
+LIBSRC=md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c
+LIBOBJ=md_rand.o randfile.o rand_lib.o rand_err.o rand_egd.o
SRC= $(LIBSRC)
diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index 34843d04dbe32c39432edd2c4f8a79af5df57e5e..79438611f284abd48e54b000a54afb6532d3f3ef 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -139,6 +139,7 @@ static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
static unsigned char md[MD_DIGEST_LENGTH];
static long md_count[2]={0,0};
static double entropy=0;
+static int initialized=0;
const char *RAND_version="RAND" OPENSSL_VERSION_PTEXT;
@@ -295,6 +296,51 @@ static void ssleay_rand_seed(const void *buf, int num)
ssleay_rand_add(buf, num, num);
}
+static void ssleay_rand_initialize(void)
+ {
+ unsigned long l;
+#ifndef GETPID_IS_MEANINGLESS
+ pid_t curr_pid = getpid();
+#endif
+#ifdef DEVRANDOM
+ FILE *fh;
+#endif
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ /* put in some default random data, we need more than just this */
+#ifndef GETPID_IS_MEANINGLESS
+ l=curr_pid;
+ RAND_add(&l,sizeof(l),0);
+ l=getuid();
+ RAND_add(&l,sizeof(l),0);
+#endif
+ l=time(NULL);
+ RAND_add(&l,sizeof(l),0);
+
+#ifdef DEVRANDOM
+ /* Use a random entropy pool device. Linux and FreeBSD have
+ * this. Use /dev/urandom if you can as /dev/random will block
+ * if it runs out of random entries. */
+
+ if ((fh = fopen(DEVRANDOM, "r")) != NULL)
+ {
+ unsigned char tmpbuf[ENTROPY_NEEDED];
+ int n;
+
+ n=fread((unsigned char *)tmpbuf,1,ENTROPY_NEEDED,fh);
+ fclose(fh);
+ RAND_add(tmpbuf,sizeof tmpbuf,n);
+ memset(tmpbuf,0,n);
+ }
+#endif
+#ifdef PURIFY
+ memset(state,0,STATE_SIZE);
+ memset(md,0,MD_DIGEST_LENGTH);
+#endif
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ initialized=1;
+ }
+
static int ssleay_rand_bytes(unsigned char *buf, int num)
{
int i,j,k,st_num,st_idx;
@@ -302,14 +348,9 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
long md_c[2];
unsigned char local_md[MD_DIGEST_LENGTH];
MD_CTX m;
- static int init=1;
- unsigned long l;
#ifndef GETPID_IS_MEANINGLESS
pid_t curr_pid = getpid();
#endif
-#ifdef DEVRANDOM
- FILE *fh;
-#endif
#ifdef PREDICT
{
@@ -342,47 +383,8 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
- if (init)
- {
- CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
- /* put in some default random data, we need more than
- * just this */
- RAND_add(&m,sizeof(m),0);
-#ifndef GETPID_IS_MEANINGLESS
- l=curr_pid;
- RAND_add(&l,sizeof(l),0);
- l=getuid();
- RAND_add(&l,sizeof(l),0);
-#endif
- l=time(NULL);
- RAND_add(&l,sizeof(l),0);
-
-#ifdef DEVRANDOM
- /*
- * Use a random entropy pool device.
- * Linux 1.3.x and FreeBSD-Current has
- * this. Use /dev/urandom if you can
- * as /dev/random will block if it runs out
- * of random entries.
- */
- if ((fh = fopen(DEVRANDOM, "r")) != NULL)
- {
- unsigned char tmpbuf[ENTROPY_NEEDED];
- int n;
-
- n=fread((unsigned char *)tmpbuf,1,ENTROPY_NEEDED,fh);
- fclose(fh);
- RAND_add(tmpbuf,sizeof tmpbuf,n);
- memset(tmpbuf,0,n);
- }
-#endif
-#ifdef PURIFY
- memset(state,0,STATE_SIZE);
- memset(md,0,MD_DIGEST_LENGTH);
-#endif
- CRYPTO_w_lock(CRYPTO_LOCK_RAND);
- init=0;
- }
+ if (!initialized)
+ ssleay_rand_initialize();
ok = (entropy >= ENTROPY_NEEDED);
@@ -473,6 +475,13 @@ static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
return (ret);
}
+int RAND_status(void)
+ {
+ if (!initialized)
+ ssleay_rand_initialize();
+ return (entropy >= ENTROPY_NEEDED);
+ }
+
#ifdef WINDOWS
#include
#include
diff --git a/crypto/rand/rand.h b/crypto/rand/rand.h
index e5d6696cb40c56403d848f919b5aafd60ff659ff..28f45ec05269965e4a9b37819b16787016932a7d 100644
--- a/crypto/rand/rand.h
+++ b/crypto/rand/rand.h
@@ -83,6 +83,8 @@ void RAND_add(const void *buf,int num,double entropy);
int RAND_load_file(const char *file,long max_bytes);
int RAND_write_file(const char *file);
const char *RAND_file_name(char *file,int num);
+int RAND_status(void);
+int RAND_egd(const char *path);
#ifdef WINDOWS
void RAND_screen(void);
#endif
diff --git a/crypto/rand/rand_egd.c b/crypto/rand/rand_egd.c
new file mode 100644
index 0000000000000000000000000000000000000000..802d35b5c29ecb1943dd2eefb68e207e7993a534
--- /dev/null
+++ b/crypto/rand/rand_egd.c
@@ -0,0 +1,108 @@
+/* crypto/rand/rand_egd.c */
+/* Written by Ulf Moeller for the OpenSSL project. */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include
+
+/* Query the EGD .
+ */
+
+#if defined(WIN32) || defined(VMS)
+int RAND_egd(const char *path)
+ {
+ return(-1);
+ }
+#else
+#include
+#include OPENSSL_UNISTD
+#include
+#include
+#include
+
+#ifndef offsetof
+# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+int RAND_egd(const char *path)
+ {
+ int ret = -1;
+ struct sockaddr_un addr;
+ int len, num;
+ int fd = -1;
+ unsigned char buf[256];
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ if (strlen(path) > sizeof(addr.sun_path))
+ return (-1);
+ strcpy(addr.sun_path,path);
+ len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1) return (-1);
+ if (connect(fd, &addr, len) == -1) goto err;
+ buf[0] = 1;
+ buf[1] = 255;
+ write(fd, buf, 2);
+ if (read(fd, buf, 1) != 1) goto err;
+ num = read(fd, buf, 255);
+ if (num < 1) goto err;
+ RAND_seed(buf, num);
+ if (RAND_status() == 1)
+ ret = num;
+ err:
+ if (fd != -1) close(fd);
+ return(ret);
+ }
+#endif
diff --git a/doc/crypto/RAND_add.pod b/doc/crypto/RAND_add.pod
index 927c59d4c3a582b8af08068f8b11da06169b1763..d6804e2a905a9dbc7f17181c91ba7debf9417036 100644
--- a/doc/crypto/RAND_add.pod
+++ b/doc/crypto/RAND_add.pod
@@ -12,6 +12,8 @@ RAND_add, RAND_seed, RAND_screen - Add entropy to the PRNG
void RAND_add(const void *buf, int num, double entropy);
+ int RAND_status(void);
+
void RAND_screen(void);
=head1 DESCRIPTION
@@ -46,7 +48,10 @@ used on servers that run without user interaction.
=head1 RETURN VALUES
-These functions do not return values.
+RAND_status() returns 1 if the PRNG has been seeded with enough data,
+0 otherwise.
+
+The other functions do not return values.
=head1 SEE ALSO
@@ -55,6 +60,7 @@ L, L, L
+
+ int RAND_egd(const char *path);
+
+=head1 DESCRIPTION
+
+RAND_egd() queries the entropy gathering daemon EGD on socket B.
+
+=head1 RETURN VALUES
+
+RAND_egd() returns the number of bytes read from the daemon on
+success, and -1 if the connection failed or the daemon did not return
+enough data to fully seed the PRNG.
+
+=head1 SEE ALSO
+
+L, L, L
+
+=head1 HISTORY
+
+RAND_egd() is available since OpenSSL 0.9.5.
+
+=cut
diff --git a/doc/crypto/rand.pod b/doc/crypto/rand.pod
index 0fafe54dd91163251873a7e5012236372045e556..5104b070a1ade2870414cb7c63fab732f4eaa586 100644
--- a/doc/crypto/rand.pod
+++ b/doc/crypto/rand.pod
@@ -13,12 +13,15 @@ rand - Pseudo-random number generator
void RAND_seed(const void *buf,int num);
void RAND_add(const void *buf,int num,int entropy);
+ int RAND_status(void);
void RAND_screen(void);
int RAND_load_file(const char *file,long max_bytes);
int RAND_write_file(const char *file);
const char *RAND_file_name(char *file,int num);
+ int RAND_egd(const char *path);
+
void RAND_set_rand_method(RAND_METHOD *meth);
RAND_METHOD *RAND_get_rand_method(void);
RAND_METHOD *RAND_SSLeay(void);
@@ -147,7 +150,8 @@ L).
=head1 SEE ALSO
L, L,
-L, L,
+L, L,
+L,
L,
L