xref: /freebsd/crypto/openssl/test/provider_test.c (revision e0c4386e)
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