| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2023-09-07 16:59:15 +08:00
										 |  |  |  * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  | #include <assert.h>
 | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  | #include <openssl/crypto.h>
 | 
					
						
							|  |  |  | #include <openssl/core_dispatch.h>
 | 
					
						
							|  |  |  | #include <openssl/core_names.h>
 | 
					
						
							|  |  |  | #include <openssl/provider.h>
 | 
					
						
							| 
									
										
										
										
											2021-05-08 00:59:47 +08:00
										 |  |  | #include <openssl/evp.h>
 | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  | #include "internal/provider.h"
 | 
					
						
							|  |  |  | #include "internal/cryptlib.h"
 | 
					
						
							| 
									
										
										
										
											2021-05-11 23:50:27 +08:00
										 |  |  | #include "crypto/evp.h"
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  | #include "crypto/context.h"
 | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | DEFINE_STACK_OF(OSSL_PROVIDER) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct child_prov_globals { | 
					
						
							|  |  |  |     const OSSL_CORE_HANDLE *handle; | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |     const OSSL_CORE_HANDLE *curr_prov; | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |     CRYPTO_RWLOCK *lock; | 
					
						
							|  |  |  |     OSSL_FUNC_core_get_libctx_fn *c_get_libctx; | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |     OSSL_FUNC_provider_register_child_cb_fn *c_provider_register_child_cb; | 
					
						
							|  |  |  |     OSSL_FUNC_provider_deregister_child_cb_fn *c_provider_deregister_child_cb; | 
					
						
							|  |  |  |     OSSL_FUNC_provider_name_fn *c_prov_name; | 
					
						
							|  |  |  |     OSSL_FUNC_provider_get0_provider_ctx_fn *c_prov_get0_provider_ctx; | 
					
						
							|  |  |  |     OSSL_FUNC_provider_get0_dispatch_fn *c_prov_get0_dispatch; | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  |     OSSL_FUNC_provider_up_ref_fn *c_prov_up_ref; | 
					
						
							|  |  |  |     OSSL_FUNC_provider_free_fn *c_prov_free; | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  | void *ossl_child_prov_ctx_new(OSSL_LIB_CTX *libctx) | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     return OPENSSL_zalloc(sizeof(struct child_prov_globals)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  | void ossl_child_prov_ctx_free(void *vgbl) | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     struct child_prov_globals *gbl = vgbl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CRYPTO_THREAD_lock_free(gbl->lock); | 
					
						
							|  |  |  |     OPENSSL_free(gbl); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static OSSL_provider_init_fn ossl_child_provider_init; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ossl_child_provider_init(const OSSL_CORE_HANDLE *handle, | 
					
						
							|  |  |  |                                     const OSSL_DISPATCH *in, | 
					
						
							|  |  |  |                                     const OSSL_DISPATCH **out, | 
					
						
							|  |  |  |                                     void **provctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; | 
					
						
							|  |  |  |     OSSL_LIB_CTX *ctx; | 
					
						
							|  |  |  |     struct child_prov_globals *gbl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (; in->function_id != 0; in++) { | 
					
						
							|  |  |  |         switch (in->function_id) { | 
					
						
							|  |  |  |         case OSSL_FUNC_CORE_GET_LIBCTX: | 
					
						
							|  |  |  |             c_get_libctx = OSSL_FUNC_core_get_libctx(in); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             /* Just ignore anything we don't understand */ | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (c_get_libctx == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * We need an OSSL_LIB_CTX but c_get_libctx returns OPENSSL_CORE_CTX. We are | 
					
						
							|  |  |  |      * a built-in provider and so we can get away with this cast. Normal | 
					
						
							|  |  |  |      * providers can't do this. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     ctx = (OSSL_LIB_CTX *)c_get_libctx(handle); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  |     gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX); | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |     if (gbl == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *provctx = gbl->c_prov_get0_provider_ctx(gbl->curr_prov); | 
					
						
							|  |  |  |     *out = gbl->c_prov_get0_dispatch(gbl->curr_prov); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  | static int provider_create_child_cb(const OSSL_CORE_HANDLE *prov, void *cbdata) | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     OSSL_LIB_CTX *ctx = cbdata; | 
					
						
							|  |  |  |     struct child_prov_globals *gbl; | 
					
						
							|  |  |  |     const char *provname; | 
					
						
							|  |  |  |     OSSL_PROVIDER *cprov; | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |     int ret = 0; | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  |     gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX); | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |     if (gbl == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-09 00:30:43 +08:00
										 |  |  |     if (!CRYPTO_THREAD_write_lock(gbl->lock)) | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |     provname = gbl->c_prov_name(prov); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * We're operating under a lock so we can store the "current" provider in | 
					
						
							|  |  |  |      * the global data. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     gbl->curr_prov = prov; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |     if ((cprov = ossl_provider_find(ctx, provname, 1)) != NULL) { | 
					
						
							|  |  |  |         /*
 | 
					
						
							| 
									
										
										
										
											2021-06-22 22:39:40 +08:00
										 |  |  |          * We free the newly created ref. We rely on the provider sticking around | 
					
						
							|  |  |  |          * in the provider store. | 
					
						
							|  |  |  |          */ | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |         ossl_provider_free(cprov); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /*
 | 
					
						
							| 
									
										
										
										
											2021-06-21 18:06:12 +08:00
										 |  |  |          * The provider already exists. It could be a previously created child, | 
					
						
							|  |  |  |          * or it could have been explicitly loaded. If explicitly loaded we | 
					
						
							|  |  |  |          * ignore it - i.e. we don't start treating it like a child. | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |          */ | 
					
						
							| 
									
										
										
										
											2021-06-21 19:08:39 +08:00
										 |  |  |         if (!ossl_provider_activate(cprov, 0, 1)) | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |             goto err; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         /*
 | 
					
						
							|  |  |  |          * Create it - passing 1 as final param so we don't try and recursively | 
					
						
							|  |  |  |          * init children | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         if ((cprov = ossl_provider_new(ctx, provname, ossl_child_provider_init, | 
					
						
							| 
									
										
										
										
											2023-08-02 23:54:01 +08:00
										 |  |  |                                        NULL, 1)) == NULL) | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |             goto err; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-29 12:48:24 +08:00
										 |  |  |         if (!ossl_provider_activate(cprov, 0, 0)) { | 
					
						
							|  |  |  |             ossl_provider_free(cprov); | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |             goto err; | 
					
						
							| 
									
										
										
										
											2023-01-29 12:48:24 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-21 16:23:30 +08:00
										 |  |  |         if (!ossl_provider_set_child(cprov, prov) | 
					
						
							| 
									
										
										
										
											2021-06-22 22:39:40 +08:00
										 |  |  |             || !ossl_provider_add_to_store(cprov, NULL, 0)) { | 
					
						
							| 
									
										
										
										
											2021-11-05 21:42:40 +08:00
										 |  |  |             ossl_provider_deactivate(cprov, 0); | 
					
						
							| 
									
										
										
										
											2021-06-21 16:23:30 +08:00
										 |  |  |             ossl_provider_free(cprov); | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |             goto err; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |     ret = 1; | 
					
						
							|  |  |  |  err: | 
					
						
							| 
									
										
										
										
											2021-11-09 00:30:43 +08:00
										 |  |  |     CRYPTO_THREAD_unlock(gbl->lock); | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int provider_remove_child_cb(const OSSL_CORE_HANDLE *prov, void *cbdata) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_LIB_CTX *ctx = cbdata; | 
					
						
							|  |  |  |     struct child_prov_globals *gbl; | 
					
						
							|  |  |  |     const char *provname; | 
					
						
							|  |  |  |     OSSL_PROVIDER *cprov; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  |     gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX); | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |     if (gbl == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     provname = gbl->c_prov_name(prov); | 
					
						
							|  |  |  |     cprov = ossl_provider_find(ctx, provname, 1); | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |     if (cprov == NULL) | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * ossl_provider_find ups the ref count, so we free it again here. We can | 
					
						
							|  |  |  |      * rely on the provider store reference count. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  |     ossl_provider_free(cprov); | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |     if (ossl_provider_is_child(cprov) | 
					
						
							| 
									
										
										
										
											2021-11-05 21:42:40 +08:00
										 |  |  |             && !ossl_provider_deactivate(cprov, 1)) | 
					
						
							| 
									
										
										
										
											2021-05-04 23:23:31 +08:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-08 00:59:47 +08:00
										 |  |  | static int provider_global_props_cb(const char *props, void *cbdata) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     OSSL_LIB_CTX *ctx = cbdata; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return evp_set_default_properties_int(ctx, props, 0, 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  | int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx, | 
					
						
							|  |  |  |                                 const OSSL_CORE_HANDLE *handle, | 
					
						
							|  |  |  |                                 const OSSL_DISPATCH *in) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct child_prov_globals *gbl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ctx == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  |     gbl = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX); | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |     if (gbl == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     gbl->handle = handle; | 
					
						
							|  |  |  |     for (; in->function_id != 0; in++) { | 
					
						
							|  |  |  |         switch (in->function_id) { | 
					
						
							|  |  |  |         case OSSL_FUNC_CORE_GET_LIBCTX: | 
					
						
							|  |  |  |             gbl->c_get_libctx = OSSL_FUNC_core_get_libctx(in); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |         case OSSL_FUNC_PROVIDER_REGISTER_CHILD_CB: | 
					
						
							|  |  |  |             gbl->c_provider_register_child_cb | 
					
						
							|  |  |  |                 = OSSL_FUNC_provider_register_child_cb(in); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case OSSL_FUNC_PROVIDER_DEREGISTER_CHILD_CB: | 
					
						
							|  |  |  |             gbl->c_provider_deregister_child_cb | 
					
						
							|  |  |  |                 = OSSL_FUNC_provider_deregister_child_cb(in); | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |         case OSSL_FUNC_PROVIDER_NAME: | 
					
						
							|  |  |  |             gbl->c_prov_name = OSSL_FUNC_provider_name(in); | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |         case OSSL_FUNC_PROVIDER_GET0_PROVIDER_CTX: | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |             gbl->c_prov_get0_provider_ctx | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |                 = OSSL_FUNC_provider_get0_provider_ctx(in); | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |         case OSSL_FUNC_PROVIDER_GET0_DISPATCH: | 
					
						
							|  |  |  |             gbl->c_prov_get0_dispatch = OSSL_FUNC_provider_get0_dispatch(in); | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  |         case OSSL_FUNC_PROVIDER_UP_REF: | 
					
						
							|  |  |  |             gbl->c_prov_up_ref | 
					
						
							|  |  |  |                 = OSSL_FUNC_provider_up_ref(in); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case OSSL_FUNC_PROVIDER_FREE: | 
					
						
							|  |  |  |             gbl->c_prov_free = OSSL_FUNC_provider_free(in); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |         default: | 
					
						
							|  |  |  |             /* Just ignore anything we don't understand */ | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-23 19:08:27 +08:00
										 |  |  |     if (gbl->c_get_libctx == NULL | 
					
						
							|  |  |  |             || gbl->c_provider_register_child_cb == NULL | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |             || gbl->c_prov_name == NULL | 
					
						
							|  |  |  |             || gbl->c_prov_get0_provider_ctx == NULL | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  |             || gbl->c_prov_get0_dispatch == NULL | 
					
						
							|  |  |  |             || gbl->c_prov_up_ref == NULL | 
					
						
							|  |  |  |             || gbl->c_prov_free == NULL) | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     gbl->lock = CRYPTO_THREAD_lock_new(); | 
					
						
							|  |  |  |     if (gbl->lock == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-13 22:35:42 +08:00
										 |  |  |     if (!gbl->c_provider_register_child_cb(gbl->handle, | 
					
						
							|  |  |  |                                            provider_create_child_cb, | 
					
						
							|  |  |  |                                            provider_remove_child_cb, | 
					
						
							| 
									
										
										
										
											2021-05-08 00:59:47 +08:00
										 |  |  |                                            provider_global_props_cb, | 
					
						
							| 
									
										
										
										
											2021-05-13 22:35:42 +08:00
										 |  |  |                                            ctx)) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-21 23:51:41 +08:00
										 |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-09 21:48:31 +08:00
										 |  |  | void ossl_provider_deinit_child(OSSL_LIB_CTX *ctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct child_prov_globals *gbl | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  |         = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX); | 
					
						
							| 
									
										
										
										
											2021-11-09 21:48:31 +08:00
										 |  |  |     if (gbl == NULL) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     gbl->c_provider_deregister_child_cb(gbl->handle); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 14:08:06 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * ossl_provider_up_ref_parent() and ossl_provider_free_parent() do | 
					
						
							|  |  |  |  * nothing in "self-referencing" child providers, i.e. when the parent | 
					
						
							|  |  |  |  * of the child provider is the same as the provider where this child | 
					
						
							|  |  |  |  * provider was created. | 
					
						
							|  |  |  |  * This allows the teardown function in the parent provider to be called | 
					
						
							|  |  |  |  * at the correct moment. | 
					
						
							|  |  |  |  * For child providers in other providers, the reference count is done to | 
					
						
							|  |  |  |  * ensure that cross referencing is recorded.  These should be cleared up | 
					
						
							|  |  |  |  * through that providers teardown, as part of freeing its child libctx. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  | int ossl_provider_up_ref_parent(OSSL_PROVIDER *prov, int activate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct child_prov_globals *gbl; | 
					
						
							| 
									
										
										
										
											2022-04-29 14:08:06 +08:00
										 |  |  |     const OSSL_CORE_HANDLE *parent_handle; | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     gbl = ossl_lib_ctx_get_data(ossl_provider_libctx(prov), | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  |                                 OSSL_LIB_CTX_CHILD_PROVIDER_INDEX); | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  |     if (gbl == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 14:08:06 +08:00
										 |  |  |     parent_handle = ossl_provider_get_parent(prov); | 
					
						
							|  |  |  |     if (parent_handle == gbl->handle) | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |     return gbl->c_prov_up_ref(parent_handle, activate); | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ossl_provider_free_parent(OSSL_PROVIDER *prov, int deactivate) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct child_prov_globals *gbl; | 
					
						
							| 
									
										
										
										
											2022-04-29 14:08:06 +08:00
										 |  |  |     const OSSL_CORE_HANDLE *parent_handle; | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     gbl = ossl_lib_ctx_get_data(ossl_provider_libctx(prov), | 
					
						
							| 
									
										
										
										
											2022-03-14 16:13:12 +08:00
										 |  |  |                                 OSSL_LIB_CTX_CHILD_PROVIDER_INDEX); | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  |     if (gbl == NULL) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 14:08:06 +08:00
										 |  |  |     parent_handle = ossl_provider_get_parent(prov); | 
					
						
							|  |  |  |     if (parent_handle == gbl->handle) | 
					
						
							|  |  |  |         return 1; | 
					
						
							| 
									
										
										
										
											2021-04-29 23:37:42 +08:00
										 |  |  |     return gbl->c_prov_free(ossl_provider_get_parent(prov), deactivate); | 
					
						
							|  |  |  | } |