rand.c revision 160814
11556Srgrimes/* apps/rand.c */ 21556Srgrimes/* ==================================================================== 31556Srgrimes * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. 41556Srgrimes * 51556Srgrimes * Redistribution and use in source and binary forms, with or without 61556Srgrimes * modification, are permitted provided that the following conditions 71556Srgrimes * are met: 81556Srgrimes * 91556Srgrimes * 1. Redistributions of source code must retain the above copyright 101556Srgrimes * notice, this list of conditions and the following disclaimer. 111556Srgrimes * 121556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 131556Srgrimes * notice, this list of conditions and the following disclaimer in 141556Srgrimes * the documentation and/or other materials provided with the 151556Srgrimes * distribution. 161556Srgrimes * 171556Srgrimes * 3. All advertising materials mentioning features or use of this 181556Srgrimes * software must display the following acknowledgment: 191556Srgrimes * "This product includes software developed by the OpenSSL Project 201556Srgrimes * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 211556Srgrimes * 221556Srgrimes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 231556Srgrimes * endorse or promote products derived from this software without 241556Srgrimes * prior written permission. For written permission, please contact 251556Srgrimes * openssl-core@openssl.org. 261556Srgrimes * 271556Srgrimes * 5. Products derived from this software may not be called "OpenSSL" 281556Srgrimes * nor may "OpenSSL" appear in their names without prior written 291556Srgrimes * permission of the OpenSSL Project. 301556Srgrimes * 311556Srgrimes * 6. Redistributions of any form whatsoever must retain the following 321556Srgrimes * acknowledgment: 331556Srgrimes * "This product includes software developed by the OpenSSL Project 341556Srgrimes * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 351556Srgrimes * 361556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 371556Srgrimes * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3836150Scharnier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 3936150Scharnier * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4036150Scharnier * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4136150Scharnier * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4250471Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 431556Srgrimes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 441556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4517987Speter * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 4617987Speter * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 4717987Speter * OF THE POSSIBILITY OF SUCH DAMAGE. 4817987Speter * ==================================================================== 4917987Speter * 5017987Speter * This product includes cryptographic software written by Eric Young 5117987Speter * (eay@cryptsoft.com). This product includes software written by Tim 5217987Speter * Hudson (tjh@cryptsoft.com). 5317987Speter * 5417987Speter */ 5569793Sobrien 5617987Speter#include "apps.h" 5718018Speter 5817987Speter#include <ctype.h> 591556Srgrimes#include <stdio.h> 601556Srgrimes#include <string.h> 6125222Ssteve 621556Srgrimes#include <openssl/bio.h> 6317987Speter#include <openssl/err.h> 6417987Speter#include <openssl/rand.h> 6517987Speter 661556Srgrimes#undef PROG 671556Srgrimes#define PROG rand_main 6817987Speter 6917987Speter/* -out file - write to file 701556Srgrimes * -rand file:file - PRNG seed files 711556Srgrimes * -base64 - encode output 721556Srgrimes * num - write 'num' bytes 731556Srgrimes */ 741556Srgrimes 751556Srgrimesint MAIN(int, char **); 761556Srgrimes 771556Srgrimesint MAIN(int argc, char **argv) 781556Srgrimes { 791556Srgrimes#ifndef OPENSSL_NO_ENGINE 801556Srgrimes ENGINE *e = NULL; 811556Srgrimes#endif 821556Srgrimes int i, r, ret = 1; 831556Srgrimes int badopt; 841556Srgrimes char *outfile = NULL; 851556Srgrimes char *inrand = NULL; 8628346Ssteve int base64 = 0; 871556Srgrimes BIO *out = NULL; 8897659Stjr int num = -1; 891556Srgrimes#ifndef OPENSSL_NO_ENGINE 901556Srgrimes char *engine=NULL; 9138536Scracauer#endif 9238950Scracauer 9338536Scracauer apps_startup(); 941556Srgrimes 9520425Ssteve if (bio_err == NULL) 9690111Simp if ((bio_err = BIO_new(BIO_s_file())) != NULL) 9720425Ssteve BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); 9890111Simp 9990111Simp if (!load_config(bio_err, NULL)) 10090111Simp goto err; 10120425Ssteve 10290111Simp badopt = 0; 10320425Ssteve i = 0; 10490111Simp while (!badopt && argv[++i] != NULL) 10590111Simp { 10690111Simp if (strcmp(argv[i], "-out") == 0) 10797659Stjr { 10897659Stjr if ((argv[i+1] != NULL) && (outfile == NULL)) 10997659Stjr outfile = argv[++i]; 11097659Stjr else 11197659Stjr badopt = 1; 11297669Stjr } 1131556Srgrimes#ifndef OPENSSL_NO_ENGINE 1141556Srgrimes else if (strcmp(argv[i], "-engine") == 0) 1151556Srgrimes { 1161556Srgrimes if ((argv[i+1] != NULL) && (engine == NULL)) 1171556Srgrimes engine = argv[++i]; 1181556Srgrimes else 1191556Srgrimes badopt = 1; 1201556Srgrimes } 1211556Srgrimes#endif 1221556Srgrimes else if (strcmp(argv[i], "-rand") == 0) 1231556Srgrimes { 1241556Srgrimes if ((argv[i+1] != NULL) && (inrand == NULL)) 12520425Ssteve inrand = argv[++i]; 1261556Srgrimes else 12790111Simp badopt = 1; 12817987Speter } 1291556Srgrimes else if (strcmp(argv[i], "-base64") == 0) 1301556Srgrimes { 1311556Srgrimes if (!base64) 1321556Srgrimes base64 = 1; 1331556Srgrimes else 1341556Srgrimes badopt = 1; 1351556Srgrimes } 1361556Srgrimes else if (isdigit((unsigned char)argv[i][0])) 13720425Ssteve { 1381556Srgrimes if (num < 0) 13920425Ssteve { 14020425Ssteve r = sscanf(argv[i], "%d", &num); 14120425Ssteve if (r == 0 || num < 0) 14220425Ssteve badopt = 1; 1431556Srgrimes } 1441556Srgrimes else 1451556Srgrimes badopt = 1; 1461556Srgrimes } 1471556Srgrimes else 14817987Speter badopt = 1; 14917987Speter } 1501556Srgrimes 1511556Srgrimes if (num < 0) 1521556Srgrimes badopt = 1; 1531556Srgrimes 1541556Srgrimes if (badopt) 1551556Srgrimes { 1561556Srgrimes BIO_printf(bio_err, "Usage: rand [options] num\n"); 1571556Srgrimes BIO_printf(bio_err, "where options are\n"); 1581556Srgrimes BIO_printf(bio_err, "-out file - write to file\n"); 1591556Srgrimes#ifndef OPENSSL_NO_ENGINE 1601556Srgrimes BIO_printf(bio_err, "-engine e - use engine e, possibly a hardware device.\n"); 1611556Srgrimes#endif 1621556Srgrimes BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); 1631556Srgrimes BIO_printf(bio_err, "-base64 - encode output\n"); 16417987Speter goto err; 16520425Ssteve } 1661556Srgrimes 16720425Ssteve#ifndef OPENSSL_NO_ENGINE 16820425Ssteve e = setup_engine(bio_err, engine, 0); 16920425Ssteve#endif 1701556Srgrimes 17117987Speter app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 17220425Ssteve if (inrand != NULL) 1731556Srgrimes BIO_printf(bio_err,"%ld semi-random bytes loaded\n", 17420425Ssteve app_RAND_load_files(inrand)); 17520425Ssteve 17620425Ssteve out = BIO_new(BIO_s_file()); 1771556Srgrimes if (out == NULL) 1781556Srgrimes goto err; 1791556Srgrimes if (outfile != NULL) 1801556Srgrimes r = BIO_write_filename(out, outfile); 1811556Srgrimes else 1821556Srgrimes { 18320425Ssteve r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); 1841556Srgrimes#ifdef OPENSSL_SYS_VMS 1851556Srgrimes { 1861556Srgrimes BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 18728346Ssteve out = BIO_push(tmpbio, out); 18817987Speter } 1891556Srgrimes#endif 1901556Srgrimes } 1911556Srgrimes if (r <= 0) 1921556Srgrimes goto err; 1931556Srgrimes 1941556Srgrimes if (base64) 1951556Srgrimes { 1961556Srgrimes BIO *b64 = BIO_new(BIO_f_base64()); 1971556Srgrimes if (b64 == NULL) 1981556Srgrimes goto err; 1991556Srgrimes out = BIO_push(b64, out); 2001556Srgrimes } 2011556Srgrimes 20217987Speter while (num > 0) 20390111Simp { 20417987Speter unsigned char buf[4096]; 2051556Srgrimes int chunk; 2061556Srgrimes 2071556Srgrimes chunk = num; 2081556Srgrimes if (chunk > (int)sizeof(buf)) 2091556Srgrimes chunk = sizeof buf; 2101556Srgrimes r = RAND_bytes(buf, chunk); 2111556Srgrimes if (r <= 0) 21296933Stjr goto err; 21396933Stjr BIO_write(out, buf, chunk); 21496933Stjr num -= chunk; 2151556Srgrimes } 21620425Ssteve BIO_flush(out); 2171556Srgrimes 21820425Ssteve app_RAND_write_file(NULL, bio_err); 21920425Ssteve ret = 0; 22020425Ssteve 2211556Srgrimeserr: 2221556Srgrimes ERR_print_errors(bio_err); 22345916Scracauer if (out) 2241556Srgrimes BIO_free_all(out); 2251556Srgrimes apps_shutdown(); 2261556Srgrimes OPENSSL_EXIT(ret); 2271556Srgrimes } 2281556Srgrimes