From d3db25f568087bc9dc89b6720f0b4213cd5585c3 Mon Sep 17 00:00:00 2001 From: Patrick Mills Date: Wed, 23 Nov 2022 15:08:51 -0500 Subject: [PATCH] Implement OSSL_PROVIDER_get0_default_search_path, add docs and tests. Reviewed-by: Todd Short Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/19752) --- crypto/provider_core.c | 13 ++++ doc/man3/OSSL_PROVIDER.pod | 10 ++++ include/openssl/provider.h | 3 +- test/build.info | 5 ++ test/provider_default_search_path_test.c | 59 +++++++++++++++++++ .../04-test_provider_default_search_path.t | 18 ++++++ util/libcrypto.num | 1 + 7 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 test/provider_default_search_path_test.c create mode 100644 test/recipes/04-test_provider_default_search_path.t diff --git a/crypto/provider_core.c b/crypto/provider_core.c index c05b2f5496..4c93abb982 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -816,6 +816,19 @@ int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *libctx, return 0; } +const char *OSSL_PROVIDER_get0_default_search_path(OSSL_LIB_CTX *libctx) +{ + struct provider_store_st *store; + char *path = NULL; + + if ((store = get_provider_store(libctx)) != NULL + && CRYPTO_THREAD_read_lock(store->default_path_lock)) { + path = store->default_path; + CRYPTO_THREAD_unlock(store->default_path_lock); + } + return path; +} + /* * Internal version that doesn't affect the store flags, and thereby avoid * locking. Direct callers must remember to set the store flags when diff --git a/doc/man3/OSSL_PROVIDER.pod b/doc/man3/OSSL_PROVIDER.pod index 715aa10b1f..cefb4a74c0 100644 --- a/doc/man3/OSSL_PROVIDER.pod +++ b/doc/man3/OSSL_PROVIDER.pod @@ -3,6 +3,7 @@ =head1 NAME OSSL_PROVIDER_set_default_search_path, +OSSL_PROVIDER_get0_default_search_path, OSSL_PROVIDER, OSSL_PROVIDER_load, OSSL_PROVIDER_try_load, OSSL_PROVIDER_unload, OSSL_PROVIDER_available, OSSL_PROVIDER_do_all, OSSL_PROVIDER_gettable_params, OSSL_PROVIDER_get_params, @@ -20,6 +21,7 @@ OSSL_PROVIDER_self_test int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *libctx, const char *path); + const char *OSSL_PROVIDER_get0_default_search_path(OSSL_LIB_CTX *libctx); OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *libctx, const char *name); OSSL_PROVIDER *OSSL_PROVIDER_try_load(OSSL_LIB_CTX *libctx, const char *name, @@ -72,6 +74,11 @@ that is to be used for looking for providers in the specified I. If left unspecified, an environment variable and a fall back default value will be used instead. +OSSL_PROVIDER_get0_default_search_path() retrieves the default search I +that is to be used for looking for providers in the specified I. +If successful returns the path or empty string; the path is valid until the +context is released or OSSL_PROVIDER_set_default_search_path() is called. + OSSL_PROVIDER_add_builtin() is used to add a built in provider to B store in the given library context, by associating a provider name with a provider initialization function. @@ -161,6 +168,9 @@ OSSL_PROVIDER_set_default_search_path(), OSSL_PROVIDER_add(), OSSL_PROVIDER_unload(), OSSL_PROVIDER_get_params() and OSSL_PROVIDER_get_capabilities() return 1 on success, or 0 on error. +OSSL_PROVIDER_get0_default_search_path() returns a pointer to a path on success, +or NULL on error or if the path has not previously been set. + OSSL_PROVIDER_load() and OSSL_PROVIDER_try_load() return a pointer to a provider object on success, or NULL on error. diff --git a/include/openssl/provider.h b/include/openssl/provider.h index dc86ff5878..088e74038e 100644 --- a/include/openssl/provider.h +++ b/include/openssl/provider.h @@ -17,8 +17,9 @@ extern "C" { # endif -/* Set the default provider search path */ +/* Set and Get a library context search path */ int OSSL_PROVIDER_set_default_search_path(OSSL_LIB_CTX *, const char *path); +const char *OSSL_PROVIDER_get0_default_search_path(OSSL_LIB_CTX *libctx); /* Load and unload a provider */ OSSL_PROVIDER *OSSL_PROVIDER_load(OSSL_LIB_CTX *, const char *name); diff --git a/test/build.info b/test/build.info index fb6a4551db..0722eff32d 100644 --- a/test/build.info +++ b/test/build.info @@ -979,6 +979,11 @@ IF[{- !$disabled{tests} -}] INCLUDE[provider_pkey_test]=../include ../apps/include DEPEND[provider_pkey_test]=../libcrypto libtestutil.a + PROGRAMS{noinst}=provider_default_search_path_test + SOURCE[provider_default_search_path_test]=provider_default_search_path_test.c + INCLUDE[provider_default_search_path_test]=../include ../apps/include + DEPEND[provider_default_search_path_test]=../libcrypto libtestutil.a + PROGRAMS{noinst}=params_test SOURCE[params_test]=params_test.c INCLUDE[params_test]=.. ../include ../apps/include diff --git a/test/provider_default_search_path_test.c b/test/provider_default_search_path_test.c new file mode 100644 index 0000000000..684a508765 --- /dev/null +++ b/test/provider_default_search_path_test.c @@ -0,0 +1,59 @@ +/* + * Copyright 2020-2022 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 + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include "testutil.h" + +static int test_default_libctx(void) +{ + OSSL_LIB_CTX *ctx = NULL; + char *path = "./some/path"; + const char *retrieved_path = NULL; + int ok; + + ok = TEST_true(OSSL_PROVIDER_set_default_search_path(ctx, path)) + && TEST_ptr(retrieved_path = OSSL_PROVIDER_get0_default_search_path(ctx)) + && TEST_str_eq(path, retrieved_path); + + return ok; +} + +static int test_explicit_libctx(void) +{ + OSSL_LIB_CTX *ctx = NULL; + char *def_libctx_path = "./some/path"; + char *path = "./another/location"; + const char *retrieved_defctx_path = NULL; + const char *retrieved_path = NULL; + int ok; + + /* Set search path for default context, then create a new context and set + another path for it. Finally, get both paths and make sure they are + still what we set and are separate. */ + ok = TEST_true(OSSL_PROVIDER_set_default_search_path(NULL, def_libctx_path)) + && TEST_ptr(ctx = OSSL_LIB_CTX_new()) + && TEST_true(OSSL_PROVIDER_set_default_search_path(ctx, path)) + && TEST_ptr(retrieved_defctx_path = OSSL_PROVIDER_get0_default_search_path(NULL)) + && TEST_str_eq(def_libctx_path, retrieved_defctx_path) + && TEST_ptr(retrieved_path = OSSL_PROVIDER_get0_default_search_path(ctx)) + && TEST_str_eq(path, retrieved_path) + && TEST_str_ne(retrieved_path, retrieved_defctx_path); + + OSSL_LIB_CTX_free(ctx); + return ok; +} + +int setup_tests(void) +{ + ADD_TEST(test_default_libctx); + ADD_TEST(test_explicit_libctx); + return 1; +} + diff --git a/test/recipes/04-test_provider_default_search_path.t b/test/recipes/04-test_provider_default_search_path.t new file mode 100644 index 0000000000..29797e62a0 --- /dev/null +++ b/test/recipes/04-test_provider_default_search_path.t @@ -0,0 +1,18 @@ +#! /usr/bin/env perl +# Copyright 2019-2022 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 +# https://www.openssl.org/source/license.html + +use strict; +use File::Spec; +use OpenSSL::Test::Simple; + +# We must ensure that OPENSSL_CONF points at an empty file. Otherwise, we +# risk that the configuration file contains statements that load providers, +# which defeats the purpose of this test. The NUL device is good enough. +$ENV{OPENSSL_CONF} = File::Spec->devnull(); + +simple_test("test_provider_default_search_path", "provider_default_search_path_test"); diff --git a/util/libcrypto.num b/util/libcrypto.num index 9820f44240..f4b7c95e55 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5505,3 +5505,4 @@ OSSL_HPKE_open ? 3_2_0 EXIST::FUNCTION: OSSL_HPKE_CTX_get_seq ? 3_2_0 EXIST::FUNCTION: OSSL_HPKE_CTX_set_seq ? 3_2_0 EXIST::FUNCTION: OSSL_HPKE_get_recommended_ikmelen ? 3_2_0 EXIST::FUNCTION: +OSSL_PROVIDER_get0_default_search_path ? 3_2_0 EXIST::FUNCTION: