summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rand/randfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/rand/randfile.c')
-rw-r--r--src/lib/libcrypto/rand/randfile.c108
1 files changed, 86 insertions, 22 deletions
diff --git a/src/lib/libcrypto/rand/randfile.c b/src/lib/libcrypto/rand/randfile.c
index 6829d4ec37..658a8d6b65 100644
--- a/src/lib/libcrypto/rand/randfile.c
+++ b/src/lib/libcrypto/rand/randfile.c
@@ -60,22 +60,35 @@
60#include <stdio.h> 60#include <stdio.h>
61#include <stdlib.h> 61#include <stdlib.h>
62#include <string.h> 62#include <string.h>
63#include <sys/types.h>
64#include <sys/stat.h>
65#include <sys/types.h>
66 63
67#include "openssl/e_os.h" 64#include "openssl/e_os.h"
68 65
66#ifdef VMS
67#include <unixio.h>
68#endif
69#ifndef NO_SYS_TYPES_H
70# include <sys/types.h>
71#endif
72#ifdef MAC_OS_pre_X
73# include <stat.h>
74#else
75# include <sys/stat.h>
76#endif
77
78#include <openssl/crypto.h>
69#include <openssl/rand.h> 79#include <openssl/rand.h>
70 80
71#undef BUFSIZE 81#undef BUFSIZE
72#define BUFSIZE 1024 82#define BUFSIZE 1024
73#define RAND_DATA 1024 83#define RAND_DATA 1024
74 84
75/* #define RFILE ".rand" - defined in ../../e_os.h */ 85/* #define RFILE ".rnd" - defined in ../../e_os.h */
76 86
77int RAND_load_file(const char *file, long bytes) 87int RAND_load_file(const char *file, long bytes)
78 { 88 {
89 /* If bytes >= 0, read up to 'bytes' bytes.
90 * if bytes == -1, read complete file. */
91
79 MS_STATIC unsigned char buf[BUFSIZE]; 92 MS_STATIC unsigned char buf[BUFSIZE];
80 struct stat sb; 93 struct stat sb;
81 int i,ret=0,n; 94 int i,ret=0,n;
@@ -85,23 +98,28 @@ int RAND_load_file(const char *file, long bytes)
85 98
86 i=stat(file,&sb); 99 i=stat(file,&sb);
87 /* If the state fails, put some crap in anyway */ 100 /* If the state fails, put some crap in anyway */
88 RAND_seed(&sb,sizeof(sb)); 101 RAND_add(&sb,sizeof(sb),0);
89 ret+=sizeof(sb);
90 if (i < 0) return(0); 102 if (i < 0) return(0);
91 if (bytes <= 0) return(ret); 103 if (bytes == 0) return(ret);
92 104
93 in=fopen(file,"rb"); 105 in=fopen(file,"rb");
94 if (in == NULL) goto err; 106 if (in == NULL) goto err;
95 for (;;) 107 for (;;)
96 { 108 {
97 n=(bytes < BUFSIZE)?(int)bytes:BUFSIZE; 109 if (bytes > 0)
110 n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
111 else
112 n = BUFSIZE;
98 i=fread(buf,1,n,in); 113 i=fread(buf,1,n,in);
99 if (i <= 0) break; 114 if (i <= 0) break;
100 /* even if n != i, use the full array */ 115 /* even if n != i, use the full array */
101 RAND_seed(buf,n); 116 RAND_add(buf,n,i);
102 ret+=i; 117 ret+=i;
103 bytes-=n; 118 if (bytes > 0)
104 if (bytes <= 0) break; 119 {
120 bytes-=n;
121 if (bytes == 0) break;
122 }
105 } 123 }
106 fclose(in); 124 fclose(in);
107 memset(buf,0,BUFSIZE); 125 memset(buf,0,BUFSIZE);
@@ -112,29 +130,48 @@ err:
112int RAND_write_file(const char *file) 130int RAND_write_file(const char *file)
113 { 131 {
114 unsigned char buf[BUFSIZE]; 132 unsigned char buf[BUFSIZE];
115 int i,ret=0; 133 int i,ret=0,err=0;
116 FILE *out; 134 FILE *out = NULL;
117 int n; 135 int n;
118 136
119 /* Under VMS, fopen(file, "wb") will craete a new version of the 137#ifdef VMS
138 /* Under VMS, fopen(file, "wb") will create a new version of the
120 same file. This is not good, so let's try updating an existing 139 same file. This is not good, so let's try updating an existing
121 one, and create file only if it doesn't already exist. This 140 one, and create file only if it doesn't already exist. */
122 should be completely harmless on system that have no file 141 /* At the same time, if we just update a file, we also need to
123 versions. -- Richard Levitte */ 142 truncate it, and unfortunately, ftruncate() and truncate() do
143 not exist everywhere. All that remains is to delete old versions
144 of the random data file (done at the end). */
145#if 0
124 out=fopen(file,"rb+"); 146 out=fopen(file,"rb+");
125 if (out == NULL && errno == ENOENT) 147 if (out == NULL && errno != ENOENT)
148 goto err;
149#endif
150#endif
151
152 if (out == NULL)
126 { 153 {
127 errno = 0; 154#if defined O_CREAT && defined O_EXCL
155 /* chmod(..., 0600) is too late to protect the file,
156 * permissions should be restrictive from the start */
157 int fd = open(file, O_CREAT | O_EXCL, 0600);
158 if (fd != -1)
159 out = fdopen(fd, "wb");
160#else
128 out=fopen(file,"wb"); 161 out=fopen(file,"wb");
162#endif
129 } 163 }
130 if (out == NULL) goto err; 164 if (out == NULL) goto err;
165#ifndef NO_CHMOD
131 chmod(file,0600); 166 chmod(file,0600);
167#endif
132 n=RAND_DATA; 168 n=RAND_DATA;
133 for (;;) 169 for (;;)
134 { 170 {
135 i=(n > BUFSIZE)?BUFSIZE:n; 171 i=(n > BUFSIZE)?BUFSIZE:n;
136 n-=BUFSIZE; 172 n-=BUFSIZE;
137 RAND_bytes(buf,i); 173 if (RAND_bytes(buf,i) <= 0)
174 err=1;
138 i=fwrite(buf,1,i,out); 175 i=fwrite(buf,1,i,out);
139 if (i <= 0) 176 if (i <= 0)
140 { 177 {
@@ -144,13 +181,40 @@ int RAND_write_file(const char *file)
144 ret+=i; 181 ret+=i;
145 if (n <= 0) break; 182 if (n <= 0) break;
146 } 183 }
184#ifdef VMS
185 /* We may have updated an existing file using mode "rb+",
186 * now remove any old extra bytes */
187#if 0
188 if (ret > 0)
189 ftruncate(fileno(out), ret);
190#else
191 /* Try to delete older versions of the file, until there aren't
192 any */
193 {
194 char *tmpf;
195
196 tmpf = Malloc(strlen(file) + 4); /* to add ";-1" and a nul */
197 if (tmpf)
198 {
199 strcpy(tmpf, file);
200 strcat(tmpf, ";-1");
201 while(delete(tmpf) == 0)
202 ;
203 rename(file,";1"); /* Make sure it's version 1, or we
204 will reach the limit (32767) at
205 some point... */
206 }
207 }
208#endif
209#endif
210
147 fclose(out); 211 fclose(out);
148 memset(buf,0,BUFSIZE); 212 memset(buf,0,BUFSIZE);
149err: 213err:
150 return(ret); 214 return(err ? -1 : ret);
151 } 215 }
152 216
153char *RAND_file_name(char *buf, int size) 217const char *RAND_file_name(char *buf, int size)
154 { 218 {
155 char *s; 219 char *s;
156 char *ret=NULL; 220 char *ret=NULL;