diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/rand/randfile.c | 108 |
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 | ||
| 77 | int RAND_load_file(const char *file, long bytes) | 87 | int 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: | |||
| 112 | int RAND_write_file(const char *file) | 130 | int 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); |
| 149 | err: | 213 | err: |
| 150 | return(ret); | 214 | return(err ? -1 : ret); |
| 151 | } | 215 | } |
| 152 | 216 | ||
| 153 | char *RAND_file_name(char *buf, int size) | 217 | const char *RAND_file_name(char *buf, int size) |
| 154 | { | 218 | { |
| 155 | char *s; | 219 | char *s; |
| 156 | char *ret=NULL; | 220 | char *ret=NULL; |
