#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.
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,
* 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
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 "
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,
* 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
/*
* 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
/*
* 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);
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.
*
{
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;
}
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;
}
*/
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)
{
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);
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)
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
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 \
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 \
--- /dev/null
+=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
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);
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: