rand.c revision 68651
1/* apps/rand.c */
2
3#include "apps.h"
4
5#include <ctype.h>
6#include <stdio.h>
7#include <string.h>
8
9#include <openssl/bio.h>
10#include <openssl/err.h>
11#include <openssl/rand.h>
12
13#undef PROG
14#define PROG rand_main
15
16/* -out file         - write to file
17 * -rand file:file   - PRNG seed files
18 * -base64           - encode output
19 * num               - write 'num' bytes
20 */
21
22int MAIN(int, char **);
23
24int MAIN(int argc, char **argv)
25	{
26	int i, r, ret = 1;
27	int badopt;
28	char *outfile = NULL;
29	char *inrand = NULL;
30	int base64 = 0;
31	BIO *out = NULL;
32	int num = -1;
33
34	apps_startup();
35
36	if (bio_err == NULL)
37		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
38			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
39
40	badopt = 0;
41	i = 0;
42	while (!badopt && argv[++i] != NULL)
43		{
44		if (strcmp(argv[i], "-out") == 0)
45			{
46			if ((argv[i+1] != NULL) && (outfile == NULL))
47				outfile = argv[++i];
48			else
49				badopt = 1;
50			}
51		else if (strcmp(argv[i], "-rand") == 0)
52			{
53			if ((argv[i+1] != NULL) && (inrand == NULL))
54				inrand = argv[++i];
55			else
56				badopt = 1;
57			}
58		else if (strcmp(argv[i], "-base64") == 0)
59			{
60			if (!base64)
61				base64 = 1;
62			else
63				badopt = 1;
64			}
65		else if (isdigit((unsigned char)argv[i][0]))
66			{
67			if (num < 0)
68				{
69				r = sscanf(argv[i], "%d", &num);
70				if (r == 0 || num < 0)
71					badopt = 1;
72				}
73			else
74				badopt = 1;
75			}
76		else
77			badopt = 1;
78		}
79
80	if (num < 0)
81		badopt = 1;
82
83	if (badopt)
84		{
85		BIO_printf(bio_err, "Usage: rand [options] num\n");
86		BIO_printf(bio_err, "where options are\n");
87		BIO_printf(bio_err, "-out file            - write to file\n");
88		BIO_printf(bio_err, "-rand file%cfile%c...  - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
89		BIO_printf(bio_err, "-base64              - encode output\n");
90		goto err;
91		}
92
93	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
94	if (inrand != NULL)
95		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
96			app_RAND_load_files(inrand));
97
98	out = BIO_new(BIO_s_file());
99	if (out == NULL)
100		goto err;
101	if (outfile != NULL)
102		r = BIO_write_filename(out, outfile);
103	else
104		{
105		r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
106#ifdef VMS
107		{
108		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
109		out = BIO_push(tmpbio, out);
110		}
111#endif
112		}
113	if (r <= 0)
114		goto err;
115
116	if (base64)
117		{
118		BIO *b64 = BIO_new(BIO_f_base64());
119		if (b64 == NULL)
120			goto err;
121		out = BIO_push(b64, out);
122		}
123
124	while (num > 0)
125		{
126		unsigned char buf[4096];
127		int chunk;
128
129		chunk = num;
130		if (chunk > sizeof buf)
131			chunk = sizeof buf;
132		r = RAND_bytes(buf, chunk);
133		if (r <= 0)
134			goto err;
135		BIO_write(out, buf, chunk);
136		num -= chunk;
137		}
138	BIO_flush(out);
139
140	app_RAND_write_file(NULL, bio_err);
141	ret = 0;
142
143err:
144	ERR_print_errors(bio_err);
145	if (out)
146		BIO_free_all(out);
147	EXIT(ret);
148	}
149