1139804Simp/* apps/rand.c */
21541Srgrimes/* ====================================================================
3165897Srwatson * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
41541Srgrimes *
5165897Srwatson * Redistribution and use in source and binary forms, with or without
6165897Srwatson * modification, are permitted provided that the following conditions
7165897Srwatson * are met:
81541Srgrimes *
91541Srgrimes * 1. Redistributions of source code must retain the above copyright
101541Srgrimes *    notice, this list of conditions and the following disclaimer.
111541Srgrimes *
121541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
131541Srgrimes *    notice, this list of conditions and the following disclaimer in
141541Srgrimes *    the documentation and/or other materials provided with the
151541Srgrimes *    distribution.
161541Srgrimes *
171541Srgrimes * 3. All advertising materials mentioning features or use of this
181541Srgrimes *    software must display the following acknowledgment:
191541Srgrimes *    "This product includes software developed by the OpenSSL Project
201541Srgrimes *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
211541Srgrimes *
221541Srgrimes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
231541Srgrimes *    endorse or promote products derived from this software without
241541Srgrimes *    prior written permission. For written permission, please contact
251541Srgrimes *    openssl-core@openssl.org.
261541Srgrimes *
271541Srgrimes * 5. Products derived from this software may not be called "OpenSSL"
281541Srgrimes *    nor may "OpenSSL" appear in their names without prior written
291541Srgrimes *    permission of the OpenSSL Project.
301541Srgrimes *
311541Srgrimes * 6. Redistributions of any form whatsoever must retain the following
321541Srgrimes *    acknowledgment:
331541Srgrimes *    "This product includes software developed by the OpenSSL Project
341541Srgrimes *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
351541Srgrimes *
361541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
371541Srgrimes * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
381541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
391541Srgrimes * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
401541Srgrimes * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
411541Srgrimes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
421541Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
431541Srgrimes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44116182Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45116182Sobrien * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46116182Sobrien * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4731778Seivind * OF THE POSSIBILITY OF SUCH DAMAGE.
48183982Sbz * ====================================================================
49183982Sbz *
5031778Seivind * This product includes cryptographic software written by Eric Young
511541Srgrimes * (eay@cryptsoft.com).  This product includes software written by Tim
5276166Smarkm * Hudson (tjh@cryptsoft.com).
531541Srgrimes *
54132548Srwatson */
5541059Speter
5670317Sjake#include "apps.h"
57219304Strasz
5891140Stanimura#include <ctype.h>
5976166Smarkm#include <stdio.h>
60150634Sjhb#include <string.h>
6191140Stanimura
62164032Srwatson#include <openssl/bio.h>
631541Srgrimes#include <openssl/err.h>
6476166Smarkm#include <openssl/rand.h>
6587218Srwatson
6631891Ssef#undef PROG
67220212Strasz#define PROG rand_main
6865495Struckman
6992976Srwatson/*-
7092976Srwatson * -out file         - write to file
71160139Sjhb * -rand file:file   - PRNG seed files
7261287Srwatson * -base64           - base64 encode output
731541Srgrimes * -hex              - hex encode output
74219028Snetchild * num               - write 'num' bytes
75219028Snetchild */
76229818Shrs
77219028Snetchildint MAIN(int, char **);
78219028Snetchild
79183982Sbzint MAIN(int argc, char **argv)
80183982Sbz{
81183982Sbz    int i, r, ret = 1;
82183982Sbz    int badopt;
83183982Sbz    char *outfile = NULL;
84155370Swsalamon    char *inrand = NULL;
85163606Srwatson    int base64 = 0;
86155370Swsalamon    int hex = 0;
8730354Sphk    BIO *out = NULL;
8830354Sphk    int num = -1;
89162383Srwatson#ifndef OPENSSL_NO_ENGINE
9087138Srwatson    char *engine = NULL;
91194498Sbrooks#endif
92194498Sbrooks
93194498Sbrooks    apps_startup();
9412221Sbde
9511332Sswallace    if (bio_err == NULL)
961541Srgrimes        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
971541Srgrimes            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
9812221Sbde
991541Srgrimes    if (!load_config(bio_err, NULL))
1001549Srgrimes        goto err;
101225617Skmacy
1021541Srgrimes    badopt = 0;
10383366Sjulian    i = 0;
1041541Srgrimes    while (!badopt && argv[++i] != NULL) {
10583366Sjulian        if (strcmp(argv[i], "-out") == 0) {
106130344Sphk            if ((argv[i + 1] != NULL) && (outfile == NULL))
10774728Sjhb                outfile = argv[++i];
10883366Sjulian            else
10974728Sjhb                badopt = 1;
1101541Srgrimes        }
1111541Srgrimes#ifndef OPENSSL_NO_ENGINE
1121541Srgrimes        else if (strcmp(argv[i], "-engine") == 0) {
1131541Srgrimes            if ((argv[i + 1] != NULL) && (engine == NULL))
11412221Sbde                engine = argv[++i];
11511332Sswallace            else
11611332Sswallace                badopt = 1;
11711332Sswallace        }
11812221Sbde#endif
1191541Srgrimes        else if (strcmp(argv[i], "-rand") == 0) {
1201549Srgrimes            if ((argv[i + 1] != NULL) && (inrand == NULL))
121225617Skmacy                inrand = argv[++i];
1221541Srgrimes            else
12383366Sjulian                badopt = 1;
1241541Srgrimes        } else if (strcmp(argv[i], "-base64") == 0) {
12574728Sjhb            if (!base64)
12683366Sjulian                base64 = 1;
12774728Sjhb            else
1281541Srgrimes                badopt = 1;
1291541Srgrimes        } else if (strcmp(argv[i], "-hex") == 0) {
1301541Srgrimes            if (!hex)
13187466Srwatson                hex = 1;
13287218Srwatson            else
13358717Sdillon                badopt = 1;
13412221Sbde        } else if (isdigit((unsigned char)argv[i][0])) {
13511332Sswallace            if (num < 0) {
13611332Sswallace                r = sscanf(argv[i], "%d", &num);
13711332Sswallace                if (r == 0 || num < 0)
13812221Sbde                    badopt = 1;
1391549Srgrimes            } else
140225617Skmacy                badopt = 1;
1411541Srgrimes        } else
14283366Sjulian            badopt = 1;
1431541Srgrimes    }
14491140Stanimura
14583366Sjulian    if (hex && base64)
14691140Stanimura        badopt = 1;
1471541Srgrimes
1481541Srgrimes    if (num < 0)
1491541Srgrimes        badopt = 1;
15028401Speter
15112221Sbde    if (badopt) {
15228401Speter        BIO_printf(bio_err, "Usage: rand [options] num\n");
15328401Speter        BIO_printf(bio_err, "where options are\n");
15428401Speter        BIO_printf(bio_err, "-out file             - write to file\n");
15528401Speter#ifndef OPENSSL_NO_ENGINE
15628401Speter        BIO_printf(bio_err,
157225617Skmacy                   "-engine e             - use engine e, possibly a hardware device.\n");
15828401Speter#endif
159114031Sjhb        BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n",
16092985Sjhb                   LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
16141726Struckman        BIO_printf(bio_err, "-base64               - base64 encode output\n");
16291140Stanimura        BIO_printf(bio_err, "-hex                  - hex encode output\n");
163114031Sjhb        goto err;
16491140Stanimura    }
165114031Sjhb#ifndef OPENSSL_NO_ENGINE
166114031Sjhb    setup_engine(bio_err, engine, 0);
167114031Sjhb#endif
168114031Sjhb
169114031Sjhb    app_RAND_load_file(NULL, bio_err, (inrand != NULL));
170114031Sjhb    if (inrand != NULL)
171114031Sjhb        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
172114031Sjhb                   app_RAND_load_files(inrand));
173114031Sjhb
17475893Sjhb    out = BIO_new(BIO_s_file());
175114031Sjhb    if (out == NULL)
176114031Sjhb        goto err;
177114031Sjhb    if (outfile != NULL)
17828401Speter        r = BIO_write_filename(out, outfile);
17928401Speter    else {
18028401Speter        r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
18128401Speter#ifdef OPENSSL_SYS_VMS
18228401Speter        {
18328401Speter            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
18428401Speter            out = BIO_push(tmpbio, out);
18528401Speter        }
18628401Speter#endif
18728401Speter    }
18828401Speter    if (r <= 0)
189225617Skmacy        goto err;
19028401Speter
191114031Sjhb    if (base64) {
19287218Srwatson        BIO *b64 = BIO_new(BIO_f_base64());
19341726Struckman        if (b64 == NULL)
19491140Stanimura            goto err;
195114031Sjhb        out = BIO_push(b64, out);
19691140Stanimura    }
197114031Sjhb
198114031Sjhb    while (num > 0) {
199114031Sjhb        unsigned char buf[4096];
200114031Sjhb        int chunk;
201114031Sjhb
202114031Sjhb        chunk = num;
203114031Sjhb        if (chunk > (int)sizeof(buf))
204114031Sjhb            chunk = sizeof buf;
205114031Sjhb        r = RAND_bytes(buf, chunk);
20675893Sjhb        if (r <= 0)
207114031Sjhb            goto err;
208114031Sjhb        if (!hex)
209114031Sjhb            BIO_write(out, buf, chunk);
21028401Speter        else {
21128401Speter            for (i = 0; i < chunk; i++)
21228401Speter                BIO_printf(out, "%02x", buf[i]);
21311332Sswallace        }
21411332Sswallace        num -= chunk;
21511332Sswallace    }
21612221Sbde    if (hex)
2171541Srgrimes        BIO_puts(out, "\n");
2181549Srgrimes    (void)BIO_flush(out);
219225617Skmacy
2201541Srgrimes    app_RAND_write_file(NULL, bio_err);
2211541Srgrimes    ret = 0;
22292987Sjhb
223130344Sphk err:
22492987Sjhb    ERR_print_errors(bio_err);
2251541Srgrimes    if (out)
2261541Srgrimes        BIO_free_all(out);
2271541Srgrimes    apps_shutdown();
2281541Srgrimes    OPENSSL_EXIT(ret);
22912221Sbde}
23011332Sswallace