1 |
/* apps/rand.c */ |
2 |
/* ==================================================================== |
3 |
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. |
4 |
* |
5 |
* Redistribution and use in source and binary forms, with or without |
6 |
* modification, are permitted provided that the following conditions |
7 |
* are met: |
8 |
* |
9 |
* 1. Redistributions of source code must retain the above copyright |
10 |
* notice, this list of conditions and the following disclaimer. |
11 |
* |
12 |
* 2. Redistributions in binary form must reproduce the above copyright |
13 |
* notice, this list of conditions and the following disclaimer in |
14 |
* the documentation and/or other materials provided with the |
15 |
* distribution. |
16 |
* |
17 |
* 3. All advertising materials mentioning features or use of this |
18 |
* software must display the following acknowledgment: |
19 |
* "This product includes software developed by the OpenSSL Project |
20 |
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)" |
21 |
* |
22 |
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
23 |
* endorse or promote products derived from this software without |
24 |
* prior written permission. For written permission, please contact |
25 |
* openssl-core@openssl.org. |
26 |
* |
27 |
* 5. Products derived from this software may not be called "OpenSSL" |
28 |
* nor may "OpenSSL" appear in their names without prior written |
29 |
* permission of the OpenSSL Project. |
30 |
* |
31 |
* 6. Redistributions of any form whatsoever must retain the following |
32 |
* acknowledgment: |
33 |
* "This product includes software developed by the OpenSSL Project |
34 |
* for use in the OpenSSL Toolkit (http://www.openssl.org/)" |
35 |
* |
36 |
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
37 |
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
38 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
39 |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
40 |
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
41 |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
42 |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
43 |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
44 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
45 |
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
46 |
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
47 |
* OF THE POSSIBILITY OF SUCH DAMAGE. |
48 |
* ==================================================================== |
49 |
* |
50 |
* This product includes cryptographic software written by Eric Young |
51 |
* (eay@cryptsoft.com). This product includes software written by Tim |
52 |
* Hudson (tjh@cryptsoft.com). |
53 |
* |
54 |
*/ |
55 |
|
56 |
#include "apps.h" |
57 |
|
58 |
#include <ctype.h> |
59 |
#include <stdio.h> |
60 |
#include <string.h> |
61 |
|
62 |
#include <openssl/bio.h> |
63 |
#include <openssl/err.h> |
64 |
#include <openssl/rand.h> |
65 |
|
66 |
#undef PROG |
67 |
#define PROG rand_main |
68 |
|
69 |
/*- |
70 |
* -out file - write to file |
71 |
* -rand file:file - PRNG seed files |
72 |
* -base64 - base64 encode output |
73 |
* -hex - hex encode output |
74 |
* num - write 'num' bytes |
75 |
*/ |
76 |
|
77 |
int MAIN(int, char **); |
78 |
|
79 |
int MAIN(int argc, char **argv) |
80 |
{ |
81 |
int i, r, ret = 1; |
82 |
int badopt; |
83 |
char *outfile = NULL; |
84 |
char *inrand = NULL; |
85 |
int base64 = 0; |
86 |
int hex = 0; |
87 |
BIO *out = NULL; |
88 |
int num = -1; |
89 |
#ifndef OPENSSL_NO_ENGINE |
90 |
char *engine = NULL; |
91 |
#endif |
92 |
|
93 |
apps_startup(); |
94 |
|
95 |
if (bio_err == NULL) |
96 |
if ((bio_err = BIO_new(BIO_s_file())) != NULL) |
97 |
BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); |
98 |
|
99 |
if (!load_config(bio_err, NULL)) |
100 |
goto err; |
101 |
|
102 |
badopt = 0; |
103 |
i = 0; |
104 |
while (!badopt && argv[++i] != NULL) { |
105 |
if (strcmp(argv[i], "-out") == 0) { |
106 |
if ((argv[i + 1] != NULL) && (outfile == NULL)) |
107 |
outfile = argv[++i]; |
108 |
else |
109 |
badopt = 1; |
110 |
} |
111 |
#ifndef OPENSSL_NO_ENGINE |
112 |
else if (strcmp(argv[i], "-engine") == 0) { |
113 |
if ((argv[i + 1] != NULL) && (engine == NULL)) |
114 |
engine = argv[++i]; |
115 |
else |
116 |
badopt = 1; |
117 |
} |
118 |
#endif |
119 |
else if (strcmp(argv[i], "-rand") == 0) { |
120 |
if ((argv[i + 1] != NULL) && (inrand == NULL)) |
121 |
inrand = argv[++i]; |
122 |
else |
123 |
badopt = 1; |
124 |
} else if (strcmp(argv[i], "-base64") == 0) { |
125 |
if (!base64) |
126 |
base64 = 1; |
127 |
else |
128 |
badopt = 1; |
129 |
} else if (strcmp(argv[i], "-hex") == 0) { |
130 |
if (!hex) |
131 |
hex = 1; |
132 |
else |
133 |
badopt = 1; |
134 |
} else if (isdigit((unsigned char)argv[i][0])) { |
135 |
if (num < 0) { |
136 |
r = sscanf(argv[i], "%d", &num); |
137 |
if (r == 0 || num < 0) |
138 |
badopt = 1; |
139 |
} else |
140 |
badopt = 1; |
141 |
} else |
142 |
badopt = 1; |
143 |
} |
144 |
|
145 |
if (hex && base64) |
146 |
badopt = 1; |
147 |
|
148 |
if (num < 0) |
149 |
badopt = 1; |
150 |
|
151 |
if (badopt) { |
152 |
BIO_printf(bio_err, "Usage: rand [options] num\n"); |
153 |
BIO_printf(bio_err, "where options are\n"); |
154 |
BIO_printf(bio_err, "-out file - write to file\n"); |
155 |
#ifndef OPENSSL_NO_ENGINE |
156 |
BIO_printf(bio_err, |
157 |
"-engine e - use engine e, possibly a hardware device.\n"); |
158 |
#endif |
159 |
BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", |
160 |
LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); |
161 |
BIO_printf(bio_err, "-base64 - base64 encode output\n"); |
162 |
BIO_printf(bio_err, "-hex - hex encode output\n"); |
163 |
goto err; |
164 |
} |
165 |
#ifndef OPENSSL_NO_ENGINE |
166 |
setup_engine(bio_err, engine, 0); |
167 |
#endif |
168 |
|
169 |
app_RAND_load_file(NULL, bio_err, (inrand != NULL)); |
170 |
if (inrand != NULL) |
171 |
BIO_printf(bio_err, "%ld semi-random bytes loaded\n", |
172 |
app_RAND_load_files(inrand)); |
173 |
|
174 |
out = BIO_new(BIO_s_file()); |
175 |
if (out == NULL) |
176 |
goto err; |
177 |
if (outfile != NULL) |
178 |
r = BIO_write_filename(out, outfile); |
179 |
else { |
180 |
r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); |
181 |
#ifdef OPENSSL_SYS_VMS |
182 |
{ |
183 |
BIO *tmpbio = BIO_new(BIO_f_linebuffer()); |
184 |
out = BIO_push(tmpbio, out); |
185 |
} |
186 |
#endif |
187 |
} |
188 |
if (r <= 0) |
189 |
goto err; |
190 |
|
191 |
if (base64) { |
192 |
BIO *b64 = BIO_new(BIO_f_base64()); |
193 |
if (b64 == NULL) |
194 |
goto err; |
195 |
out = BIO_push(b64, out); |
196 |
} |
197 |
|
198 |
while (num > 0) { |
199 |
unsigned char buf[4096]; |
200 |
int chunk; |
201 |
|
202 |
chunk = num; |
203 |
if (chunk > (int)sizeof(buf)) |
204 |
chunk = sizeof buf; |
205 |
r = RAND_bytes(buf, chunk); |
206 |
if (r <= 0) |
207 |
goto err; |
208 |
if (!hex) |
209 |
BIO_write(out, buf, chunk); |
210 |
else { |
211 |
for (i = 0; i < chunk; i++) |
212 |
BIO_printf(out, "%02x", buf[i]); |
213 |
} |
214 |
num -= chunk; |
215 |
} |
216 |
if (hex) |
217 |
BIO_puts(out, "\n"); |
218 |
(void)BIO_flush(out); |
219 |
|
220 |
app_RAND_write_file(NULL, bio_err); |
221 |
ret = 0; |
222 |
|
223 |
err: |
224 |
ERR_print_errors(bio_err); |
225 |
if (out) |
226 |
BIO_free_all(out); |
227 |
apps_shutdown(); |
228 |
OPENSSL_EXIT(ret); |
229 |
} |