X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Frand.c;h=28e4b8716022d292b3251a7b774e2b5ccbdf43a8;hb=b50dc8d84850e0452a7a4d742ed0a0fa46fe491e;hp=188d09a5b543f5e04db7a68a9b0fd1a457b1b84a;hpb=ca1ca15642673854814f48dc4bef71dbb0f7a97c;p=mono.git diff --git a/mono/metadata/rand.c b/mono/metadata/rand.c index 188d09a5b54..28e4b871602 100644 --- a/mono/metadata/rand.c +++ b/mono/metadata/rand.c @@ -7,7 +7,7 @@ * Sebastien Pouliot (sebastien@ximian.com) * * (C) 2001 Ximian, Inc. - * (C) 2004 Novell (http://www.novell.com) + * Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) */ #include @@ -94,7 +94,8 @@ get_entropy_from_server (const char *path, guchar *buf, int len) #if defined (PLATFORM_WIN32) -#include +#include +#include #ifndef PROV_INTEL_SEC #define PROV_INTEL_SEC 22 @@ -103,6 +104,13 @@ get_entropy_from_server (const char *path, guchar *buf, int len) #define CRYPT_VERIFY_CONTEXT 0xF0000000 #endif +MonoBoolean +ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngOpen (void) +{ + /* FALSE == Local (instance) handle for randomness */ + return FALSE; +} + gpointer ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngInitialize (MonoArray *seed) { @@ -151,13 +159,14 @@ ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngGetBytes (gpo if (!CryptGenRandom (provider, len, buf)) { CryptReleaseContext (provider, 0); /* we may have lost our context with CryptoAPI, but all hope isn't lost yet! */ - provider = ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngInitialize (NULL); + provider = (HCRYPTPROV) ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngInitialize (NULL); if (!CryptGenRandom (provider, len, buf)) { CryptReleaseContext (provider, 0); provider = 0; /* exception will be thrown in managed code */ } - } + } + return (gpointer) provider; } void @@ -173,14 +182,13 @@ ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngClose (gpoint #endif static gboolean egd = FALSE; +static gint file = -1; -gpointer -ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngInitialize (MonoArray *seed) +MonoBoolean +ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngOpen (void) { - gint file = -1; - - if (egd) - return -1; + if (egd || (file >= 0)) + return TRUE; #if defined (NAME_DEV_URANDOM) file = open (NAME_DEV_URANDOM, O_RDONLY); @@ -194,37 +202,47 @@ ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngInitialize (M if (file < 0) { const char *socket_path = g_getenv("MONO_EGD_SOCKET"); egd = (socket_path != NULL); - return -1; } + /* TRUE == Global handle for randomness */ + return TRUE; +} + +gpointer +ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngInitialize (MonoArray *seed) +{ /* if required exception will be thrown in managed code */ - return ((file < 0) ? NULL : (gpointer) file); + return ((!egd && (file < 0)) ? NULL : GINT_TO_POINTER (file)); } gpointer ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngGetBytes (gpointer handle, MonoArray *arry) { - gint file = (gint) handle; + gint file = GPOINTER_TO_INT (handle); guint32 len = mono_array_length (arry); guchar *buf = mono_array_addr (arry, guchar, 0); if (egd) { - const char *socket_path = getenv ("MONO_EGD_SOCKET"); + const char *socket_path = g_getenv ("MONO_EGD_SOCKET"); /* exception will be thrown in managed code */ if (socket_path == NULL) return NULL; get_entropy_from_server (socket_path, mono_array_addr (arry, guchar, 0), mono_array_length (arry)); - return -1; - } - else { + return (gpointer) -1; + } else { /* Read until the buffer is filled. This may block if using NAME_DEV_RANDOM. */ gint count = 0; gint err; do { err = read (file, buf + count, len - count); + if (err < 0) { + if (errno == EINTR) + continue; + break; + } count += err; - } while (err >= 0 && count < len); + } while (count < len); if (err < 0) { g_warning("Entropy error! Error in read (%s).", strerror (errno)); @@ -241,8 +259,6 @@ ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngGetBytes (gpo void ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngClose (gpointer handle) { - if (!egd) - close ((gint) handle); } #endif /* OS definition */