rand.c 3.1 KB
Newer Older
1 2 3 4 5 6
/* apps/rand.c */

#include "apps.h"

#include <ctype.h>
#include <stdio.h>
7
#include <string.h>
8 9 10 11

#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rand.h>
12
#include <openssl/engine.h>
13 14 15 16 17 18 19 20 21 22 23 24 25 26

#undef PROG
#define PROG rand_main

/* -out file         - write to file
 * -rand file:file   - PRNG seed files
 * -base64           - encode output
 * num               - write 'num' bytes
 */

int MAIN(int, char **);

int MAIN(int argc, char **argv)
	{
27
	ENGINE *e = NULL;
28 29 30
	int i, r, ret = 1;
	int badopt;
	char *outfile = NULL;
31
	char *inrand = NULL;
32 33 34
	int base64 = 0;
	BIO *out = NULL;
	int num = -1;
35
	char *engine=NULL;
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53

	apps_startup();

	if (bio_err == NULL)
		if ((bio_err = BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);

	badopt = 0;
	i = 0;
	while (!badopt && argv[++i] != NULL)
		{
		if (strcmp(argv[i], "-out") == 0)
			{
			if ((argv[i+1] != NULL) && (outfile == NULL))
				outfile = argv[++i];
			else
				badopt = 1;
			}
54
		else if (strcmp(argv[i], "-engine") == 0)
55 56 57 58 59 60
			{
			if ((argv[i+1] != NULL) && (engine == NULL))
				engine = argv[++i];
			else
				badopt = 1;
			}
61 62 63 64 65 66 67 68 69 70 71 72 73 74
		else if (strcmp(argv[i], "-rand") == 0)
			{
			if ((argv[i+1] != NULL) && (inrand == NULL))
				inrand = argv[++i];
			else
				badopt = 1;
			}
		else if (strcmp(argv[i], "-base64") == 0)
			{
			if (!base64)
				base64 = 1;
			else
				badopt = 1;
			}
B
Bodo Möller 已提交
75
		else if (isdigit((unsigned char)argv[i][0]))
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
			{
			if (num < 0)
				{
				r = sscanf(argv[i], "%d", &num);
				if (r == 0 || num < 0)
					badopt = 1;
				}
			else
				badopt = 1;
			}
		else
			badopt = 1;
		}

	if (num < 0)
		badopt = 1;
	
	if (badopt) 
		{
		BIO_printf(bio_err, "Usage: rand [options] num\n");
		BIO_printf(bio_err, "where options are\n");
97
		BIO_printf(bio_err, "-out file             - write to file\n");
L
Typo  
Lutz Jänicke 已提交
98
		BIO_printf(bio_err, "-engine e             - use engine e, possibly a hardware device.\n");
99 100
		BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
		BIO_printf(bio_err, "-base64               - encode output\n");
101 102 103
		goto err;
		}

104
        e = setup_engine(bio_err, engine, 0);
105

106
	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
107 108 109 110 111 112 113 114 115 116
	if (inrand != NULL)
		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
			app_RAND_load_files(inrand));

	out = BIO_new(BIO_s_file());
	if (out == NULL)
		goto err;
	if (outfile != NULL)
		r = BIO_write_filename(out, outfile);
	else
117
		{
118
		r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
119
#ifdef OPENSSL_SYS_VMS
120 121 122 123 124 125
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
		}
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
	if (r <= 0)
		goto err;

	if (base64)
		{
		BIO *b64 = BIO_new(BIO_f_base64());
		if (b64 == NULL)
			goto err;
		out = BIO_push(b64, out);
		}
	
	while (num > 0) 
		{
		unsigned char buf[4096];
		int chunk;

		chunk = num;
		if (chunk > sizeof buf)
			chunk = sizeof buf;
		r = RAND_bytes(buf, chunk);
		if (r <= 0)
			goto err;
		BIO_write(out, buf, chunk);
		num -= chunk;
		}
	BIO_flush(out);

	app_RAND_write_file(NULL, bio_err);
	ret = 0;
	
err:
	ERR_print_errors(bio_err);
	if (out)
		BIO_free_all(out);
160
	apps_shutdown();
161 162
	EXIT(ret);
	}