randfile.c revision 55714
1235267Sgabor/* crypto/rand/randfile.c */ 2235267Sgabor/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3235267Sgabor * All rights reserved. 4235267Sgabor * 5251245Sgabor * This package is an SSL implementation written 6235267Sgabor * by Eric Young (eay@cryptsoft.com). 7235267Sgabor * The implementation was written so as to conform with Netscapes SSL. 8235267Sgabor * 9235267Sgabor * This library is free for commercial and non-commercial use as long as 10235267Sgabor * the following conditions are aheared to. The following conditions 11235267Sgabor * apply to all code found in this distribution, be it the RC4, RSA, 12235267Sgabor * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13235267Sgabor * included with this distribution is covered by the same copyright terms 14235267Sgabor * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15235267Sgabor * 16235267Sgabor * Copyright remains Eric Young's, and as such any Copyright notices in 17235267Sgabor * the code are not to be removed. 18235267Sgabor * If this package is used in a product, Eric Young should be given attribution 19235267Sgabor * as the author of the parts of the library used. 20235267Sgabor * This can be in the form of a textual message at program startup or 21235267Sgabor * in documentation (online or textual) provided with the package. 22235267Sgabor * 23235267Sgabor * Redistribution and use in source and binary forms, with or without 24235267Sgabor * modification, are permitted provided that the following conditions 25235267Sgabor * are met: 26235267Sgabor * 1. Redistributions of source code must retain the copyright 27235267Sgabor * notice, this list of conditions and the following disclaimer. 28235267Sgabor * 2. Redistributions in binary form must reproduce the above copyright 29235267Sgabor * notice, this list of conditions and the following disclaimer in the 30235267Sgabor * documentation and/or other materials provided with the distribution. 31264744Spfg * 3. All advertising materials mentioning features or use of this software 32235267Sgabor * must display the following acknowledgement: 33235267Sgabor * "This product includes cryptographic software written by 34235267Sgabor * Eric Young (eay@cryptsoft.com)" 35235267Sgabor * The word 'cryptographic' can be left out if the rouines from the library 36235267Sgabor * being used are not cryptographic related :-). 37235267Sgabor * 4. If you include any Windows specific code (or a derivative thereof) from 38235267Sgabor * the apps directory (application code) you must include an acknowledgement: 39235267Sgabor * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40235267Sgabor * 41235267Sgabor * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42235267Sgabor * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43235267Sgabor * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44264744Spfg * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45235267Sgabor * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46235267Sgabor * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47235267Sgabor * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48235267Sgabor * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49235267Sgabor * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50235267Sgabor * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51235267Sgabor * SUCH DAMAGE. 52235267Sgabor * 53235267Sgabor * The licence and distribution terms for any publically available version or 54235267Sgabor * derivative of this code cannot be changed. i.e. this code cannot simply be 55235267Sgabor * copied and put under another distribution licence 56235267Sgabor * [including the GNU Public Licence.] 57235267Sgabor */ 58235267Sgabor 59235267Sgabor#include <errno.h> 60235267Sgabor#include <stdio.h> 61235267Sgabor#include <stdlib.h> 62235267Sgabor#include <string.h> 63235267Sgabor#include <sys/types.h> 64235267Sgabor#include <sys/stat.h> 65235267Sgabor#include <sys/types.h> 66235267Sgabor 67264744Spfg#include "openssl/e_os.h" 68235267Sgabor 69235267Sgabor#include <openssl/rand.h> 70235267Sgabor 71235267Sgabor#undef BUFSIZE 72235267Sgabor#define BUFSIZE 1024 73235267Sgabor#define RAND_DATA 1024 74235267Sgabor 75235267Sgabor/* #define RFILE ".rand" - defined in ../../e_os.h */ 76235267Sgabor 77235267Sgaborint RAND_load_file(const char *file, long bytes) 78235267Sgabor { 79235267Sgabor MS_STATIC unsigned char buf[BUFSIZE]; 80235267Sgabor struct stat sb; 81235267Sgabor int i,ret=0,n; 82235267Sgabor FILE *in; 83235267Sgabor 84235267Sgabor if (file == NULL) return(0); 85235267Sgabor 86235267Sgabor i=stat(file,&sb); 87235267Sgabor /* If the state fails, put some crap in anyway */ 88235267Sgabor RAND_seed(&sb,sizeof(sb)); 89235267Sgabor ret+=sizeof(sb); 90235267Sgabor if (i < 0) return(0); 91235267Sgabor if (bytes <= 0) return(ret); 92235267Sgabor 93235267Sgabor in=fopen(file,"rb"); 94235267Sgabor if (in == NULL) goto err; 95235267Sgabor for (;;) 96242430Sgabor { 97235267Sgabor n=(bytes < BUFSIZE)?(int)bytes:BUFSIZE; 98235267Sgabor i=fread(buf,1,n,in); 99235267Sgabor if (i <= 0) break; 100235267Sgabor /* even if n != i, use the full array */ 101235267Sgabor RAND_seed(buf,n); 102235267Sgabor ret+=i; 103235267Sgabor bytes-=n; 104235267Sgabor if (bytes <= 0) break; 105235267Sgabor } 106235267Sgabor fclose(in); 107235267Sgabor memset(buf,0,BUFSIZE); 108235267Sgaborerr: 109235267Sgabor return(ret); 110235267Sgabor } 111235267Sgabor 112235267Sgaborint RAND_write_file(const char *file) 113235267Sgabor { 114235267Sgabor unsigned char buf[BUFSIZE]; 115235267Sgabor int i,ret=0; 116235267Sgabor FILE *out; 117235267Sgabor int n; 118235267Sgabor 119235267Sgabor /* Under VMS, fopen(file, "wb") will craete a new version of the 120235267Sgabor same file. This is not good, so let's try updating an existing 121235267Sgabor one, and create file only if it doesn't already exist. This 122235267Sgabor should be completely harmless on system that have no file 123235267Sgabor versions. -- Richard Levitte */ 124235267Sgabor out=fopen(file,"rb+"); 125235267Sgabor if (out == NULL && errno == ENOENT) 126235267Sgabor { 127235267Sgabor errno = 0; 128235267Sgabor out=fopen(file,"wb"); 129235267Sgabor } 130235267Sgabor if (out == NULL) goto err; 131235267Sgabor chmod(file,0600); 132235267Sgabor n=RAND_DATA; 133235267Sgabor for (;;) 134235267Sgabor { 135235267Sgabor i=(n > BUFSIZE)?BUFSIZE:n; 136235267Sgabor n-=BUFSIZE; 137235267Sgabor RAND_bytes(buf,i); 138264744Spfg i=fwrite(buf,1,i,out); 139235267Sgabor if (i <= 0) 140235267Sgabor { 141235267Sgabor ret=0; 142235267Sgabor break; 143 } 144 ret+=i; 145 if (n <= 0) break; 146 } 147 fclose(out); 148 memset(buf,0,BUFSIZE); 149err: 150 return(ret); 151 } 152 153char *RAND_file_name(char *buf, int size) 154 { 155 char *s; 156 char *ret=NULL; 157 158 s=getenv("RANDFILE"); 159 if (s != NULL) 160 { 161 strncpy(buf,s,size-1); 162 buf[size-1]='\0'; 163 ret=buf; 164 } 165 else 166 { 167 s=getenv("HOME"); 168 if (s == NULL) return(RFILE); 169 if (((int)(strlen(s)+strlen(RFILE)+2)) > size) 170 return(RFILE); 171 strcpy(buf,s); 172#ifndef VMS 173 strcat(buf,"/"); 174#endif 175 strcat(buf,RFILE); 176 ret=buf; 177 } 178 return(ret); 179 } 180