Standardize apps use of -rand, etc.

Standardized the -rand flag and added a new one:
    -rand file...
            Always reads the specified files
    -writerand file
            Always writes to the file on exit

For apps that use a config file, the RANDFILE config parameter reads
the file at startup (to seed the RNG) and write to it on exit if
the -writerand flag isn't used.

Ensured that every app that took -rand also took -writerand, and
made sure all of that agreed with all the documentation.

Fix error reporting in write_file and -rand

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/3862)
master
Rich Salz 6 years ago
parent e90fc053c3
commit 3ee1eac27a

@ -10,108 +10,82 @@
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/rand.h>
#include <openssl/conf.h>
static int seeded = 0;
static int egdsocket = 0;
static const char *save_rand_file;
int app_RAND_load_file(const char *file, int dont_warn)
void app_RAND_load_conf(CONF *c, const char *section)
{
int consider_randfile = (file == NULL);
char buffer[200];
const char *randfile = NCONF_get_string(c, section, "RANDFILE");
if (file == NULL) {
file = RAND_file_name(buffer, sizeof buffer);
#ifndef OPENSSL_NO_EGD
} else if (RAND_egd(file) > 0) {
/*
* we try if the given filename is an EGD socket. if it is, we don't
* write anything back to the file.
*/
egdsocket = 1;
return 1;
#endif
if (randfile == NULL) {
ERR_clear_error();
return;
}
if (file == NULL || !RAND_load_file(file, -1)) {
if (RAND_status() == 0) {
if (!dont_warn) {
BIO_printf(bio_err, "unable to load 'random state'\n");
BIO_printf(bio_err,
"This means that the random number generator has not been seeded\n");
BIO_printf(bio_err, "with much random data.\n");
if (consider_randfile) { /* explanation does not apply when a
* file is explicitly named */
BIO_printf(bio_err,
"Consider setting the RANDFILE environment variable to point at a file that\n");
BIO_printf(bio_err,
"'random' data can be kept in (the file will be overwritten).\n");
}
}
return 0;
}
if (RAND_load_file(randfile, -1) < 0) {
BIO_printf(bio_err, "Can't load %s into RNG\n", randfile);
ERR_print_errors(bio_err);
return;
}
seeded = 1;
return 1;
if (save_rand_file == NULL)
save_rand_file = randfile;
}
long app_RAND_load_files(char *name)
static int loadfiles(char *name)
{
char *p, *n;
int last;
long tot = 0;
#ifndef OPENSSL_NO_EGD
int egd;
#endif
int last, ret = 1;
for (;;) {
for ( ; ; ) {
last = 0;
for (p = name; ((*p != '\0') && (*p != LIST_SEPARATOR_CHAR)); p++) ;
for (p = name; *p != '\0' && *p != LIST_SEPARATOR_CHAR; p++)
continue;
if (*p == '\0')
last = 1;
*p = '\0';
if (RAND_load_file(name, -1) < 0) {
BIO_printf(bio_err, "Can't load %s into RNG\n", name);
ERR_print_errors(bio_err);
ret = 0;
}
n = name;
name = p + 1;
if (*n == '\0')
break;
#ifndef OPENSSL_NO_EGD
egd = RAND_egd(n);
if (egd > 0)
tot += egd;
else
#endif
tot += RAND_load_file(n, -1);
if (last)
break;
name = p + 1;
if (*name == '\0')
break;
}
if (tot > 512)
app_RAND_allow_write_file();
return (tot);
return ret;
}
int app_RAND_write_file(const char *file)
void app_RAND_write(void)
{
char buffer[200];
if (egdsocket || !seeded) {
/*
* If we didn't manage to read the seed file, don't write a
* file out -- it would suppress a crucial warning the next
* time we want to use it.
*/
return 0;
if (save_rand_file == NULL)
return;
if (RAND_write_file(save_rand_file) == -1) {
BIO_printf(bio_err, "Cannot write random bytes:\n");
ERR_print_errors(bio_err);
}
if (file == NULL)
file = RAND_file_name(buffer, sizeof buffer);
if (file == NULL || !RAND_write_file(file)) {
BIO_printf(bio_err, "unable to write 'random state'\n");
return 0;
}
return 1;
}
void app_RAND_allow_write_file(void)
/*
* See comments in opt_verify for explanation of this.
*/
enum r_range { OPT_R_ENUM };
int opt_rand(int opt)
{
seeded = 1;
switch ((enum r_range)opt) {
case OPT_R__FIRST:
case OPT_R__LAST:
break;
case OPT_R_RAND:
return loadfiles(opt_arg());
break;
case OPT_R_WRITERAND:
save_rand_file = opt_arg();
break;
}
return 1;
}

@ -40,16 +40,8 @@
*/
#define _UC(c) ((unsigned char)(c))
int app_RAND_load_file(const char *file, int dont_warn);
int app_RAND_write_file(const char *file);
/*
* When `file' is NULL, use defaults. `bio_e' is for error messages.
*/
void app_RAND_allow_write_file(void);
long app_RAND_load_files(char *file); /* `file' is a list of files to read,
* separated by LIST_SEPARATOR_CHAR
* (see e_os.h). The string is
* destroyed! */
void app_RAND_load_conf(CONF *c, const char *section);
void app_RAND_write(void);
extern char *default_config_file;
extern BIO *bio_in;
@ -177,7 +169,7 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
case OPT_V_ALLOW_PROXY_CERTS
/*
* Common "extended"? options.
* Common "extended validation" options.
*/
# define OPT_X_ENUM \
OPT_X__FIRST=1000, \
@ -299,6 +291,20 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
(o == OPT_S_NOSSL3 || o == OPT_S_NOTLS1 || o == OPT_S_NOTLS1_1 \
|| o == OPT_S_NOTLS1_2 || o == OPT_S_NOTLS1_3)
/*
* Random state options.
*/
# define OPT_R_ENUM \
OPT_R__FIRST=1500, OPT_R_RAND, OPT_R_WRITERAND, OPT_R__LAST
# define OPT_R_OPTIONS \
{"rand", OPT_R_RAND, 's', "Load the file(s) into the random number generator"}, \
{"writerand", OPT_R_WRITERAND, '>', "Write random data to the specified file"}
# define OPT_R_CASES \
OPT_R__FIRST: case OPT_R__LAST: break; \
case OPT_R_RAND: case OPT_R_WRITERAND
/*
* Option parsing.
*/
@ -373,6 +379,7 @@ char *opt_reset(void);
char **opt_rest(void);
int opt_num_rest(void);
int opt_verify(int i, X509_VERIFY_PARAM *vpm);
int opt_rand(int i);
void opt_help(const OPTIONS * list);
int opt_format_error(const char *s, unsigned long flags);

@ -153,6 +153,7 @@ typedef enum OPTION_choice {
OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
OPT_R_ENUM,
/* Do not change the order here; see related case statements below */
OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
} OPTION_CHOICE;
@ -217,6 +218,7 @@ const OPTIONS ca_options[] = {
"sets compromise time to val and the revocation reason to keyCompromise"},
{"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's',
"sets compromise time to val and the revocation reason to CACompromise"},
OPT_R_OPTIONS,
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
@ -247,7 +249,7 @@ int ca_main(int argc, char **argv)
char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL;
const char *serialfile = NULL, *subj = NULL;
char *prog, *startdate = NULL, *enddate = NULL;
char *dbfile = NULL, *f, *randfile = NULL;
char *dbfile = NULL, *f;
char new_cert[CERT_MAX + 1];
char tmp[10 + 1] = "\0";
char *const *pp;
@ -332,6 +334,10 @@ opthelp:
case OPT_PASSIN:
passinarg = opt_arg();
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_KEY:
key = opt_arg();
break;
@ -465,10 +471,7 @@ end_of_options:
}
}
randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
if (randfile == NULL)
ERR_clear_error();
app_RAND_load_file(randfile, 0);
app_RAND_load_conf(conf, BASE_SECTION);
f = NCONF_get_string(conf, section, STRING_MASK);
if (f == NULL)
@ -1220,7 +1223,6 @@ end_of_options:
if (ret)
ERR_print_errors(bio_err);
app_RAND_write_file(randfile);
if (free_key)
OPENSSL_free(key);
BN_free(serial);

@ -76,10 +76,11 @@ typedef enum OPTION_choice {
OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE,
OPT_CAPATH, OPT_NOCAPATH, OPT_NOCAFILE,OPT_CONTENT, OPT_PRINT,
OPT_SECRETKEY, OPT_SECRETKEYID, OPT_PWRI_PASSWORD, OPT_ECONTENT_TYPE,
OPT_RAND, OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP,
OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP,
OPT_CERTSOUT, OPT_MD, OPT_INKEY, OPT_KEYFORM, OPT_KEYOPT, OPT_RR_FROM,
OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP,
OPT_3DES_WRAP, OPT_ENGINE,
OPT_R_ENUM,
OPT_V_ENUM,
OPT_CIPHER
} OPTION_CHOICE;
@ -152,8 +153,6 @@ const OPTIONS cms_options[] = {
{"secretkeyid", OPT_SECRETKEYID, 's'},
{"pwri_password", OPT_PWRI_PASSWORD, 's'},
{"econtent_type", OPT_ECONTENT_TYPE, 's'},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"to", OPT_TO, 's', "To address"},
{"from", OPT_FROM, 's', "From address"},
@ -169,6 +168,7 @@ const OPTIONS cms_options[] = {
{"receipt_request_from", OPT_RR_FROM, 's'},
{"receipt_request_to", OPT_RR_TO, 's'},
{"", OPT_CIPHER, '-', "Any supported cipher"},
OPT_R_OPTIONS,
OPT_V_OPTIONS,
{"aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key"},
{"aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key"},
@ -202,16 +202,13 @@ int cms_main(int argc, char **argv)
const char *CAfile = NULL, *CApath = NULL;
char *certsoutfile = NULL;
int noCAfile = 0, noCApath = 0;
char *infile = NULL, *outfile = NULL, *rctfile = NULL, *inrand = NULL;
char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile =
NULL;
char *infile = NULL, *outfile = NULL, *rctfile = NULL;
char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = NULL;
char *to = NULL, *from = NULL, *subject = NULL, *prog;
cms_key_param *key_first = NULL, *key_param = NULL;
int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched =
0;
int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched = 0;
int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
int need_rand = 0, operation = 0, ret = 1, rr_print = 0, rr_allorfirst =
-1;
int operation = 0, ret = 1, rr_print = 0, rr_allorfirst = -1;
int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
size_t secret_keylen = 0, secret_keyidlen = 0;
unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
@ -449,10 +446,6 @@ int cms_main(int argc, char **argv)
goto opthelp;
}
break;
case OPT_RAND:
inrand = opt_arg();
need_rand = 1;
break;
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
@ -568,6 +561,10 @@ int cms_main(int argc, char **argv)
goto end;
vpmtouched++;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_3DES_WRAP:
# ifndef OPENSSL_NO_DES
wrap_cipher = EVP_des_ede3_wrap();
@ -624,7 +621,6 @@ int cms_main(int argc, char **argv)
}
signerfile = NULL;
keyfile = NULL;
need_rand = 1;
} else if (operation == SMIME_DECRYPT) {
if (recipfile == NULL && keyfile == NULL
&& secret_key == NULL && pwri_pass == NULL) {
@ -638,7 +634,6 @@ int cms_main(int argc, char **argv)
BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
goto opthelp;
}
need_rand = 1;
} else if (!operation) {
goto opthelp;
}
@ -648,13 +643,6 @@ int cms_main(int argc, char **argv)
goto end;
}
if (need_rand) {
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
}
ret = 2;
if (!(operation & SMIME_SIGNERS))
@ -1083,8 +1071,6 @@ int cms_main(int argc, char **argv)
end:
if (ret)
ERR_print_errors(bio_err);
if (need_rand)
app_RAND_write_file(NULL);
sk_X509_pop_free(encerts, X509_free);
sk_X509_pop_free(other, X509_free);
X509_VERIFY_PARAM_free(vpm);

@ -29,11 +29,12 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_C, OPT_R, OPT_RAND, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY,
OPT_C, OPT_R, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY,
OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL,
OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT,
OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT,
OPT_DIGEST
OPT_DIGEST,
OPT_R_ENUM,
} OPTION_CHOICE;
const OPTIONS dgst_options[] = {
@ -43,8 +44,6 @@ const OPTIONS dgst_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"c", OPT_C, '-', "Print the digest with separating colons"},
{"r", OPT_R, '-', "Print the digest in coreutils format"},
{"rand", OPT_RAND, 's',
"Use file(s) containing random data to seed RNG or an EGD sock"},
{"out", OPT_OUT, '>', "Output to filename rather than stdout"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"sign", OPT_SIGN, 's', "Sign digest using private key"},
@ -65,6 +64,7 @@ const OPTIONS dgst_options[] = {
{"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
{"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"},
{"", OPT_DIGEST, '-', "Any supported digest"},
OPT_R_OPTIONS,
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
{"engine_impl", OPT_ENGINE_IMPL, '-',
@ -84,7 +84,7 @@ int dgst_main(int argc, char **argv)
char *passinarg = NULL, *passin = NULL;
const EVP_MD *md = NULL, *m;
const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
const char *sigfile = NULL, *randfile = NULL;
const char *sigfile = NULL;
OPTION_CHOICE o;
int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0;
@ -113,8 +113,9 @@ int dgst_main(int argc, char **argv)
case OPT_R:
separator = 2;
break;
case OPT_RAND:
randfile = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_OUT:
outfile = opt_arg();
@ -223,9 +224,6 @@ int dgst_main(int argc, char **argv)
out_bin = 0;
}
if (randfile != NULL)
app_RAND_load_file(randfile, 0);
out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
if (out == NULL)
goto end;

@ -36,7 +36,8 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT,
OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT,
OPT_RAND, OPT_DSAPARAM, OPT_C, OPT_2, OPT_5
OPT_DSAPARAM, OPT_C, OPT_2, OPT_5,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS dhparam_options[] = {
@ -50,8 +51,7 @@ const OPTIONS dhparam_options[] = {
{"check", OPT_CHECK, '-', "Check the DH parameters"},
{"text", OPT_TEXT, '-', "Print a text form of the DH parameters"},
{"noout", OPT_NOOUT, '-', "Don't output any DH parameters"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"C", OPT_C, '-', "Print C code"},
{"2", OPT_2, '-', "Generate parameters using 2 as the generator value"},
{"5", OPT_5, '-', "Generate parameters using 5 as the generator value"},
@ -69,7 +69,7 @@ int dhparam_main(int argc, char **argv)
{
BIO *in = NULL, *out = NULL;
DH *dh = NULL;
char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
char *infile = NULL, *outfile = NULL, *prog;
ENGINE *e = NULL;
#ifndef OPENSSL_NO_DSA
int dsaparam = 0;
@ -130,8 +130,9 @@ int dhparam_main(int argc, char **argv)
case OPT_NOOUT:
noout = 1;
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
}
}
@ -165,13 +166,6 @@ int dhparam_main(int argc, char **argv)
}
BN_GENCB_set(cb, dh_cb, bio_err);
if (!app_RAND_load_file(NULL, 1) && inrand == NULL) {
BIO_printf(bio_err,
"warning, not much extra random data, consider using the -rand option\n");
}
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
# ifndef OPENSSL_NO_DSA
if (dsaparam) {
@ -211,7 +205,6 @@ int dhparam_main(int argc, char **argv)
}
BN_GENCB_free(cb);
app_RAND_write_file(NULL);
} else {
in = bio_open_default(infile, 'r', informat);

@ -29,7 +29,7 @@ static int dsa_cb(int p, int n, BN_GENCB *cb);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C,
OPT_NOOUT, OPT_GENKEY, OPT_RAND, OPT_ENGINE
OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS dsaparam_options[] = {
@ -42,7 +42,7 @@ const OPTIONS dsaparam_options[] = {
{"C", OPT_C, '-', "Output C code"},
{"noout", OPT_NOOUT, '-', "No output"},
{"genkey", OPT_GENKEY, '-', "Generate a DSA key"},
{"rand", OPT_RAND, 's', "Files to use for random number input"},
OPT_R_OPTIONS,
# ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
# endif
@ -55,10 +55,10 @@ int dsaparam_main(int argc, char **argv)
DSA *dsa = NULL;
BIO *in = NULL, *out = NULL;
BN_GENCB *cb = NULL;
int numbits = -1, num = 0, genkey = 0, need_rand = 0;
int numbits = -1, num = 0, genkey = 0;
int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0;
int ret = 1, i, text = 0, private = 0;
char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
char *infile = NULL, *outfile = NULL, *prog;
OPTION_CHOICE o;
prog = opt_init(argc, argv, dsaparam_options);
@ -97,11 +97,11 @@ int dsaparam_main(int argc, char **argv)
C = 1;
break;
case OPT_GENKEY:
genkey = need_rand = 1;
genkey = 1;
break;
case OPT_RAND:
inrand = opt_arg();
need_rand = 1;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_NOOUT:
noout = 1;
@ -116,7 +116,6 @@ int dsaparam_main(int argc, char **argv)
goto end;
/* generate a key */
numbits = num;
need_rand = 1;
}
private = genkey ? 1 : 0;
@ -127,13 +126,6 @@ int dsaparam_main(int argc, char **argv)
if (out == NULL)
goto end;
if (need_rand) {
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
}
if (numbits > 0) {
cb = BN_GENCB_new();
if (cb == NULL) {
@ -141,7 +133,6 @@ int dsaparam_main(int argc, char **argv)
goto end;
}
BN_GENCB_set(cb, dsa_cb, bio_err);
assert(need_rand);
dsa = DSA_new();
if (dsa == NULL) {
BIO_printf(bio_err, "Error allocating DSA object\n");
@ -217,7 +208,6 @@ int dsaparam_main(int argc, char **argv)
if (genkey) {
DSA *dsakey;
assert(need_rand);
if ((dsakey = DSAparams_dup(dsa)) == NULL)
goto end;
if (!DSA_generate_key(dsakey)) {
@ -233,8 +223,6 @@ int dsaparam_main(int argc, char **argv)
NULL);
DSA_free(dsakey);
}
if (need_rand)
app_RAND_write_file(NULL);
ret = 0;
end:
BN_GENCB_free(cb);

@ -29,7 +29,8 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C,
OPT_CHECK, OPT_LIST_CURVES, OPT_NO_SEED, OPT_NOOUT, OPT_NAME,
OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_RAND, OPT_ENGINE
OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_ENGINE,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS ecparam_options[] = {
@ -52,7 +53,7 @@ const OPTIONS ecparam_options[] = {
{"param_enc", OPT_PARAM_ENC, 's',
"Specifies the way the ec parameters are encoded"},
{"genkey", OPT_GENKEY, '-', "Generate ec key"},
{"rand", OPT_RAND, 's', "Files to use for random number input"},
OPT_R_OPTIONS,
# ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
# endif
@ -80,7 +81,7 @@ int ecparam_main(int argc, char **argv)
BIO *in = NULL, *out = NULL;
EC_GROUP *group = NULL;
point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
char *curve_name = NULL, *inrand = NULL;
char *curve_name = NULL;
char *infile = NULL, *outfile = NULL, *prog;
unsigned char *buffer = NULL;
OPTION_CHOICE o;
@ -88,7 +89,7 @@ int ecparam_main(int argc, char **argv)
int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0;
int ret = 1, private = 0;
int list_curves = 0, no_seed = 0, check = 0, new_form = 0;
int text = 0, i, need_rand = 0, genkey = 0;
int text = 0, i, genkey = 0;
prog = opt_init(argc, argv, ecparam_options);
while ((o = opt_next()) != OPT_EOF) {
@ -149,11 +150,11 @@ int ecparam_main(int argc, char **argv)
new_asn1_flag = 1;
break;
case OPT_GENKEY:
genkey = need_rand = 1;
genkey = 1;
break;
case OPT_RAND:
inrand = opt_arg();
need_rand = 1;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
@ -395,21 +396,12 @@ int ecparam_main(int argc, char **argv)
}
}
if (need_rand) {
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
}
if (genkey) {
EC_KEY *eckey = EC_KEY_new();
if (eckey == NULL)
goto end;
assert(need_rand);
if (EC_KEY_set_group(eckey, group) == 0) {
BIO_printf(bio_err, "unable to set group when generating key\n");
EC_KEY_free(eckey);
@ -432,9 +424,6 @@ int ecparam_main(int argc, char **argv)
EC_KEY_free(eckey);
}
if (need_rand)
app_RAND_write_file(NULL);
ret = 0;
end:
BN_free(ec_p);

@ -43,7 +43,8 @@ typedef enum OPTION_choice {
OPT_E, OPT_IN, OPT_OUT, OPT_PASS, OPT_ENGINE, OPT_D, OPT_P, OPT_V,
OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A,
OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE,
OPT_UPPER_S, OPT_IV, OPT_MD, OPT_CIPHER
OPT_UPPER_S, OPT_IV, OPT_MD, OPT_CIPHER,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS enc_options[] = {
@ -74,6 +75,7 @@ const OPTIONS enc_options[] = {
{"md", OPT_MD, 's', "Use specified digest to create a key from the passphrase"},
{"none", OPT_NONE, '-', "Don't encrypt"},
{"", OPT_CIPHER, '-', "Any supported cipher"},
OPT_R_OPTIONS,
#ifdef ZLIB
{"z", OPT_Z, '-', "Use zlib as the 'encryption'"},
#endif
@ -255,6 +257,10 @@ int enc_main(int argc, char **argv)
case OPT_NONE:
cipher = NULL;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
}
}

@ -26,7 +26,8 @@ NON_EMPTY_TRANSLATION_UNIT
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_RAND, OPT_CIPHER
OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS gendsa_options[] = {
@ -35,8 +36,7 @@ const OPTIONS gendsa_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"out", OPT_OUT, '>', "Output the key to the specified file"},
{"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
# ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
@ -50,7 +50,7 @@ int gendsa_main(int argc, char **argv)
BIO *out = NULL, *in = NULL;
DSA *dsa = NULL;
const EVP_CIPHER *enc = NULL;
char *inrand = NULL, *dsaparams = NULL;
char *dsaparams = NULL;
char *outfile = NULL, *passoutarg = NULL, *passout = NULL, *prog;
OPTION_CHOICE o;
int ret = 1, private = 0;
@ -77,8 +77,9 @@ int gendsa_main(int argc, char **argv)
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_CIPHER:
if (!opt_cipher(opt_unknown(), &enc))
@ -114,21 +115,11 @@ int gendsa_main(int argc, char **argv)
if (out == NULL)
goto end2;
if (!app_RAND_load_file(NULL, 1) && inrand == NULL) {
BIO_printf(bio_err,
"warning, not much extra random data, consider using the -rand option\n");
}
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
DSA_get0_pqg(dsa, &p, NULL, NULL);
BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(p));
if (!DSA_generate_key(dsa))
goto end;
app_RAND_write_file(NULL);
assert(private);
if (!PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout))
goto end;

@ -33,7 +33,8 @@ static int genrsa_cb(int p, int n, BN_GENCB *cb);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_3, OPT_F4, OPT_ENGINE,
OPT_OUT, OPT_RAND, OPT_PASSOUT, OPT_CIPHER
OPT_OUT, OPT_PASSOUT, OPT_CIPHER,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS genrsa_options[] = {
@ -42,8 +43,7 @@ const OPTIONS genrsa_options[] = {
{"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
{"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
{"out", OPT_OUT, 's', "Output the key to specified file"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
{"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
# ifndef OPENSSL_NO_ENGINE
@ -65,7 +65,7 @@ int genrsa_main(int argc, char **argv)
int ret = 1, num = DEFBITS, private = 0;
unsigned long f4 = RSA_F4;
char *outfile = NULL, *passoutarg = NULL, *passout = NULL;
char *inrand = NULL, *prog, *hexe, *dece;
char *prog, *hexe, *dece;
OPTION_CHOICE o;
if (bn == NULL || cb == NULL)
@ -96,8 +96,9 @@ int genrsa_main(int argc, char **argv)
case OPT_ENGINE:
eng = setup_engine(opt_arg(), 0);
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_PASSOUT:
passoutarg = opt_arg();
@ -124,15 +125,6 @@ int genrsa_main(int argc, char **argv)
if (out == NULL)
goto end;
if (!app_RAND_load_file(NULL, 1) && inrand == NULL
&& !RAND_status()) {
BIO_printf(bio_err,
"warning, not much extra random data, consider using the -rand option\n");
}
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n",
num);
rsa = eng ? RSA_new_method(eng) : RSA_new();
@ -142,8 +134,6 @@ int genrsa_main(int argc, char **argv)
if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, cb))
goto end;
app_RAND_write_file(NULL);
RSA_get0_key(rsa, NULL, &e, NULL);
hexe = BN_bn2hex(e);
dece = BN_bn2dec(e);

@ -240,6 +240,7 @@ int main(int argc, char *argv[])
OPENSSL_free(default_config_file);
lh_FUNCTION_free(prog);
OPENSSL_free(arg.argv);
app_RAND_write();
BIO_free(bio_in);
BIO_free_all(bio_out);

@ -65,7 +65,8 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_IN,
OPT_NOVERIFY, OPT_QUIET, OPT_TABLE, OPT_REVERSE, OPT_APR1,
OPT_1, OPT_5, OPT_6, OPT_CRYPT, OPT_AIXMD5, OPT_SALT, OPT_STDIN
OPT_1, OPT_5, OPT_6, OPT_CRYPT, OPT_AIXMD5, OPT_SALT, OPT_STDIN,
OPT_R_ENUM,
} OPTION_CHOICE;
const OPTIONS passwd_options[] = {
@ -90,6 +91,7 @@ const OPTIONS passwd_options[] = {
# ifndef OPENSSL_NO_DES
{"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"},
# endif
OPT_R_OPTIONS,
{NULL}
};
@ -182,6 +184,10 @@ int passwd_main(int argc, char **argv)
in_stdin = 1;
pw_source_defined = 1;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
}
}
argc = opt_num_rest();

@ -53,9 +53,10 @@ typedef enum OPTION_choice {
OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER,
OPT_DESCERT, OPT_EXPORT, OPT_NOITER, OPT_MACITER, OPT_NOMACITER,
OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE,
OPT_RAND, OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME,
OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME,
OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE
OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS pkcs12_options[] = {
@ -91,8 +92,7 @@ const OPTIONS pkcs12_options[] = {
{"macalg", OPT_MACALG, 's',
"Digest algorithm used in MAC (default SHA1)"},
{"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"inkey", OPT_INKEY, 's', "Private key if not infile"},
{"certfile", OPT_CERTFILE, '<', "Load certs from file"},
{"name", OPT_NAME, 's', "Use name as friendly name"},
@ -133,7 +133,7 @@ int pkcs12_main(int argc, char **argv)
int ret = 1, macver = 1, add_lmk = 0, private = 0;
int noprompt = 0;
char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL;
char *passin = NULL, *passout = NULL, *macalg = NULL;
char *cpass = NULL, *mpass = NULL, *badpass = NULL;
const char *CApath = NULL, *CAfile = NULL, *prog;
int noCApath = 0, noCAfile = 0;
@ -225,8 +225,9 @@ int pkcs12_main(int argc, char **argv)
if (!set_pbe(&key_pbe, opt_arg()))
goto opthelp;
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_INKEY:
keyname = opt_arg();
@ -314,13 +315,6 @@ int pkcs12_main(int argc, char **argv)
mpass = macpass;
}
if (export_cert || inrand != NULL) {
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
}
if (twopass) {
/* To avoid bit rot */
if (1) {
@ -576,8 +570,6 @@ int pkcs12_main(int argc, char **argv)
ret = 0;
end:
PKCS12_free(p12);
if (export_cert || inrand)
app_RAND_write_file(NULL);
release_engine(e);
BIO_free(in);
BIO_free_all(out);

@ -24,7 +24,8 @@ typedef enum OPTION_choice {
OPT_SCRYPT, OPT_SCRYPT_N, OPT_SCRYPT_R, OPT_SCRYPT_P,
#endif
OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT,
OPT_TRADITIONAL
OPT_TRADITIONAL,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS pkcs8_options[] = {
@ -36,6 +37,7 @@ const OPTIONS pkcs8_options[] = {
{"topk8", OPT_TOPK8, '-', "Output PKCS8 file"},
{"noiter", OPT_NOITER, '-', "Use 1 as iteration count"},
{"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"},
OPT_R_OPTIONS,
{"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"},
{"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"},
{"v2prf", OPT_V2PRF, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"},
@ -112,6 +114,10 @@ int pkcs8_main(int argc, char **argv)
case OPT_NOCRYPT:
nocrypt = 1;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_TRADITIONAL:
traditional = 1;
break;
@ -248,7 +254,6 @@ int pkcs8_main(int argc, char **argv)
BIO_printf(bio_err, "Password required\n");
goto end;
}
app_RAND_load_file(NULL, 0);
p8 = PKCS8_set0_pbe(p8pass, strlen(p8pass), p8inf, pbe);
if (p8 == NULL) {
X509_ALGOR_free(pbe);
@ -256,7 +261,6 @@ int pkcs8_main(int argc, char **argv)
ERR_print_errors(bio_err);
goto end;
}
app_RAND_write_file(NULL);
assert(private);
if (outformat == FORMAT_PEM)
PEM_write_bio_PKCS8(out, p8);

@ -36,7 +36,8 @@ typedef enum OPTION_choice {
OPT_PUBIN, OPT_CERTIN, OPT_ASN1PARSE, OPT_HEXDUMP, OPT_SIGN,
OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN,
OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN
OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS pkeyutl_options[] = {
@ -64,6 +65,7 @@ const OPTIONS pkeyutl_options[] = {
{"peerform", OPT_PEERFORM, 'E', "Peer key format - default PEM"},
{"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"},
{"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"},
OPT_R_OPTIONS,
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
{"engine_impl", OPT_ENGINE_IMPL, '-',
@ -134,6 +136,10 @@ int pkeyutl_main(int argc, char **argv)
if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyform))
goto opthelp;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
@ -238,9 +244,6 @@ int pkeyutl_main(int argc, char **argv)
goto end;
}
/* FIXME: seed PRNG only if needed */
app_RAND_load_file(NULL, 0);
if (pkey_op != EVP_PKEY_OP_DERIVE) {
in = bio_open_default(infile, 'r', FORMAT_BINARY);
if (in == NULL)

@ -19,7 +19,8 @@
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_OUT, OPT_ENGINE, OPT_RAND, OPT_BASE64, OPT_HEX
OPT_OUT, OPT_ENGINE, OPT_BASE64, OPT_HEX,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS rand_options[] = {
@ -27,8 +28,7 @@ const OPTIONS rand_options[] = {
{OPT_HELP_STR, 1, '-', "Valid options are:\n"},
{"help", OPT_HELP, '-', "Display this summary"},
{"out", OPT_OUT, '>', "Output file"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"base64", OPT_BASE64, '-', "Base64 encode output"},
{"hex", OPT_HEX, '-', "Hex encode output"},
#ifndef OPENSSL_NO_ENGINE
@ -41,7 +41,7 @@ int rand_main(int argc, char **argv)
{
ENGINE *e = NULL;
BIO *out = NULL;
char *inrand = NULL, *outfile = NULL, *prog;
char *outfile = NULL, *prog;
OPTION_CHOICE o;
int format = FORMAT_BINARY, i, num = -1, r, ret = 1;
@ -63,8 +63,9 @@ int rand_main(int argc, char **argv)
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_BASE64:
format = FORMAT_BASE64;
@ -80,11 +81,6 @@ int rand_main(int argc, char **argv)
if (argc != 1 || !opt_int(argv[0], &num) || num < 0)
goto opthelp;
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
out = bio_open_default(outfile, 'w', format);
if (out == NULL)
goto end;
@ -118,7 +114,7 @@ int rand_main(int argc, char **argv)
}
if (format == FORMAT_TEXT)
BIO_puts(out, "\n");
if (BIO_flush(out) <= 0 || !app_RAND_write_file(NULL))
if (BIO_flush(out) <= 0)
goto end;
ret = 0;

@ -76,12 +76,13 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_KEYGEN_ENGINE, OPT_KEY,
OPT_PUBKEY, OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT,
OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_RAND, OPT_NEWKEY,
OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_NEWKEY,
OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS,
OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509,
OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_EXTENSIONS,
OPT_REQEXTS, OPT_PRECERT, OPT_MD
OPT_REQEXTS, OPT_PRECERT, OPT_MD,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS req_options[] = {
@ -98,8 +99,7 @@ const OPTIONS req_options[] = {
{"keyout", OPT_KEYOUT, '>', "File to send the key to"},
{"passin", OPT_PASSIN, 's', "Private key password source"},
{"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"newkey", OPT_NEWKEY, 's', "Specify as type:bits"},
{"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"},
{"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
@ -151,7 +151,7 @@ int req_main(int argc, char **argv)
const EVP_CIPHER *cipher = NULL;
const EVP_MD *md_alg = NULL, *digest = NULL;
char *extensions = NULL, *infile = NULL;
char *outfile = NULL, *keyfile = NULL, *inrand = NULL;
char *outfile = NULL, *keyfile = NULL;
char *keyalgstr = NULL, *p, *prog, *passargin = NULL, *passargout = NULL;
char *passin = NULL, *passout = NULL;
char *nofree_passin = NULL, *nofree_passout = NULL;
@ -234,8 +234,9 @@ int req_main(int argc, char **argv)
case OPT_PASSOUT:
passargout = opt_arg();
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_NEWKEY:
keyalg = opt_arg();
@ -454,20 +455,12 @@ int req_main(int argc, char **argv)
/* load_key() has already printed an appropriate message */