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