From 021a65527735af2ddc063d9300138660e3782a15 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Wed, 20 Feb 2019 22:55:43 +0100 Subject: [PATCH] Add provider tests Two tests are added, one that tests the internal API, the other tests the public API. Those two tests both test the same provider, which acts both as a built-in provider and as a loadable provider module. Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/8287) --- test/build.info | 23 +++++ test/p_test.c | 110 +++++++++++++++++++++++ test/provider_internal_test.c | 79 ++++++++++++++++ test/provider_test.c | 69 ++++++++++++++ test/recipes/02-test_internal_provider.t | 18 ++++ test/recipes/04-test_provider.t | 18 ++++ 6 files changed, 317 insertions(+) create mode 100644 test/p_test.c create mode 100644 test/provider_internal_test.c create mode 100644 test/provider_test.c create mode 100644 test/recipes/02-test_internal_provider.t create mode 100644 test/recipes/04-test_provider.t diff --git a/test/build.info b/test/build.info index 4dd400f6ab..f7ec8a27db 100644 --- a/test/build.info +++ b/test/build.info @@ -578,6 +578,29 @@ IF[{- !$disabled{tests} -}] SOURCE[context_internal_test]=context_internal_test.c INCLUDE[context_internal_test]=.. ../include ../apps/include DEPEND[context_internal_test]=../libcrypto.a libtestutil.a + + PROGRAMS{noinst}=provider_internal_test + DEFINE[provider_internal_test]=PROVIDER_INIT_FUNCTION_NAME=p_test_init + SOURCE[provider_internal_test]=provider_internal_test.c p_test.c + INCLUDE[provider_internal_test]=../include ../apps/include + DEPEND[provider_internal_test]=../libcrypto.a libtestutil.a + PROGRAMS{noinst}=provider_test + DEFINE[provider_test]=PROVIDER_INIT_FUNCTION_NAME=p_test_init + SOURCE[provider_test]=provider_test.c p_test.c + INCLUDE[provider_test]=../include ../apps/include + DEPEND[provider_test]=../libcrypto.a libtestutil.a + IF[{- !$disabled{shared} -}] + MODULES{noinst}=p_test + SOURCE[p_test]=p_test.c + INCLUDE[p_test]=../include + IF[{- defined $target{shared_defflag} -}] + SOURCE[p_test]=p_test.ld + GENERATE[p_test.ld]=../util/providers.num + ENDIF + ELSE + DEFINE[provider_test]=OPENSSL_NO_SHARED + DEFINE[provider_internal_test]=OPENSSL_NO_SHARED + ENDIF ENDIF {- diff --git a/test/p_test.c b/test/p_test.c new file mode 100644 index 0000000000..6dc04103c4 --- /dev/null +++ b/test/p_test.c @@ -0,0 +1,110 @@ +/* + * Copyright 2019 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 + */ + +/* + * This is a very simple provider that does absolutely nothing except respond + * to provider global parameter requests. It does this by simply echoing back + * a parameter request it makes to the loading library. + */ + +#include +#include + +/* + * When built as an object file to link the application with, we get the + * init function name through the macro PROVIDER_INIT_FUNCTION_NAME. If + * not defined, we use the standard init function name for the shared + * object form. + */ +#ifdef PROVIDER_INIT_FUNCTION_NAME +# define OSSL_provider_init PROVIDER_INIT_FUNCTION_NAME +#endif + +#include +#include + +static OSSL_core_get_param_types_fn *c_get_param_types = NULL; +static OSSL_core_get_params_fn *c_get_params = NULL; + +/* Tell the core what params we provide and what type they are */ +static const OSSL_ITEM p_param_types[] = { + { OSSL_PARAM_UTF8_STRING, "greeting" }, + { 0, NULL } +}; + +static const OSSL_ITEM *p_get_param_types(const OSSL_PROVIDER *_) +{ + return p_param_types; +} + +static int p_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) +{ + const OSSL_PARAM *p = params; + int ok = 1; + + for (; ok && p->key != NULL; p++) { + if (strcmp(p->key, "greeting") == 0) { + static char *opensslv = NULL; + static char *provname = NULL; + static OSSL_PARAM counter_request[] = { + { "openssl-version", OSSL_PARAM_UTF8_STRING_PTR, + &opensslv, sizeof(&opensslv), NULL }, + { "provider-name", OSSL_PARAM_UTF8_STRING_PTR, + &provname, sizeof(&provname), NULL}, + { NULL, 0, NULL, 0, NULL } + }; + char buf[256]; + size_t buf_l; + + if (c_get_params(prov, counter_request)) { + const char *versionp = *(void **)counter_request[0].buffer; + const char *namep = *(void **)counter_request[1].buffer; + sprintf(buf, "Hello OpenSSL %.20s, greetings from %s!", + versionp, namep); + } else { + sprintf(buf, "Howdy stranger..."); + } + + *p->return_size = buf_l = strlen(buf) + 1; + if (p->buffer_size >= buf_l) + strncpy(p->buffer, buf, buf_l); + else + ok = 0; + } + } + return ok; +} + +static const OSSL_DISPATCH p_test_table[] = { + { OSSL_FUNC_PROVIDER_GET_PARAM_TYPES, (void (*)(void))p_get_param_types }, + { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))p_get_params }, + { 0, NULL } +}; + +int OSSL_provider_init(const OSSL_PROVIDER *provider, + const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out) +{ + for (; in->function_id != 0; in++) { + switch (in->function_id) { + case OSSL_FUNC_CORE_GET_PARAM_TYPES: + c_get_param_types = OSSL_get_core_get_param_types(in); + break; + case OSSL_FUNC_CORE_GET_PARAMS: + c_get_params = OSSL_get_core_get_params(in); + break; + default: + /* Just ignore anything we don't understand */ + break; + } + } + + *out = p_test_table; + return 1; +} diff --git a/test/provider_internal_test.c b/test/provider_internal_test.c new file mode 100644 index 0000000000..c423808f3e --- /dev/null +++ b/test/provider_internal_test.c @@ -0,0 +1,79 @@ +/* + * Copyright 2019 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 "internal/provider.h" +#include "testutil.h" + +extern OSSL_provider_init_fn PROVIDER_INIT_FUNCTION_NAME; + +static char buf[256]; +static size_t buf_l = 0; +static OSSL_PARAM greeting_request[] = { + { "greeting", OSSL_PARAM_UTF8_STRING, buf, sizeof(buf), &buf_l }, + { NULL, 0, NULL, 0, NULL } +}; + +static int test_provider(OSSL_PROVIDER *prov) +{ + const char *name = NULL; + const char *greeting = NULL; + char expected_greeting[256]; + int ret = 0; + + if (!TEST_ptr(name = ossl_provider_name(prov))) + return 0; + + snprintf(expected_greeting, sizeof(expected_greeting), + "Hello OpenSSL %.20s, greetings from %s!", + OPENSSL_VERSION_STR, name); + + ret = + TEST_true(ossl_provider_activate(prov)) + && TEST_true(ossl_provider_get_params(prov, greeting_request)) + && TEST_ptr(greeting = greeting_request[0].buffer) + && TEST_size_t_gt(greeting_request[0].buffer_size, 0) + && TEST_str_eq(greeting, expected_greeting); + + ossl_provider_free(prov); + return ret; +} + +static int test_builtin_provider(void) +{ + const char *name = "p_test_builtin"; + OSSL_PROVIDER *prov = NULL; + + return + TEST_ptr(prov = + ossl_provider_new(NULL, name, PROVIDER_INIT_FUNCTION_NAME)) + && test_provider(prov); +} + +#ifndef OPENSSL_NO_SHARED +static int test_loaded_provider(void) +{ + const char *name = "p_test"; + OSSL_PROVIDER *prov = NULL; + + return + TEST_ptr(prov = ossl_provider_new(NULL, name, NULL)) + && test_provider(prov); +} +#endif + +int setup_tests(void) +{ + ADD_TEST(test_builtin_provider); +#ifndef OPENSSL_NO_SHARED + ADD_TEST(test_loaded_provider); +#endif + return 1; +} + diff --git a/test/provider_test.c b/test/provider_test.c new file mode 100644 index 0000000000..738cd7bc45 --- /dev/null +++ b/test/provider_test.c @@ -0,0 +1,69 @@ +/* + * Copyright 2019 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" + +extern OSSL_provider_init_fn PROVIDER_INIT_FUNCTION_NAME; + +static char buf[256]; +static size_t buf_l = 0; +static OSSL_PARAM greeting_request[] = { + { "greeting", OSSL_PARAM_UTF8_STRING, buf, sizeof(buf), &buf_l }, + { NULL, 0, NULL, 0, NULL } +}; + +static int test_provider(const char *name) +{ + OSSL_PROVIDER *prov = NULL; + const char *greeting = NULL; + char expected_greeting[256]; + + snprintf(expected_greeting, sizeof(expected_greeting), + "Hello OpenSSL %.20s, greetings from %s!", + OPENSSL_VERSION_STR, name); + + return + TEST_ptr(prov = OSSL_PROVIDER_load(NULL, name)) + && TEST_true(OSSL_PROVIDER_get_params(prov, greeting_request)) + && TEST_ptr(greeting = greeting_request[0].buffer) + && TEST_size_t_gt(greeting_request[0].buffer_size, 0) + && TEST_str_eq(greeting, expected_greeting) + && TEST_true(OSSL_PROVIDER_unload(prov)); +} + +static int test_builtin_provider(void) +{ + const char *name = "p_test_builtin"; + + return + TEST_true(OSSL_PROVIDER_add_builtin(NULL, name, + PROVIDER_INIT_FUNCTION_NAME)) + && test_provider(name); +} + +#ifndef OPENSSL_NO_SHARED +static int test_loaded_provider(void) +{ + const char *name = "p_test"; + + return test_provider(name); +} +#endif + +int setup_tests(void) +{ + ADD_TEST(test_builtin_provider); +#ifndef OPENSSL_NO_SHARED + ADD_TEST(test_loaded_provider); +#endif + return 1; +} + diff --git a/test/recipes/02-test_internal_provider.t b/test/recipes/02-test_internal_provider.t new file mode 100644 index 0000000000..8275eb2725 --- /dev/null +++ b/test/recipes/02-test_internal_provider.t @@ -0,0 +1,18 @@ +#! /usr/bin/env perl +# Copyright 2019 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 OpenSSL::Test qw(:DEFAULT bldtop_dir); +use OpenSSL::Test::Simple; +use OpenSSL::Test::Utils; + +setup("test_internal_provider"); + +$ENV{"OPENSSL_MODULES"} = bldtop_dir("test"); + +simple_test("test_internal_provider", "provider_internal_test"); diff --git a/test/recipes/04-test_provider.t b/test/recipes/04-test_provider.t new file mode 100644 index 0000000000..9195a424cd --- /dev/null +++ b/test/recipes/04-test_provider.t @@ -0,0 +1,18 @@ +#! /usr/bin/env perl +# Copyright 2019 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 OpenSSL::Test qw(:DEFAULT bldtop_dir); +use OpenSSL::Test::Simple; +use OpenSSL::Test::Utils; + +setup("test_provider"); + +$ENV{"OPENSSL_MODULES"} = bldtop_dir("test"); + +simple_test("test_provider", "provider_test");