diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-03-16 21:46:13 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-03-16 22:39:40 +0100 |
commit | be8fdbe623d31504fd280dca002c3702ba2a36da (patch) | |
tree | 62c0a53189bb659302cb48781c9cdd5b0bb48014 | |
parent | b1fd9941fcaac338054948d2a07d45481f9308f6 (diff) | |
download | gnutls-be8fdbe623d31504fd280dca002c3702ba2a36da.tar.gz |
Corrected nettle's RNG behavior on fork and added a test case.
-rw-r--r-- | lib/nettle/rnd.c | 11 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/rng-fork.c | 100 |
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"); + } +} |