OLD | NEW |
1 /* crypto/rand/randfile.c */ | 1 /* crypto/rand/randfile.c */ |
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * This package is an SSL implementation written | 5 * This package is an SSL implementation written |
6 * by Eric Young (eay@cryptsoft.com). | 6 * by Eric Young (eay@cryptsoft.com). |
7 * The implementation was written so as to conform with Netscapes SSL. | 7 * The implementation was written so as to conform with Netscapes SSL. |
8 * | 8 * |
9 * This library is free for commercial and non-commercial use as long as | 9 * This library is free for commercial and non-commercial use as long as |
10 * the following conditions are aheared to. The following conditions | 10 * the following conditions are aheared to. The following conditions |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 #include <openssl/crypto.h> | 68 #include <openssl/crypto.h> |
69 #include <openssl/rand.h> | 69 #include <openssl/rand.h> |
70 #include <openssl/buffer.h> | 70 #include <openssl/buffer.h> |
71 | 71 |
72 #ifdef OPENSSL_SYS_VMS | 72 #ifdef OPENSSL_SYS_VMS |
73 #include <unixio.h> | 73 #include <unixio.h> |
74 #endif | 74 #endif |
75 #ifndef NO_SYS_TYPES_H | 75 #ifndef NO_SYS_TYPES_H |
76 # include <sys/types.h> | 76 # include <sys/types.h> |
77 #endif | 77 #endif |
78 #ifdef MAC_OS_pre_X | 78 #ifndef OPENSSL_NO_POSIX_IO |
79 # include <stat.h> | |
80 #else | |
81 # include <sys/stat.h> | 79 # include <sys/stat.h> |
82 #endif | 80 #endif |
83 | 81 |
84 #ifdef _WIN32 | 82 #ifdef _WIN32 |
85 #define stat _stat | 83 #define stat _stat |
86 #define chmod _chmod | 84 #define chmod _chmod |
87 #define open _open | 85 #define open _open |
88 #define fdopen _fdopen | 86 #define fdopen _fdopen |
89 #endif | 87 #endif |
90 | 88 |
(...skipping 13 matching lines...) Expand all Loading... |
104 | 102 |
105 /* Note that these functions are intended for seed files only. | 103 /* Note that these functions are intended for seed files only. |
106 * Entropy devices and EGD sockets are handled in rand_unix.c */ | 104 * Entropy devices and EGD sockets are handled in rand_unix.c */ |
107 | 105 |
108 int RAND_load_file(const char *file, long bytes) | 106 int RAND_load_file(const char *file, long bytes) |
109 { | 107 { |
110 /* If bytes >= 0, read up to 'bytes' bytes. | 108 /* If bytes >= 0, read up to 'bytes' bytes. |
111 * if bytes == -1, read complete file. */ | 109 * if bytes == -1, read complete file. */ |
112 | 110 |
113 MS_STATIC unsigned char buf[BUFSIZE]; | 111 MS_STATIC unsigned char buf[BUFSIZE]; |
| 112 #ifndef OPENSSL_NO_POSIX_IO |
114 struct stat sb; | 113 struct stat sb; |
| 114 #endif |
115 int i,ret=0,n; | 115 int i,ret=0,n; |
116 FILE *in; | 116 FILE *in; |
117 | 117 |
118 if (file == NULL) return(0); | 118 if (file == NULL) return(0); |
119 | 119 |
| 120 #ifndef OPENSSL_NO_POSIX_IO |
120 #ifdef PURIFY | 121 #ifdef PURIFY |
121 /* struct stat can have padding and unused fields that may not be | 122 /* struct stat can have padding and unused fields that may not be |
122 * initialized in the call to stat(). We need to clear the entire | 123 * initialized in the call to stat(). We need to clear the entire |
123 * structure before calling RAND_add() to avoid complaints from | 124 * structure before calling RAND_add() to avoid complaints from |
124 * applications such as Valgrind. | 125 * applications such as Valgrind. |
125 */ | 126 */ |
126 memset(&sb, 0, sizeof(sb)); | 127 memset(&sb, 0, sizeof(sb)); |
127 #endif | 128 #endif |
128 | |
129 if (stat(file,&sb) < 0) return(0); | 129 if (stat(file,&sb) < 0) return(0); |
130 RAND_add(&sb,sizeof(sb),0.0); | 130 RAND_add(&sb,sizeof(sb),0.0); |
| 131 #endif |
131 if (bytes == 0) return(ret); | 132 if (bytes == 0) return(ret); |
132 | 133 |
133 #ifdef OPENSSL_SYS_VMS | 134 #ifdef OPENSSL_SYS_VMS |
134 in=vms_fopen(file,"rb",VMS_OPEN_ATTRS); | 135 in=vms_fopen(file,"rb",VMS_OPEN_ATTRS); |
135 #else | 136 #else |
136 in=fopen(file,"rb"); | 137 in=fopen(file,"rb"); |
137 #endif | 138 #endif |
138 if (in == NULL) goto err; | 139 if (in == NULL) goto err; |
139 #if defined(S_ISBLK) && defined(S_ISCHR) | 140 #if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPNESSL_NO_POSIX_IO) |
140 » if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { | 141 » if (sb.st_mode & (S_IFBLK | S_IFCHR)) { |
141 /* this file is a device. we don't want read an infinite number | 142 /* this file is a device. we don't want read an infinite number |
142 * of bytes from a random device, nor do we want to use buffered | 143 * of bytes from a random device, nor do we want to use buffered |
143 * I/O because we will waste system entropy. | 144 * I/O because we will waste system entropy. |
144 */ | 145 */ |
145 bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */ | 146 bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */ |
| 147 #ifndef OPENSSL_NO_SETVBUF_IONBF |
146 setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */ | 148 setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */ |
| 149 #endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ |
147 } | 150 } |
148 #endif | 151 #endif |
149 for (;;) | 152 for (;;) |
150 { | 153 { |
151 if (bytes > 0) | 154 if (bytes > 0) |
152 n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE; | 155 n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE; |
153 else | 156 else |
154 n = BUFSIZE; | 157 n = BUFSIZE; |
155 i=fread(buf,1,n,in); | 158 i=fread(buf,1,n,in); |
156 if (i <= 0) break; | 159 if (i <= 0) break; |
(...skipping 15 matching lines...) Expand all Loading... |
172 err: | 175 err: |
173 return(ret); | 176 return(ret); |
174 } | 177 } |
175 | 178 |
176 int RAND_write_file(const char *file) | 179 int RAND_write_file(const char *file) |
177 { | 180 { |
178 unsigned char buf[BUFSIZE]; | 181 unsigned char buf[BUFSIZE]; |
179 int i,ret=0,rand_err=0; | 182 int i,ret=0,rand_err=0; |
180 FILE *out = NULL; | 183 FILE *out = NULL; |
181 int n; | 184 int n; |
| 185 #ifndef OPENSSL_NO_POSIX_IO |
182 struct stat sb; | 186 struct stat sb; |
183 | 187 |
184 i=stat(file,&sb); | 188 i=stat(file,&sb); |
185 if (i != -1) { | 189 if (i != -1) { |
186 #if defined(S_ISBLK) && defined(S_ISCHR) | 190 #if defined(S_ISBLK) && defined(S_ISCHR) |
187 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { | 191 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { |
188 /* this file is a device. we don't write back to it. | 192 /* this file is a device. we don't write back to it. |
189 * we "succeed" on the assumption this is some sort | 193 * we "succeed" on the assumption this is some sort |
190 * of random device. Otherwise attempting to write to | 194 * of random device. Otherwise attempting to write to |
191 * and chmod the device causes problems. | 195 * and chmod the device causes problems. |
192 */ | 196 */ |
193 return(1); | 197 return(1); |
194 } | 198 } |
195 #endif | 199 #endif |
196 } | 200 } |
| 201 #endif |
197 | 202 |
198 #if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_VMS) | 203 #if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VM
S) |
199 { | 204 { |
200 » /* For some reason Win32 can't write to files created this way */ | 205 #ifndef O_BINARY |
201 » | 206 #define O_BINARY 0 |
| 207 #endif |
202 /* chmod(..., 0600) is too late to protect the file, | 208 /* chmod(..., 0600) is too late to protect the file, |
203 * permissions should be restrictive from the start */ | 209 * permissions should be restrictive from the start */ |
204 » int fd = open(file, O_CREAT, 0600); | 210 » int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600); |
205 if (fd != -1) | 211 if (fd != -1) |
206 out = fdopen(fd, "wb"); | 212 out = fdopen(fd, "wb"); |
207 } | 213 } |
208 #endif | 214 #endif |
209 | 215 |
210 #ifdef OPENSSL_SYS_VMS | 216 #ifdef OPENSSL_SYS_VMS |
211 /* VMS NOTE: Prior versions of this routine created a _new_ | 217 /* VMS NOTE: Prior versions of this routine created a _new_ |
212 * version of the rand file for each call into this routine, then | 218 * version of the rand file for each call into this routine, then |
213 * deleted all existing versions named ;-1, and finally renamed | 219 * deleted all existing versions named ;-1, and finally renamed |
214 * the current version as ';1'. Under concurrent usage, this | 220 * the current version as ';1'. Under concurrent usage, this |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 | 264 |
259 fclose(out); | 265 fclose(out); |
260 OPENSSL_cleanse(buf,BUFSIZE); | 266 OPENSSL_cleanse(buf,BUFSIZE); |
261 err: | 267 err: |
262 return (rand_err ? -1 : ret); | 268 return (rand_err ? -1 : ret); |
263 } | 269 } |
264 | 270 |
265 const char *RAND_file_name(char *buf, size_t size) | 271 const char *RAND_file_name(char *buf, size_t size) |
266 { | 272 { |
267 char *s=NULL; | 273 char *s=NULL; |
268 int ok = 0; | |
269 #ifdef __OpenBSD__ | 274 #ifdef __OpenBSD__ |
270 struct stat sb; | 275 struct stat sb; |
271 #endif | 276 #endif |
272 | 277 |
273 if (OPENSSL_issetugid() == 0) | 278 if (OPENSSL_issetugid() == 0) |
274 s=getenv("RANDFILE"); | 279 s=getenv("RANDFILE"); |
275 if (s != NULL && *s && strlen(s) + 1 < size) | 280 if (s != NULL && *s && strlen(s) + 1 < size) |
276 { | 281 { |
277 if (BUF_strlcpy(buf,s,size) >= size) | 282 if (BUF_strlcpy(buf,s,size) >= size) |
278 return NULL; | 283 return NULL; |
279 } | 284 } |
280 else | 285 else |
281 { | 286 { |
282 if (OPENSSL_issetugid() == 0) | 287 if (OPENSSL_issetugid() == 0) |
283 s=getenv("HOME"); | 288 s=getenv("HOME"); |
284 #ifdef DEFAULT_HOME | 289 #ifdef DEFAULT_HOME |
285 if (s == NULL) | 290 if (s == NULL) |
286 { | 291 { |
287 s = DEFAULT_HOME; | 292 s = DEFAULT_HOME; |
288 } | 293 } |
289 #endif | 294 #endif |
290 if (s && *s && strlen(s)+strlen(RFILE)+2 < size) | 295 if (s && *s && strlen(s)+strlen(RFILE)+2 < size) |
291 { | 296 { |
292 BUF_strlcpy(buf,s,size); | 297 BUF_strlcpy(buf,s,size); |
293 #ifndef OPENSSL_SYS_VMS | 298 #ifndef OPENSSL_SYS_VMS |
294 BUF_strlcat(buf,"/",size); | 299 BUF_strlcat(buf,"/",size); |
295 #endif | 300 #endif |
296 BUF_strlcat(buf,RFILE,size); | 301 BUF_strlcat(buf,RFILE,size); |
297 ok = 1; | |
298 } | 302 } |
299 else | 303 else |
300 buf[0] = '\0'; /* no file name */ | 304 buf[0] = '\0'; /* no file name */ |
301 } | 305 } |
302 | 306 |
303 #ifdef __OpenBSD__ | 307 #ifdef __OpenBSD__ |
304 /* given that all random loads just fail if the file can't be | 308 /* given that all random loads just fail if the file can't be |
305 * seen on a stat, we stat the file we're returning, if it | 309 * seen on a stat, we stat the file we're returning, if it |
306 * fails, use /dev/arandom instead. this allows the user to | 310 * fails, use /dev/arandom instead. this allows the user to |
307 * use their own source for good random data, but defaults | 311 * use their own source for good random data, but defaults |
308 * to something hopefully decent if that isn't available. | 312 * to something hopefully decent if that isn't available. |
309 */ | 313 */ |
310 | 314 |
311 » if (!ok) | 315 » if (!buf[0]) |
312 if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) { | 316 if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) { |
313 return(NULL); | 317 return(NULL); |
314 } | 318 } |
315 if (stat(buf,&sb) == -1) | 319 if (stat(buf,&sb) == -1) |
316 if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) { | 320 if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) { |
317 return(NULL); | 321 return(NULL); |
318 } | 322 } |
319 | 323 |
320 #endif | 324 #endif |
321 return(buf); | 325 return(buf); |
322 } | 326 } |
OLD | NEW |