| =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 |