Home | History | Annotate | Line # | Download | only in test
      1      1.1  christos /*
      2      1.1  christos  * Copyright 2021-2023 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 <openssl/crypto.h>
     11      1.1  christos #include <openssl/provider.h>
     12      1.1  christos #include <openssl/decoder.h>
     13      1.1  christos #include <openssl/encoder.h>
     14      1.1  christos #include <openssl/store.h>
     15      1.1  christos #include <openssl/rand.h>
     16      1.1  christos #include <openssl/core_names.h>
     17      1.1  christos #include "testutil.h"
     18      1.1  christos 
     19      1.1  christos static int dummy_decoder_decode(void *ctx, OSSL_CORE_BIO *cin, int selection,
     20  1.1.1.2  christos     OSSL_CALLBACK *object_cb, void *object_cbarg,
     21  1.1.1.2  christos     OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
     22      1.1  christos {
     23      1.1  christos     return 0;
     24      1.1  christos }
     25      1.1  christos 
     26      1.1  christos static const OSSL_DISPATCH dummy_decoder_functions[] = {
     27      1.1  christos     { OSSL_FUNC_DECODER_DECODE, (void (*)(void))dummy_decoder_decode },
     28      1.1  christos     OSSL_DISPATCH_END
     29      1.1  christos };
     30      1.1  christos 
     31      1.1  christos static const OSSL_ALGORITHM dummy_decoders[] = {
     32      1.1  christos     { "DUMMY", "provider=dummy,input=pem", dummy_decoder_functions },
     33      1.1  christos     { NULL, NULL, NULL }
     34      1.1  christos };
     35      1.1  christos 
     36      1.1  christos static int dummy_encoder_encode(void *ctx, OSSL_CORE_BIO *out,
     37  1.1.1.2  christos     const void *obj_raw,
     38  1.1.1.2  christos     const OSSL_PARAM obj_abstract[], int selection,
     39  1.1.1.2  christos     OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
     40      1.1  christos {
     41      1.1  christos     return 0;
     42      1.1  christos }
     43      1.1  christos 
     44      1.1  christos static const OSSL_DISPATCH dummy_encoder_functions[] = {
     45      1.1  christos     { OSSL_FUNC_DECODER_DECODE, (void (*)(void))dummy_encoder_encode },
     46      1.1  christos     OSSL_DISPATCH_END
     47      1.1  christos };
     48      1.1  christos 
     49      1.1  christos static const OSSL_ALGORITHM dummy_encoders[] = {
     50      1.1  christos     { "DUMMY", "provider=dummy,output=pem", dummy_encoder_functions },
     51      1.1  christos     { NULL, NULL, NULL }
     52      1.1  christos };
     53      1.1  christos 
     54      1.1  christos static void *dummy_store_open(void *provctx, const char *uri)
     55      1.1  christos {
     56      1.1  christos     return NULL;
     57      1.1  christos }
     58      1.1  christos 
     59  1.1.1.2  christos static int dummy_store_load(void *loaderctx, OSSL_CALLBACK *object_cb,
     60  1.1.1.2  christos     void *object_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb,
     61  1.1.1.2  christos     void *pw_cbarg)
     62      1.1  christos {
     63      1.1  christos     return 0;
     64      1.1  christos }
     65      1.1  christos 
     66      1.1  christos static int dumm_store_eof(void *loaderctx)
     67      1.1  christos {
     68      1.1  christos     return 0;
     69      1.1  christos }
     70      1.1  christos 
     71      1.1  christos static int dummy_store_close(void *loaderctx)
     72      1.1  christos {
     73      1.1  christos     return 0;
     74      1.1  christos }
     75      1.1  christos 
     76      1.1  christos static const OSSL_DISPATCH dummy_store_functions[] = {
     77      1.1  christos     { OSSL_FUNC_STORE_OPEN, (void (*)(void))dummy_store_open },
     78      1.1  christos     { OSSL_FUNC_STORE_LOAD, (void (*)(void))dummy_store_load },
     79      1.1  christos     { OSSL_FUNC_STORE_EOF, (void (*)(void))dumm_store_eof },
     80      1.1  christos     { OSSL_FUNC_STORE_CLOSE, (void (*)(void))dummy_store_close },
     81      1.1  christos     OSSL_DISPATCH_END
     82      1.1  christos };
     83      1.1  christos 
     84      1.1  christos static const OSSL_ALGORITHM dummy_store[] = {
     85      1.1  christos     { "DUMMY", "provider=dummy", dummy_store_functions },
     86      1.1  christos     { NULL, NULL, NULL }
     87      1.1  christos };
     88      1.1  christos 
     89      1.1  christos static void *dummy_rand_newctx(void *provctx, void *parent,
     90  1.1.1.2  christos     const OSSL_DISPATCH *parent_calls)
     91      1.1  christos {
     92      1.1  christos     return provctx;
     93      1.1  christos }
     94      1.1  christos 
     95      1.1  christos static void dummy_rand_freectx(void *vctx)
     96      1.1  christos {
     97      1.1  christos }
     98      1.1  christos 
     99      1.1  christos static int dummy_rand_instantiate(void *vdrbg, unsigned int strength,
    100  1.1.1.2  christos     int prediction_resistance,
    101  1.1.1.2  christos     const unsigned char *pstr, size_t pstr_len,
    102  1.1.1.2  christos     const OSSL_PARAM params[])
    103      1.1  christos {
    104      1.1  christos     return 1;
    105      1.1  christos }
    106      1.1  christos 
    107      1.1  christos static int dummy_rand_uninstantiate(void *vdrbg)
    108      1.1  christos {
    109      1.1  christos     return 1;
    110      1.1  christos }
    111      1.1  christos 
    112      1.1  christos static int dummy_rand_generate(void *vctx, unsigned char *out, size_t outlen,
    113  1.1.1.2  christos     unsigned int strength, int prediction_resistance,
    114  1.1.1.2  christos     const unsigned char *addin, size_t addin_len)
    115      1.1  christos {
    116      1.1  christos     size_t i;
    117      1.1  christos 
    118  1.1.1.2  christos     for (i = 0; i < outlen; i++)
    119      1.1  christos         out[i] = (unsigned char)(i & 0xff);
    120      1.1  christos 
    121      1.1  christos     return 1;
    122      1.1  christos }
    123      1.1  christos 
    124      1.1  christos static const OSSL_PARAM *dummy_rand_gettable_ctx_params(void *vctx, void *provctx)
    125      1.1  christos {
    126      1.1  christos     static const OSSL_PARAM known_gettable_ctx_params[] = {
    127      1.1  christos         OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),
    128      1.1  christos         OSSL_PARAM_END
    129      1.1  christos     };
    130      1.1  christos     return known_gettable_ctx_params;
    131      1.1  christos }
    132      1.1  christos 
    133      1.1  christos static int dummy_rand_get_ctx_params(void *vctx, OSSL_PARAM params[])
    134      1.1  christos {
    135      1.1  christos     OSSL_PARAM *p;
    136      1.1  christos 
    137      1.1  christos     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
    138      1.1  christos     if (p != NULL && !OSSL_PARAM_set_size_t(p, INT_MAX))
    139      1.1  christos         return 0;
    140      1.1  christos 
    141      1.1  christos     return 1;
    142      1.1  christos }
    143      1.1  christos 
    144      1.1  christos static int dummy_rand_enable_locking(void *vtest)
    145      1.1  christos {
    146      1.1  christos     return 1;
    147      1.1  christos }
    148      1.1  christos 
    149      1.1  christos static int dummy_rand_lock(void *vtest)
    150      1.1  christos {
    151      1.1  christos     return 1;
    152      1.1  christos }
    153      1.1  christos 
    154      1.1  christos static void dummy_rand_unlock(void *vtest)
    155      1.1  christos {
    156      1.1  christos }
    157      1.1  christos 
    158      1.1  christos static const OSSL_DISPATCH dummy_rand_functions[] = {
    159      1.1  christos     { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))dummy_rand_newctx },
    160      1.1  christos     { OSSL_FUNC_RAND_FREECTX, (void (*)(void))dummy_rand_freectx },
    161      1.1  christos     { OSSL_FUNC_RAND_INSTANTIATE, (void (*)(void))dummy_rand_instantiate },
    162      1.1  christos     { OSSL_FUNC_RAND_UNINSTANTIATE, (void (*)(void))dummy_rand_uninstantiate },
    163      1.1  christos     { OSSL_FUNC_RAND_GENERATE, (void (*)(void))dummy_rand_generate },
    164      1.1  christos     { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
    165  1.1.1.2  christos         (void (*)(void))dummy_rand_gettable_ctx_params },
    166  1.1.1.2  christos     { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void (*)(void))dummy_rand_get_ctx_params },
    167  1.1.1.2  christos     { OSSL_FUNC_RAND_ENABLE_LOCKING, (void (*)(void))dummy_rand_enable_locking },
    168  1.1.1.2  christos     { OSSL_FUNC_RAND_LOCK, (void (*)(void))dummy_rand_lock },
    169  1.1.1.2  christos     { OSSL_FUNC_RAND_UNLOCK, (void (*)(void))dummy_rand_unlock },
    170      1.1  christos     OSSL_DISPATCH_END
    171      1.1  christos };
    172      1.1  christos 
    173      1.1  christos static const OSSL_ALGORITHM dummy_rand[] = {
    174      1.1  christos     { "DUMMY", "provider=dummy", dummy_rand_functions },
    175      1.1  christos     { NULL, NULL, NULL }
    176      1.1  christos };
    177      1.1  christos 
    178      1.1  christos static const OSSL_ALGORITHM *dummy_query(void *provctx, int operation_id,
    179  1.1.1.2  christos     int *no_cache)
    180      1.1  christos {
    181      1.1  christos     *no_cache = 0;
    182      1.1  christos     switch (operation_id) {
    183      1.1  christos     case OSSL_OP_DECODER:
    184      1.1  christos         return dummy_decoders;
    185      1.1  christos     case OSSL_OP_ENCODER:
    186      1.1  christos         return dummy_encoders;
    187      1.1  christos     case OSSL_OP_STORE:
    188      1.1  christos         return dummy_store;
    189      1.1  christos     case OSSL_OP_RAND:
    190      1.1  christos         return dummy_rand;
    191      1.1  christos     }
    192      1.1  christos     return NULL;
    193      1.1  christos }
    194      1.1  christos 
    195      1.1  christos static const OSSL_DISPATCH dummy_dispatch_table[] = {
    196      1.1  christos     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))dummy_query },
    197      1.1  christos     { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OSSL_LIB_CTX_free },
    198      1.1  christos     OSSL_DISPATCH_END
    199      1.1  christos };
    200      1.1  christos 
    201      1.1  christos static int dummy_provider_init(const OSSL_CORE_HANDLE *handle,
    202  1.1.1.2  christos     const OSSL_DISPATCH *in,
    203  1.1.1.2  christos     const OSSL_DISPATCH **out,
    204  1.1.1.2  christos     void **provctx)
    205      1.1  christos {
    206      1.1  christos     OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new_child(handle, in);
    207      1.1  christos     unsigned char buf[32];
    208      1.1  christos 
    209      1.1  christos     *provctx = (void *)libctx;
    210      1.1  christos     *out = dummy_dispatch_table;
    211      1.1  christos 
    212      1.1  christos     /*
    213      1.1  christos      * Do some work using the child libctx, to make sure this is possible from
    214      1.1  christos      * inside the init function.
    215      1.1  christos      */
    216      1.1  christos     if (RAND_bytes_ex(libctx, buf, sizeof(buf), 0) <= 0)
    217      1.1  christos         return 0;
    218      1.1  christos 
    219      1.1  christos     return 1;
    220      1.1  christos }
    221      1.1  christos 
    222      1.1  christos /*
    223      1.1  christos  * Try fetching and freeing various things.
    224      1.1  christos  * Test 0: Decoder
    225      1.1  christos  * Test 1: Encoder
    226      1.1  christos  * Test 2: Store loader
    227      1.1  christos  * Test 3: EVP_RAND
    228      1.1  christos  * Test 4-7: As above, but additionally with a query string
    229      1.1  christos  */
    230      1.1  christos static int fetch_test(int tst)
    231      1.1  christos {
    232      1.1  christos     OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new();
    233      1.1  christos     OSSL_PROVIDER *dummyprov = NULL;
    234      1.1  christos     OSSL_PROVIDER *nullprov = NULL;
    235      1.1  christos     OSSL_DECODER *decoder = NULL;
    236      1.1  christos     OSSL_ENCODER *encoder = NULL;
    237      1.1  christos     OSSL_STORE_LOADER *loader = NULL;
    238      1.1  christos     int testresult = 0;
    239      1.1  christos     unsigned char buf[32];
    240      1.1  christos     int query = tst > 3;
    241      1.1  christos 
    242      1.1  christos     if (!TEST_ptr(libctx))
    243      1.1  christos         goto err;
    244      1.1  christos 
    245      1.1  christos     if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, "dummy-prov",
    246  1.1.1.2  christos             dummy_provider_init))
    247  1.1.1.2  christos         || !TEST_ptr(nullprov = OSSL_PROVIDER_load(libctx, "default"))
    248  1.1.1.2  christos         || !TEST_ptr(dummyprov = OSSL_PROVIDER_load(libctx, "dummy-prov")))
    249      1.1  christos         goto err;
    250      1.1  christos 
    251      1.1  christos     switch (tst % 4) {
    252      1.1  christos     case 0:
    253      1.1  christos         decoder = OSSL_DECODER_fetch(libctx, "DUMMY",
    254  1.1.1.2  christos             query ? "provider=dummy" : NULL);
    255      1.1  christos         if (!TEST_ptr(decoder))
    256      1.1  christos             goto err;
    257      1.1  christos         break;
    258      1.1  christos     case 1:
    259      1.1  christos         encoder = OSSL_ENCODER_fetch(libctx, "DUMMY",
    260  1.1.1.2  christos             query ? "provider=dummy" : NULL);
    261      1.1  christos         if (!TEST_ptr(encoder))
    262      1.1  christos             goto err;
    263      1.1  christos         break;
    264      1.1  christos     case 2:
    265      1.1  christos         loader = OSSL_STORE_LOADER_fetch(libctx, "DUMMY",
    266  1.1.1.2  christos             query ? "provider=dummy" : NULL);
    267      1.1  christos         if (!TEST_ptr(loader))
    268      1.1  christos             goto err;
    269      1.1  christos         break;
    270      1.1  christos     case 3:
    271      1.1  christos         if (!TEST_true(RAND_set_DRBG_type(libctx, "DUMMY",
    272  1.1.1.2  christos                 query ? "provider=dummy" : NULL,
    273  1.1.1.2  christos                 NULL, NULL))
    274  1.1.1.2  christos             || !TEST_int_ge(RAND_bytes_ex(libctx, buf, sizeof(buf), 0), 1))
    275      1.1  christos             goto err;
    276      1.1  christos         break;
    277      1.1  christos     default:
    278      1.1  christos         goto err;
    279      1.1  christos     }
    280      1.1  christos 
    281      1.1  christos     testresult = 1;
    282  1.1.1.2  christos err:
    283      1.1  christos     OSSL_DECODER_free(decoder);
    284      1.1  christos     OSSL_ENCODER_free(encoder);
    285      1.1  christos     OSSL_STORE_LOADER_free(loader);
    286      1.1  christos     OSSL_PROVIDER_unload(dummyprov);
    287      1.1  christos     OSSL_PROVIDER_unload(nullprov);
    288      1.1  christos     OSSL_LIB_CTX_free(libctx);
    289      1.1  christos     return testresult;
    290      1.1  christos }
    291      1.1  christos 
    292      1.1  christos int setup_tests(void)
    293      1.1  christos {
    294      1.1  christos     ADD_ALL_TESTS(fetch_test, 8);
    295      1.1  christos 
    296      1.1  christos     return 1;
    297      1.1  christos }
    298