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 10280304Sjkim * 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 69280304Sjkim/*- 70280304Sjkim * -out file - write to file 7159191Skris * -rand file:file - PRNG seed files 72194206Ssimon * -base64 - base64 encode output 73194206Ssimon * -hex - hex encode output 7459191Skris * num - write 'num' bytes 7559191Skris */ 7659191Skris 7759191Skrisint MAIN(int, char **); 7859191Skris 7959191Skrisint MAIN(int argc, char **argv) 80280304Sjkim{ 81280304Sjkim int i, r, ret = 1; 82280304Sjkim int badopt; 83280304Sjkim char *outfile = NULL; 84280304Sjkim char *inrand = NULL; 85280304Sjkim int base64 = 0; 86280304Sjkim int hex = 0; 87280304Sjkim BIO *out = NULL; 88280304Sjkim int num = -1; 89111147Snectar#ifndef OPENSSL_NO_ENGINE 90280304Sjkim char *engine = NULL; 91111147Snectar#endif 9259191Skris 93280304Sjkim apps_startup(); 9459191Skris 95280304Sjkim if (bio_err == NULL) 96280304Sjkim if ((bio_err = BIO_new(BIO_s_file())) != NULL) 97280304Sjkim BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 9859191Skris 99280304Sjkim if (!load_config(bio_err, NULL)) 100280304Sjkim goto err; 101109998Smarkm 102280304Sjkim badopt = 0; 103280304Sjkim i = 0; 104280304Sjkim while (!badopt && argv[++i] != NULL) { 105280304Sjkim if (strcmp(argv[i], "-out") == 0) { 106280304Sjkim if ((argv[i + 1] != NULL) && (outfile == NULL)) 107280304Sjkim outfile = argv[++i]; 108280304Sjkim else 109280304Sjkim badopt = 1; 110280304Sjkim } 111111147Snectar#ifndef OPENSSL_NO_ENGINE 112280304Sjkim else if (strcmp(argv[i], "-engine") == 0) { 113280304Sjkim if ((argv[i + 1] != NULL) && (engine == NULL)) 114280304Sjkim engine = argv[++i]; 115280304Sjkim else 116280304Sjkim badopt = 1; 117280304Sjkim } 118111147Snectar#endif 119280304Sjkim else if (strcmp(argv[i], "-rand") == 0) { 120280304Sjkim if ((argv[i + 1] != NULL) && (inrand == NULL)) 121280304Sjkim inrand = argv[++i]; 122280304Sjkim else 123280304Sjkim badopt = 1; 124280304Sjkim } else if (strcmp(argv[i], "-base64") == 0) { 125280304Sjkim if (!base64) 126280304Sjkim base64 = 1; 127280304Sjkim else 128280304Sjkim badopt = 1; 129280304Sjkim } else if (strcmp(argv[i], "-hex") == 0) { 130280304Sjkim if (!hex) 131280304Sjkim hex = 1; 132280304Sjkim else 133280304Sjkim badopt = 1; 134280304Sjkim } else if (isdigit((unsigned char)argv[i][0])) { 135280304Sjkim if (num < 0) { 136280304Sjkim r = sscanf(argv[i], "%d", &num); 137280304Sjkim if (r == 0 || num < 0) 138280304Sjkim badopt = 1; 139280304Sjkim } else 140280304Sjkim badopt = 1; 141280304Sjkim } else 142280304Sjkim badopt = 1; 143280304Sjkim } 14459191Skris 145280304Sjkim if (hex && base64) 146280304Sjkim badopt = 1; 147194206Ssimon 148280304Sjkim if (num < 0) 149280304Sjkim badopt = 1; 150280304Sjkim 151280304Sjkim if (badopt) { 152280304Sjkim BIO_printf(bio_err, "Usage: rand [options] num\n"); 153280304Sjkim BIO_printf(bio_err, "where options are\n"); 154280304Sjkim BIO_printf(bio_err, "-out file - write to file\n"); 155111147Snectar#ifndef OPENSSL_NO_ENGINE 156280304Sjkim BIO_printf(bio_err, 157280304Sjkim "-engine e - use engine e, possibly a hardware device.\n"); 158111147Snectar#endif 159280304Sjkim BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", 160280304Sjkim LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); 161280304Sjkim BIO_printf(bio_err, "-base64 - base64 encode output\n"); 162280304Sjkim BIO_printf(bio_err, "-hex - hex encode output\n"); 163280304Sjkim goto err; 164280304Sjkim } 165111147Snectar#ifndef OPENSSL_NO_ENGINE 166280304Sjkim setup_engine(bio_err, engine, 0); 167111147Snectar#endif 168109998Smarkm 169280304Sjkim app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 170280304Sjkim if (inrand != NULL) 171280304Sjkim BIO_printf(bio_err, "%ld semi-random bytes loaded\n", 172280304Sjkim app_RAND_load_files(inrand)); 17359191Skris 174280304Sjkim out = BIO_new(BIO_s_file()); 175280304Sjkim if (out == NULL) 176280304Sjkim goto err; 177280304Sjkim if (outfile != NULL) 178280304Sjkim r = BIO_write_filename(out, outfile); 179280304Sjkim else { 180280304Sjkim r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT); 181109998Smarkm#ifdef OPENSSL_SYS_VMS 182280304Sjkim { 183280304Sjkim BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 184280304Sjkim out = BIO_push(tmpbio, out); 185280304Sjkim } 18668651Skris#endif 187280304Sjkim } 188280304Sjkim if (r <= 0) 189280304Sjkim goto err; 19059191Skris 191280304Sjkim if (base64) { 192280304Sjkim BIO *b64 = BIO_new(BIO_f_base64()); 193280304Sjkim if (b64 == NULL) 194280304Sjkim goto err; 195280304Sjkim out = BIO_push(b64, out); 196280304Sjkim } 19759191Skris 198280304Sjkim while (num > 0) { 199280304Sjkim unsigned char buf[4096]; 200280304Sjkim int chunk; 20159191Skris 202280304Sjkim chunk = num; 203280304Sjkim if (chunk > (int)sizeof(buf)) 204280304Sjkim chunk = sizeof buf; 205280304Sjkim r = RAND_bytes(buf, chunk); 206280304Sjkim if (r <= 0) 207280304Sjkim goto err; 208280304Sjkim if (!hex) 209280304Sjkim BIO_write(out, buf, chunk); 210280304Sjkim else { 211280304Sjkim for (i = 0; i < chunk; i++) 212280304Sjkim BIO_printf(out, "%02x", buf[i]); 213280304Sjkim } 214280304Sjkim num -= chunk; 215280304Sjkim } 216280304Sjkim if (hex) 217280304Sjkim BIO_puts(out, "\n"); 218280304Sjkim (void)BIO_flush(out); 219280304Sjkim 220280304Sjkim app_RAND_write_file(NULL, bio_err); 221280304Sjkim ret = 0; 222280304Sjkim 223280304Sjkim err: 224280304Sjkim ERR_print_errors(bio_err); 225280304Sjkim if (out) 226280304Sjkim BIO_free_all(out); 227280304Sjkim apps_shutdown(); 228280304Sjkim OPENSSL_EXIT(ret); 229280304Sjkim} 230