| 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 |