/soc/2015/mmcc/rand: dcf27ec371f2: Add a randomness source for W...

Eion Robb eion at robbmob.com
Fri Aug 21 23:21:25 EDT 2015


Changeset: dcf27ec371f20b091578b7447cd1066dc51300f2
Author:	 Eion Robb <eion at robbmob.com>
Date:	 2015-08-21 23:19 -0400
Branch:	 default
URL: https://hg.pidgin.im/soc/2015/mmcc/rand/rev/dcf27ec371f2

Description:

Add a randomness source for Windows to fall back on when the SSL API isn't
available.

diffstat:

 libpurple/util.c           |   6 +++++-
 libpurple/win32/win32dep.c |  20 ++++++++++++++++++++
 libpurple/win32/win32dep.h |   1 +
 3 files changed, 26 insertions(+), 1 deletions(-)

diffs (86 lines):

diff --git a/libpurple/util.c b/libpurple/util.c
--- a/libpurple/util.c
+++ b/libpurple/util.c
@@ -5001,8 +5001,11 @@ purple_util_random(void *buf, size_t len
 	/* use SSL API if available... */
 	if (purple_ssl_is_supported() && ops && ops->rand_bytes) {
 		return (ops->rand_bytes)(buf, len);
-	/* ...otherwise, fall back to /dev/urandom */
+	/* ...otherwise, fall back to /dev/urandom or Windows alternative */
 	} else {
+#ifdef _WIN32
+		return wpurple_rand_bytes(buf, len);
+#else	/* _WIN32 */
 		fd = open("/dev/urandom", O_RDONLY);
 		if (fd < 0) {
 			purple_debug_error("purple_random",
@@ -5026,6 +5029,7 @@ purple_util_random(void *buf, size_t len
 		close(fd);
 		return 0;
 	}
+#endif	/* _WIN32 */
 }
 
 #if 0
diff --git a/libpurple/win32/win32dep.c b/libpurple/win32/win32dep.c
--- a/libpurple/win32/win32dep.c
+++ b/libpurple/win32/win32dep.c
@@ -23,6 +23,7 @@
  *
  */
 #include "internal.h"
+#include <wincrypt.h>
 #include <winuser.h>
 
 #include "debug.h"
@@ -40,6 +41,8 @@ static char *app_data_dir = NULL, *bin_d
 
 static HINSTANCE libpurpledll_hInstance = NULL;
 
+static HCRYPTPROV hCryptoServiceProvider = 0;
+
 /*
  *  PUBLIC CODE
  */
@@ -618,6 +621,20 @@ int wpurple_input_pipe(int pipefd[2])
 	}
 }
 
+int wpurple_rand_bytes(void *buf, size_t len) {
+	if (hCryptoServiceProvider == 0) {
+		purple_debug_error("wpurple", "No crypto service provider could be created\n");
+		return -1;
+	}
+	
+	if (!CryptGenRandom(hCryptoServiceProvider, len, buf)) {
+		purple_debug_error("wpurple", "Generating random number failed\n");
+		return -1;
+	}
+	
+	return 0;
+}	
+
 void wpurple_init(void) {
 	WORD wVersionRequested;
 	WSADATA wsaData;
@@ -650,6 +667,9 @@ void wpurple_init(void) {
 		purple_debug_error("wpurple", "Could not find a usable WinSock DLL.  Oh well.\n");
 		WSACleanup();
 	}
+	
+	/* Crypto init */
+	CryptAcquireContextA(&hCryptoServiceProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
 
 	if (purple_debug_is_verbose())
 		purple_debug_misc("wpurple", "wpurple_init end\n");
diff --git a/libpurple/win32/win32dep.h b/libpurple/win32/win32dep.h
--- a/libpurple/win32/win32dep.h
+++ b/libpurple/win32/win32dep.h
@@ -63,6 +63,7 @@ char *wpurple_read_reg_string(HKEY rootk
 gboolean wpurple_write_reg_string(HKEY rootkey, const char *subkey, const char *valname, const char *value);
 char *wpurple_escape_dirsep(const char *filename); /* needs to be g_free'd */
 GIOChannel *wpurple_g_io_channel_win32_new_socket(int socket); /* Until we get the post-2.8 glib win32 giochannel implementation working, use the thread-based one */
+int wpurple_rand_bytes(void *buf, size_t len);
 
 /* Simulate unix pipes by creating a pair of connected sockets */
 int wpurple_input_pipe(int pipefd[2]);



More information about the Commits mailing list