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

View File

@ -60,35 +60,22 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "openssl/e_os.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> #include <openssl/rand.h>
#undef BUFSIZE #undef BUFSIZE
#define BUFSIZE 1024 #define BUFSIZE 1024
#define RAND_DATA 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) 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]; MS_STATIC unsigned char buf[BUFSIZE];
struct stat sb; struct stat sb;
int i,ret=0,n; int i,ret=0,n;
@ -98,28 +85,23 @@ int RAND_load_file(const char *file, long bytes)
i=stat(file,&sb); i=stat(file,&sb);
/* If the state fails, put some crap in anyway */ /* 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 (i < 0) return(0);
if (bytes == 0) return(ret); if (bytes <= 0) return(ret);
in=fopen(file,"rb"); in=fopen(file,"rb");
if (in == NULL) goto err; if (in == NULL) goto err;
for (;;) for (;;)
{ {
if (bytes > 0) n=(bytes < BUFSIZE)?(int)bytes:BUFSIZE;
n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
else
n = BUFSIZE;
i=fread(buf,1,n,in); i=fread(buf,1,n,in);
if (i <= 0) break; if (i <= 0) break;
/* even if n != i, use the full array */ /* even if n != i, use the full array */
RAND_add(buf,n,i); RAND_seed(buf,n);
ret+=i; ret+=i;
if (bytes > 0) bytes-=n;
{ if (bytes <= 0) break;
bytes-=n;
if (bytes == 0) break;
}
} }
fclose(in); fclose(in);
memset(buf,0,BUFSIZE); memset(buf,0,BUFSIZE);
@ -130,33 +112,29 @@ err:
int RAND_write_file(const char *file) int RAND_write_file(const char *file)
{ {
unsigned char buf[BUFSIZE]; unsigned char buf[BUFSIZE];
int i,ret=0,err=0; int i,ret=0;
FILE *out = NULL; FILE *out;
int n; 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, /* Under VMS, fopen(file, "wb") will craete a new version of the
* permissions should be restrictive from the start */ same file. This is not good, so let's try updating an existing
int fd = open(file, O_CREAT | O_EXCL, 0600); one, and create file only if it doesn't already exist. This
if (fd != -1) should be completely harmless on system that have no file
out = fdopen(fd, "wb"); versions. -- Richard Levitte */
#endif out=fopen(file,"rb+");
if (out == NULL) if (out == NULL && errno == ENOENT)
out = fopen(file,"wb"); {
if (out == NULL) goto err; errno = 0;
out=fopen(file,"wb");
#ifndef NO_CHMOD }
if (out == NULL) goto err;
chmod(file,0600); chmod(file,0600);
#endif
n=RAND_DATA; n=RAND_DATA;
for (;;) for (;;)
{ {
i=(n > BUFSIZE)?BUFSIZE:n; i=(n > BUFSIZE)?BUFSIZE:n;
n-=BUFSIZE; n-=BUFSIZE;
if (RAND_bytes(buf,i) <= 0) RAND_bytes(buf,i);
err=1;
i=fwrite(buf,1,i,out); i=fwrite(buf,1,i,out);
if (i <= 0) if (i <= 0)
{ {
@ -165,78 +143,37 @@ int RAND_write_file(const char *file)
} }
ret+=i; ret+=i;
if (n <= 0) break; 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); fclose(out);
memset(buf,0,BUFSIZE); memset(buf,0,BUFSIZE);
err: err:
return(err ? -1 : ret); return(ret);
} }
const char *RAND_file_name(char *buf, int size) const char *RAND_file_name(char *buf, int size)
{ {
char *s = NULL; char *s;
char *ret=NULL; char *ret=NULL;
struct stat sb;
if (issetugid() == 0) s=getenv("RANDFILE");
s = getenv("RANDFILE"); if (s != NULL)
if (s != NULL && *s && strlen(s) + 1 < size)
{ {
strlcpy(buf,s,size); strncpy(buf,s,size-1);
buf[size-1]='\0';
ret=buf; ret=buf;
} }
else else
{ {
if (issetugid() == 0) s=getenv("HOME");
s=getenv("HOME"); if (s == NULL) return(RFILE);
if (s && *s && strlen(s)+strlen(RFILE)+2 < size) if (((int)(strlen(s)+strlen(RFILE)+2)) > size)
{ return(RFILE);
strlcpy(buf,s,size); strcpy(buf,s);
#ifndef VMS #ifndef VMS
strlcat(buf,"/",size); strcat(buf,"/");
#endif #endif
strlcat(buf,RFILE,size); strcat(buf,RFILE);
ret=buf; 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); return(ret);
} }