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