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