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