]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Make ossl_trace_param_values an official api function
authorNeil Horman <nhorman@openssl.org>
Mon, 14 Oct 2024 17:23:33 +0000 (13:23 -0400)
committerNeil Horman <nhorman@openssl.org>
Tue, 19 Nov 2024 13:38:25 +0000 (08:38 -0500)
lots of people may want to print params to a buffer.  Make it part of
our api

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

crypto/params_from_text.c
crypto/property/property.c
crypto/provider_core.c
doc/build.info
doc/man3/OSSL_PARAM_print_to_bio.pod [new file with mode: 0644]
include/openssl/params.h
util/libcrypto.num

index e603dfec6467ec26732be71f3f7412d96cafe2d6..7532d4d43923f4c9ff194f076b6d285f8dd52e5f 100644 (file)
@@ -12,6 +12,7 @@
 #include <openssl/ebcdic.h>
 #include <openssl/err.h>
 #include <openssl/params.h>
+#include <openssl/buffer.h>
 
 /*
  * When processing text to params, we're trying to be smart with numbers.
@@ -197,6 +198,111 @@ static int construct_from_text(OSSL_PARAM *to, const OSSL_PARAM *paramdef,
     return 1;
 }
 
+/**
+ * OSSL_PARAM_print_to_bio - Print OSSL_PARAM array to a bio 
+ *
+ * @p:        Array of OSSL_PARAM structures containing keys and values.
+ * @bio:      Pointer to bio where the formatted output will be written.
+ * @print_values: If non-zero, prints both keys and values. If zero, only keys
+ *                are printed.
+ *
+ * This function iterates through the given array of OSSL_PARAM structures,
+ * printing each key to an in-memory buffer, and optionally printing its
+ * value based on the provided data type. Supported types include integers,
+ * strings, octet strings, and real numbers.
+ *
+ * Return:    1 on success, 0 on failure.
+ */
+int OSSL_PARAM_print_to_bio(const OSSL_PARAM *p, BIO *bio, int print_values)
+{
+    int64_t i;
+    uint64_t u;
+    BIGNUM *bn;
+#ifndef OPENSSL_SYS_UEFI
+    double d;
+#endif
+    int ok = -1;
+    int dok;
+
+    /*
+     * Iterate through each key in the array printing its key and value
+     */
+    for (; p->key != NULL; p++) {
+        ok = -1;
+        ok = BIO_printf(bio, "%s: ", p->key);
+
+        if (ok == -1)
+            goto end;
+
+        /*
+         * if printing of values was not requested, just move on
+         * to the next param, after adding a newline to the buffer
+         */
+        if (print_values == 0) {
+            BIO_printf(bio, "\n");
+            continue;
+        }
+
+        switch (p->data_type) {
+        case OSSL_PARAM_UNSIGNED_INTEGER:
+            if (p->data_size > sizeof(int64_t)) {
+                if (OSSL_PARAM_get_BN(p, &bn))
+                    ok = BN_print(bio, bn);
+                else
+                    ok = BIO_printf(bio, "error getting value\n");
+            } else {
+                if (OSSL_PARAM_get_uint64(p, &u))
+                    ok = BIO_printf(bio, "%llu\n", (unsigned long long int)u);
+                else
+                    ok = BIO_printf(bio, "error getting value\n");
+            }
+            break;
+        case OSSL_PARAM_INTEGER:
+            if (p->data_size > sizeof(int64_t)) {
+                if (OSSL_PARAM_get_BN(p, &bn))
+                    ok = BN_print(bio, bn);
+                else
+                    ok = BIO_printf(bio, "error getting value\n");
+            } else {
+                if (OSSL_PARAM_get_int64(p, &i))
+                    ok = BIO_printf(bio, "%lld\n", (long long int)i);
+                else
+                    ok = BIO_printf(bio, "error getting value\n");
+            }
+            break;
+        case OSSL_PARAM_UTF8_PTR:
+            ok = BIO_dump(bio, p->data, p->data_size);
+            break;
+        case OSSL_PARAM_UTF8_STRING:
+            ok = BIO_dump(bio, (char *)p->data, p->data_size);
+            break;
+        case OSSL_PARAM_OCTET_PTR:
+        case OSSL_PARAM_OCTET_STRING:
+            ok = BIO_dump(bio, (char *)p->data, p->data_size);
+            break;
+        case OSSL_PARAM_REAL:
+            dok = 0;
+#ifndef OPENSSL_SYS_UEFI
+            dok = OSSL_PARAM_get_double(p, &d);
+#endif
+            if (dok == 1)
+                ok = BIO_printf(bio, "%f\n", d);
+            else
+                ok = BIO_printf(bio, "error getting value\n");
+            break;
+        default:
+            ok = BIO_printf(bio, "unknown type (%u) of %zu bytes\n",
+                            p->data_type, p->data_size);
+            break;
+        }
+        if (ok == -1)
+            goto end;
+    }
+
+end:
+    return ok == -1 ? 0 : 1;
+}
+
 int OSSL_PARAM_allocate_from_text(OSSL_PARAM *to,
                                   const OSSL_PARAM *paramdefs,
                                   const char *key, const char *value,
index 18c71bd446209f3109e64a81844659037fa35d9d..4916ea450d277adc9f1a6b100165235b4c137ede 100644 (file)
@@ -297,7 +297,7 @@ static int ossl_method_store_insert(OSSL_METHOD_STORE *store, ALGORITHM *alg)
  * reference count and destruction callbacks.
  *
  * @param store Pointer to the OSSL_METHOD_STORE where the method will be added.
- *        must be non-null.
+ *              Must be non-null.
  * @param prov Pointer to the OSSL_PROVIDER for the provider of the method.
  *             Must be non-null.
  * @param nid (identifier) associated with the method, must be > 0
@@ -402,10 +402,11 @@ int ossl_method_store_add(OSSL_METHOD_STORE *store, const OSSL_PROVIDER *prov,
 
         if (tmpimpl->provider == impl->provider
             && tmpimpl->properties == impl->properties)
-            goto err;
+            break;
     }
 
-    if (sk_IMPLEMENTATION_push(alg->impls, impl)) {
+    if (i == sk_IMPLEMENTATION_num(alg->impls)
+        && sk_IMPLEMENTATION_push(alg->impls, impl)) {
         ret = 1;
         OSSL_TRACE_BEGIN(QUERY) {
             BIO_printf(trc_out, "Adding to method store "
@@ -503,7 +504,8 @@ alg_cleanup_by_provider(ossl_uintmax_t idx, ALGORITHM *alg, void *arg)
                 char buf[512];
                 size_t size;
 
-                size = ossl_property_list_to_string(NULL, impl->properties, buf, 512);
+                size = ossl_property_list_to_string(NULL, impl->properties, buf,
+                                                    sizeof(buf));
                 BIO_printf(trc_out, "Removing implementation from "
                            "query cache\nproperties %s\nprovider %s\n",
                            size == 0 ? "none" : buf,
@@ -597,7 +599,7 @@ void ossl_method_store_do_all(OSSL_METHOD_STORE *store,
  * successful, it returns the method and its associated provider.
  *
  * @param store Pointer to the OSSL_METHOD_STORE from which to fetch the method.
- *        Must be non-null
+ *              Must be non-null.
  * @param nid (identifier) of the method to be fetched. Must be > 0
  * @param prop_query String containing the property query to match against.
  * @param prov_rw Pointer to the OSSL_PROVIDER to restrict the search to, or
@@ -669,7 +671,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store,
 
     /*
      * Search for a provider that provides this implementation.
-     * if the requested provider is NULL, then any provider will do,
+     * If the requested provider is NULL, then any provider will do,
      * otherwise we should try to find the one that matches the requested
      * provider.  Note that providers are given implicit preference via the
      * ordering of the implementation stack
@@ -688,7 +690,7 @@ int ossl_method_store_fetch(OSSL_METHOD_STORE *store,
 
     /*
      * If there are optional properties specified
-     * the search again, and select the provider that matches the
+     * then run the search again, and select the provider that matches the
      * most options
      */
     optional = ossl_property_has_optional(pq);
index 8ae357d1e2d6aa4ef36f973b5739196d1790cc4b..1b16b2790592fd0be60c9e3ed1aa71cd4e7296dc 100644 (file)
@@ -1618,74 +1618,6 @@ OSSL_LIB_CTX *ossl_provider_libctx(const OSSL_PROVIDER *prov)
     return prov != NULL ? prov->libctx : NULL;
 }
 
-/**
- * @brief Prints the parameter values of an OSSL_PARAM array to a BIO.
- *
- * This function iterates over an array of OSSL_PARAM structures and prints the
- * value of each parameter to the specified BIO stream. The parameter type is
- * detected, and the value is printed accordingly.
- *
- * @param p Array of OSSL_PARAM structures to be printed.
- * @param b BIO stream to print the parameter values to.
- *
- * The supported parameter types are:
- * - OSSL_PARAM_UNSIGNED_INTEGER: Unsigned integer values.
- * - OSSL_PARAM_INTEGER: Signed integer values.
- * - OSSL_PARAM_UTF8_PTR: Pointer to a UTF-8 string.
- * - OSSL_PARAM_UTF8_STRING: UTF-8 string.
- * - OSSL_PARAM_OCTET_PTR/OCTET_STRING: Binary data (size in bytes).
- */
-#ifndef FIPS_MODULE
-static void trace_print_param_values(const OSSL_PARAM p[], BIO *b)
-{
-    int64_t i;
-    uint64_t u;
-# ifndef OPENSSL_SYS_UEFI
-    double d;
-# endif
-
-    for (; p->key != NULL; p++) {
-        BIO_printf(b, "%s: ", p->key);
-        switch (p->data_type) {
-        case OSSL_PARAM_UNSIGNED_INTEGER:
-            if (OSSL_PARAM_get_uint64(p, &u))
-                BIO_printf(b, "%llu\n", (unsigned long long int)u);
-            else
-                BIO_printf(b, "error getting value\n");
-            break;
-        case OSSL_PARAM_INTEGER:
-            if (OSSL_PARAM_get_int64(p, &i))
-                BIO_printf(b, "%lld\n", (long long int)i);
-            else
-                BIO_printf(b, "error getting value\n");
-            break;
-        case OSSL_PARAM_UTF8_PTR:
-            BIO_printf(b, "'%s'\n", *(char **)(p->data));
-            break;
-        case OSSL_PARAM_UTF8_STRING:
-            BIO_printf(b, "'%s'\n", (char *)p->data);
-            break;
-        case OSSL_PARAM_OCTET_PTR:
-        case OSSL_PARAM_OCTET_STRING:
-            BIO_printf(b, "<%zu bytes>\n", p->data_size);
-            break;
-# ifndef OPENSSL_SYS_UEFI
-        case OSSL_PARAM_REAL:
-            if (OSSL_PARAM_get_double(p, &d))
-                BIO_printf(b, "%f\n", d);
-            else
-                BIO_printf(b, "error getting value\n");
-            break;
-# endif
-        default:
-            BIO_printf(b, "unknown type (%u) of %zu bytes\n",
-                       p->data_type, p->data_size);
-            break;
-        }
-    }
-}
-#endif
-
 /**
  * @brief Tears down the given provider.
  *
@@ -1732,16 +1664,26 @@ const OSSL_PARAM *ossl_provider_gettable_params(const OSSL_PROVIDER *prov)
 {
     const OSSL_PARAM *ret = NULL;
 
-    if (prov->gettable_params != NULL) {
+    if (prov->gettable_params != NULL)
         ret = prov->gettable_params(prov->provctx);
+
 #ifndef FIPS_MODULE
-        OSSL_TRACE_BEGIN(PROVIDER) {
-            BIO_printf(trc_out, "(provider %s) gettable params\n",
-                       ossl_provider_name(prov));
-            trace_print_param_values(ret, trc_out);
-        } OSSL_TRACE_END(PROVIDER);
+    OSSL_TRACE_BEGIN(PROVIDER) {
+        char *buf = NULL;
+
+        BIO_printf(trc_out, "(provider %s) gettable params\n",
+                   ossl_provider_name(prov));
+        BIO_printf(trc_out, "Parameters:\n");
+        if (prov->gettable_params != NULL) {
+            if (!OSSL_PARAM_print_to_bio(ret, trc_out, 0))
+                BIO_printf(trc_out, "Failed to parse param values\n");
+            OPENSSL_free(buf);
+        } else {
+            BIO_printf(trc_out, "Provider doesn't implement gettable_params\n");
+        }
+    } OSSL_TRACE_END(PROVIDER);
 #endif
-    }
+
     return ret;
 }
 
@@ -1768,13 +1710,18 @@ int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
 
     ret = prov->get_params(prov->provctx, params);
 #ifndef FIPS_MODULE
-    if (ret == 1) {
-        OSSL_TRACE_BEGIN(PROVIDER) {
-            BIO_printf(trc_out,
-                       "(provider %s) calling get_params\n", prov->name);
-            trace_print_param_values(params, trc_out);
-        } OSSL_TRACE_END(PROVIDER);
-    }
+    OSSL_TRACE_BEGIN(PROVIDER) {
+
+        BIO_printf(trc_out,
+                   "(provider %s) calling get_params\n", prov->name);
+        if (ret == 1) {
+            BIO_printf(trc_out, "Parameters:\n");
+            if (!OSSL_PARAM_print_to_bio(params, trc_out, 1))
+                BIO_printf(trc_out, "Failed to parse param values\n");
+        } else {
+            BIO_printf(trc_out, "get_params call failed\n");
+        }
+    } OSSL_TRACE_END(PROVIDER);
 #endif
     return ret;
 }
@@ -1795,18 +1742,21 @@ int ossl_provider_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
  */
 int ossl_provider_self_test(const OSSL_PROVIDER *prov)
 {
-    int ret;
-
-    if (prov->self_test == NULL)
-        return 1;
+    int ret = 1;
 
-    ret = prov->self_test(prov->provctx);
+    if (prov->self_test != NULL)
+        ret = prov->self_test(prov->provctx);
 
 #ifndef FIPS_MODULE
     OSSL_TRACE_BEGIN(PROVIDER) {
-        BIO_printf(trc_out,
-                   "(provider %s) Calling self_test, ret = %d\n",
-                   prov->name, ret);
+        if (prov->self_test != NULL) 
+            BIO_printf(trc_out,
+                       "(provider %s) Calling self_test, ret = %d\n",
+                       prov->name, ret);
+        else
+            BIO_printf(trc_out,
+                       "(provider %s) doesn't implement self_test\n",
+                       prov->name);
     } OSSL_TRACE_END(PROVIDER);
 #endif
     if (ret == 0)
@@ -1875,15 +1825,21 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
 {
     const OSSL_ALGORITHM *res;
 
-    if (prov->query_operation == NULL)
+    if (prov->query_operation == NULL) {
+#ifndef FIPS_MODULE
+        OSSL_TRACE_BEGIN(PROVIDER) {
+            BIO_printf(trc_out, "provider %s lacks query operation!\n",
+                       prov->name);
+        } OSSL_TRACE_END(PROVIDER);
+#endif
         return NULL;
+    }
 
     res = prov->query_operation(prov->provctx, operation_id, no_cache);
 #ifndef FIPS_MODULE
-    if (res != NULL) {
-        OSSL_TRACE_BEGIN(PROVIDER) {
-            const OSSL_ALGORITHM *idx;
-
+    OSSL_TRACE_BEGIN(PROVIDER) {
+        const OSSL_ALGORITHM *idx;
+        if (res != NULL) {
             BIO_printf(trc_out,
                        "(provider %s) Calling query, available algs are:\n", prov->name);
 
@@ -1898,8 +1854,10 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov,
                            res->algorithm_description == NULL ? "none" :
                            res->algorithm_description);
             }
-        } OSSL_TRACE_END(PROVIDER);
-    }
+        } else {
+            BIO_printf(trc_out, "(provider %s) query_operation failed\n", prov->name);
+        }
+    } OSSL_TRACE_END(PROVIDER);
 #endif
 
 #if defined(OPENSSL_NO_CACHED_FETCH)
index 490422b5597e62a097e17f966e8d636e667b4b4b..6ad291201dc82947122fe9fb01ce576965b4ff06 100644 (file)
@@ -1787,6 +1787,10 @@ DEPEND[html/man3/OSSL_PARAM_int.html]=man3/OSSL_PARAM_int.pod
 GENERATE[html/man3/OSSL_PARAM_int.html]=man3/OSSL_PARAM_int.pod
 DEPEND[man/man3/OSSL_PARAM_int.3]=man3/OSSL_PARAM_int.pod
 GENERATE[man/man3/OSSL_PARAM_int.3]=man3/OSSL_PARAM_int.pod
+DEPEND[html/man3/OSSL_PARAM_print_to_bio.html]=man3/OSSL_PARAM_print_to_bio.pod
+GENERATE[html/man3/OSSL_PARAM_print_to_bio.html]=man3/OSSL_PARAM_print_to_bio.pod
+DEPEND[man/man3/OSSL_PARAM_print_to_bio.3]=man3/OSSL_PARAM_print_to_bio.pod
+GENERATE[man/man3/OSSL_PARAM_print_to_bio.3]=man3/OSSL_PARAM_print_to_bio.pod
 DEPEND[html/man3/OSSL_PROVIDER.html]=man3/OSSL_PROVIDER.pod
 GENERATE[html/man3/OSSL_PROVIDER.html]=man3/OSSL_PROVIDER.pod
 DEPEND[man/man3/OSSL_PROVIDER.3]=man3/OSSL_PROVIDER.pod
@@ -3450,6 +3454,7 @@ html/man3/OSSL_PARAM_BLD.html \
 html/man3/OSSL_PARAM_allocate_from_text.html \
 html/man3/OSSL_PARAM_dup.html \
 html/man3/OSSL_PARAM_int.html \
+html/man3/OSSL_PARAM_print_to_bio.html \
 html/man3/OSSL_PROVIDER.html \
 html/man3/OSSL_QUIC_client_method.html \
 html/man3/OSSL_SELF_TEST_new.html \
@@ -4113,6 +4118,7 @@ man/man3/OSSL_PARAM_BLD.3 \
 man/man3/OSSL_PARAM_allocate_from_text.3 \
 man/man3/OSSL_PARAM_dup.3 \
 man/man3/OSSL_PARAM_int.3 \
+man/man3/OSSL_PARAM_print_to_bio.3 \
 man/man3/OSSL_PROVIDER.3 \
 man/man3/OSSL_QUIC_client_method.3 \
 man/man3/OSSL_SELF_TEST_new.3 \
diff --git a/doc/man3/OSSL_PARAM_print_to_bio.pod b/doc/man3/OSSL_PARAM_print_to_bio.pod
new file mode 100644 (file)
index 0000000..8822f6f
--- /dev/null
@@ -0,0 +1,42 @@
+=pod
+
+=head1 NAME
+
+OSSL_PARAM_print_to_bio
+- OSSL_PARAM interrogation utilities 
+
+=head1 SYNOPSIS
+
+ #include <openssl/params.h>
+
+ int OSSL_PARAM_print_to_bio(const OSSL_PARAM *p, BIO *bio,
+                             int print_values);
+
+=head1 DESCRIPTION
+
+OSSL_PARAM_print_to_bio() formats each parameter contained in the
+passed in array of B<OSSL_PARAM> values I<p>, and prints both the key,
+and optionally its value, to a provided B<BIO>.
+I<p> must be a non-null array of OSSL_PARAM values, terminated
+with a value containing a null I<key> member.
+I<print_values> is a control parameter, indicating that key values should be
+printed, in addition to key names.
+
+=head1 RETURN VALUES
+
+OSSL_PARAM_print_to_bio() returns 1 on success, and 0 on failure 
+
+=head1 HISTORY
+
+OSSL_PARAM_print_to_bio() was added in OpenSSL 3.5
+
+=head1 COPYRIGHT
+
+Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index d75eab07649060caa1cc0a0caef4de879fcdb904..d4b855dffb1fe9480a8d49d3288d9605e9237a97 100644 (file)
@@ -100,6 +100,9 @@ int OSSL_PARAM_allocate_from_text(OSSL_PARAM *to,
                                   const char *key, const char *value,
                                   size_t value_n, int *found);
 
+int OSSL_PARAM_print_to_bio(const OSSL_PARAM *params, BIO *bio,
+                            int print_values);
+
 int OSSL_PARAM_get_int(const OSSL_PARAM *p, int *val);
 int OSSL_PARAM_get_uint(const OSSL_PARAM *p, unsigned int *val);
 int OSSL_PARAM_get_long(const OSSL_PARAM *p, long int *val);
index 25cf30781c119ca70fd26c4debc10defe80e51af..88765ed9da051bc863d2c041ced155c47485329b 100644 (file)
@@ -5775,3 +5775,4 @@ d2i_OSSL_PRIVILEGE_POLICY_ID            ? 3_5_0   EXIST::FUNCTION:
 i2d_OSSL_PRIVILEGE_POLICY_ID            ?      3_5_0   EXIST::FUNCTION:
 OSSL_PRIVILEGE_POLICY_ID_free           ?      3_5_0   EXIST::FUNCTION:
 OSSL_PRIVILEGE_POLICY_ID_new            ?      3_5_0   EXIST::FUNCTION:
+OSSL_PARAM_print_to_bio                 ?      3_5_0   EXIST::FUNCTION: