| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2023-09-07 16:59:15 +08:00
										 |  |  |  * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							|  |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <openssl/crypto.h>
 | 
					
						
							|  |  |  | #include <openssl/provider.h>
 | 
					
						
							|  |  |  | #include <openssl/decoder.h>
 | 
					
						
							|  |  |  | #include <openssl/encoder.h>
 | 
					
						
							|  |  |  | #include <openssl/store.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-16 23:57:18 +08:00
										 |  |  | #include <openssl/rand.h>
 | 
					
						
							|  |  |  | #include <openssl/core_names.h>
 | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  | #include "testutil.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_decoder_decode(void *ctx, OSSL_CORE_BIO *cin, int selection, | 
					
						
							|  |  |  |                                 OSSL_CALLBACK *object_cb, void *object_cbarg, | 
					
						
							|  |  |  |                                 OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_DISPATCH dummy_decoder_functions[] = { | 
					
						
							|  |  |  |     { OSSL_FUNC_DECODER_DECODE, (void (*)(void))dummy_decoder_decode }, | 
					
						
							| 
									
										
										
										
											2023-04-19 22:08:22 +08:00
										 |  |  |     OSSL_DISPATCH_END | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_ALGORITHM dummy_decoders[] = { | 
					
						
							|  |  |  |     { "DUMMY", "provider=dummy,input=pem", dummy_decoder_functions }, | 
					
						
							|  |  |  |     { NULL, NULL, NULL } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_encoder_encode(void *ctx, OSSL_CORE_BIO *out, | 
					
						
							|  |  |  |                                 const void *obj_raw, | 
					
						
							|  |  |  |                                 const OSSL_PARAM obj_abstract[], int selection, | 
					
						
							|  |  |  |                                 OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_DISPATCH dummy_encoder_functions[] = { | 
					
						
							|  |  |  |     { OSSL_FUNC_DECODER_DECODE, (void (*)(void))dummy_encoder_encode }, | 
					
						
							| 
									
										
										
										
											2023-04-19 22:08:22 +08:00
										 |  |  |     OSSL_DISPATCH_END | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_ALGORITHM dummy_encoders[] = { | 
					
						
							|  |  |  |     { "DUMMY", "provider=dummy,output=pem", dummy_encoder_functions }, | 
					
						
							|  |  |  |     { NULL, NULL, NULL } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void *dummy_store_open(void *provctx, const char *uri) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_store_load(void *loaderctx,  OSSL_CALLBACK *object_cb, | 
					
						
							|  |  |  |                             void *object_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb, | 
					
						
							|  |  |  |                             void *pw_cbarg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dumm_store_eof(void *loaderctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_store_close(void *loaderctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_DISPATCH dummy_store_functions[] = { | 
					
						
							|  |  |  |     { OSSL_FUNC_STORE_OPEN, (void (*)(void))dummy_store_open }, | 
					
						
							|  |  |  |     { OSSL_FUNC_STORE_LOAD, (void (*)(void))dummy_store_load }, | 
					
						
							|  |  |  |     { OSSL_FUNC_STORE_EOF, (void (*)(void))dumm_store_eof }, | 
					
						
							|  |  |  |     { OSSL_FUNC_STORE_CLOSE, (void (*)(void))dummy_store_close }, | 
					
						
							| 
									
										
										
										
											2023-04-19 22:08:22 +08:00
										 |  |  |     OSSL_DISPATCH_END | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_ALGORITHM dummy_store[] = { | 
					
						
							|  |  |  |     { "DUMMY", "provider=dummy", dummy_store_functions }, | 
					
						
							|  |  |  |     { NULL, NULL, NULL } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-16 23:57:18 +08:00
										 |  |  | static void *dummy_rand_newctx(void *provctx, void *parent, | 
					
						
							|  |  |  |                                const OSSL_DISPATCH *parent_calls) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return provctx; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void dummy_rand_freectx(void *vctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_rand_instantiate(void *vdrbg, unsigned int strength, | 
					
						
							|  |  |  |                                   int prediction_resistance, | 
					
						
							|  |  |  |                                   const unsigned char *pstr, size_t pstr_len, | 
					
						
							|  |  |  |                                   const OSSL_PARAM params[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_rand_uninstantiate(void *vdrbg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_rand_generate(void *vctx, unsigned char *out, size_t outlen, | 
					
						
							|  |  |  |                                unsigned int strength, int prediction_resistance, | 
					
						
							|  |  |  |                                const unsigned char *addin, size_t addin_len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     size_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i <outlen; i++) | 
					
						
							|  |  |  |         out[i] = (unsigned char)(i & 0xff); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_PARAM *dummy_rand_gettable_ctx_params(void *vctx, void *provctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static const OSSL_PARAM known_gettable_ctx_params[] = { | 
					
						
							|  |  |  |         OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL), | 
					
						
							|  |  |  |         OSSL_PARAM_END | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     return known_gettable_ctx_params; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_rand_get_ctx_params(void *vctx, OSSL_PARAM params[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_PARAM *p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST); | 
					
						
							|  |  |  |     if (p != NULL && !OSSL_PARAM_set_size_t(p, INT_MAX)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_rand_enable_locking(void *vtest) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_rand_lock(void *vtest) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void dummy_rand_unlock(void *vtest) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_DISPATCH dummy_rand_functions[] = { | 
					
						
							|  |  |  |     { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))dummy_rand_newctx }, | 
					
						
							|  |  |  |     { OSSL_FUNC_RAND_FREECTX, (void (*)(void))dummy_rand_freectx }, | 
					
						
							|  |  |  |     { OSSL_FUNC_RAND_INSTANTIATE, (void (*)(void))dummy_rand_instantiate }, | 
					
						
							|  |  |  |     { OSSL_FUNC_RAND_UNINSTANTIATE, (void (*)(void))dummy_rand_uninstantiate }, | 
					
						
							|  |  |  |     { OSSL_FUNC_RAND_GENERATE, (void (*)(void))dummy_rand_generate }, | 
					
						
							|  |  |  |     { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS, | 
					
						
							|  |  |  |       (void(*)(void))dummy_rand_gettable_ctx_params }, | 
					
						
							|  |  |  |     { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))dummy_rand_get_ctx_params }, | 
					
						
							|  |  |  |     { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))dummy_rand_enable_locking }, | 
					
						
							|  |  |  |     { OSSL_FUNC_RAND_LOCK, (void(*)(void))dummy_rand_lock }, | 
					
						
							|  |  |  |     { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))dummy_rand_unlock }, | 
					
						
							| 
									
										
										
										
											2023-04-19 22:08:22 +08:00
										 |  |  |     OSSL_DISPATCH_END | 
					
						
							| 
									
										
										
										
											2021-06-16 23:57:18 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_ALGORITHM dummy_rand[] = { | 
					
						
							|  |  |  |     { "DUMMY", "provider=dummy", dummy_rand_functions }, | 
					
						
							|  |  |  |     { NULL, NULL, NULL } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  | static const OSSL_ALGORITHM *dummy_query(void *provctx, int operation_id, | 
					
						
							|  |  |  |                                          int *no_cache) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     *no_cache = 0; | 
					
						
							|  |  |  |     switch (operation_id) { | 
					
						
							|  |  |  |     case OSSL_OP_DECODER: | 
					
						
							|  |  |  |         return dummy_decoders; | 
					
						
							|  |  |  |     case OSSL_OP_ENCODER: | 
					
						
							|  |  |  |         return dummy_encoders; | 
					
						
							|  |  |  |     case OSSL_OP_STORE: | 
					
						
							|  |  |  |         return dummy_store; | 
					
						
							| 
									
										
										
										
											2021-06-16 23:57:18 +08:00
										 |  |  |     case OSSL_OP_RAND: | 
					
						
							|  |  |  |         return dummy_rand; | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const OSSL_DISPATCH dummy_dispatch_table[] = { | 
					
						
							|  |  |  |     { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))dummy_query }, | 
					
						
							|  |  |  |     { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OSSL_LIB_CTX_free }, | 
					
						
							| 
									
										
										
										
											2023-04-19 22:08:22 +08:00
										 |  |  |     OSSL_DISPATCH_END | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int dummy_provider_init(const OSSL_CORE_HANDLE *handle, | 
					
						
							|  |  |  |                                const OSSL_DISPATCH *in, | 
					
						
							|  |  |  |                                const OSSL_DISPATCH **out, | 
					
						
							|  |  |  |                                void **provctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new_child(handle, in); | 
					
						
							| 
									
										
										
										
											2021-06-21 20:01:57 +08:00
										 |  |  |     unsigned char buf[32]; | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     *provctx = (void *)libctx; | 
					
						
							|  |  |  |     *out = dummy_dispatch_table; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-21 20:01:57 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * Do some work using the child libctx, to make sure this is possible from | 
					
						
							|  |  |  |      * inside the init function. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-11-15 00:20:32 +08:00
										 |  |  |     if (RAND_bytes_ex(libctx, buf, sizeof(buf), 0) <= 0) | 
					
						
							| 
									
										
										
										
											2021-06-21 20:01:57 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Try fetching and freeing various things. | 
					
						
							|  |  |  |  * Test 0: Decoder | 
					
						
							|  |  |  |  * Test 1: Encoder | 
					
						
							|  |  |  |  * Test 2: Store loader | 
					
						
							| 
									
										
										
										
											2021-06-16 23:57:18 +08:00
										 |  |  |  * Test 3: EVP_RAND | 
					
						
							| 
									
										
										
										
											2022-01-10 22:46:46 +08:00
										 |  |  |  * Test 4-7: As above, but additionally with a query string | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | static int fetch_test(int tst) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new(); | 
					
						
							|  |  |  |     OSSL_PROVIDER *dummyprov = NULL; | 
					
						
							| 
									
										
										
										
											2021-06-21 20:01:57 +08:00
										 |  |  |     OSSL_PROVIDER *nullprov = NULL; | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |     OSSL_DECODER *decoder = NULL; | 
					
						
							|  |  |  |     OSSL_ENCODER *encoder = NULL; | 
					
						
							|  |  |  |     OSSL_STORE_LOADER *loader = NULL; | 
					
						
							|  |  |  |     int testresult = 0; | 
					
						
							| 
									
										
										
										
											2021-06-16 23:57:18 +08:00
										 |  |  |     unsigned char buf[32]; | 
					
						
							| 
									
										
										
										
											2022-01-10 22:46:46 +08:00
										 |  |  |     int query = tst > 3; | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!TEST_ptr(libctx)) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, "dummy-prov", | 
					
						
							|  |  |  |                                              dummy_provider_init)) | 
					
						
							| 
									
										
										
										
											2021-06-21 20:01:57 +08:00
										 |  |  |             || !TEST_ptr(nullprov = OSSL_PROVIDER_load(libctx, "default")) | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |             || !TEST_ptr(dummyprov = OSSL_PROVIDER_load(libctx, "dummy-prov"))) | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-10 22:46:46 +08:00
										 |  |  |     switch (tst % 4) { | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |     case 0: | 
					
						
							| 
									
										
										
										
											2022-01-10 22:46:46 +08:00
										 |  |  |         decoder = OSSL_DECODER_fetch(libctx, "DUMMY", | 
					
						
							|  |  |  |                                      query ? "provider=dummy" : NULL); | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |         if (!TEST_ptr(decoder)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 1: | 
					
						
							| 
									
										
										
										
											2022-01-10 22:46:46 +08:00
										 |  |  |         encoder = OSSL_ENCODER_fetch(libctx, "DUMMY", | 
					
						
							|  |  |  |                                      query ? "provider=dummy" : NULL); | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |         if (!TEST_ptr(encoder)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 2: | 
					
						
							| 
									
										
										
										
											2022-01-10 22:46:46 +08:00
										 |  |  |         loader = OSSL_STORE_LOADER_fetch(libctx, "DUMMY", | 
					
						
							|  |  |  |                                          query ? "provider=dummy" : NULL); | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |         if (!TEST_ptr(loader)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-06-16 23:57:18 +08:00
										 |  |  |     case 3: | 
					
						
							| 
									
										
										
										
											2022-01-10 22:46:46 +08:00
										 |  |  |         if (!TEST_true(RAND_set_DRBG_type(libctx, "DUMMY", | 
					
						
							|  |  |  |                                           query ? "provider=dummy" : NULL, | 
					
						
							|  |  |  |                                           NULL, NULL)) | 
					
						
							| 
									
										
										
										
											2021-06-16 23:57:18 +08:00
										 |  |  |                 || !TEST_int_ge(RAND_bytes_ex(libctx, buf, sizeof(buf), 0), 1)) | 
					
						
							|  |  |  |             goto err; | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |     default: | 
					
						
							|  |  |  |         goto err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     testresult = 1; | 
					
						
							|  |  |  |  err: | 
					
						
							|  |  |  |     OSSL_DECODER_free(decoder); | 
					
						
							|  |  |  |     OSSL_ENCODER_free(encoder); | 
					
						
							|  |  |  |     OSSL_STORE_LOADER_free(loader); | 
					
						
							|  |  |  |     OSSL_PROVIDER_unload(dummyprov); | 
					
						
							| 
									
										
										
										
											2021-06-21 20:01:57 +08:00
										 |  |  |     OSSL_PROVIDER_unload(nullprov); | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  |     OSSL_LIB_CTX_free(libctx); | 
					
						
							|  |  |  |     return testresult; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int setup_tests(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-01-10 22:46:46 +08:00
										 |  |  |     ADD_ALL_TESTS(fetch_test, 8); | 
					
						
							| 
									
										
										
										
											2021-06-14 19:56:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } |