159191Skris/* apps/rand.c */ 2109998Smarkm/* ==================================================================== 3109998Smarkm * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 4109998Smarkm * 5109998Smarkm * Redistribution and use in source and binary forms, with or without 6109998Smarkm * modification, are permitted provided that the following conditions 7109998Smarkm * are met: 8109998Smarkm * 9109998Smarkm * 1. Redistributions of source code must retain the above copyright 10109998Smarkm * notice, this list of conditions and the following disclaimer. 11109998Smarkm * 12109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 13109998Smarkm * notice, this list of conditions and the following disclaimer in 14109998Smarkm * the documentation and/or other materials provided with the 15109998Smarkm * distribution. 16109998Smarkm * 17109998Smarkm * 3. All advertising materials mentioning features or use of this 18109998Smarkm * software must display the following acknowledgment: 19109998Smarkm * "This product includes software developed by the OpenSSL Project 20109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21109998Smarkm * 22109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23109998Smarkm * endorse or promote products derived from this software without 24109998Smarkm * prior written permission. For written permission, please contact 25109998Smarkm * openssl-core@openssl.org. 26109998Smarkm * 27109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 28109998Smarkm * nor may "OpenSSL" appear in their names without prior written 29109998Smarkm * permission of the OpenSSL Project. 30109998Smarkm * 31109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 32109998Smarkm * acknowledgment: 33109998Smarkm * "This product includes software developed by the OpenSSL Project 34109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35109998Smarkm * 36109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 48109998Smarkm * ==================================================================== 49109998Smarkm * 50109998Smarkm * This product includes cryptographic software written by Eric Young 51109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 52109998Smarkm * Hudson (tjh@cryptsoft.com). 53109998Smarkm * 54109998Smarkm */ 5559191Skris 5659191Skris#include "apps.h" 5759191Skris 5859191Skris#include <ctype.h> 5959191Skris#include <stdio.h> 6059191Skris#include <string.h> 6159191Skris 6259191Skris#include <openssl/bio.h> 6359191Skris#include <openssl/err.h> 6459191Skris#include <openssl/rand.h> 6559191Skris 6659191Skris#undef PROG 6759191Skris#define PROG rand_main 6859191Skris 6959191Skris/* -out file - write to file 7059191Skris * -rand file:file - PRNG seed files 71194206Ssimon * -base64 - base64 encode output 72194206Ssimon * -hex - hex encode output 7359191Skris * num - write 'num' bytes 7459191Skris */ 7559191Skris 7659191Skrisint MAIN(int, char **); 7759191Skris 7859191Skrisint MAIN(int argc, char **argv) 7959191Skris { 8059191Skris int i, r, ret = 1; 8159191Skris int badopt; 8259191Skris char *outfile = NULL; 8359191Skris char *inrand = NULL; 8459191Skris int base64 = 0; 85194206Ssimon int hex = 0; 8659191Skris BIO *out = NULL; 8759191Skris int num = -1; 88111147Snectar#ifndef OPENSSL_NO_ENGINE 89109998Smarkm char *engine=NULL; 90111147Snectar#endif 9159191Skris 9259191Skris apps_startup(); 9359191Skris 9459191Skris if (bio_err == NULL) 9559191Skris if ((bio_err = BIO_new(BIO_s_file())) != NULL) 9659191Skris BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); 9759191Skris 98109998Smarkm if (!load_config(bio_err, NULL)) 99109998Smarkm goto err; 100109998Smarkm 10159191Skris badopt = 0; 10259191Skris i = 0; 10359191Skris while (!badopt && argv[++i] != NULL) 10459191Skris { 10559191Skris if (strcmp(argv[i], "-out") == 0) 10659191Skris { 10759191Skris if ((argv[i+1] != NULL) && (outfile == NULL)) 10859191Skris outfile = argv[++i]; 10959191Skris else 11059191Skris badopt = 1; 11159191Skris } 112111147Snectar#ifndef OPENSSL_NO_ENGINE 113109998Smarkm else if (strcmp(argv[i], "-engine") == 0) 114109998Smarkm { 115109998Smarkm if ((argv[i+1] != NULL) && (engine == NULL)) 116109998Smarkm engine = argv[++i]; 117109998Smarkm else 118109998Smarkm badopt = 1; 119109998Smarkm } 120111147Snectar#endif 12159191Skris else if (strcmp(argv[i], "-rand") == 0) 12259191Skris { 12359191Skris if ((argv[i+1] != NULL) && (inrand == NULL)) 12459191Skris inrand = argv[++i]; 12559191Skris else 12659191Skris badopt = 1; 12759191Skris } 12859191Skris else if (strcmp(argv[i], "-base64") == 0) 12959191Skris { 13059191Skris if (!base64) 13159191Skris base64 = 1; 13259191Skris else 13359191Skris badopt = 1; 13459191Skris } 135194206Ssimon else if (strcmp(argv[i], "-hex") == 0) 136194206Ssimon { 137194206Ssimon if (!hex) 138194206Ssimon hex = 1; 139194206Ssimon else 140194206Ssimon badopt = 1; 141194206Ssimon } 14268651Skris else if (isdigit((unsigned char)argv[i][0])) 14359191Skris { 14459191Skris if (num < 0) 14559191Skris { 14659191Skris r = sscanf(argv[i], "%d", &num); 14759191Skris if (r == 0 || num < 0) 14859191Skris badopt = 1; 14959191Skris } 15059191Skris else 15159191Skris badopt = 1; 15259191Skris } 15359191Skris else 15459191Skris badopt = 1; 15559191Skris } 15659191Skris 157194206Ssimon if (hex && base64) 158194206Ssimon badopt = 1; 159194206Ssimon 16059191Skris if (num < 0) 16159191Skris badopt = 1; 16259191Skris 16359191Skris if (badopt) 16459191Skris { 16559191Skris BIO_printf(bio_err, "Usage: rand [options] num\n"); 16659191Skris BIO_printf(bio_err, "where options are\n"); 167109998Smarkm BIO_printf(bio_err, "-out file - write to file\n"); 168111147Snectar#ifndef OPENSSL_NO_ENGINE 169109998Smarkm BIO_printf(bio_err, "-engine e - use engine e, possibly a hardware device.\n"); 170111147Snectar#endif 171109998Smarkm BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); 172194206Ssimon BIO_printf(bio_err, "-base64 - base64 encode output\n"); 173194206Ssimon BIO_printf(bio_err, "-hex - hex encode output\n"); 17459191Skris goto err; 17559191Skris } 17659191Skris 177111147Snectar#ifndef OPENSSL_NO_ENGINE 178215697Ssimon setup_engine(bio_err, engine, 0); 179111147Snectar#endif 180109998Smarkm 18159191Skris app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 18259191Skris if (inrand != NULL) 18359191Skris BIO_printf(bio_err,"%ld semi-random bytes loaded\n", 18459191Skris app_RAND_load_files(inrand)); 18559191Skris 18659191Skris out = BIO_new(BIO_s_file()); 18759191Skris if (out == NULL) 18859191Skris goto err; 18959191Skris if (outfile != NULL) 19059191Skris r = BIO_write_filename(out, outfile); 19159191Skris else 19268651Skris { 19359191Skris r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); 194109998Smarkm#ifdef OPENSSL_SYS_VMS 19568651Skris { 19668651Skris BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 19768651Skris out = BIO_push(tmpbio, out); 19868651Skris } 19968651Skris#endif 20068651Skris } 20159191Skris if (r <= 0) 20259191Skris goto err; 20359191Skris 20459191Skris if (base64) 20559191Skris { 20659191Skris BIO *b64 = BIO_new(BIO_f_base64()); 20759191Skris if (b64 == NULL) 20859191Skris goto err; 20959191Skris out = BIO_push(b64, out); 21059191Skris } 21159191Skris 21259191Skris while (num > 0) 21359191Skris { 21459191Skris unsigned char buf[4096]; 21559191Skris int chunk; 21659191Skris 21759191Skris chunk = num; 218160814Ssimon if (chunk > (int)sizeof(buf)) 21959191Skris chunk = sizeof buf; 22059191Skris r = RAND_bytes(buf, chunk); 22159191Skris if (r <= 0) 22259191Skris goto err; 223194206Ssimon if (!hex) 224194206Ssimon BIO_write(out, buf, chunk); 225194206Ssimon else 226194206Ssimon { 227194206Ssimon for (i = 0; i < chunk; i++) 228194206Ssimon BIO_printf(out, "%02x", buf[i]); 229194206Ssimon } 23059191Skris num -= chunk; 23159191Skris } 232194206Ssimon if (hex) 233194206Ssimon BIO_puts(out, "\n"); 234194206Ssimon (void)BIO_flush(out); 23559191Skris 23659191Skris app_RAND_write_file(NULL, bio_err); 23759191Skris ret = 0; 23859191Skris 23959191Skriserr: 24059191Skris ERR_print_errors(bio_err); 24159191Skris if (out) 24259191Skris BIO_free_all(out); 243109998Smarkm apps_shutdown(); 244109998Smarkm OPENSSL_EXIT(ret); 24559191Skris } 246