randfile.c revision 55714
155714Skris/* crypto/rand/randfile.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
855714Skris *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1555714Skris *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
2255714Skris *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4055714Skris *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
5255714Skris *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <errno.h>
6055714Skris#include <stdio.h>
6155714Skris#include <stdlib.h>
6255714Skris#include <string.h>
6355714Skris#include <sys/types.h>
6455714Skris#include <sys/stat.h>
6555714Skris#include <sys/types.h>
6655714Skris
6755714Skris#include "openssl/e_os.h"
6855714Skris
6955714Skris#include <openssl/rand.h>
7055714Skris
7155714Skris#undef BUFSIZE
7255714Skris#define BUFSIZE	1024
7355714Skris#define RAND_DATA 1024
7455714Skris
7555714Skris/* #define RFILE ".rand" - defined in ../../e_os.h */
7655714Skris
7755714Skrisint RAND_load_file(const char *file, long bytes)
7855714Skris	{
7955714Skris	MS_STATIC unsigned char buf[BUFSIZE];
8055714Skris	struct stat sb;
8155714Skris	int i,ret=0,n;
8255714Skris	FILE *in;
8355714Skris
8455714Skris	if (file == NULL) return(0);
8555714Skris
8655714Skris	i=stat(file,&sb);
8755714Skris	/* If the state fails, put some crap in anyway */
8855714Skris	RAND_seed(&sb,sizeof(sb));
8955714Skris	ret+=sizeof(sb);
9055714Skris	if (i < 0) return(0);
9155714Skris	if (bytes <= 0) return(ret);
9255714Skris
9355714Skris	in=fopen(file,"rb");
9455714Skris	if (in == NULL) goto err;
9555714Skris	for (;;)
9655714Skris		{
9755714Skris		n=(bytes < BUFSIZE)?(int)bytes:BUFSIZE;
9855714Skris		i=fread(buf,1,n,in);
9955714Skris		if (i <= 0) break;
10055714Skris		/* even if n != i, use the full array */
10155714Skris		RAND_seed(buf,n);
10255714Skris		ret+=i;
10355714Skris		bytes-=n;
10455714Skris		if (bytes <= 0) break;
10555714Skris		}
10655714Skris	fclose(in);
10755714Skris	memset(buf,0,BUFSIZE);
10855714Skriserr:
10955714Skris	return(ret);
11055714Skris	}
11155714Skris
11255714Skrisint RAND_write_file(const char *file)
11355714Skris	{
11455714Skris	unsigned char buf[BUFSIZE];
11555714Skris	int i,ret=0;
11655714Skris	FILE *out;
11755714Skris	int n;
11855714Skris
11955714Skris	/* Under VMS, fopen(file, "wb") will craete a new version of the
12055714Skris	   same file.  This is not good, so let's try updating an existing
12155714Skris	   one, and create file only if it doesn't already exist.  This
12255714Skris	   should be completely harmless on system that have no file
12355714Skris	   versions.					-- Richard Levitte */
12455714Skris	out=fopen(file,"rb+");
12555714Skris	if (out == NULL && errno == ENOENT)
12655714Skris		{
12755714Skris		errno = 0;
12855714Skris		out=fopen(file,"wb");
12955714Skris		}
13055714Skris	if (out == NULL) goto err;
13155714Skris	chmod(file,0600);
13255714Skris	n=RAND_DATA;
13355714Skris	for (;;)
13455714Skris		{
13555714Skris		i=(n > BUFSIZE)?BUFSIZE:n;
13655714Skris		n-=BUFSIZE;
13755714Skris		RAND_bytes(buf,i);
13855714Skris		i=fwrite(buf,1,i,out);
13955714Skris		if (i <= 0)
14055714Skris			{
14155714Skris			ret=0;
14255714Skris			break;
14355714Skris			}
14455714Skris		ret+=i;
14555714Skris		if (n <= 0) break;
14655714Skris		}
14755714Skris	fclose(out);
14855714Skris	memset(buf,0,BUFSIZE);
14955714Skriserr:
15055714Skris	return(ret);
15155714Skris	}
15255714Skris
15355714Skrischar *RAND_file_name(char *buf, int size)
15455714Skris	{
15555714Skris	char *s;
15655714Skris	char *ret=NULL;
15755714Skris
15855714Skris	s=getenv("RANDFILE");
15955714Skris	if (s != NULL)
16055714Skris		{
16155714Skris		strncpy(buf,s,size-1);
16255714Skris		buf[size-1]='\0';
16355714Skris		ret=buf;
16455714Skris		}
16555714Skris	else
16655714Skris		{
16755714Skris		s=getenv("HOME");
16855714Skris		if (s == NULL) return(RFILE);
16955714Skris		if (((int)(strlen(s)+strlen(RFILE)+2)) > size)
17055714Skris			return(RFILE);
17155714Skris		strcpy(buf,s);
17255714Skris#ifndef VMS
17355714Skris		strcat(buf,"/");
17455714Skris#endif
17555714Skris		strcat(buf,RFILE);
17655714Skris		ret=buf;
17755714Skris		}
17855714Skris	return(ret);
17955714Skris	}
180