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