OPENSSL_info(): add the item OPENSSL_INFO_SEED_SOURCE and use it
authorRichard Levitte <levitte@openssl.org>
Sat, 24 Aug 2019 10:40:10 +0000 (12:40 +0200)
committerRichard Levitte <levitte@openssl.org>
Tue, 27 Aug 2019 16:44:36 +0000 (18:44 +0200)
'openssl version -r' prints the seed source based on compiler macros.
This does not necessarily reflect the library's idea of what seed
sources to use, so we reimplement the list of seed sources as a
OPENSSL_info() item and display that instead.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9689)

apps/info.c
apps/version.c
crypto/info.c
doc/man1/openssl-info.pod
include/openssl/crypto.h

index a2c359e0f86399f07657fa48b941cf05873aa5ff..d67ed87df33ad2419eccf61f760706a62bee59dc 100644 (file)
@@ -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) {
index 35bfb95c09c6b926ce902308ff4619e29275a587..caa3e76ffec15a1255b6e4ced484a10a626fd42b 100644 (file)
@@ -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;
index 5a929ddd037debc6b3188184d1ec6e649bea9abc..c5eb1fcba9b8f78fcf84e5055ad8b2beaf6e5438 100644 (file)
 #include <openssl/crypto.h>
 #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;
     }
index 42b1a9ea5b723c508125ab3781bba5f846f11758..2b9383fc9d3d313863836444c114cdf867e654f5 100644 (file)
@@ -14,6 +14,7 @@ B<openssl info>
 [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
index f8789176d575c06ec0281d102fdcd8970fc8436e..e16e3e47438c46e3e1cf17437b4638efea665f3b 100644 (file)
@@ -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);