Browse Source

Implement OSSL_PROVIDER_get0_default_search_path, add docs and tests.

Reviewed-by: Todd Short <todd.short@me.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19752)
Patrick Mills 1 year ago
parent
commit
d3db25f568

+ 13 - 0
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

+ 10 - 0
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<libctx>.
 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<path>
+that is to be used for looking for providers in the specified I<libctx>.
+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<OSSL_PROVIDER> 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.
 

+ 2 - 1
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);

+ 5 - 0
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

+ 59 - 0
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 <stddef.h>
+#include <openssl/provider.h>
+#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;
+}
+

+ 18 - 0
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");

+ 1 - 0
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: