]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Corrected nettle's RNG behavior on fork and added a test case.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 16 Mar 2011 20:46:13 +0000 (21:46 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 16 Mar 2011 20:46:13 +0000 (21:46 +0100)
lib/nettle/rnd.c
tests/Makefile.am
tests/rng-fork.c [new file with mode: 0644]

index 9ccb398fe3c3f6bb61b35f3b91c53b316adee1ef..8af0adde579907bf9f5c85002b5765214d056946 100644 (file)
@@ -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;
     }
 }
 
index 09c4052bd8a7ae9fec2ed3bce0be445c5c492c93..54447e71c461bb53232649e0f5ad5d0fcf62081d 100644 (file)
@@ -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 (file)
index 0000000..1e4b5e5
--- /dev/null
@@ -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");
+    }
+}