backout 1.1 -> 1.2 (use /dev/urandom if no value can be found),

/dev/urandom is not a normal file - there'll be no EOF.
noticed by Manuel Bouyer.
This commit is contained in:
itojun 2001-03-21 19:49:50 +00:00
parent ee84bdd76e
commit 522ac04d08
1 changed files with 40 additions and 103 deletions

View File

@ -60,35 +60,22 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "openssl/e_os.h"
#ifdef VMS
#include <unixio.h>
#endif
#ifndef NO_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef MAC_OS_pre_X
# include <stat.h>
#else
# include <sys/stat.h>
#endif
#include <openssl/crypto.h>
#include <openssl/rand.h>
#undef BUFSIZE
#define BUFSIZE 1024
#define RAND_DATA 1024
/* #define RFILE ".rnd" - defined in ../../e_os.h */
/* #define RFILE ".rand" - defined in ../../e_os.h */
int RAND_load_file(const char *file, long bytes)
{
/* If bytes >= 0, read up to 'bytes' bytes.
* if bytes == -1, read complete file. */
MS_STATIC unsigned char buf[BUFSIZE];
struct stat sb;
int i,ret=0,n;
@ -98,28 +85,23 @@ int RAND_load_file(const char *file, long bytes)
i=stat(file,&sb);
/* If the state fails, put some crap in anyway */
RAND_add(&sb,sizeof(sb),0);
RAND_seed(&sb,sizeof(sb));
ret+=sizeof(sb);
if (i < 0) return(0);
if (bytes == 0) return(ret);
if (bytes <= 0) return(ret);
in=fopen(file,"rb");
if (in == NULL) goto err;
for (;;)
{
if (bytes > 0)
n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
else
n = BUFSIZE;
n=(bytes < BUFSIZE)?(int)bytes:BUFSIZE;
i=fread(buf,1,n,in);
if (i <= 0) break;
/* even if n != i, use the full array */
RAND_add(buf,n,i);
RAND_seed(buf,n);
ret+=i;
if (bytes > 0)
{
bytes-=n;
if (bytes == 0) break;
}
bytes-=n;
if (bytes <= 0) break;
}
fclose(in);
memset(buf,0,BUFSIZE);
@ -130,33 +112,29 @@ err:
int RAND_write_file(const char *file)
{
unsigned char buf[BUFSIZE];
int i,ret=0,err=0;
FILE *out = NULL;
int i,ret=0;
FILE *out;
int n;
#if defined(O_CREAT) && defined(O_EXCL) && !defined(WIN32)
/* For some reason Win32 can't write to files created this way */
/* chmod(..., 0600) is too late to protect the file,
* permissions should be restrictive from the start */
int fd = open(file, O_CREAT | O_EXCL, 0600);
if (fd != -1)
out = fdopen(fd, "wb");
#endif
if (out == NULL)
out = fopen(file,"wb");
if (out == NULL) goto err;
#ifndef NO_CHMOD
/* Under VMS, fopen(file, "wb") will craete a new version of the
same file. This is not good, so let's try updating an existing
one, and create file only if it doesn't already exist. This
should be completely harmless on system that have no file
versions. -- Richard Levitte */
out=fopen(file,"rb+");
if (out == NULL && errno == ENOENT)
{
errno = 0;
out=fopen(file,"wb");
}
if (out == NULL) goto err;
chmod(file,0600);
#endif
n=RAND_DATA;
for (;;)
{
i=(n > BUFSIZE)?BUFSIZE:n;
n-=BUFSIZE;
if (RAND_bytes(buf,i) <= 0)
err=1;
RAND_bytes(buf,i);
i=fwrite(buf,1,i,out);
if (i <= 0)
{
@ -165,78 +143,37 @@ int RAND_write_file(const char *file)
}
ret+=i;
if (n <= 0) break;
}
#ifdef VMS
/* Try to delete older versions of the file, until there aren't
any */
{
char *tmpf;
tmpf = Malloc(strlen(file) + 4); /* to add ";-1" and a nul */
if (tmpf)
{
strcpy(tmpf, file);
strcat(tmpf, ";-1");
while(delete(tmpf) == 0)
;
rename(file,";1"); /* Make sure it's version 1, or we
will reach the limit (32767) at
some point... */
}
}
#endif /* VMS */
fclose(out);
memset(buf,0,BUFSIZE);
err:
return(err ? -1 : ret);
return(ret);
}
const char *RAND_file_name(char *buf, int size)
{
char *s = NULL;
char *s;
char *ret=NULL;
struct stat sb;
if (issetugid() == 0)
s = getenv("RANDFILE");
if (s != NULL && *s && strlen(s) + 1 < size)
s=getenv("RANDFILE");
if (s != NULL)
{
strlcpy(buf,s,size);
strncpy(buf,s,size-1);
buf[size-1]='\0';
ret=buf;
}
else
{
if (issetugid() == 0)
s=getenv("HOME");
if (s && *s && strlen(s)+strlen(RFILE)+2 < size)
{
strlcpy(buf,s,size);
s=getenv("HOME");
if (s == NULL) return(RFILE);
if (((int)(strlen(s)+strlen(RFILE)+2)) > size)
return(RFILE);
strcpy(buf,s);
#ifndef VMS
strlcat(buf,"/",size);
strcat(buf,"/");
#endif
strlcat(buf,RFILE,size);
ret=buf;
}
strcat(buf,RFILE);
ret=buf;
}
#ifdef DEVRANDOM
/* 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 DEVRANDOM instead. the allows the user to
* use their own source for good random data, but defaults
* to something hopefully decent if that isn't available.
*/
if (ret == NULL)
ret = DEVRANDOM;
if (stat(ret,&sb) == -1)
ret = DEVRANDOM;
#else
/* old behavior */
if (ret == NULL)
ret = RFILE;
#endif
return(ret);
}