1*e0c4386eSCy Schubert /*
2*e0c4386eSCy Schubert * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
3*e0c4386eSCy Schubert *
4*e0c4386eSCy Schubert * Licensed under the Apache License 2.0 (the "License"). You may not use
5*e0c4386eSCy Schubert * this file except in compliance with the License. You can obtain a copy
6*e0c4386eSCy Schubert * in the file LICENSE in the source distribution or at
7*e0c4386eSCy Schubert * https://www.openssl.org/source/license.html
8*e0c4386eSCy Schubert */
9*e0c4386eSCy Schubert
10*e0c4386eSCy Schubert #include <stddef.h>
11*e0c4386eSCy Schubert #include <openssl/provider.h>
12*e0c4386eSCy Schubert #include "testutil.h"
13*e0c4386eSCy Schubert
14*e0c4386eSCy Schubert extern OSSL_provider_init_fn PROVIDER_INIT_FUNCTION_NAME;
15*e0c4386eSCy Schubert
16*e0c4386eSCy Schubert static char buf[256];
17*e0c4386eSCy Schubert static OSSL_PARAM greeting_request[] = {
18*e0c4386eSCy Schubert { "greeting", OSSL_PARAM_UTF8_STRING, buf, sizeof(buf) },
19*e0c4386eSCy Schubert { NULL, 0, NULL, 0, 0 }
20*e0c4386eSCy Schubert };
21*e0c4386eSCy Schubert
22*e0c4386eSCy Schubert static unsigned int digestsuccess = 0;
23*e0c4386eSCy Schubert static OSSL_PARAM digest_check[] = {
24*e0c4386eSCy Schubert { "digest-check", OSSL_PARAM_UNSIGNED_INTEGER, &digestsuccess,
25*e0c4386eSCy Schubert sizeof(digestsuccess) },
26*e0c4386eSCy Schubert { NULL, 0, NULL, 0, 0 }
27*e0c4386eSCy Schubert };
28*e0c4386eSCy Schubert
29*e0c4386eSCy Schubert static unsigned int stopsuccess = 0;
30*e0c4386eSCy Schubert static OSSL_PARAM stop_property_mirror[] = {
31*e0c4386eSCy Schubert { "stop-property-mirror", OSSL_PARAM_UNSIGNED_INTEGER, &stopsuccess,
32*e0c4386eSCy Schubert sizeof(stopsuccess) },
33*e0c4386eSCy Schubert { NULL, 0, NULL, 0, 0 }
34*e0c4386eSCy Schubert };
35*e0c4386eSCy Schubert
test_provider(OSSL_LIB_CTX ** libctx,const char * name,OSSL_PROVIDER * legacy)36*e0c4386eSCy Schubert static int test_provider(OSSL_LIB_CTX **libctx, const char *name,
37*e0c4386eSCy Schubert OSSL_PROVIDER *legacy)
38*e0c4386eSCy Schubert {
39*e0c4386eSCy Schubert OSSL_PROVIDER *prov = NULL;
40*e0c4386eSCy Schubert const char *greeting = NULL;
41*e0c4386eSCy Schubert char expected_greeting[256];
42*e0c4386eSCy Schubert int ok = 0;
43*e0c4386eSCy Schubert long err;
44*e0c4386eSCy Schubert int dolegacycheck = (legacy != NULL);
45*e0c4386eSCy Schubert OSSL_PROVIDER *deflt = NULL, *base = NULL;
46*e0c4386eSCy Schubert
47*e0c4386eSCy Schubert BIO_snprintf(expected_greeting, sizeof(expected_greeting),
48*e0c4386eSCy Schubert "Hello OpenSSL %.20s, greetings from %s!",
49*e0c4386eSCy Schubert OPENSSL_VERSION_STR, name);
50*e0c4386eSCy Schubert
51*e0c4386eSCy Schubert
52*e0c4386eSCy Schubert /*
53*e0c4386eSCy Schubert * We set properties that we know the providers we are using don't have.
54*e0c4386eSCy Schubert * This should mean that the p_test provider will fail any fetches - which
55*e0c4386eSCy Schubert * is something we test inside the provider.
56*e0c4386eSCy Schubert */
57*e0c4386eSCy Schubert EVP_set_default_properties(*libctx, "fips=yes");
58*e0c4386eSCy Schubert /*
59*e0c4386eSCy Schubert * Check that it is possible to have a built-in provider mirrored in
60*e0c4386eSCy Schubert * a child lib ctx.
61*e0c4386eSCy Schubert */
62*e0c4386eSCy Schubert if (!TEST_ptr(base = OSSL_PROVIDER_load(*libctx, "base")))
63*e0c4386eSCy Schubert goto err;
64*e0c4386eSCy Schubert if (!TEST_ptr(prov = OSSL_PROVIDER_load(*libctx, name)))
65*e0c4386eSCy Schubert goto err;
66*e0c4386eSCy Schubert
67*e0c4386eSCy Schubert /*
68*e0c4386eSCy Schubert * Once the provider is loaded we clear the default properties and fetches
69*e0c4386eSCy Schubert * should start working again.
70*e0c4386eSCy Schubert */
71*e0c4386eSCy Schubert EVP_set_default_properties(*libctx, "");
72*e0c4386eSCy Schubert if (dolegacycheck) {
73*e0c4386eSCy Schubert if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check))
74*e0c4386eSCy Schubert || !TEST_true(digestsuccess))
75*e0c4386eSCy Schubert goto err;
76*e0c4386eSCy Schubert
77*e0c4386eSCy Schubert /*
78*e0c4386eSCy Schubert * Check that a provider can prevent property mirroring if it sets its
79*e0c4386eSCy Schubert * own properties explicitly
80*e0c4386eSCy Schubert */
81*e0c4386eSCy Schubert if (!TEST_true(OSSL_PROVIDER_get_params(prov, stop_property_mirror))
82*e0c4386eSCy Schubert || !TEST_true(stopsuccess))
83*e0c4386eSCy Schubert goto err;
84*e0c4386eSCy Schubert EVP_set_default_properties(*libctx, "fips=yes");
85*e0c4386eSCy Schubert if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check))
86*e0c4386eSCy Schubert || !TEST_true(digestsuccess))
87*e0c4386eSCy Schubert goto err;
88*e0c4386eSCy Schubert EVP_set_default_properties(*libctx, "");
89*e0c4386eSCy Schubert }
90*e0c4386eSCy Schubert if (!TEST_true(OSSL_PROVIDER_get_params(prov, greeting_request))
91*e0c4386eSCy Schubert || !TEST_ptr(greeting = greeting_request[0].data)
92*e0c4386eSCy Schubert || !TEST_size_t_gt(greeting_request[0].data_size, 0)
93*e0c4386eSCy Schubert || !TEST_str_eq(greeting, expected_greeting))
94*e0c4386eSCy Schubert goto err;
95*e0c4386eSCy Schubert
96*e0c4386eSCy Schubert /* Make sure we got the error we were expecting */
97*e0c4386eSCy Schubert err = ERR_peek_last_error();
98*e0c4386eSCy Schubert if (!TEST_int_gt(err, 0)
99*e0c4386eSCy Schubert || !TEST_int_eq(ERR_GET_REASON(err), 1))
100*e0c4386eSCy Schubert goto err;
101*e0c4386eSCy Schubert
102*e0c4386eSCy Schubert OSSL_PROVIDER_unload(legacy);
103*e0c4386eSCy Schubert legacy = NULL;
104*e0c4386eSCy Schubert
105*e0c4386eSCy Schubert if (dolegacycheck) {
106*e0c4386eSCy Schubert /* Legacy provider should also be unloaded from child libctx */
107*e0c4386eSCy Schubert if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check))
108*e0c4386eSCy Schubert || !TEST_false(digestsuccess))
109*e0c4386eSCy Schubert goto err;
110*e0c4386eSCy Schubert /*
111*e0c4386eSCy Schubert * Loading the legacy provider again should make it available again in
112*e0c4386eSCy Schubert * the child libctx. Loading and unloading the default provider should
113*e0c4386eSCy Schubert * have no impact on the child because the child loads it explicitly
114*e0c4386eSCy Schubert * before this point.
115*e0c4386eSCy Schubert */
116*e0c4386eSCy Schubert legacy = OSSL_PROVIDER_load(*libctx, "legacy");
117*e0c4386eSCy Schubert deflt = OSSL_PROVIDER_load(*libctx, "default");
118*e0c4386eSCy Schubert if (!TEST_ptr(deflt)
119*e0c4386eSCy Schubert || !TEST_true(OSSL_PROVIDER_available(*libctx, "default")))
120*e0c4386eSCy Schubert goto err;
121*e0c4386eSCy Schubert OSSL_PROVIDER_unload(deflt);
122*e0c4386eSCy Schubert deflt = NULL;
123*e0c4386eSCy Schubert if (!TEST_ptr(legacy)
124*e0c4386eSCy Schubert || !TEST_false(OSSL_PROVIDER_available(*libctx, "default"))
125*e0c4386eSCy Schubert || !TEST_true(OSSL_PROVIDER_get_params(prov, digest_check))
126*e0c4386eSCy Schubert || !TEST_true(digestsuccess))
127*e0c4386eSCy Schubert goto err;
128*e0c4386eSCy Schubert OSSL_PROVIDER_unload(legacy);
129*e0c4386eSCy Schubert legacy = NULL;
130*e0c4386eSCy Schubert }
131*e0c4386eSCy Schubert
132*e0c4386eSCy Schubert if (!TEST_true(OSSL_PROVIDER_unload(base)))
133*e0c4386eSCy Schubert goto err;
134*e0c4386eSCy Schubert base = NULL;
135*e0c4386eSCy Schubert if (!TEST_true(OSSL_PROVIDER_unload(prov)))
136*e0c4386eSCy Schubert goto err;
137*e0c4386eSCy Schubert prov = NULL;
138*e0c4386eSCy Schubert
139*e0c4386eSCy Schubert /*
140*e0c4386eSCy Schubert * We must free the libctx to force the provider to really be unloaded from
141*e0c4386eSCy Schubert * memory
142*e0c4386eSCy Schubert */
143*e0c4386eSCy Schubert OSSL_LIB_CTX_free(*libctx);
144*e0c4386eSCy Schubert *libctx = NULL;
145*e0c4386eSCy Schubert
146*e0c4386eSCy Schubert /* We print out all the data to make sure it can still be accessed */
147*e0c4386eSCy Schubert ERR_print_errors_fp(stderr);
148*e0c4386eSCy Schubert ok = 1;
149*e0c4386eSCy Schubert err:
150*e0c4386eSCy Schubert OSSL_PROVIDER_unload(base);
151*e0c4386eSCy Schubert OSSL_PROVIDER_unload(deflt);
152*e0c4386eSCy Schubert OSSL_PROVIDER_unload(legacy);
153*e0c4386eSCy Schubert legacy = NULL;
154*e0c4386eSCy Schubert OSSL_PROVIDER_unload(prov);
155*e0c4386eSCy Schubert OSSL_LIB_CTX_free(*libctx);
156*e0c4386eSCy Schubert *libctx = NULL;
157*e0c4386eSCy Schubert return ok;
158*e0c4386eSCy Schubert }
159*e0c4386eSCy Schubert
test_builtin_provider(void)160*e0c4386eSCy Schubert static int test_builtin_provider(void)
161*e0c4386eSCy Schubert {
162*e0c4386eSCy Schubert OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
163*e0c4386eSCy Schubert const char *name = "p_test_builtin";
164*e0c4386eSCy Schubert int ok;
165*e0c4386eSCy Schubert
166*e0c4386eSCy Schubert ok =
167*e0c4386eSCy Schubert TEST_ptr(libctx)
168*e0c4386eSCy Schubert && TEST_true(OSSL_PROVIDER_add_builtin(libctx, name,
169*e0c4386eSCy Schubert PROVIDER_INIT_FUNCTION_NAME))
170*e0c4386eSCy Schubert && test_provider(&libctx, name, NULL);
171*e0c4386eSCy Schubert
172*e0c4386eSCy Schubert OSSL_LIB_CTX_free(libctx);
173*e0c4386eSCy Schubert
174*e0c4386eSCy Schubert return ok;
175*e0c4386eSCy Schubert }
176*e0c4386eSCy Schubert
177*e0c4386eSCy Schubert /* Test relies on fetching the MD4 digest from the legacy provider */
178*e0c4386eSCy Schubert #ifndef OPENSSL_NO_MD4
test_builtin_provider_with_child(void)179*e0c4386eSCy Schubert static int test_builtin_provider_with_child(void)
180*e0c4386eSCy Schubert {
181*e0c4386eSCy Schubert OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
182*e0c4386eSCy Schubert const char *name = "p_test";
183*e0c4386eSCy Schubert OSSL_PROVIDER *legacy;
184*e0c4386eSCy Schubert
185*e0c4386eSCy Schubert if (!TEST_ptr(libctx))
186*e0c4386eSCy Schubert return 0;
187*e0c4386eSCy Schubert
188*e0c4386eSCy Schubert legacy = OSSL_PROVIDER_load(libctx, "legacy");
189*e0c4386eSCy Schubert if (legacy == NULL) {
190*e0c4386eSCy Schubert /*
191*e0c4386eSCy Schubert * In this case we assume we've been built with "no-legacy" and skip
192*e0c4386eSCy Schubert * this test (there is no OPENSSL_NO_LEGACY)
193*e0c4386eSCy Schubert */
194*e0c4386eSCy Schubert OSSL_LIB_CTX_free(libctx);
195*e0c4386eSCy Schubert return 1;
196*e0c4386eSCy Schubert }
197*e0c4386eSCy Schubert
198*e0c4386eSCy Schubert if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, name,
199*e0c4386eSCy Schubert PROVIDER_INIT_FUNCTION_NAME))) {
200*e0c4386eSCy Schubert OSSL_LIB_CTX_free(libctx);
201*e0c4386eSCy Schubert return 0;
202*e0c4386eSCy Schubert }
203*e0c4386eSCy Schubert
204*e0c4386eSCy Schubert /* test_provider will free libctx and unload legacy as part of the test */
205*e0c4386eSCy Schubert return test_provider(&libctx, name, legacy);
206*e0c4386eSCy Schubert }
207*e0c4386eSCy Schubert #endif
208*e0c4386eSCy Schubert
209*e0c4386eSCy Schubert #ifndef NO_PROVIDER_MODULE
test_loaded_provider(void)210*e0c4386eSCy Schubert static int test_loaded_provider(void)
211*e0c4386eSCy Schubert {
212*e0c4386eSCy Schubert OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
213*e0c4386eSCy Schubert const char *name = "p_test";
214*e0c4386eSCy Schubert
215*e0c4386eSCy Schubert if (!TEST_ptr(libctx))
216*e0c4386eSCy Schubert return 0;
217*e0c4386eSCy Schubert
218*e0c4386eSCy Schubert /* test_provider will free libctx as part of the test */
219*e0c4386eSCy Schubert return test_provider(&libctx, name, NULL);
220*e0c4386eSCy Schubert }
221*e0c4386eSCy Schubert #endif
222*e0c4386eSCy Schubert
223*e0c4386eSCy Schubert typedef enum OPTION_choice {
224*e0c4386eSCy Schubert OPT_ERR = -1,
225*e0c4386eSCy Schubert OPT_EOF = 0,
226*e0c4386eSCy Schubert OPT_LOADED,
227*e0c4386eSCy Schubert OPT_TEST_ENUM
228*e0c4386eSCy Schubert } OPTION_CHOICE;
229*e0c4386eSCy Schubert
test_get_options(void)230*e0c4386eSCy Schubert const OPTIONS *test_get_options(void)
231*e0c4386eSCy Schubert {
232*e0c4386eSCy Schubert static const OPTIONS test_options[] = {
233*e0c4386eSCy Schubert OPT_TEST_OPTIONS_DEFAULT_USAGE,
234*e0c4386eSCy Schubert { "loaded", OPT_LOADED, '-', "Run test with a loaded provider" },
235*e0c4386eSCy Schubert { NULL }
236*e0c4386eSCy Schubert };
237*e0c4386eSCy Schubert return test_options;
238*e0c4386eSCy Schubert }
239*e0c4386eSCy Schubert
setup_tests(void)240*e0c4386eSCy Schubert int setup_tests(void)
241*e0c4386eSCy Schubert {
242*e0c4386eSCy Schubert OPTION_CHOICE o;
243*e0c4386eSCy Schubert int loaded = 0;
244*e0c4386eSCy Schubert
245*e0c4386eSCy Schubert while ((o = opt_next()) != OPT_EOF) {
246*e0c4386eSCy Schubert switch (o) {
247*e0c4386eSCy Schubert case OPT_TEST_CASES:
248*e0c4386eSCy Schubert break;
249*e0c4386eSCy Schubert case OPT_LOADED:
250*e0c4386eSCy Schubert loaded = 1;
251*e0c4386eSCy Schubert break;
252*e0c4386eSCy Schubert default:
253*e0c4386eSCy Schubert return 0;
254*e0c4386eSCy Schubert }
255*e0c4386eSCy Schubert }
256*e0c4386eSCy Schubert
257*e0c4386eSCy Schubert if (!loaded) {
258*e0c4386eSCy Schubert ADD_TEST(test_builtin_provider);
259*e0c4386eSCy Schubert #ifndef OPENSSL_NO_MD4
260*e0c4386eSCy Schubert ADD_TEST(test_builtin_provider_with_child);
261*e0c4386eSCy Schubert #endif
262*e0c4386eSCy Schubert }
263*e0c4386eSCy Schubert #ifndef NO_PROVIDER_MODULE
264*e0c4386eSCy Schubert else {
265*e0c4386eSCy Schubert ADD_TEST(test_loaded_provider);
266*e0c4386eSCy Schubert }
267*e0c4386eSCy Schubert #endif
268*e0c4386eSCy Schubert return 1;
269*e0c4386eSCy Schubert }
270*e0c4386eSCy Schubert
271