diff --git a/apps/info.c b/apps/info.c index a2c359e0f8..d67ed87df3 100644 --- a/apps/info.c +++ b/apps/info.c @@ -14,7 +14,7 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_CONFIGDIR, OPT_ENGINESDIR, OPT_MODULESDIR, OPT_DSOEXT, OPT_DIRNAMESEP, - OPT_LISTSEP + OPT_LISTSEP, OPT_SEEDS } OPTION_CHOICE; const OPTIONS info_options[] = { @@ -30,6 +30,7 @@ const OPTIONS info_options[] = { {"dsoext", OPT_DSOEXT, '-', "Configured extension for modules"}, {"dirnamesep", OPT_DIRNAMESEP, '-', "Directory-filename separator"}, {"listsep", OPT_LISTSEP, '-', "List separator character"}, + {"seeds", OPT_SEEDS, '-', "Seed sources"}, {NULL} }; @@ -74,6 +75,10 @@ opthelp: type = OPENSSL_INFO_LIST_SEPARATOR; dirty++; break; + case OPT_SEEDS: + type = OPENSSL_INFO_SEED_SOURCE; + dirty++; + break; } } if (opt_num_rest() != 0) { diff --git a/apps/version.c b/apps/version.c index 35bfb95c09..caa3e76ffe 100644 --- a/apps/version.c +++ b/apps/version.c @@ -157,40 +157,8 @@ opthelp: printf("%s\n", OpenSSL_version(OPENSSL_ENGINES_DIR)); if (moddir) printf("%s\n", OpenSSL_version(OPENSSL_MODULES_DIR)); - if (seed) { - printf("Seeding source:"); -#ifdef OPENSSL_RAND_SEED_RTDSC - printf(" rtdsc"); -#endif -#ifdef OPENSSL_RAND_SEED_RDCPU - printf(" rdrand ( rdseed rdrand )"); -#endif -#ifdef OPENSSL_RAND_SEED_LIBRANDOM - printf(" C-library-random"); -#endif -#ifdef OPENSSL_RAND_SEED_GETRANDOM - printf(" getrandom-syscall"); -#endif -#ifdef OPENSSL_RAND_SEED_DEVRANDOM - { - static const char *dev[] = { DEVRANDOM, NULL }; - printlist(" random-device", dev); - } -#endif -#ifdef OPENSSL_RAND_SEED_EGD - { - static const char *dev[] = { DEVRANDOM_EGD, NULL }; - printlist(" EGD", dev); - } -#endif -#ifdef OPENSSL_RAND_SEED_NONE - printf(" none"); -#endif -#ifdef OPENSSL_RAND_SEED_OS - printf(" os-specific"); -#endif - printf("\n"); - } + if (seed) + printf("Seeding source: %s\n", OPENSSL_info(OPENSSL_INFO_SEED_SOURCE)); ret = 0; end: return ret; diff --git a/crypto/info.c b/crypto/info.c index 5a929ddd03..c5eb1fcba9 100644 --- a/crypto/info.c +++ b/crypto/info.c @@ -11,9 +11,78 @@ #include #include "internal/dso_conf.h" #include "e_os.h" +#include "buildinf.h" +#include "internal/thread_once.h" + +static char *seed_sources = NULL; +static CRYPTO_ONCE init_info = CRYPTO_ONCE_STATIC_INIT; + +DEFINE_RUN_ONCE_STATIC(init_info_strings) +{ + { + static char seeds[512] = ""; + +#define add_seeds_string(str) \ + do { \ + if (seeds[0] != '\0') \ + OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \ + OPENSSL_strlcat(seeds, str, sizeof(seeds)); \ + } while (0) +#define add_seeds_stringlist(label, strlist) \ + do { \ + add_seeds_string(label "("); \ + { \ + const char *dev[] = strlist; \ + int first = 1; \ + \ + for (; *dev != NULL; dev++) { \ + if (!first) \ + OPENSSL_strlcat(seeds, " ", sizeof(seeds)); \ + first = 0; \ + OPENSSL_strlcat(seeds, *dev, sizeof(seeds)); \ + } \ + } \ + OPENSSL_strlcat(seeds, ")", sizeof(seeds)); \ + } while (0) + +#ifdef OPENSSL_RAND_SEED_NONE + add_seeds_string("none"); +#endif +#ifdef OPENSSL_RAND_SEED_RTDSC + add_seeds_string("stdsc"); +#endif +#ifdef OPENSSL_RAND_SEED_RDCPU + add_seeds_string("rdrand ( rdseed rdrand )"); +#endif +#ifdef OPENSSL_RAND_SEED_LIBRANDOM + add_seeds_string("C-library-random"); +#endif +#ifdef OPENSSL_RAND_SEED_GETRANDOM + add_seeds_string("getrandom-syscall"); +#endif +#ifdef OPENSSL_RAND_SEED_DEVRANDOM + add_seeds_stringlist("random-device", { DEVRANDOM, NULL }); +#endif +#ifdef OPENSSL_RAND_SEED_EGD + add_seeds_stringlist("EGD", { DEVRANDOM_EGD, NULL }); +#endif +#ifdef OPENSSL_RAND_SEED_OS + add_seeds_string("os-specific"); +#endif + seed_sources = seeds; + } + return 1; +} const char *OPENSSL_info(int t) { + /* + * We don't care about the result. Worst case scenario, the strings + * won't be initialised, i.e. remain NULL, which means that the info + * isn't available anyway... + */ + (void)RUN_ONCE(&init_info, init_info_strings); + switch (t) { case OPENSSL_INFO_CONFIG_DIR: return OPENSSLDIR; @@ -36,6 +105,8 @@ const char *OPENSSL_info(int t) static const char list_sep[] = { LIST_SEPARATOR_CHAR, '\0' }; return list_sep; } + case OPENSSL_INFO_SEED_SOURCE: + return seed_sources; default: break; } diff --git a/doc/man1/openssl-info.pod b/doc/man1/openssl-info.pod index 42b1a9ea5b..2b9383fc9d 100644 --- a/doc/man1/openssl-info.pod +++ b/doc/man1/openssl-info.pod @@ -14,6 +14,7 @@ B [B<-dsoext>] [B<-dirfilesep>] [B<-listsep]> +[B<-seeds]> =head1 DESCRIPTION @@ -62,6 +63,10 @@ Outputs the OpenSSL list separator character. This is typically used to construct C<$PATH> (C<%PATH%> on Windows) style lists. +=item B<-seeds> + +Outputs the randomness seed sources. + =back =head1 HISTORY diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index f8789176d5..e16e3e4743 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -181,6 +181,7 @@ const char *OPENSSL_info(int type); # define OPENSSL_INFO_DSO_EXTENSION 1004 # define OPENSSL_INFO_DIR_FILENAME_SEPARATOR 1005 # define OPENSSL_INFO_LIST_SEPARATOR 1006 +# define OPENSSL_INFO_SEED_SOURCE 1007 int OPENSSL_issetugid(void);