changeset 9884:df977f0f2fb2

Make gc_random work under Windows. Based on patch from Adam Strzelecki <ono@java.pl> in <http://lists.gnu.org/archive/html/help-gsasl/2008-02/msg00000.html>.
author Simon Josefsson <simon@josefsson.org>
date Fri, 11 Apr 2008 09:16:11 +0200
parents f447d0fc935f
children 13bea8949414
files ChangeLog lib/gc-gnulib.c
diffstat 2 files changed, 39 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Apr 10 12:58:26 2008 +0200
+++ b/ChangeLog	Fri Apr 11 09:16:11 2008 +0200
@@ -1,3 +1,10 @@
+2008-04-11  Simon Josefsson  <simon@josefsson.org>
+
+	* lib/gc-gnulib.c: On Windows, use CryptGenRandom from CSP instead
+	of attempting to use non-existing /dev/*random.  Based on patch
+	from Adam Strzelecki <ono@java.pl> in
+	<http://lists.gnu.org/archive/html/help-gsasl/2008-02/msg00000.html>.
+
 2008-04-08  Bruno Haible  <bruno@clisp.org>
 
 	Add tentative support for emx+gcc.
--- a/lib/gc-gnulib.c	Thu Apr 10 12:58:26 2008 +0200
+++ b/lib/gc-gnulib.c	Fri Apr 11 09:16:11 2008 +0200
@@ -1,5 +1,5 @@
 /* gc-gnulib.c --- Common gnulib internal crypto interface functions
- * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007  Simon Josefsson
+ * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008  Simon Josefsson
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published
@@ -73,15 +73,40 @@
 #undef open
 #undef close
 
+#ifdef GNULIB_GC_RANDOM
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#  include <wincrypt.h>
+HCRYPTPROV g_hProv = 0;
+# endif
+#endif
+
 Gc_rc
 gc_init (void)
 {
+#ifdef GNULIB_GC_RANDOM
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  if(g_hProv)
+    CryptReleaseContext(g_hProv, 0);
+  CryptAcquireContext(&g_hProv, NULL, NULL, PROV_RSA_FULL, 0);
+# endif
+#endif
+
   return GC_OK;
 }
 
 void
 gc_done (void)
 {
+#ifdef GNULIB_GC_RANDOM
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  if(g_hProv)
+    {
+      CryptReleaseContext(g_hProv, 0);
+      g_hProv = 0;
+    }
+# endif
+#endif
+
   return;
 }
 
@@ -92,6 +117,11 @@
 static Gc_rc
 randomize (int level, char *data, size_t datalen)
 {
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  if(!g_hProv)
+    return GC_RANDOM_ERROR;
+  CryptGenRandom(g_hProv, (DWORD)datalen, data);
+#else
   int fd;
   const char *device;
   size_t len = 0;
@@ -140,6 +170,7 @@
   rc = close (fd);
   if (rc < 0)
     return GC_RANDOM_ERROR;
+#endif
 
   return GC_OK;
 }