rand.c revision 160814
11556Srgrimes/* apps/rand.c */
21556Srgrimes/* ====================================================================
31556Srgrimes * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
41556Srgrimes *
51556Srgrimes * Redistribution and use in source and binary forms, with or without
61556Srgrimes * modification, are permitted provided that the following conditions
71556Srgrimes * are met:
81556Srgrimes *
91556Srgrimes * 1. Redistributions of source code must retain the above copyright
101556Srgrimes *    notice, this list of conditions and the following disclaimer.
111556Srgrimes *
121556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
131556Srgrimes *    notice, this list of conditions and the following disclaimer in
141556Srgrimes *    the documentation and/or other materials provided with the
151556Srgrimes *    distribution.
161556Srgrimes *
171556Srgrimes * 3. All advertising materials mentioning features or use of this
181556Srgrimes *    software must display the following acknowledgment:
191556Srgrimes *    "This product includes software developed by the OpenSSL Project
201556Srgrimes *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
211556Srgrimes *
221556Srgrimes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
231556Srgrimes *    endorse or promote products derived from this software without
241556Srgrimes *    prior written permission. For written permission, please contact
251556Srgrimes *    openssl-core@openssl.org.
261556Srgrimes *
271556Srgrimes * 5. Products derived from this software may not be called "OpenSSL"
281556Srgrimes *    nor may "OpenSSL" appear in their names without prior written
291556Srgrimes *    permission of the OpenSSL Project.
301556Srgrimes *
311556Srgrimes * 6. Redistributions of any form whatsoever must retain the following
321556Srgrimes *    acknowledgment:
331556Srgrimes *    "This product includes software developed by the OpenSSL Project
341556Srgrimes *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
351556Srgrimes *
361556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
371556Srgrimes * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3836150Scharnier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
3936150Scharnier * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4036150Scharnier * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4136150Scharnier * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4250471Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
431556Srgrimes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
441556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4517987Speter * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4617987Speter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4717987Speter * OF THE POSSIBILITY OF SUCH DAMAGE.
4817987Speter * ====================================================================
4917987Speter *
5017987Speter * This product includes cryptographic software written by Eric Young
5117987Speter * (eay@cryptsoft.com).  This product includes software written by Tim
5217987Speter * Hudson (tjh@cryptsoft.com).
5317987Speter *
5417987Speter */
5569793Sobrien
5617987Speter#include "apps.h"
5718018Speter
5817987Speter#include <ctype.h>
591556Srgrimes#include <stdio.h>
601556Srgrimes#include <string.h>
6125222Ssteve
621556Srgrimes#include <openssl/bio.h>
6317987Speter#include <openssl/err.h>
6417987Speter#include <openssl/rand.h>
6517987Speter
661556Srgrimes#undef PROG
671556Srgrimes#define PROG rand_main
6817987Speter
6917987Speter/* -out file         - write to file
701556Srgrimes * -rand file:file   - PRNG seed files
711556Srgrimes * -base64           - encode output
721556Srgrimes * num               - write 'num' bytes
731556Srgrimes */
741556Srgrimes
751556Srgrimesint MAIN(int, char **);
761556Srgrimes
771556Srgrimesint MAIN(int argc, char **argv)
781556Srgrimes	{
791556Srgrimes#ifndef OPENSSL_NO_ENGINE
801556Srgrimes	ENGINE *e = NULL;
811556Srgrimes#endif
821556Srgrimes	int i, r, ret = 1;
831556Srgrimes	int badopt;
841556Srgrimes	char *outfile = NULL;
851556Srgrimes	char *inrand = NULL;
8628346Ssteve	int base64 = 0;
871556Srgrimes	BIO *out = NULL;
8897659Stjr	int num = -1;
891556Srgrimes#ifndef OPENSSL_NO_ENGINE
901556Srgrimes	char *engine=NULL;
9138536Scracauer#endif
9238950Scracauer
9338536Scracauer	apps_startup();
941556Srgrimes
9520425Ssteve	if (bio_err == NULL)
9690111Simp		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
9720425Ssteve			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
9890111Simp
9990111Simp	if (!load_config(bio_err, NULL))
10090111Simp		goto err;
10120425Ssteve
10290111Simp	badopt = 0;
10320425Ssteve	i = 0;
10490111Simp	while (!badopt && argv[++i] != NULL)
10590111Simp		{
10690111Simp		if (strcmp(argv[i], "-out") == 0)
10797659Stjr			{
10897659Stjr			if ((argv[i+1] != NULL) && (outfile == NULL))
10997659Stjr				outfile = argv[++i];
11097659Stjr			else
11197659Stjr				badopt = 1;
11297669Stjr			}
1131556Srgrimes#ifndef OPENSSL_NO_ENGINE
1141556Srgrimes		else if (strcmp(argv[i], "-engine") == 0)
1151556Srgrimes			{
1161556Srgrimes			if ((argv[i+1] != NULL) && (engine == NULL))
1171556Srgrimes				engine = argv[++i];
1181556Srgrimes			else
1191556Srgrimes				badopt = 1;
1201556Srgrimes			}
1211556Srgrimes#endif
1221556Srgrimes		else if (strcmp(argv[i], "-rand") == 0)
1231556Srgrimes			{
1241556Srgrimes			if ((argv[i+1] != NULL) && (inrand == NULL))
12520425Ssteve				inrand = argv[++i];
1261556Srgrimes			else
12790111Simp				badopt = 1;
12817987Speter			}
1291556Srgrimes		else if (strcmp(argv[i], "-base64") == 0)
1301556Srgrimes			{
1311556Srgrimes			if (!base64)
1321556Srgrimes				base64 = 1;
1331556Srgrimes			else
1341556Srgrimes				badopt = 1;
1351556Srgrimes			}
1361556Srgrimes		else if (isdigit((unsigned char)argv[i][0]))
13720425Ssteve			{
1381556Srgrimes			if (num < 0)
13920425Ssteve				{
14020425Ssteve				r = sscanf(argv[i], "%d", &num);
14120425Ssteve				if (r == 0 || num < 0)
14220425Ssteve					badopt = 1;
1431556Srgrimes				}
1441556Srgrimes			else
1451556Srgrimes				badopt = 1;
1461556Srgrimes			}
1471556Srgrimes		else
14817987Speter			badopt = 1;
14917987Speter		}
1501556Srgrimes
1511556Srgrimes	if (num < 0)
1521556Srgrimes		badopt = 1;
1531556Srgrimes
1541556Srgrimes	if (badopt)
1551556Srgrimes		{
1561556Srgrimes		BIO_printf(bio_err, "Usage: rand [options] num\n");
1571556Srgrimes		BIO_printf(bio_err, "where options are\n");
1581556Srgrimes		BIO_printf(bio_err, "-out file             - write to file\n");
1591556Srgrimes#ifndef OPENSSL_NO_ENGINE
1601556Srgrimes		BIO_printf(bio_err, "-engine e             - use engine e, possibly a hardware device.\n");
1611556Srgrimes#endif
1621556Srgrimes		BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
1631556Srgrimes		BIO_printf(bio_err, "-base64               - encode output\n");
16417987Speter		goto err;
16520425Ssteve		}
1661556Srgrimes
16720425Ssteve#ifndef OPENSSL_NO_ENGINE
16820425Ssteve        e = setup_engine(bio_err, engine, 0);
16920425Ssteve#endif
1701556Srgrimes
17117987Speter	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
17220425Ssteve	if (inrand != NULL)
1731556Srgrimes		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
17420425Ssteve			app_RAND_load_files(inrand));
17520425Ssteve
17620425Ssteve	out = BIO_new(BIO_s_file());
1771556Srgrimes	if (out == NULL)
1781556Srgrimes		goto err;
1791556Srgrimes	if (outfile != NULL)
1801556Srgrimes		r = BIO_write_filename(out, outfile);
1811556Srgrimes	else
1821556Srgrimes		{
18320425Ssteve		r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
1841556Srgrimes#ifdef OPENSSL_SYS_VMS
1851556Srgrimes		{
1861556Srgrimes		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
18728346Ssteve		out = BIO_push(tmpbio, out);
18817987Speter		}
1891556Srgrimes#endif
1901556Srgrimes		}
1911556Srgrimes	if (r <= 0)
1921556Srgrimes		goto err;
1931556Srgrimes
1941556Srgrimes	if (base64)
1951556Srgrimes		{
1961556Srgrimes		BIO *b64 = BIO_new(BIO_f_base64());
1971556Srgrimes		if (b64 == NULL)
1981556Srgrimes			goto err;
1991556Srgrimes		out = BIO_push(b64, out);
2001556Srgrimes		}
2011556Srgrimes
20217987Speter	while (num > 0)
20390111Simp		{
20417987Speter		unsigned char buf[4096];
2051556Srgrimes		int chunk;
2061556Srgrimes
2071556Srgrimes		chunk = num;
2081556Srgrimes		if (chunk > (int)sizeof(buf))
2091556Srgrimes			chunk = sizeof buf;
2101556Srgrimes		r = RAND_bytes(buf, chunk);
2111556Srgrimes		if (r <= 0)
21296933Stjr			goto err;
21396933Stjr		BIO_write(out, buf, chunk);
21496933Stjr		num -= chunk;
2151556Srgrimes		}
21620425Ssteve	BIO_flush(out);
2171556Srgrimes
21820425Ssteve	app_RAND_write_file(NULL, bio_err);
21920425Ssteve	ret = 0;
22020425Ssteve
2211556Srgrimeserr:
2221556Srgrimes	ERR_print_errors(bio_err);
22345916Scracauer	if (out)
2241556Srgrimes		BIO_free_all(out);
2251556Srgrimes	apps_shutdown();
2261556Srgrimes	OPENSSL_EXIT(ret);
2271556Srgrimes	}
2281556Srgrimes