From 9dbe35a4dd8d5fce96c627f000d15395f32bc55a Mon Sep 17 00:00:00 2001
From: tjw <tjw@edf5b092-35ff-0310-97b2-ce42778d08ea>
Date: Fri, 16 Feb 2007 23:50:37 +0000
Subject: * (bug 3019) use the operating system's random number generator if
 possible   when generating the qkey file

git-svn-id: svn://svn.icculus.org/quake3/trunk@1046 edf5b092-35ff-0310-97b2-ce42778d08ea
---
 code/client/cl_main.c   | 10 +++-------
 code/qcommon/common.c   | 21 +++++++++++++++++++++
 code/qcommon/md5.c      |  4 ++--
 code/qcommon/q_shared.h |  2 ++
 code/qcommon/qcommon.h  |  2 ++
 code/unix/unix_shared.c | 16 ++++++++++++++++
 code/win32/win_shared.c | 19 +++++++++++++++++++
 7 files changed, 65 insertions(+), 9 deletions(-)

(limited to 'code')

diff --git a/code/client/cl_main.c b/code/client/cl_main.c
index bb8d635..cfb1313 100644
--- a/code/client/cl_main.c
+++ b/code/client/cl_main.c
@@ -2534,18 +2534,14 @@ static void CL_GenerateQKey(void)
 		return;
 	}
 	else {
-		int i;
-
 		if( len > 0 ) {
 			Com_Printf( "QKEY file size != %d, regenerating\n",
 				QKEY_SIZE );
 		}
 
-		srand(time(0));
-		for(i = 0; i < sizeof(buff) - 1; i++) {
-			buff[i] = (unsigned char)(rand() % 255);
-		}
-		buff[i] = 0;
+		Com_Printf( "QKEY building random string\n" );
+		Com_RandomBytes( buff, sizeof(buff) );
+
 		f = FS_SV_FOpenFileWrite( QKEY_FILE );
 		if( !f ) {
 			Com_Printf( "QKEY could not open %s for write\n",
diff --git a/code/qcommon/common.c b/code/qcommon/common.c
index ca56db0..defb5fa 100644
--- a/code/qcommon/common.c
+++ b/code/qcommon/common.c
@@ -3217,3 +3217,24 @@ void Field_AutoComplete( field_t *field )
 
 	Field_CompleteCommand( completionField->buffer, qtrue, qtrue );
 }
+
+/*
+==================
+Com_RandomBytes
+
+fills string array with len radom bytes, peferably from the OS randomizer
+==================
+*/
+void Com_RandomBytes( byte *string, int len )
+{
+	int i;
+
+	if( Sys_RandomBytes( string, len ) )
+		return;
+
+	Com_Printf( "Com_RandomBytes: using weak randomization\n" );
+	srand( time( 0 ) );
+	for( i = 0; i < len; i++ )
+		string[i] = (unsigned char)( rand() % 255 );
+}
+
diff --git a/code/qcommon/md5.c b/code/qcommon/md5.c
index dcb4e44..5cf12bb 100644
--- a/code/qcommon/md5.c
+++ b/code/qcommon/md5.c
@@ -263,7 +263,7 @@ char *Com_MD5File( const char *fn, int length, const char *prefix, int prefix_le
 	unsigned char digest[16] = {""}; 
 	fileHandle_t f;
 	MD5_CTX md5;
-	char buffer[2048];
+	byte buffer[2048];
 	int i;
 	int filelen = 0;
 	int r = 0;
@@ -296,7 +296,7 @@ char *Com_MD5File( const char *fn, int length, const char *prefix, int prefix_le
 		if(r + total > length)
 			r = length - total;
 		total += r;
-		MD5Update(&md5 , (unsigned char *)buffer, r);
+		MD5Update(&md5 , buffer, r);
 		if(r < sizeof(buffer) || total >= length)
 			break;
 	}
diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h
index 74958ff..f4b9bd2 100644
--- a/code/qcommon/q_shared.h
+++ b/code/qcommon/q_shared.h
@@ -640,6 +640,8 @@ void	QDECL Com_sprintf (char *dest, int size, const char *fmt, ...) __attribute_
 char *Com_SkipTokens( char *s, int numTokens, char *sep );
 char *Com_SkipCharset( char *s, char *sep );
 
+void Com_RandomBytes( byte *string, int len );
+
 // mode parm for FS_FOpenFile
 typedef enum {
 	FS_READ,
diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h
index 8bde028..f0d6722 100644
--- a/code/qcommon/qcommon.h
+++ b/code/qcommon/qcommon.h
@@ -1001,6 +1001,8 @@ int		Sys_Milliseconds (void);
 
 void	Sys_SnapVector( float *v );
 
+qboolean Sys_RandomBytes( byte *string, int len );
+
 // the system console is shown when a dedicated server is running
 void	Sys_DisplaySystemConsole( qboolean show );
 
diff --git a/code/unix/unix_shared.c b/code/unix/unix_shared.c
index c037813..a607a2f 100644
--- a/code/unix/unix_shared.c
+++ b/code/unix/unix_shared.c
@@ -174,6 +174,22 @@ char *strlwr (char *s) {
   return s; // bk001204 - duh
 }
 
+qboolean Sys_RandomBytes( byte *string, int len )
+{
+  FILE *fp;
+
+  fp = fopen( "/dev/urandom", "r" );
+  if( !fp )
+    return qfalse;
+
+  if( !fread( string, sizeof( byte ), len, fp ) ) {
+	fclose( fp );
+	return qfalse;
+  }
+  fclose( fp );
+  return qtrue; 
+}
+
 //============================================
 
 #define	MAX_FOUND_FILES	0x1000
diff --git a/code/win32/win_shared.c b/code/win32/win_shared.c
index f28ff3a..24e3079 100644
--- a/code/win32/win_shared.c
+++ b/code/win32/win_shared.c
@@ -32,6 +32,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include <direct.h>
 #include <io.h>
 #include <conio.h>
+#include <wincrypt.h>
 
 /*
 ================
@@ -81,6 +82,24 @@ void Sys_SnapVector( float *v )
 }
 #endif
 
+qboolean Sys_RandomBytes( byte *string, int len )
+{
+	HCRYPTPROV  prov;
+
+	if( !CryptAcquireContext( &prov, NULL, NULL,
+		PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) )  {
+
+		return qfalse;
+	}
+
+	if( !CryptGenRandom( prov, len, (BYTE *)string ) )  {
+		CryptReleaseContext( prov, 0 );
+		return qfalse;
+	}
+	CryptReleaseContext( prov, 0 );
+	return qtrue;
+}
+
 
 /*
 **
-- 
cgit v1.2.3