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