summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-03-16 21:46:13 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-03-16 22:39:40 +0100
commitbe8fdbe623d31504fd280dca002c3702ba2a36da (patch)
tree62c0a53189bb659302cb48781c9cdd5b0bb48014
parentb1fd9941fcaac338054948d2a07d45481f9308f6 (diff)
downloadgnutls-be8fdbe623d31504fd280dca002c3702ba2a36da.tar.gz
Corrected nettle's RNG behavior on fork and added a test case.
-rw-r--r--lib/nettle/rnd.c11
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/rng-fork.c100
3 files changed, 109 insertions, 4 deletions
diff --git a/lib/nettle/rnd.c b/lib/nettle/rnd.c
index 9ccb398fe3..8af0adde57 100644
--- a/lib/nettle/rnd.c
+++ b/lib/nettle/rnd.c
@@ -250,7 +250,6 @@ do_device_source_urandom (int init)
if ((device_fd > 0)
&& (init || ((now - device_last_read) > DEVICE_READ_INTERVAL)))
{
-
/* More than a minute since we last read the device */
uint8_t buf[DEVICE_READ_SIZE_MAX];
uint32_t done;
@@ -348,7 +347,7 @@ static int
do_device_source (int init)
{
static pid_t pid; /* detect fork() */
- int ret;
+ int ret, reseed = 0;
static int (*do_source) (int init) = NULL;
/* using static var here is ok since we are
* always called with mutexes down
@@ -380,9 +379,15 @@ do_device_source (int init)
{ /* fork() detected */
device_last_read = 0;
pid = getpid();
+ reseed = 1;
}
- return do_source (init);
+ ret = do_source (init);
+
+ if (reseed)
+ yarrow256_slow_reseed (&yctx);
+
+ return ret;
}
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b8adcfd94e..cd6e4d1698 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -60,7 +60,7 @@ ctests = simple gc set_pkcs12_cred certder certuniqueid mpi \
crq_key_id x509sign-verify cve-2009-1415 cve-2009-1416 \
crq_apis init_roundtrip pkcs12_s2k_pem dn2 mini-eagain \
nul-in-x509-names x509_altname pkcs12_encode mini-x509 \
- mini-x509-rehandshake #gendh
+ mini-x509-rehandshake rng-fork #gendh
if ENABLE_OPENSSL
ctests += openssl
diff --git a/tests/rng-fork.c b/tests/rng-fork.c
new file mode 100644
index 0000000000..1e4b5e531d
--- /dev/null
+++ b/tests/rng-fork.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2008, 2010 Free Software Foundation, Inc.
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "utils.h"
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+#include "../lib/random.h"
+
+static void dump(const char* name, unsigned char* buf, int buf_size)
+{
+int i;
+ printf("%s: ", name);
+ for(i=0;i<buf_size;i++)
+ printf("%.2x:", buf[i]);
+ printf("\n");
+}
+
+
+
+void
+doit (void)
+{
+ unsigned char buf1[32];
+ unsigned char buf2[32];
+ pid_t pid;
+ int ret;
+ FILE* fp;
+
+
+ gnutls_global_init ();
+
+ pid = fork();
+ if (pid == 0)
+ {
+ fp = fopen("/tmp/rng-test", "w");
+ if (fp == NULL)
+ fail("cannot open file");
+
+ _gnutls_rnd (GNUTLS_RND_RANDOM, buf1, sizeof (buf1));
+ if (debug) dump("buf1", buf1, sizeof(buf1));
+
+ fwrite(buf1, 1, sizeof(buf1), fp);
+ fclose(fp);
+ }
+ else
+ {
+ /* daddy */
+ _gnutls_rnd (GNUTLS_RND_RANDOM, buf2, sizeof (buf2));
+ if (debug) dump("buf2", buf2, sizeof(buf2));
+ waitpid(pid, NULL, 0);
+
+ fp = fopen("/tmp/rng-test", "r");
+ if (fp == NULL)
+ fail("cannot open file");
+
+ ret = fread(buf1, 1, sizeof(buf1), fp);
+
+ if (ret != sizeof(buf1))
+ {
+ fail("error testing the random generator.");
+ return;
+ }
+
+ if (memcmp(buf1, buf2, sizeof(buf1))==0)
+ {
+ fail("error in the random generator. Produces same valus after fork()");
+ return;
+ }
+
+ success("success");
+ }
+}