| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-05-03 18:52:38 +08:00
										 |  |  |  * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							|  |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stddef.h>
 | 
					
						
							|  |  |  | #include <openssl/provider.h>
 | 
					
						
							|  |  |  | #include "testutil.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern OSSL_provider_init_fn PROVIDER_INIT_FUNCTION_NAME; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char buf[256]; | 
					
						
							|  |  |  | static OSSL_PARAM greeting_request[] = { | 
					
						
							| 
									
										
										
										
											2019-06-24 12:43:55 +08:00
										 |  |  |     { "greeting", OSSL_PARAM_UTF8_STRING, buf, sizeof(buf) }, | 
					
						
							|  |  |  |     { NULL, 0, NULL, 0, 0 } | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  | static unsigned int digestsuccess = 0; | 
					
						
							|  |  |  | static OSSL_PARAM digest_check[] = { | 
					
						
							|  |  |  |     { "digest-check", OSSL_PARAM_UNSIGNED_INTEGER, &digestsuccess, | 
					
						
							|  |  |  |       sizeof(digestsuccess) }, | 
					
						
							|  |  |  |     { NULL, 0, NULL, 0, 0 } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 23:50:27 +08:00
										 |  |  | static unsigned int stopsuccess = 0; | 
					
						
							|  |  |  | static OSSL_PARAM stop_property_mirror[] = { | 
					
						
							|  |  |  |     { "stop-property-mirror", OSSL_PARAM_UNSIGNED_INTEGER, &stopsuccess, | 
					
						
							|  |  |  |       sizeof(stopsuccess) }, | 
					
						
							|  |  |  |     { NULL, 0, NULL, 0, 0 } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  | static int test_provider(OSSL_LIB_CTX **libctx, const char *name, | 
					
						
							|  |  |  |                          OSSL_PROVIDER *legacy) | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     OSSL_PROVIDER *prov = NULL; | 
					
						
							|  |  |  |     const char *greeting = NULL; | 
					
						
							|  |  |  |     char expected_greeting[256]; | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  |     int ok = 0; | 
					
						
							|  |  |  |     long err; | 
					
						
							| 
									
										
										
										
											2021-04-26 23:00:04 +08:00
										 |  |  |     int dolegacycheck = (legacy != NULL); | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  |     OSSL_PROVIDER *deflt = NULL, *base = NULL; | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-25 09:37:24 +08:00
										 |  |  |     BIO_snprintf(expected_greeting, sizeof(expected_greeting), | 
					
						
							| 
									
										
										
										
											2019-03-26 13:20:22 +08:00
										 |  |  |                  "Hello OpenSSL %.20s, greetings from %s!", | 
					
						
							|  |  |  |                  OPENSSL_VERSION_STR, name); | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-11 18:44:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * We set properties that we know the providers we are using don't have. | 
					
						
							|  |  |  |      * This should mean that the p_test provider will fail any fetches - which | 
					
						
							|  |  |  |      * is something we test inside the provider. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     EVP_set_default_properties(*libctx, "fips=yes"); | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  |     /*
 | 
					
						
							| 
									
										
										
										
											2021-05-11 18:44:43 +08:00
										 |  |  |      * Check that it is possible to have a built-in provider mirrored in | 
					
						
							|  |  |  |      * a child lib ctx. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  |     if (!TEST_ptr(base = OSSL_PROVIDER_load(*libctx, "base"))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |     if (!TEST_ptr(prov = OSSL_PROVIDER_load(*libctx, name))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2021-05-11 18:44:43 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Once the provider is loaded we clear the default properties and fetches | 
					
						
							|  |  |  |      * should start working again. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     EVP_set_default_properties(*libctx, ""); | 
					
						
							| 
									
										
										
										
											2021-04-26 23:00:04 +08:00
										 |  |  |     if (dolegacycheck) { | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |         if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check)) | 
					
						
							|  |  |  |                 || !TEST_true(digestsuccess)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							| 
									
										
										
										
											2021-05-11 23:50:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * Check that a provider can prevent property mirroring if it sets its | 
					
						
							|  |  |  |          * own properties explicitly | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         if (!TEST_true(OSSL_PROVIDER_get_params(prov, stop_property_mirror)) | 
					
						
							|  |  |  |                 || !TEST_true(stopsuccess)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         EVP_set_default_properties(*libctx, "fips=yes"); | 
					
						
							|  |  |  |         if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check)) | 
					
						
							|  |  |  |                 || !TEST_true(digestsuccess)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         EVP_set_default_properties(*libctx, ""); | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (!TEST_true(OSSL_PROVIDER_get_params(prov, greeting_request)) | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  |             || !TEST_ptr(greeting = greeting_request[0].data) | 
					
						
							|  |  |  |             || !TEST_size_t_gt(greeting_request[0].data_size, 0) | 
					
						
							| 
									
										
										
										
											2021-04-26 23:00:04 +08:00
										 |  |  |             || !TEST_str_eq(greeting, expected_greeting)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Make sure we got the error we were expecting */ | 
					
						
							|  |  |  |     err = ERR_peek_last_error(); | 
					
						
							|  |  |  |     if (!TEST_int_gt(err, 0) | 
					
						
							|  |  |  |             || !TEST_int_eq(ERR_GET_REASON(err), 1)) | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |     OSSL_PROVIDER_unload(legacy); | 
					
						
							|  |  |  |     legacy = NULL; | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-26 23:00:04 +08:00
										 |  |  |     if (dolegacycheck) { | 
					
						
							|  |  |  |         /* Legacy provider should also be unloaded from child libctx */ | 
					
						
							|  |  |  |         if (!TEST_true(OSSL_PROVIDER_get_params(prov, digest_check)) | 
					
						
							|  |  |  |                 || !TEST_false(digestsuccess)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * Loading the legacy provider again should make it available again in | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  |          * the child libctx. Loading and unloading the default provider should | 
					
						
							|  |  |  |          * have no impact on the child because the child loads it explicitly | 
					
						
							|  |  |  |          * before this point. | 
					
						
							| 
									
										
										
										
											2021-04-26 23:00:04 +08:00
										 |  |  |          */ | 
					
						
							|  |  |  |         legacy = OSSL_PROVIDER_load(*libctx, "legacy"); | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  |         deflt = OSSL_PROVIDER_load(*libctx, "default"); | 
					
						
							|  |  |  |         if (!TEST_ptr(deflt) | 
					
						
							|  |  |  |                 || !TEST_true(OSSL_PROVIDER_available(*libctx, "default"))) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         OSSL_PROVIDER_unload(deflt); | 
					
						
							|  |  |  |         deflt = NULL; | 
					
						
							| 
									
										
										
										
											2021-04-26 23:00:04 +08:00
										 |  |  |         if (!TEST_ptr(legacy) | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  |                 || !TEST_false(OSSL_PROVIDER_available(*libctx, "default")) | 
					
						
							| 
									
										
										
										
											2021-04-26 23:00:04 +08:00
										 |  |  |                 || !TEST_true(OSSL_PROVIDER_get_params(prov, digest_check)) | 
					
						
							|  |  |  |                 || !TEST_true(digestsuccess)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |         OSSL_PROVIDER_unload(legacy); | 
					
						
							|  |  |  |         legacy = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  |     if (!TEST_true(OSSL_PROVIDER_unload(base))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     base = NULL; | 
					
						
							| 
									
										
										
										
											2021-04-26 23:00:04 +08:00
										 |  |  |     if (!TEST_true(OSSL_PROVIDER_unload(prov))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     prov = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * We must free the libctx to force the provider to really be unloaded from | 
					
						
							|  |  |  |      * memory | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     OSSL_LIB_CTX_free(*libctx); | 
					
						
							|  |  |  |     *libctx = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* We print out all the data to make sure it can still be accessed */ | 
					
						
							|  |  |  |     ERR_print_errors_fp(stderr); | 
					
						
							|  |  |  |     ok = 1; | 
					
						
							|  |  |  |  err: | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  |     OSSL_PROVIDER_unload(base); | 
					
						
							|  |  |  |     OSSL_PROVIDER_unload(deflt); | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |     OSSL_PROVIDER_unload(legacy); | 
					
						
							|  |  |  |     legacy = NULL; | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  |     OSSL_PROVIDER_unload(prov); | 
					
						
							|  |  |  |     OSSL_LIB_CTX_free(*libctx); | 
					
						
							|  |  |  |     *libctx = NULL; | 
					
						
							|  |  |  |     return ok; | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int test_builtin_provider(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  |     OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new(); | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  |     const char *name = "p_test_builtin"; | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  |     int ok; | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  |     ok = | 
					
						
							|  |  |  |         TEST_ptr(libctx) | 
					
						
							|  |  |  |         && TEST_true(OSSL_PROVIDER_add_builtin(libctx, name, | 
					
						
							|  |  |  |                                                PROVIDER_INIT_FUNCTION_NAME)) | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |         && test_provider(&libctx, name, NULL); | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     OSSL_LIB_CTX_free(libctx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ok; | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  | /* Test relies on fetching the MD4 digest from the legacy provider */ | 
					
						
							|  |  |  | #ifndef OPENSSL_NO_MD4
 | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  | static int test_builtin_provider_with_child(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new(); | 
					
						
							|  |  |  |     const char *name = "p_test"; | 
					
						
							|  |  |  |     OSSL_PROVIDER *legacy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!TEST_ptr(libctx)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     legacy = OSSL_PROVIDER_load(libctx, "legacy"); | 
					
						
							|  |  |  |     if (legacy == NULL) { | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * In this case we assume we've been built with "no-legacy" and skip | 
					
						
							|  |  |  |          * this test (there is no OPENSSL_NO_LEGACY) | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2022-04-26 17:04:49 +08:00
										 |  |  |         OSSL_LIB_CTX_free(libctx); | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, name, | 
					
						
							| 
									
										
										
										
											2022-04-26 17:04:49 +08:00
										 |  |  |                                              PROVIDER_INIT_FUNCTION_NAME))) { | 
					
						
							|  |  |  |         OSSL_LIB_CTX_free(libctx); | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2022-04-26 17:04:49 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* test_provider will free libctx and unload legacy as part of the test */ | 
					
						
							|  |  |  |     return test_provider(&libctx, name, legacy); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-04 18:35:47 +08:00
										 |  |  | #ifndef NO_PROVIDER_MODULE
 | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | static int test_loaded_provider(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  |     OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new(); | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  |     const char *name = "p_test"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-16 18:10:26 +08:00
										 |  |  |     if (!TEST_ptr(libctx)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* test_provider will free libctx as part of the test */ | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |     return test_provider(&libctx, name, NULL); | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  | typedef enum OPTION_choice { | 
					
						
							|  |  |  |     OPT_ERR = -1, | 
					
						
							|  |  |  |     OPT_EOF = 0, | 
					
						
							|  |  |  |     OPT_LOADED, | 
					
						
							|  |  |  |     OPT_TEST_ENUM | 
					
						
							|  |  |  | } OPTION_CHOICE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const OPTIONS *test_get_options(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static const OPTIONS test_options[] = { | 
					
						
							|  |  |  |         OPT_TEST_OPTIONS_DEFAULT_USAGE, | 
					
						
							|  |  |  |         { "loaded", OPT_LOADED, '-', "Run test with a loaded provider" }, | 
					
						
							|  |  |  |         { NULL } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     return test_options; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | int setup_tests(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |     OPTION_CHOICE o; | 
					
						
							|  |  |  |     int loaded = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while ((o = opt_next()) != OPT_EOF) { | 
					
						
							|  |  |  |         switch (o) { | 
					
						
							|  |  |  |         case OPT_TEST_CASES: | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case OPT_LOADED: | 
					
						
							|  |  |  |             loaded = 1; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!loaded) { | 
					
						
							|  |  |  |         ADD_TEST(test_builtin_provider); | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  | #ifndef OPENSSL_NO_MD4
 | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |         ADD_TEST(test_builtin_provider_with_child); | 
					
						
							| 
									
										
										
										
											2021-05-05 00:38:10 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-04 18:35:47 +08:00
										 |  |  | #ifndef NO_PROVIDER_MODULE
 | 
					
						
							| 
									
										
										
										
											2021-04-22 22:58:50 +08:00
										 |  |  |     else { | 
					
						
							|  |  |  |         ADD_TEST(test_loaded_provider); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-02-21 05:55:43 +08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |