list: add capability to print details about the current DRBGs
authorPauli <paul.dale@oracle.com>
Mon, 21 Sep 2020 23:36:53 +0000 (09:36 +1000)
committerPauli <paul.dale@oracle.com>
Wed, 23 Sep 2020 05:28:30 +0000 (15:28 +1000)
This allows a user to confirm that the DRBG their configuration specified is
being used.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12931)

apps/include/app_params.h
apps/lib/app_params.c
apps/list.c

index 2060b5200efa269c4f6ce3f9959d31c9c7968280..d282fd657f78d2808e0c08c83d391b15525ec096 100644 (file)
@@ -10,4 +10,5 @@
 #include <openssl/core.h>
 
 int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent);
+void print_param_value(const OSSL_PARAM *p, int indent);
 
index 3305b1e9226918a3412dd0a14cd2bd4c0d79d4c0..04337cbc83ee098756128f3f5bcc64fd373b9ae2 100644 (file)
@@ -94,3 +94,39 @@ int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent)
     return 1;
 }
 
+void print_param_value(const OSSL_PARAM *p, int indent)
+{
+    int64_t i;
+    uint64_t u;
+
+    printf("%*s%s: ", indent, "", p->key);
+    switch (p->data_type) {
+    case OSSL_PARAM_UNSIGNED_INTEGER:
+        if (OSSL_PARAM_get_uint64(p, &u))
+            BIO_printf(bio_out, "%llu\n", (unsigned long long int)u);
+        else
+            BIO_printf(bio_out, "error getting value\n");
+        break;
+    case OSSL_PARAM_INTEGER:
+        if (OSSL_PARAM_get_int64(p, &i))
+            BIO_printf(bio_out, "%lld\n", (long long int)i);
+        else
+            BIO_printf(bio_out, "error getting value\n");
+        break;
+    case OSSL_PARAM_UTF8_PTR:
+        BIO_printf(bio_out, "'%s'\n", *(char **)(p->data));
+        break;
+    case OSSL_PARAM_UTF8_STRING:
+        BIO_printf(bio_out, "'%s'\n", (char *)p->data);
+        break;
+    case OSSL_PARAM_OCTET_PTR:
+    case OSSL_PARAM_OCTET_STRING:
+        BIO_printf(bio_out, "<%zu bytes>\n", p->data_size);
+        break;
+    default:
+        BIO_printf(bio_out, "unknown type (%u) of %zu bytes\n",
+                   p->data_type, p->data_size);
+        break;
+    }
+}
+
index fd018991e12c150c573c589414e241bbcb1224da..b2ddef920191f22487a5788be139a0db968abe3f 100644 (file)
@@ -19,6 +19,7 @@
 #include <openssl/encoder.h>
 #include <openssl/decoder.h>
 #include <openssl/core_names.h>
+#include <openssl/rand.h>
 #include "apps.h"
 #include "app_params.h"
 #include "progs.h"
@@ -352,6 +353,74 @@ static void list_random_generators(void)
     sk_EVP_RAND_pop_free(rands, EVP_RAND_free);
 }
 
+static void display_random(const char *name, EVP_RAND_CTX *drbg)
+{
+    EVP_RAND *rand;
+    uint64_t u;
+    const char *p;
+    const OSSL_PARAM *gettables;
+    OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+    unsigned char buf[1000];
+
+    BIO_printf(bio_out, "%s:\n", name);
+    if (drbg != NULL) {
+        rand = EVP_RAND_CTX_rand(drbg);
+
+        BIO_printf(bio_out, "  %s", EVP_RAND_name(rand));
+        BIO_printf(bio_out, " @ %s\n",
+                   OSSL_PROVIDER_name(EVP_RAND_provider(rand)));
+
+        switch (EVP_RAND_state(drbg)) {
+        case EVP_RAND_STATE_UNINITIALISED:
+            p = "uninitialised";
+            break;
+        case EVP_RAND_STATE_READY:
+            p = "ready";
+            break;
+        case EVP_RAND_STATE_ERROR:
+            p = "error";
+            break;
+        default:
+            p = "unknown";
+            break;
+        }
+        BIO_printf(bio_out, "  state = %s\n", p);
+
+        gettables = EVP_RAND_gettable_ctx_params(rand);
+        if (gettables != NULL)
+            for (; gettables->key != NULL; gettables++) {
+                /* State has been dealt with already, so ignore */
+                if (strcasecmp(gettables->key, OSSL_RAND_PARAM_STATE) == 0)
+                    continue;
+                /* Outside of verbose mode, we skip non-string values */
+                if (gettables->data_type != OSSL_PARAM_UTF8_STRING
+                        && gettables->data_type != OSSL_PARAM_UTF8_PTR
+                        && !verbose)
+                    continue;
+                params->key = gettables->key;
+                params->data_type = gettables->data_type;
+                if (gettables->data_type == OSSL_PARAM_UNSIGNED_INTEGER
+                        || gettables->data_type == OSSL_PARAM_INTEGER) {
+                    params->data = &u;
+                    params->data_size = sizeof(u);
+                } else {
+                    params->data = buf;
+                    params->data_size = sizeof(buf);
+                }
+                params->return_size = 0;
+                if (EVP_RAND_get_ctx_params(drbg, params))
+                    print_param_value(params, 2);
+            }
+    }
+}
+
+static void list_random_instances(void)
+{
+    display_random("primary", RAND_get0_primary(NULL));
+    display_random("public", RAND_get0_public(NULL));
+    display_random("private", RAND_get0_private(NULL));
+}
+
 /*
  * Encoders
  */
@@ -819,8 +888,8 @@ typedef enum HELPLIST_CHOICE {
     OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
     OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
     OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED,
-    OPT_KDF_ALGORITHMS, OPT_RANDOM_GENERATORS, OPT_ENCODERS,
-    OPT_DECODERS,
+    OPT_KDF_ALGORITHMS, OPT_RANDOM_INSTANCES, OPT_RANDOM_GENERATORS,
+    OPT_ENCODERS, OPT_DECODERS,
     OPT_MISSING_HELP, OPT_OBJECTS,
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     OPT_ENGINES, 
@@ -844,6 +913,8 @@ const OPTIONS list_options[] = {
      "List of message digest algorithms"},
     {"kdf-algorithms", OPT_KDF_ALGORITHMS, '-',
      "List of key derivation and pseudo random function algorithms"},
+    {"random-instances", OPT_RANDOM_INSTANCES, '-',
+     "List the primary, pubic and private random number generator details"},
     {"random-generators", OPT_RANDOM_GENERATORS, '-',
      "List of random number generators"},
     {"mac-algorithms", OPT_MAC_ALGORITHMS, '-',
@@ -880,6 +951,7 @@ int list_main(int argc, char **argv)
     int one = 0, done = 0;
     struct {
         unsigned int commands:1;
+        unsigned int random_instances:1;
         unsigned int random_generators:1;
         unsigned int digest_commands:1;
         unsigned int digest_algorithms:1;
@@ -928,6 +1000,9 @@ opthelp:
         case OPT_KDF_ALGORITHMS:
             todo.kdf_algorithms = 1;
             break;
+        case OPT_RANDOM_INSTANCES:
+            todo.random_instances = 1;
+            break;
         case OPT_RANDOM_GENERATORS:
             todo.random_generators = 1;
             break;
@@ -986,6 +1061,8 @@ opthelp:
 
     if (todo.commands)
         list_type(FT_general, one);
+    if (todo.random_instances)
+        list_random_instances();
     if (todo.random_generators)
         list_random_generators();
     if (todo.digest_commands)