]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/provider_test.c
Copyright year updates
[thirdparty/openssl.git] / test / provider_test.c
CommitLineData
021a6552 1/*
da1c088f 2 * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
021a6552
RL
3 *
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
8 */
9
10#include <stddef.h>
11#include <openssl/provider.h>
4f3e3d9d 12#include <openssl/param_build.h>
021a6552
RL
13#include "testutil.h"
14
15extern OSSL_provider_init_fn PROVIDER_INIT_FUNCTION_NAME;
16
17static char buf[256];
021a6552 18static OSSL_PARAM greeting_request[] = {
4e7991b4
P
19 { "greeting", OSSL_PARAM_UTF8_STRING, buf, sizeof(buf) },
20 { NULL, 0, NULL, 0, 0 }
021a6552
RL
21};
22
5442611d
MC
23static unsigned int digestsuccess = 0;
24static OSSL_PARAM digest_check[] = {
25 { "digest-check", OSSL_PARAM_UNSIGNED_INTEGER, &digestsuccess,
26 sizeof(digestsuccess) },
27 { NULL, 0, NULL, 0, 0 }
28};
29
b1c053ac
MC
30static unsigned int stopsuccess = 0;
31static OSSL_PARAM stop_property_mirror[] = {
32 { "stop-property-mirror", OSSL_PARAM_UNSIGNED_INTEGER, &stopsuccess,
33 sizeof(stopsuccess) },
34 { NULL, 0, NULL, 0, 0 }
35};
36
5442611d
MC
37static int test_provider(OSSL_LIB_CTX **libctx, const char *name,
38 OSSL_PROVIDER *legacy)
021a6552
RL
39{
40 OSSL_PROVIDER *prov = NULL;
41 const char *greeting = NULL;
42 char expected_greeting[256];
81c15ed0
MC
43 int ok = 0;
44 long err;
3b85bcfa 45 int dolegacycheck = (legacy != NULL);
fb9b3a7b 46 OSSL_PROVIDER *deflt = NULL, *base = NULL;
021a6552 47
f4b4574f 48 BIO_snprintf(expected_greeting, sizeof(expected_greeting),
866cc233
SL
49 "Hello OpenSSL %.20s, greetings from %s!",
50 OPENSSL_VERSION_STR, name);
021a6552 51
18cb5c31
MC
52
53 /*
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.
57 */
58 EVP_set_default_properties(*libctx, "fips=yes");
fb9b3a7b 59 /*
18cb5c31
MC
60 * Check that it is possible to have a built-in provider mirrored in
61 * a child lib ctx.
62 */
fb9b3a7b
MC
63 if (!TEST_ptr(base = OSSL_PROVIDER_load(*libctx, "base")))
64 goto err;
5442611d
MC
65 if (!TEST_ptr(prov = OSSL_PROVIDER_load(*libctx, name)))
66 goto err;
18cb5c31
MC
67
68 /*
69 * Once the provider is loaded we clear the default properties and fetches
70 * should start working again.
71 */
72 EVP_set_default_properties(*libctx, "");
3b85bcfa 73 if (dolegacycheck) {
5442611d
MC
74 if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check))
75 || !TEST_true(digestsuccess))
76 goto err;
b1c053ac
MC
77
78 /*
79 * Check that a provider can prevent property mirroring if it sets its
80 * own properties explicitly
81 */
82 if (!TEST_true(OSSL_PROVIDER_get_params(prov, stop_property_mirror))
83 || !TEST_true(stopsuccess))
84 goto err;
85 EVP_set_default_properties(*libctx, "fips=yes");
86 if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check))
87 || !TEST_true(digestsuccess))
88 goto err;
89 EVP_set_default_properties(*libctx, "");
5442611d
MC
90 }
91 if (!TEST_true(OSSL_PROVIDER_get_params(prov, greeting_request))
81c15ed0
MC
92 || !TEST_ptr(greeting = greeting_request[0].data)
93 || !TEST_size_t_gt(greeting_request[0].data_size, 0)
3b85bcfa
MC
94 || !TEST_str_eq(greeting, expected_greeting))
95 goto err;
96
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))
81c15ed0
MC
101 goto err;
102
5442611d
MC
103 OSSL_PROVIDER_unload(legacy);
104 legacy = NULL;
81c15ed0 105
3b85bcfa
MC
106 if (dolegacycheck) {
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))
110 goto err;
111 /*
112 * Loading the legacy provider again should make it available again in
fb9b3a7b
MC
113 * the child libctx. Loading and unloading the default provider should
114 * have no impact on the child because the child loads it explicitly
115 * before this point.
3b85bcfa
MC
116 */
117 legacy = OSSL_PROVIDER_load(*libctx, "legacy");
fb9b3a7b
MC
118 deflt = OSSL_PROVIDER_load(*libctx, "default");
119 if (!TEST_ptr(deflt)
120 || !TEST_true(OSSL_PROVIDER_available(*libctx, "default")))
121 goto err;
122 OSSL_PROVIDER_unload(deflt);
123 deflt = NULL;
3b85bcfa 124 if (!TEST_ptr(legacy)
fb9b3a7b 125 || !TEST_false(OSSL_PROVIDER_available(*libctx, "default"))
3b85bcfa
MC
126 || !TEST_true(OSSL_PROVIDER_get_params(prov, digest_check))
127 || !TEST_true(digestsuccess))
128 goto err;
129 OSSL_PROVIDER_unload(legacy);
130 legacy = NULL;
131 }
132
fb9b3a7b
MC
133 if (!TEST_true(OSSL_PROVIDER_unload(base)))
134 goto err;
135 base = NULL;
3b85bcfa
MC
136 if (!TEST_true(OSSL_PROVIDER_unload(prov)))
137 goto err;
138 prov = NULL;
139
81c15ed0
MC
140 /*
141 * We must free the libctx to force the provider to really be unloaded from
142 * memory
143 */
144 OSSL_LIB_CTX_free(*libctx);
145 *libctx = NULL;
146
81c15ed0
MC
147 /* We print out all the data to make sure it can still be accessed */
148 ERR_print_errors_fp(stderr);
149 ok = 1;
150 err:
fb9b3a7b
MC
151 OSSL_PROVIDER_unload(base);
152 OSSL_PROVIDER_unload(deflt);
5442611d
MC
153 OSSL_PROVIDER_unload(legacy);
154 legacy = NULL;
81c15ed0
MC
155 OSSL_PROVIDER_unload(prov);
156 OSSL_LIB_CTX_free(*libctx);
157 *libctx = NULL;
158 return ok;
021a6552
RL
159}
160
4f3e3d9d
DB
161#ifndef NO_PROVIDER_MODULE
162static int test_provider_ex(OSSL_LIB_CTX **libctx, const char *name)
163{
164 OSSL_PROVIDER *prov = NULL;
165 const char *greeting = NULL;
166 int ok = 0;
167 long err;
168 const char custom_buf[] = "Custom greeting";
169 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
170 OSSL_PARAM *params = NULL;
171
172 OSSL_PARAM_BLD_push_utf8_string(bld, "greeting", custom_buf, strlen(custom_buf));
173 params = OSSL_PARAM_BLD_to_param(bld);
174
175 OSSL_PARAM_BLD_free(bld);
176
177 if (!TEST_ptr(prov = OSSL_PROVIDER_load_ex(*libctx, name, params)))
178 goto err;
179
180 if (!TEST_true(OSSL_PROVIDER_get_params(prov, greeting_request))
181 || !TEST_ptr(greeting = greeting_request[0].data)
182 || !TEST_size_t_gt(greeting_request[0].data_size, 0)
183 || !TEST_str_eq(greeting, custom_buf))
184 goto err;
185
186 /* Make sure we got the error we were expecting */
187 err = ERR_peek_last_error();
188 if (!TEST_int_gt(err, 0)
189 || !TEST_int_eq(ERR_GET_REASON(err), 1))
190 goto err;
191
192 if (!TEST_true(OSSL_PROVIDER_unload(prov)))
193 goto err;
194 prov = NULL;
195
196 /*
197 * We must free the libctx to force the provider to really be unloaded from
198 * memory
199 */
200 OSSL_LIB_CTX_free(*libctx);
201 *libctx = NULL;
202
203 /* We print out all the data to make sure it can still be accessed */
204 ERR_print_errors_fp(stderr);
205 ok = 1;
206 err:
207 OSSL_PARAM_free(params);
208 OSSL_PROVIDER_unload(prov);
209 OSSL_LIB_CTX_free(*libctx);
210 *libctx = NULL;
211 return ok;
212}
213#endif
214
021a6552
RL
215static int test_builtin_provider(void)
216{
81c15ed0 217 OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
021a6552 218 const char *name = "p_test_builtin";
81c15ed0 219 int ok;
021a6552 220
81c15ed0
MC
221 ok =
222 TEST_ptr(libctx)
223 && TEST_true(OSSL_PROVIDER_add_builtin(libctx, name,
224 PROVIDER_INIT_FUNCTION_NAME))
5442611d 225 && test_provider(&libctx, name, NULL);
81c15ed0
MC
226
227 OSSL_LIB_CTX_free(libctx);
228
229 return ok;
021a6552
RL
230}
231
fb9b3a7b
MC
232/* Test relies on fetching the MD4 digest from the legacy provider */
233#ifndef OPENSSL_NO_MD4
5442611d
MC
234static int test_builtin_provider_with_child(void)
235{
236 OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
237 const char *name = "p_test";
238 OSSL_PROVIDER *legacy;
239
240 if (!TEST_ptr(libctx))
241 return 0;
242
243 legacy = OSSL_PROVIDER_load(libctx, "legacy");
244 if (legacy == NULL) {
245 /*
246 * In this case we assume we've been built with "no-legacy" and skip
247 * this test (there is no OPENSSL_NO_LEGACY)
248 */
49d874e0 249 OSSL_LIB_CTX_free(libctx);
5442611d
MC
250 return 1;
251 }
252
253 if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, name,
49d874e0
RL
254 PROVIDER_INIT_FUNCTION_NAME))) {
255 OSSL_LIB_CTX_free(libctx);
5442611d 256 return 0;
49d874e0 257 }
5442611d
MC
258
259 /* test_provider will free libctx and unload legacy as part of the test */
260 return test_provider(&libctx, name, legacy);
261}
fb9b3a7b 262#endif
5442611d 263
2a2bc6fc 264#ifndef NO_PROVIDER_MODULE
021a6552
RL
265static int test_loaded_provider(void)
266{
81c15ed0 267 OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
021a6552 268 const char *name = "p_test";
4f3e3d9d 269 int res = 0;
021a6552 270
81c15ed0
MC
271 if (!TEST_ptr(libctx))
272 return 0;
273
274 /* test_provider will free libctx as part of the test */
4f3e3d9d
DB
275 res = test_provider(&libctx, name, NULL);
276
277 libctx = OSSL_LIB_CTX_new();
278 if (!TEST_ptr(libctx))
279 return 0;
280
281 /* test_provider_ex will free libctx as part of the test */
282 res = res && test_provider_ex(&libctx, name);
283
284 return res;
021a6552
RL
285}
286#endif
287
5442611d
MC
288typedef enum OPTION_choice {
289 OPT_ERR = -1,
290 OPT_EOF = 0,
291 OPT_LOADED,
292 OPT_TEST_ENUM
293} OPTION_CHOICE;
294
295const OPTIONS *test_get_options(void)
296{
297 static const OPTIONS test_options[] = {
298 OPT_TEST_OPTIONS_DEFAULT_USAGE,
299 { "loaded", OPT_LOADED, '-', "Run test with a loaded provider" },
300 { NULL }
301 };
302 return test_options;
303}
304
021a6552
RL
305int setup_tests(void)
306{
5442611d
MC
307 OPTION_CHOICE o;
308 int loaded = 0;
309
310 while ((o = opt_next()) != OPT_EOF) {
311 switch (o) {
312 case OPT_TEST_CASES:
313 break;
314 case OPT_LOADED:
315 loaded = 1;
316 break;
317 default:
318 return 0;
319 }
320 }
321
322 if (!loaded) {
323 ADD_TEST(test_builtin_provider);
fb9b3a7b 324#ifndef OPENSSL_NO_MD4
5442611d 325 ADD_TEST(test_builtin_provider_with_child);
fb9b3a7b 326#endif
5442611d 327 }
2a2bc6fc 328#ifndef NO_PROVIDER_MODULE
5442611d
MC
329 else {
330 ADD_TEST(test_loaded_provider);
331 }
021a6552
RL
332#endif
333 return 1;
334}
335