[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openssl-cvs
Subject:    [CVS] OpenSSL: openssl/crypto/rand/ rand_unix.c randfile.c
From:       "Richard Levitte" <levitte () openssl ! org>
Date:       2003-12-27 16:02:22
[Download RAW message or body]

  OpenSSL CVS Repository
  http://cvs.openssl.org/
  ____________________________________________________________________________

  Server: cvs.openssl.org                  Name:   Richard Levitte
  Root:   /e/openssl/cvs                   Email:  levitte@openssl.org
  Module: openssl                          Date:   27-Dec-2003 17:02:22
  Branch: HEAD                             Handle: 2003122716022200

  Modified files:
    openssl/crypto/rand     rand_unix.c randfile.c

  Log:
    Check if a random "file" is really a device file, and treat it
    specially if it is.
    Add a few OpenBSD-specific cases.
    This is part of a large change submitted by Markus Friedl <markus@openbsd.org>

  Summary:
    Revision    Changes     Path
    1.14        +19 -0      openssl/crypto/rand/rand_unix.c
    1.43        +56 -11     openssl/crypto/rand/randfile.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: openssl/crypto/rand/rand_unix.c
  ============================================================================
  $ cvs diff -u -r1.13 -r1.14 rand_unix.c
  --- openssl/crypto/rand/rand_unix.c	28 Nov 2003 13:10:46 -0000	1.13
  +++ openssl/crypto/rand/rand_unix.c	27 Dec 2003 16:02:22 -0000	1.14
  @@ -125,6 +125,24 @@
   #include <unistd.h>
   #include <time.h>
   
  +#ifdef __OpenBSD__
  +int RAND_poll(void)
  +{
  +	u_int32_t rnd = 0, i;
  +	unsigned char buf[ENTROPY_NEEDED];
  +
  +	for (i = 0; i < sizeof(buf); i++) {
  +		if (i % 4 == 0)
  +			rnd = arc4random();
  +		buf[i] = rnd;
  +		rnd >>= 8;
  +	}
  +	RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
  +	memset(buf, 0, sizeof(buf));
  +
  +	return 1;
  +}
  +#else
   int RAND_poll(void)
   {
   	unsigned long l;
  @@ -236,6 +254,7 @@
   #endif
   }
   
  +#endif
   #endif
   
   #if defined(OPENSSL_SYS_VXWORKS)
  @@ .
  patch -p0 <<'@@ .'
  Index: openssl/crypto/rand/randfile.c
  ============================================================================
  $ cvs diff -u -r1.42 -r1.43 randfile.c
  --- openssl/crypto/rand/randfile.c	28 Nov 2002 08:03:59 -0000	1.42
  +++ openssl/crypto/rand/randfile.c	27 Dec 2003 16:02:22 -0000	1.43
  @@ -56,6 +56,9 @@
    * [including the GNU Public Licence.]
    */
   
  +/* We need to define this to get macros like S_IFBLK and S_IFCHR */
  +#define _XOPEN_SOURCE 1
  +
   #include <errno.h>
   #include <stdio.h>
   #include <stdlib.h>
  @@ -64,6 +67,7 @@
   #include "e_os.h"
   #include <openssl/crypto.h>
   #include <openssl/rand.h>
  +#include <openssl/buffer.h>
   
   #ifdef OPENSSL_SYS_VMS
   #include <unixio.h>
  @@ -106,6 +110,14 @@
   
   	in=fopen(file,"rb");
   	if (in == NULL) goto err;
  +	if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
  +	  /* this file is a device. we don't want read an infinite number
  +	   * of bytes from a random device, nor do we want to use buffered
  +	   * I/O because we will waste system entropy. 
  +	   */
  +	  bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
  +	  setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
  +	}
   	for (;;)
   		{
   		if (bytes > 0)
  @@ -135,7 +147,20 @@
   	int i,ret=0,rand_err=0;
   	FILE *out = NULL;
   	int n;
  +	struct stat sb;
   	
  +	i=stat(file,&sb);
  +	if (i != -1) { 
  +	  if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
  +	    /* this file is a device. we don't write back to it. 
  +	     * we "succeed" on the assumption this is some sort 
  +	     * of random device. Otherwise attempting to write to 
  +	     * and chmod the device causes problems.
  +	     */
  +	    return(1); 
  +	  }
  +	}
  +
   #if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32)
   	/* For some reason Win32 can't write to files created this way */
   	
  @@ -197,16 +222,17 @@
   const char *RAND_file_name(char *buf, size_t size)
   	{
   	char *s=NULL;
  -	char *ret=NULL;
  +	int ok = 0;
  +#ifdef __OpenBSD__
  +	struct stat sb;
  +#endif
   
   	if (OPENSSL_issetugid() == 0)
   		s=getenv("RANDFILE");
  -	if (s != NULL)
  +	if (s != NULL && *s && strlen(s) + 1 < size)
   		{
  -		if(strlen(s) >= size)
  +		if (BUF_strlcpy(buf,s,size) >= size)
   			return NULL;
  -		strcpy(buf,s);
  -		ret=buf;
   		}
   	else
   		{
  @@ -218,17 +244,36 @@
   			s = DEFAULT_HOME;
   			}
   #endif
  -		if (s != NULL && (strlen(s)+strlen(RFILE)+2 < size))
  +		if (s && *s && strlen(s)+strlen(RFILE)+2 < size)
   			{
  -			strcpy(buf,s);
  +			BUF_strlcpy(buf,s,size);
   #ifndef OPENSSL_SYS_VMS
  -			strcat(buf,"/");
  +			BUF_strlcat(buf,"/",size);
   #endif
  -			strcat(buf,RFILE);
  -			ret=buf;
  +			BUF_strlcat(buf,RFILE,size);
  +			ok = 1;
   			}
   		else
   		  	buf[0] = '\0'; /* no file name */
   		}
  -	return(ret);
  +
  +#ifdef __OpenBSD__
  +	/* given that all random loads just fail if the file can't be 
  +	 * seen on a stat, we stat the file we're returning, if it
  +	 * fails, use /dev/arandom instead. this allows the user to 
  +	 * use their own source for good random data, but defaults
  +	 * to something hopefully decent if that isn't available. 
  +	 */
  +
  +	if (!ok)
  +		if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) {
  +			return(NULL);
  +		}	
  +	if (stat(buf,&sb) == -1)
  +		if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) {
  +			return(NULL);
  +		}	
  +
  +#endif
  +	return(buf);
   	}
  @@ .
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
CVS Repository Commit List                     openssl-cvs@openssl.org
Automated List Manager                           majordomo@openssl.org
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic