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