X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Frand.c;h=d5edec6dcba31bfce6d191b645cff9d6671ecaa7;hb=eb01ce450f4c7179632520b7741f00feec65dfe5;hp=e2f78f78b7db94ab18bea889f88d1752a358cfa1;hpb=699e59742843044f6efa1726b7cb64f19d909e64;p=mono.git diff --git a/mono/metadata/rand.c b/mono/metadata/rand.c index e2f78f78b7d..d5edec6dcba 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 @@ -15,7 +15,9 @@ #include #include #include +#ifdef HAVE_UNISTD_H #include +#endif #include #include @@ -94,7 +96,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 +106,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 +161,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 +184,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 (gpointer) -1; + if (egd || (file >= 0)) + return TRUE; #if defined (NAME_DEV_URANDOM) file = open (NAME_DEV_URANDOM, O_RDONLY); @@ -194,17 +204,23 @@ 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 (gpointer) -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); @@ -215,16 +231,20 @@ ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngGetBytes (gpo return NULL; get_entropy_from_server (socket_path, mono_array_addr (arry, guchar, 0), mono_array_length (arry)); return (gpointer) -1; - } - else { + } 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 +261,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 */