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");