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