rand.c revision 109998
1192886Sedwin/* apps/rand.c */
2192886Sedwin/* ====================================================================
32744Swollman * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
420091Swollman *
520091Swollman * Redistribution and use in source and binary forms, with or without
620091Swollman * modification, are permitted provided that the following conditions
7149511Swollman * are met:
8149511Swollman *
9149511Swollman * 1. Redistributions of source code must retain the above copyright
102744Swollman *    notice, this list of conditions and the following disclaimer.
11309568Sglebius *
12309568Sglebius * 2. Redistributions in binary form must reproduce the above copyright
13309568Sglebius *    notice, this list of conditions and the following disclaimer in
14309568Sglebius *    the documentation and/or other materials provided with the
15309568Sglebius *    distribution.
16309568Sglebius *
17309568Sglebius * 3. All advertising materials mentioning features or use of this
182744Swollman *    software must display the following acknowledgment:
1920091Swollman *    "This product includes software developed by the OpenSSL Project
2020091Swollman *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
2120091Swollman *
2243009Swollman * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23273438Sdelphij *    endorse or promote products derived from this software without
24199405Sobrien *    prior written permission. For written permission, please contact
2543009Swollman *    openssl-core@openssl.org.
26199405Sobrien *
2743009Swollman * 5. Products derived from this software may not be called "OpenSSL"
2820091Swollman *    nor may "OpenSSL" appear in their names without prior written
2920091Swollman *    permission of the OpenSSL Project.
3020091Swollman *
312744Swollman * 6. Redistributions of any form whatsoever must retain the following
322744Swollman *    acknowledgment:
332744Swollman *    "This product includes software developed by the OpenSSL Project
342744Swollman *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
352744Swollman *
36309568Sglebius * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
3775264Swollman * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3875264Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3975264Swollman * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
40309568Sglebius * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4175264Swollman * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42257682Sedwin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
432744Swollman * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
442744Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
452744Swollman * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
462744Swollman * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
472744Swollman * OF THE POSSIBILITY OF SUCH DAMAGE.
482744Swollman * ====================================================================
492744Swollman *
502744Swollman * This product includes cryptographic software written by Eric Young
51309568Sglebius * (eay@cryptsoft.com).  This product includes software written by Tim
522744Swollman * Hudson (tjh@cryptsoft.com).
53309568Sglebius *
54309568Sglebius */
55309568Sglebius
56309568Sglebius#include "apps.h"
57309568Sglebius
58309568Sglebius#include <ctype.h>
59309568Sglebius#include <stdio.h>
60309568Sglebius#include <string.h>
61309568Sglebius
62309568Sglebius#include <openssl/bio.h>
63309568Sglebius#include <openssl/err.h>
64309568Sglebius#include <openssl/rand.h>
65309568Sglebius
66309568Sglebius#undef PROG
67309568Sglebius#define PROG rand_main
68309568Sglebius
69309568Sglebius/* -out file         - write to file
70309568Sglebius * -rand file:file   - PRNG seed files
71309568Sglebius * -base64           - encode output
72309568Sglebius * num               - write 'num' bytes
73309568Sglebius */
74309568Sglebius
75309568Sglebiusint MAIN(int, char **);
76309568Sglebius
77309568Sglebiusint MAIN(int argc, char **argv)
78309568Sglebius	{
79	ENGINE *e = NULL;
80	int i, r, ret = 1;
81	int badopt;
82	char *outfile = NULL;
83	char *inrand = NULL;
84	int base64 = 0;
85	BIO *out = NULL;
86	int num = -1;
87	char *engine=NULL;
88
89	apps_startup();
90
91	if (bio_err == NULL)
92		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
93			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
94
95	if (!load_config(bio_err, NULL))
96		goto err;
97
98	badopt = 0;
99	i = 0;
100	while (!badopt && argv[++i] != NULL)
101		{
102		if (strcmp(argv[i], "-out") == 0)
103			{
104			if ((argv[i+1] != NULL) && (outfile == NULL))
105				outfile = argv[++i];
106			else
107				badopt = 1;
108			}
109		else if (strcmp(argv[i], "-engine") == 0)
110			{
111			if ((argv[i+1] != NULL) && (engine == NULL))
112				engine = argv[++i];
113			else
114				badopt = 1;
115			}
116		else if (strcmp(argv[i], "-rand") == 0)
117			{
118			if ((argv[i+1] != NULL) && (inrand == NULL))
119				inrand = argv[++i];
120			else
121				badopt = 1;
122			}
123		else if (strcmp(argv[i], "-base64") == 0)
124			{
125			if (!base64)
126				base64 = 1;
127			else
128				badopt = 1;
129			}
130		else if (isdigit((unsigned char)argv[i][0]))
131			{
132			if (num < 0)
133				{
134				r = sscanf(argv[i], "%d", &num);
135				if (r == 0 || num < 0)
136					badopt = 1;
137				}
138			else
139				badopt = 1;
140			}
141		else
142			badopt = 1;
143		}
144
145	if (num < 0)
146		badopt = 1;
147
148	if (badopt)
149		{
150		BIO_printf(bio_err, "Usage: rand [options] num\n");
151		BIO_printf(bio_err, "where options are\n");
152		BIO_printf(bio_err, "-out file             - write to file\n");
153		BIO_printf(bio_err, "-engine e             - use engine e, possibly a hardware device.\n");
154		BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
155		BIO_printf(bio_err, "-base64               - encode output\n");
156		goto err;
157		}
158
159        e = setup_engine(bio_err, engine, 0);
160
161	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
162	if (inrand != NULL)
163		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
164			app_RAND_load_files(inrand));
165
166	out = BIO_new(BIO_s_file());
167	if (out == NULL)
168		goto err;
169	if (outfile != NULL)
170		r = BIO_write_filename(out, outfile);
171	else
172		{
173		r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
174#ifdef OPENSSL_SYS_VMS
175		{
176		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
177		out = BIO_push(tmpbio, out);
178		}
179#endif
180		}
181	if (r <= 0)
182		goto err;
183
184	if (base64)
185		{
186		BIO *b64 = BIO_new(BIO_f_base64());
187		if (b64 == NULL)
188			goto err;
189		out = BIO_push(b64, out);
190		}
191
192	while (num > 0)
193		{
194		unsigned char buf[4096];
195		int chunk;
196
197		chunk = num;
198		if (chunk > sizeof buf)
199			chunk = sizeof buf;
200		r = RAND_bytes(buf, chunk);
201		if (r <= 0)
202			goto err;
203		BIO_write(out, buf, chunk);
204		num -= chunk;
205		}
206	BIO_flush(out);
207
208	app_RAND_write_file(NULL, bio_err);
209	ret = 0;
210
211err:
212	ERR_print_errors(bio_err);
213	if (out)
214		BIO_free_all(out);
215	apps_shutdown();
216	OPENSSL_EXIT(ret);
217	}
218