rand.c 3.4 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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
	if (engine != NULL)
		{
		if((e = ENGINE_by_id(engine)) == NULL)
			{
			BIO_printf(bio_err,"invalid engine \"%s\"\n",
				engine);
			goto err;
			}
		if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
			{
			BIO_printf(bio_err,"can't use that engine\n");
			goto err;
			}
		BIO_printf(bio_err,"engine \"%s\" set.\n", engine);
		/* Free our "structural" reference. */
		ENGINE_free(e);
		}

122
	app_RAND_load_file(NULL, bio_err, (inrand != NULL));
123 124 125 126 127 128 129 130 131 132
	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
133
		{
134
		r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
135
#ifdef OPENSSL_SYS_VMS
136 137 138 139 140 141
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
		}
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
	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);
	EXIT(ret);
	}