summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-04-22 15:58:50 +0100
committerMatt Caswell <matt@openssl.org>2021-05-11 14:59:43 +0100
commit5442611dffed2c345ef83d494f2ef7ffb9cf3883 (patch)
tree5291ec32b87aa8e13cb9befed9fe8f39505272be /test
parentd0efad482f7d72db3d52bdb0380bd019e6d59de8 (diff)
Add a test for OSSL_LIB_CTX_new_child()
Check that we can create such a libctx and usable providers are loaded into it. Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/14991)
Diffstat (limited to 'test')
-rw-r--r--test/p_test.c48
-rw-r--r--test/provider_test.c95
-rw-r--r--test/recipes/04-test_provider.t7
3 files changed, 140 insertions, 10 deletions
diff --git a/test/p_test.c b/test/p_test.c
index 6f55abda01..421287edb3 100644
--- a/test/p_test.c
+++ b/test/p_test.c
@@ -30,11 +30,14 @@
#include <openssl/core.h>
#include <openssl/core_dispatch.h>
#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/crypto.h>
typedef struct p_test_ctx {
char *thisfile;
char *thisfunc;
const OSSL_CORE_HANDLE *handle;
+ OSSL_LIB_CTX *libctx;
} P_TEST_CTX;
static OSSL_FUNC_core_gettable_params_fn *c_gettable_params = NULL;
@@ -46,6 +49,7 @@ static OSSL_FUNC_core_vset_error_fn *c_vset_error;
/* Tell the core what params we provide and what type they are */
static const OSSL_PARAM p_param_types[] = {
{ "greeting", OSSL_PARAM_UTF8_STRING, NULL, 0, 0 },
+ { "digest-check", OSSL_PARAM_UNSIGNED_INTEGER, NULL, 0, 0},
{ NULL, 0, NULL, 0, 0 }
};
@@ -109,6 +113,36 @@ static int p_get_params(void *provctx, OSSL_PARAM params[])
strcpy(p->data, buf);
else
ok = 0;
+ } else if (strcmp(p->key, "digest-check") == 0) {
+ unsigned int digestsuccess = 0;
+
+ /*
+ * Test we can use an algorithm from another provider. We're using
+ * legacy to check that legacy is actually available and we haven't
+ * just fallen back to default.
+ */
+#ifdef PROVIDER_INIT_FUNCTION_NAME
+ EVP_MD *md4 = EVP_MD_fetch(ctx->libctx, "MD4", NULL);
+ EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
+ const char *msg = "Hello world";
+ unsigned char out[16];
+
+ if (md4 != NULL && mdctx != NULL) {
+ if (EVP_DigestInit_ex(mdctx, md4, NULL)
+ && EVP_DigestUpdate(mdctx, (const unsigned char *)msg,
+ strlen(msg))
+ &&EVP_DigestFinal(mdctx, out, NULL))
+ digestsuccess = 1;
+ }
+ EVP_MD_CTX_free(mdctx);
+ EVP_MD_free(md4);
+#endif
+ if (p->data_size >= sizeof(digestsuccess)) {
+ *(unsigned int *)p->data = digestsuccess;
+ p->return_size = sizeof(digestsuccess);
+ } else {
+ ok = 0;
+ }
}
}
return ok;
@@ -146,11 +180,12 @@ static const OSSL_DISPATCH p_test_table[] = {
};
int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
- const OSSL_DISPATCH *in,
+ const OSSL_DISPATCH *oin,
const OSSL_DISPATCH **out,
void **provctx)
{
P_TEST_CTX *ctx;
+ const OSSL_DISPATCH *in = oin;
for (; in->function_id != 0; in++) {
switch (in->function_id) {
@@ -191,6 +226,14 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
ctx->thisfile = strdup(OPENSSL_FILE);
ctx->thisfunc = strdup(OPENSSL_FUNC);
ctx->handle = handle;
+#ifdef PROVIDER_INIT_FUNCTION_NAME
+ /* We only do this if we are linked with libcrypto */
+ ctx->libctx = OSSL_LIB_CTX_new_child(handle, oin);
+ if (ctx->libctx == NULL) {
+ p_teardown(ctx);
+ return 0;
+ }
+#endif
/*
* Set a spurious error to check error handling works correctly. This will
@@ -207,6 +250,9 @@ static void p_teardown(void *provctx)
{
P_TEST_CTX *ctx = (P_TEST_CTX *)provctx;
+#ifdef PROVIDER_INIT_FUNCTION_NAME
+ OSSL_LIB_CTX_free(ctx->libctx);
+#endif
free(ctx->thisfile);
free(ctx->thisfunc);
free(ctx);
diff --git a/test/provider_test.c b/test/provider_test.c
index d89611b9b2..0abf55e33d 100644
--- a/test/provider_test.c
+++ b/test/provider_test.c
@@ -19,7 +19,15 @@ static OSSL_PARAM greeting_request[] = {
{ NULL, 0, NULL, 0, 0 }
};
-static int test_provider(OSSL_LIB_CTX **libctx, const char *name)
+static unsigned int digestsuccess = 0;
+static OSSL_PARAM digest_check[] = {
+ { "digest-check", OSSL_PARAM_UNSIGNED_INTEGER, &digestsuccess,
+ sizeof(digestsuccess) },
+ { NULL, 0, NULL, 0, 0 }
+};
+
+static int test_provider(OSSL_LIB_CTX **libctx, const char *name,
+ OSSL_PROVIDER *legacy)
{
OSSL_PROVIDER *prov = NULL;
const char *greeting = NULL;
@@ -31,8 +39,14 @@ static int test_provider(OSSL_LIB_CTX **libctx, const char *name)
"Hello OpenSSL %.20s, greetings from %s!",
OPENSSL_VERSION_STR, name);
- if (!TEST_ptr(prov = OSSL_PROVIDER_load(*libctx, name))
- || !TEST_true(OSSL_PROVIDER_get_params(prov, greeting_request))
+ if (!TEST_ptr(prov = OSSL_PROVIDER_load(*libctx, name)))
+ goto err;
+ if (legacy != NULL) {
+ if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check))
+ || !TEST_true(digestsuccess))
+ goto err;
+ }
+ if (!TEST_true(OSSL_PROVIDER_get_params(prov, greeting_request))
|| !TEST_ptr(greeting = greeting_request[0].data)
|| !TEST_size_t_gt(greeting_request[0].data_size, 0)
|| !TEST_str_eq(greeting, expected_greeting)
@@ -40,6 +54,8 @@ static int test_provider(OSSL_LIB_CTX **libctx, const char *name)
goto err;
prov = NULL;
+ OSSL_PROVIDER_unload(legacy);
+ legacy = NULL;
/*
* We must free the libctx to force the provider to really be unloaded from
@@ -58,6 +74,8 @@ static int test_provider(OSSL_LIB_CTX **libctx, const char *name)
ERR_print_errors_fp(stderr);
ok = 1;
err:
+ OSSL_PROVIDER_unload(legacy);
+ legacy = NULL;
OSSL_PROVIDER_unload(prov);
OSSL_LIB_CTX_free(*libctx);
*libctx = NULL;
@@ -74,13 +92,39 @@ static int test_builtin_provider(void)
TEST_ptr(libctx)
&& TEST_true(OSSL_PROVIDER_add_builtin(libctx, name,
PROVIDER_INIT_FUNCTION_NAME))
- && test_provider(&libctx, name);
+ && test_provider(&libctx, name, NULL);
OSSL_LIB_CTX_free(libctx);
return ok;
}
+static int test_builtin_provider_with_child(void)
+{
+ OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
+ const char *name = "p_test";
+ OSSL_PROVIDER *legacy;
+
+ if (!TEST_ptr(libctx))
+ return 0;
+
+ legacy = OSSL_PROVIDER_load(libctx, "legacy");
+ if (legacy == NULL) {
+ /*
+ * In this case we assume we've been built with "no-legacy" and skip
+ * this test (there is no OPENSSL_NO_LEGACY)
+ */
+ return 1;
+ }
+
+ if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, name,
+ PROVIDER_INIT_FUNCTION_NAME)))
+ return 0;
+
+ /* test_provider will free libctx and unload legacy as part of the test */
+ return test_provider(&libctx, name, legacy);
+}
+
#ifndef NO_PROVIDER_MODULE
static int test_loaded_provider(void)
{
@@ -91,15 +135,52 @@ static int test_loaded_provider(void)
return 0;
/* test_provider will free libctx as part of the test */
- return test_provider(&libctx, name);
+ return test_provider(&libctx, name, NULL);
}
#endif
+typedef enum OPTION_choice {
+ OPT_ERR = -1,
+ OPT_EOF = 0,
+ OPT_LOADED,
+ OPT_TEST_ENUM
+} OPTION_CHOICE;
+
+const OPTIONS *test_get_options(void)
+{
+ static const OPTIONS test_options[] = {
+ OPT_TEST_OPTIONS_DEFAULT_USAGE,
+ { "loaded", OPT_LOADED, '-', "Run test with a loaded provider" },
+ { NULL }
+ };
+ return test_options;
+}
+
int setup_tests(void)
{
- ADD_TEST(test_builtin_provider);
+ OPTION_CHOICE o;
+ int loaded = 0;
+
+ while ((o = opt_next()) != OPT_EOF) {
+ switch (o) {
+ case OPT_TEST_CASES:
+ break;
+ case OPT_LOADED:
+ loaded = 1;
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ if (!loaded) {
+ ADD_TEST(test_builtin_provider);
+ ADD_TEST(test_builtin_provider_with_child);
+ }
#ifndef NO_PROVIDER_MODULE
- ADD_TEST(test_loaded_provider);
+ else {
+ ADD_TEST(test_loaded_provider);
+ }
#endif
return 1;
}
diff --git a/test/recipes/04-test_provider.t b/test/recipes/04-test_provider.t
index 9195a424cd..44274f8f07 100644
--- a/test/recipes/04-test_provider.t
+++ b/test/recipes/04-test_provider.t
@@ -8,11 +8,14 @@
use strict;
use OpenSSL::Test qw(:DEFAULT bldtop_dir);
-use OpenSSL::Test::Simple;
use OpenSSL::Test::Utils;
setup("test_provider");
+plan tests => 2;
+
+ok(run(test(['provider_test'])), "provider_test");
+
$ENV{"OPENSSL_MODULES"} = bldtop_dir("test");
-simple_test("test_provider", "provider_test");
+ok(run(test(['provider_test', '-loaded'])), "provider_test -loaded");