[331] | 1 | /*
|
---|
| 2 | * Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
|
---|
| 3 | *
|
---|
| 4 | * Licensed under the OpenSSL license (the "License"). You may not use
|
---|
| 5 | * this file except in compliance with the License. You can obtain a copy
|
---|
| 6 | * in the file LICENSE in the source distribution or at
|
---|
| 7 | * https://www.openssl.org/source/license.html
|
---|
| 8 | */
|
---|
| 9 |
|
---|
| 10 | #include "apps.h"
|
---|
| 11 |
|
---|
| 12 | #include <ctype.h>
|
---|
| 13 | #include <stdio.h>
|
---|
| 14 | #include <string.h>
|
---|
| 15 |
|
---|
| 16 | #include <openssl/bio.h>
|
---|
| 17 | #include <openssl/err.h>
|
---|
| 18 | #include <openssl/rand.h>
|
---|
| 19 |
|
---|
| 20 | typedef enum OPTION_choice {
|
---|
| 21 | OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
---|
| 22 | OPT_OUT, OPT_ENGINE, OPT_RAND, OPT_BASE64, OPT_HEX
|
---|
| 23 | } OPTION_CHOICE;
|
---|
| 24 |
|
---|
| 25 | OPTIONS rand_options[] = {
|
---|
| 26 | {OPT_HELP_STR, 1, '-', "Usage: %s [flags] num\n"},
|
---|
| 27 | {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
|
---|
| 28 | {"help", OPT_HELP, '-', "Display this summary"},
|
---|
| 29 | {"out", OPT_OUT, '>', "Output file"},
|
---|
| 30 | {"rand", OPT_RAND, 's',
|
---|
| 31 | "Load the file(s) into the random number generator"},
|
---|
| 32 | {"base64", OPT_BASE64, '-', "Base64 encode output"},
|
---|
| 33 | {"hex", OPT_HEX, '-', "Hex encode output"},
|
---|
| 34 | #ifndef OPENSSL_NO_ENGINE
|
---|
| 35 | {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
|
---|
| 36 | #endif
|
---|
| 37 | {NULL}
|
---|
| 38 | };
|
---|
| 39 |
|
---|
| 40 | int rand_main(int argc, char **argv)
|
---|
| 41 | {
|
---|
| 42 | ENGINE *e = NULL;
|
---|
| 43 | BIO *out = NULL;
|
---|
| 44 | char *inrand = NULL, *outfile = NULL, *prog;
|
---|
| 45 | OPTION_CHOICE o;
|
---|
| 46 | int format = FORMAT_BINARY, i, num = -1, r, ret = 1;
|
---|
| 47 |
|
---|
| 48 | prog = opt_init(argc, argv, rand_options);
|
---|
| 49 | while ((o = opt_next()) != OPT_EOF) {
|
---|
| 50 | switch (o) {
|
---|
| 51 | case OPT_EOF:
|
---|
| 52 | case OPT_ERR:
|
---|
| 53 | opthelp:
|
---|
| 54 | BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
|
---|
| 55 | goto end;
|
---|
| 56 | case OPT_HELP:
|
---|
| 57 | opt_help(rand_options);
|
---|
| 58 | ret = 0;
|
---|
| 59 | goto end;
|
---|
| 60 | case OPT_OUT:
|
---|
| 61 | outfile = opt_arg();
|
---|
| 62 | break;
|
---|
| 63 | case OPT_ENGINE:
|
---|
| 64 | e = setup_engine(opt_arg(), 0);
|
---|
| 65 | break;
|
---|
| 66 | case OPT_RAND:
|
---|
| 67 | inrand = opt_arg();
|
---|
| 68 | break;
|
---|
| 69 | case OPT_BASE64:
|
---|
| 70 | format = FORMAT_BASE64;
|
---|
| 71 | break;
|
---|
| 72 | case OPT_HEX:
|
---|
| 73 | format = FORMAT_TEXT;
|
---|
| 74 | break;
|
---|
| 75 | }
|
---|
| 76 | }
|
---|
| 77 | argc = opt_num_rest();
|
---|
| 78 | argv = opt_rest();
|
---|
| 79 |
|
---|
| 80 | if (argc != 1 || !opt_int(argv[0], &num) || num < 0)
|
---|
| 81 | goto opthelp;
|
---|
| 82 |
|
---|
| 83 | app_RAND_load_file(NULL, (inrand != NULL));
|
---|
| 84 | if (inrand != NULL)
|
---|
| 85 | BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
|
---|
| 86 | app_RAND_load_files(inrand));
|
---|
| 87 |
|
---|
| 88 | out = bio_open_default(outfile, 'w', format);
|
---|
| 89 | if (out == NULL)
|
---|
| 90 | goto end;
|
---|
| 91 |
|
---|
| 92 | if (format == FORMAT_BASE64) {
|
---|
| 93 | BIO *b64 = BIO_new(BIO_f_base64());
|
---|
| 94 | if (b64 == NULL)
|
---|
| 95 | goto end;
|
---|
| 96 | out = BIO_push(b64, out);
|
---|
| 97 | }
|
---|
| 98 |
|
---|
| 99 | while (num > 0) {
|
---|
| 100 | unsigned char buf[4096];
|
---|
| 101 | int chunk;
|
---|
| 102 |
|
---|
| 103 | chunk = num;
|
---|
| 104 | if (chunk > (int)sizeof(buf))
|
---|
| 105 | chunk = sizeof buf;
|
---|
| 106 | r = RAND_bytes(buf, chunk);
|
---|
| 107 | if (r <= 0)
|
---|
| 108 | goto end;
|
---|
| 109 | if (format != FORMAT_TEXT) {
|
---|
| 110 | if (BIO_write(out, buf, chunk) != chunk)
|
---|
| 111 | goto end;
|
---|
| 112 | } else {
|
---|
| 113 | for (i = 0; i < chunk; i++)
|
---|
| 114 | if (BIO_printf(out, "%02x", buf[i]) != 2)
|
---|
| 115 | goto end;
|
---|
| 116 | }
|
---|
| 117 | num -= chunk;
|
---|
| 118 | }
|
---|
| 119 | if (format == FORMAT_TEXT)
|
---|
| 120 | BIO_puts(out, "\n");
|
---|
| 121 | if (BIO_flush(out) <= 0 || !app_RAND_write_file(NULL))
|
---|
| 122 | goto end;
|
---|
| 123 |
|
---|
| 124 | ret = 0;
|
---|
| 125 |
|
---|
| 126 | end:
|
---|
| 127 | if (ret != 0)
|
---|
| 128 | ERR_print_errors(bio_err);
|
---|
| 129 | release_engine(e);
|
---|
| 130 | BIO_free_all(out);
|
---|
| 131 | return (ret);
|
---|
| 132 | }
|
---|