2 * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include <openssl/provider.h>
12 #include <openssl/param_build.h>
15 extern OSSL_provider_init_fn PROVIDER_INIT_FUNCTION_NAME
;
18 static OSSL_PARAM greeting_request
[] = {
19 { "greeting", OSSL_PARAM_UTF8_STRING
, buf
, sizeof(buf
) },
20 { NULL
, 0, NULL
, 0, 0 }
23 static unsigned int digestsuccess
= 0;
24 static OSSL_PARAM digest_check
[] = {
25 { "digest-check", OSSL_PARAM_UNSIGNED_INTEGER
, &digestsuccess
,
26 sizeof(digestsuccess
) },
27 { NULL
, 0, NULL
, 0, 0 }
30 static unsigned int stopsuccess
= 0;
31 static OSSL_PARAM stop_property_mirror
[] = {
32 { "stop-property-mirror", OSSL_PARAM_UNSIGNED_INTEGER
, &stopsuccess
,
33 sizeof(stopsuccess
) },
34 { NULL
, 0, NULL
, 0, 0 }
37 static int test_provider(OSSL_LIB_CTX
**libctx
, const char *name
,
38 OSSL_PROVIDER
*legacy
)
40 OSSL_PROVIDER
*prov
= NULL
;
41 const char *greeting
= NULL
;
42 char expected_greeting
[256];
45 int dolegacycheck
= (legacy
!= NULL
);
46 OSSL_PROVIDER
*deflt
= NULL
, *base
= NULL
;
48 BIO_snprintf(expected_greeting
, sizeof(expected_greeting
),
49 "Hello OpenSSL %.20s, greetings from %s!",
50 OPENSSL_VERSION_STR
, name
);
54 * We set properties that we know the providers we are using don't have.
55 * This should mean that the p_test provider will fail any fetches - which
56 * is something we test inside the provider.
58 EVP_set_default_properties(*libctx
, "fips=yes");
60 * Check that it is possible to have a built-in provider mirrored in
63 if (!TEST_ptr(base
= OSSL_PROVIDER_load(*libctx
, "base")))
65 if (!TEST_ptr(prov
= OSSL_PROVIDER_load(*libctx
, name
)))
69 * Once the provider is loaded we clear the default properties and fetches
70 * should start working again.
72 EVP_set_default_properties(*libctx
, "");
74 if (!TEST_true(OSSL_PROVIDER_get_params(prov
, digest_check
))
75 || !TEST_true(digestsuccess
))
79 * Check that a provider can prevent property mirroring if it sets its
80 * own properties explicitly
82 if (!TEST_true(OSSL_PROVIDER_get_params(prov
, stop_property_mirror
))
83 || !TEST_true(stopsuccess
))
85 EVP_set_default_properties(*libctx
, "fips=yes");
86 if (!TEST_true(OSSL_PROVIDER_get_params(prov
, digest_check
))
87 || !TEST_true(digestsuccess
))
89 EVP_set_default_properties(*libctx
, "");
91 if (!TEST_true(OSSL_PROVIDER_get_params(prov
, greeting_request
))
92 || !TEST_ptr(greeting
= greeting_request
[0].data
)
93 || !TEST_size_t_gt(greeting_request
[0].data_size
, 0)
94 || !TEST_str_eq(greeting
, expected_greeting
))
97 /* Make sure we got the error we were expecting */
98 err
= ERR_peek_last_error();
99 if (!TEST_int_gt(err
, 0)
100 || !TEST_int_eq(ERR_GET_REASON(err
), 1))
103 OSSL_PROVIDER_unload(legacy
);
107 /* Legacy provider should also be unloaded from child libctx */
108 if (!TEST_true(OSSL_PROVIDER_get_params(prov
, digest_check
))
109 || !TEST_false(digestsuccess
))
112 * Loading the legacy provider again should make it available again in
113 * the child libctx. Loading and unloading the default provider should
114 * have no impact on the child because the child loads it explicitly
117 legacy
= OSSL_PROVIDER_load(*libctx
, "legacy");
118 deflt
= OSSL_PROVIDER_load(*libctx
, "default");
120 || !TEST_true(OSSL_PROVIDER_available(*libctx
, "default")))
122 OSSL_PROVIDER_unload(deflt
);
124 if (!TEST_ptr(legacy
)
125 || !TEST_false(OSSL_PROVIDER_available(*libctx
, "default"))
126 || !TEST_true(OSSL_PROVIDER_get_params(prov
, digest_check
))
127 || !TEST_true(digestsuccess
))
129 OSSL_PROVIDER_unload(legacy
);
133 if (!TEST_true(OSSL_PROVIDER_unload(base
)))
136 if (!TEST_true(OSSL_PROVIDER_unload(prov
)))
141 * We must free the libctx to force the provider to really be unloaded from
144 OSSL_LIB_CTX_free(*libctx
);
147 /* We print out all the data to make sure it can still be accessed */
148 ERR_print_errors_fp(stderr
);
151 OSSL_PROVIDER_unload(base
);
152 OSSL_PROVIDER_unload(deflt
);
153 OSSL_PROVIDER_unload(legacy
);
155 OSSL_PROVIDER_unload(prov
);
156 OSSL_LIB_CTX_free(*libctx
);
161 #ifndef NO_PROVIDER_MODULE
162 static int test_provider_ex(OSSL_LIB_CTX
**libctx
, const char *name
)
164 OSSL_PROVIDER
*prov
= NULL
;
165 const char *greeting
= NULL
;
168 const char custom_buf
[] = "Custom greeting";
169 OSSL_PARAM_BLD
*bld
= NULL
;
170 OSSL_PARAM
*params
= NULL
;
172 if (!TEST_ptr(bld
= OSSL_PARAM_BLD_new())
173 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld
, "greeting", custom_buf
,
175 || !TEST_ptr(params
= OSSL_PARAM_BLD_to_param(bld
))) {
179 if (!TEST_ptr(prov
= OSSL_PROVIDER_load_ex(*libctx
, name
, params
)))
182 if (!TEST_true(OSSL_PROVIDER_get_params(prov
, greeting_request
))
183 || !TEST_ptr(greeting
= greeting_request
[0].data
)
184 || !TEST_size_t_gt(greeting_request
[0].data_size
, 0)
185 || !TEST_str_eq(greeting
, custom_buf
))
188 /* Make sure we got the error we were expecting */
189 err
= ERR_peek_last_error();
190 if (!TEST_int_gt(err
, 0)
191 || !TEST_int_eq(ERR_GET_REASON(err
), 1))
194 if (!TEST_true(OSSL_PROVIDER_unload(prov
)))
199 * We must free the libctx to force the provider to really be unloaded from
202 OSSL_LIB_CTX_free(*libctx
);
205 /* We print out all the data to make sure it can still be accessed */
206 ERR_print_errors_fp(stderr
);
209 OSSL_PARAM_BLD_free(bld
);
210 OSSL_PARAM_free(params
);
211 OSSL_PROVIDER_unload(prov
);
212 OSSL_LIB_CTX_free(*libctx
);
218 static int test_builtin_provider(void)
220 OSSL_LIB_CTX
*libctx
= OSSL_LIB_CTX_new();
221 const char *name
= "p_test_builtin";
226 && TEST_true(OSSL_PROVIDER_add_builtin(libctx
, name
,
227 PROVIDER_INIT_FUNCTION_NAME
))
228 && test_provider(&libctx
, name
, NULL
);
230 OSSL_LIB_CTX_free(libctx
);
235 /* Test relies on fetching the MD4 digest from the legacy provider */
236 #ifndef OPENSSL_NO_MD4
237 static int test_builtin_provider_with_child(void)
239 OSSL_LIB_CTX
*libctx
= OSSL_LIB_CTX_new();
240 const char *name
= "p_test";
241 OSSL_PROVIDER
*legacy
;
243 if (!TEST_ptr(libctx
))
246 legacy
= OSSL_PROVIDER_load(libctx
, "legacy");
247 if (legacy
== NULL
) {
249 * In this case we assume we've been built with "no-legacy" and skip
250 * this test (there is no OPENSSL_NO_LEGACY)
252 OSSL_LIB_CTX_free(libctx
);
256 if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx
, name
,
257 PROVIDER_INIT_FUNCTION_NAME
))) {
258 OSSL_LIB_CTX_free(libctx
);
262 /* test_provider will free libctx and unload legacy as part of the test */
263 return test_provider(&libctx
, name
, legacy
);
267 #ifndef NO_PROVIDER_MODULE
268 static int test_loaded_provider(void)
270 OSSL_LIB_CTX
*libctx
= OSSL_LIB_CTX_new();
271 const char *name
= "p_test";
274 if (!TEST_ptr(libctx
))
277 /* test_provider will free libctx as part of the test */
278 res
= test_provider(&libctx
, name
, NULL
);
280 libctx
= OSSL_LIB_CTX_new();
281 if (!TEST_ptr(libctx
))
284 /* test_provider_ex will free libctx as part of the test */
285 res
= res
&& test_provider_ex(&libctx
, name
);
291 typedef enum OPTION_choice
{
298 const OPTIONS
*test_get_options(void)
300 static const OPTIONS test_options
[] = {
301 OPT_TEST_OPTIONS_DEFAULT_USAGE
,
302 { "loaded", OPT_LOADED
, '-', "Run test with a loaded provider" },
308 int setup_tests(void)
313 while ((o
= opt_next()) != OPT_EOF
) {
326 ADD_TEST(test_builtin_provider
);
327 #ifndef OPENSSL_NO_MD4
328 ADD_TEST(test_builtin_provider_with_child
);
331 #ifndef NO_PROVIDER_MODULE
333 ADD_TEST(test_loaded_provider
);