|  | =pod | 
|  |  | 
|  | =head1 NAME | 
|  |  | 
|  | ossl_lib_ctx_get_data, ossl_lib_ctx_run_once, ossl_lib_ctx_onfree, | 
|  | ossl_lib_ctx_is_child | 
|  | - internal OSSL_LIB_CTX routines | 
|  |  | 
|  | =head1 SYNOPSIS | 
|  |  | 
|  | #include <openssl/types.h> | 
|  | #include "internal/cryptlib.h" | 
|  |  | 
|  | typedef struct ossl_lib_ctx_method { | 
|  | int priority; | 
|  | void *(*new_func)(OSSL_LIB_CTX *ctx); | 
|  | void (*free_func)(void *); | 
|  | } OSSL_LIB_CTX_METHOD; | 
|  |  | 
|  | void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index, | 
|  | const OSSL_LIB_CTX_METHOD *meth); | 
|  |  | 
|  | int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx, | 
|  | ossl_lib_ctx_run_once_fn run_once_fn); | 
|  | int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn); | 
|  |  | 
|  | int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx); | 
|  |  | 
|  | =head1 DESCRIPTION | 
|  |  | 
|  | Internally, the OpenSSL library context B<OSSL_LIB_CTX> is implemented | 
|  | as a B<CRYPTO_EX_DATA>, which allows data from diverse parts of the | 
|  | library to be added and removed dynamically. | 
|  | Each such data item must have a corresponding CRYPTO_EX_DATA index | 
|  | associated with it. Unlike normal CRYPTO_EX_DATA objects we use static indexes | 
|  | to identify data items. These are mapped transparently to CRYPTO_EX_DATA dynamic | 
|  | indexes internally to the implementation. | 
|  | See the example further down to see how that's done. | 
|  |  | 
|  | ossl_lib_ctx_get_data() is used to retrieve a pointer to the data in | 
|  | the library context I<ctx> associated with the given I<index>. An | 
|  | OSSL_LIB_CTX_METHOD must be defined and given in the I<meth> parameter. The index | 
|  | for it should be defined in cryptlib.h. The functions through the method are | 
|  | used to create or free items that are stored at that index whenever a library | 
|  | context is created or freed, meaning that the code that use a data item of that | 
|  | index doesn't have to worry about that, just use the data available. | 
|  |  | 
|  | Deallocation of an index happens automatically when the library | 
|  | context is freed. | 
|  |  | 
|  | ossl_lib_ctx_run_once is used to run some initialisation routine I<run_once_fn> | 
|  | exactly once per library context I<ctx> object. Each initialisation routine | 
|  | should be allocate a unique run once index in cryptlib.h. | 
|  |  | 
|  | Any resources allocated via a run once initialisation routine can be cleaned up | 
|  | using ossl_lib_ctx_onfree. This associates an "on free" routine I<onfreefn> with | 
|  | the library context I<ctx>. When I<ctx> is freed all associated "on free" | 
|  | routines are called. | 
|  |  | 
|  | ossl_lib_ctx_is_child() returns 1 if this library context is a child and 0 | 
|  | otherwise. | 
|  |  | 
|  | =head1 RETURN VALUES | 
|  |  | 
|  | ossl_lib_ctx_get_data() returns a pointer on success, or NULL on | 
|  | failure. | 
|  |  | 
|  | =head1 EXAMPLES | 
|  |  | 
|  | =head2 Initialization | 
|  |  | 
|  | For a type C<FOO> that should end up in the OpenSSL library context, a | 
|  | small bit of initialization is needed, i.e. to associate a constructor | 
|  | and a destructor to an index. | 
|  |  | 
|  | typedef struct foo_st { | 
|  | int i; | 
|  | void *data; | 
|  | } FOO; | 
|  |  | 
|  | static void *foo_new(OSSL_LIB_CTX *ctx) | 
|  | { | 
|  | FOO *ptr = OPENSSL_zalloc(sizeof(*foo)); | 
|  | if (ptr != NULL) | 
|  | ptr->i = 42; | 
|  | return ptr; | 
|  | } | 
|  | static void foo_free(void *ptr) | 
|  | { | 
|  | OPENSSL_free(ptr); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Include a reference to this in the methods table in context.c | 
|  | * OSSL_LIB_CTX_FOO_INDEX should be added to internal/cryptlib.h | 
|  | * Priorities can be OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, | 
|  | * OSSL_LIB_CTX_METHOD_PRIORITY_1, OSSL_LIB_CTX_METHOD_PRIORITY_2, etc. | 
|  | * Default priority is low (0). The higher the priority the earlier the | 
|  | * method's destructor will be called when the library context is cleaned up. | 
|  | */ | 
|  | const OSSL_LIB_CTX_METHOD foo_method = { | 
|  | OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY, | 
|  | foo_new, | 
|  | foo_free | 
|  | }; | 
|  |  | 
|  | =head2 Usage | 
|  |  | 
|  | To get and use the data stored in the library context, simply do this: | 
|  |  | 
|  | /* | 
|  | * ctx is received from a caller, | 
|  | */ | 
|  | FOO *data = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_FOO_INDEX, &foo_method); | 
|  |  | 
|  | =head2 Run Once | 
|  |  | 
|  | void foo_cleanup(OSSL_LIB_CTX *ctx) | 
|  | { | 
|  | /* Free foo resources associated with ctx */ | 
|  | } | 
|  |  | 
|  | static ossl_lib_ctx_run_once_fn do_foo_init; | 
|  | static int do_foo_init(OSSL_LIB_CTX *ctx) | 
|  | { | 
|  | /* Allocate and initialise some foo resources and associated with ctx */ | 
|  | return ossl_lib_ctx_onfree(ctx, &foo_cleanup) | 
|  | } | 
|  |  | 
|  | int foo_some_function(OSSL_LIB_CTX *ctx) | 
|  | { | 
|  | if (!ossl_lib_ctx_run_once(ctx, | 
|  | OSSL_LIB_CTX_FOO_RUN_ONCE_INDEX, | 
|  | do_foo_init)) | 
|  | return 0; | 
|  |  | 
|  | /* Do some work using foo resources in ctx */ | 
|  | } | 
|  |  | 
|  |  | 
|  | =head1 SEE ALSO | 
|  |  | 
|  | L<OSSL_LIB_CTX(3)> | 
|  |  | 
|  | =head1 COPYRIGHT | 
|  |  | 
|  | Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. | 
|  |  | 
|  | 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 | 
|  | L<https://www.openssl.org/source/license.html>. | 
|  |  | 
|  | =cut |