=head1 NAME
-ossl_lib_ctx_get_data, ossl_lib_ctx_run_once, ossl_lib_ctx_onfree
+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 "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;
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
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
/*
* 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
};
ossl_provider_find, ossl_provider_new, ossl_provider_up_ref,
ossl_provider_free,
ossl_provider_set_fallback, ossl_provider_set_module_path,
-ossl_provider_add_parameter,
+ossl_provider_add_parameter, ossl_provider_set_child, ossl_provider_get_parent,
+ossl_provider_up_ref_parent, ossl_provider_free_parent,
+ossl_provider_get0_dispatch, ossl_provider_init_child_providers,
+ossl_provider_init_as_child,
ossl_provider_activate, ossl_provider_deactivate, ossl_provider_available,
ossl_provider_ctx,
ossl_provider_doall_activated,
int ossl_provider_add_parameter(OSSL_PROVIDER *prov, const char *name,
const char *value);
+ /* Child Providers */
+ int ossl_provider_set_child(OSSL_PROVIDER *prov,
+ const OSSL_CORE_HANDLE *handle);
+ const OSSL_CORE_HANDLE *ossl_provider_get_parent(OSSL_PROVIDER *prov);
+ int ossl_provider_up_ref_parent(OSSL_PROVIDER *prov, int activate);
+ int ossl_provider_free_parent(OSSL_PROVIDER *prov, int deactivate);
+
/*
* Activate the Provider
* If the Provider is a module, the module will be loaded
*/
- int ossl_provider_activate(OSSL_PROVIDER *prov, int retain_fallbacks);
+ int ossl_provider_activate(OSSL_PROVIDER *prov, int retain_fallbacks,
+ int upcalls);
int ossl_provider_deactivate(OSSL_PROVIDER *prov);
/* Check if provider is available (activated) */
int ossl_provider_available(OSSL_PROVIDER *prov);
/* Return pointer to the provider's context */
void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
+ const OSSL_DISPATCH *ossl_provider_get0_dispatch(const OSSL_PROVIDER *prov);
+
/* Iterate over all loaded providers */
int ossl_provider_doall_activated(OSSL_LIB_CTX *,
int (*cb)(OSSL_PROVIDER *provider,
int *result);
int ossl_provider_clear_all_operation_bits(OSSL_LIB_CTX *libctx);
+ int ossl_provider_init_child_providers(OSSL_LIB_CTX *ctx);
+ int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx,
+ const OSSL_CORE_HANDLE *handle,
+ const OSSL_DISPATCH *in);
+
+
=head1 DESCRIPTION
I<OSSL_PROVIDER> is a type that holds all the necessary information
Only text parameters can be given, and it's up to the provider to
interpret them.
+ossl_provider_set_child() marks this provider as a child of a provider in the
+parent library context. I<handle> is the B<OSSL_CORE_HANDLE> object passed to
+the provider's B<OSSL_provider_init> function.
+
+ossl_provider_get_parent() obtains the handle on the parent provider.
+
+ossl_provider_up_ref_parent() increases the reference count on the parent
+provider. If I<activate> is nonzero then the parent provider is also activated.
+
+ossl_provider_free_parent() decreases the reference count on the parent
+provider. If I<deactivate> is nonzero then the parent provider is also
+deactivated.
+
ossl_provider_activate() "activates" the provider for the given
provider object I<prov> by incrementing its activation count, flagging
it as activated, and initializing it if it isn't already initialized.
=back
If I<retain_fallbacks> is zero, fallbacks are disabled. If it is nonzero,
-fallbacks are left unchanged.
+fallbacks are left unchanged. If I<upcalls> is nonzero then, if this is a child
+provider, upcalls to the parent libctx will be made to inform it of an
+up-ref.
ossl_provider_deactivate() "deactivates" the provider for the given
provider object I<prov> by decrementing its activation count. When
Outside of the provider, it's completely opaque, but it needs to be
passed back to some of the provider functions.
+ossl_provider_get0_dispatch() returns the dispatch table that the provider
+initially returned in the I<out> parameter of its B<OSSL_provider_init>
+function.
+
ossl_provider_doall_activated() iterates over all the currently
"activated" providers, and calls I<cb> for each of them.
If no providers have been "activated" yet, it tries to activate all
ossl_provider_clear_all_operation_bits() clears all of the operation bits
to (0) for all providers in the library context I<libctx>.
+ossl_provider_init_child_providers() registers the callbacks required to
+receive notifications about loading and unloading of providers in the parent
+library context.
+
+ossl_provider_init_as_child() stores in the library context I<ctx> references to
+the necessary upcalls for managing child providers. The I<handle> and I<in>
+parameters are the B<OSSL_CORE_HANDLE> and B<OSSL_DISPATCH> pointers that were
+passed to the provider's B<OSSL_provider_init> function.
+
=head1 NOTES
Locating a provider module happens as follows:
=head1 NAME
OSSL_LIB_CTX, OSSL_LIB_CTX_new, OSSL_LIB_CTX_new_from_dispatch,
-OSSL_LIB_CTX_free, OSSL_LIB_CTX_load_config, OSSL_LIB_CTX_get0_global_default,
-OSSL_LIB_CTX_set0_default
+OSSL_LIB_CTX_new_child, OSSL_LIB_CTX_free, OSSL_LIB_CTX_load_config,
+OSSL_LIB_CTX_get0_global_default, OSSL_LIB_CTX_set0_default
- OpenSSL library context
=head1 SYNOPSIS
OSSL_LIB_CTX *OSSL_LIB_CTX_new(void);
OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE *handle,
const OSSL_DISPATCH *in);
+ OSSL_LIB_CTX *OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE *handle,
+ const OSSL_DISPATCH *in);
int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file);
void OSSL_LIB_CTX_free(OSSL_LIB_CTX *ctx);
OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void);
L<BIO_new_from_core_bio(3)>, require the library context to be created in this
way in order to work.
+OSSL_LIB_CTX_new_child() is only useful to provider authors and does the same
+thing as OSSL_LIB_CTX_new_from_dispatch() except that it additionally links the
+new library context to the application library context. The new library context
+is a full library context in its own right, but will have all the same providers
+available to it that are available in the application library context (without
+having to reload them). If the application loads or unloads providers from the
+application library context then this will be automatically mirrored in the
+child library context.
+
+In addition providers that are not loaded in the parent library context can be
+explicitly loaded into the child library context independently from the parent
+library context. Providers loaded independently in this way will not be mirrored
+in the parent library context and will not be affected if the parent library
+context subsequently loads the same provider.
+
+A provider may call the function L<OSSL_PROVIDER_load(3)> with the child library
+context as required. If the provider already exists due to it being mirrored
+from the parent library context then it will remain available and its reference
+count will be increased. If L<OSSL_PROVIDER_load(3)> is called in this way then
+L<OSSL_PROVIDER_unload(3)> should be subsequently called to decrement the
+reference count. L<OSSL_PROVIDER_unload(3)> must not be called for a provider in
+the child library context that did not have an earlier L<OSSL_PROVIDER_load(3)>
+call for that provider in that child library context.
+
+OSSL_LIB_CTX_new_child() must only be called from within the scope of a
+provider's B<OSSL_provider_init> function (see L<provider-base(7)>). Calling it
+outside of that function may succeed but may not correctly mirror all providers
+and is considered undefined behaviour. When called from within the scope of a
+provider's B<OSSL_provider_init> function the currently initialising provider is
+not yet available in the application's library context and therefore will
+similarly not yet be available in the newly constructed child library context.
+As soon as the B<OSSL_provider_init> function returns then the new provider is
+available in the application's library context and will be similarly mirrored in
+the child library context. Since the current provider is still initialising
+the provider should not attempt to perform fetches, or call any function that
+performs a fetch using the child library context until after the initialisation
+function has completed.
+
OSSL_LIB_CTX_load_config() loads a configuration file using the given C<ctx>.
This can be used to associate a library context with providers that are loaded
from a configuration.
OSSL_PROVIDER_available, OSSL_PROVIDER_do_all,
OSSL_PROVIDER_gettable_params, OSSL_PROVIDER_get_params,
OSSL_PROVIDER_query_operation, OSSL_PROVIDER_unquery_operation,
-OSSL_PROVIDER_get0_provider_ctx, OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_name,
-OSSL_PROVIDER_get_capabilities, OSSL_PROVIDER_self_test
+OSSL_PROVIDER_get0_provider_ctx, OSSL_PROVIDER_get0_dispatch,
+OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_name, OSSL_PROVIDER_get_capabilities,
+OSSL_PROVIDER_self_test
- provider routines
=head1 SYNOPSIS
int operation_id,
const OSSL_ALGORITHM *algs);
void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov);
+ const OSSL_DISPATCH *OSSL_PROVIDER_get0_dispatch(const OSSL_PROVIDER *prov);
int OSSL_PROVIDER_add_builtin(OSSL_LIB_CTX *libctx, const char *name,
ossl_provider_init_fn *init_fn);
provider. The provider context is an opaque handle set by the provider itself
and is passed back to the provider by libcrypto in various function calls.
+OSSL_PROVIDER_get0_dispatch() returns the provider's dispatch table as it was
+returned in the I<out> parameter from the provider's init function. See
+L<provider-base(7)>.
+
If it is permissible to cache references to this array then I<*no_store> is set
to 0 or 1 otherwise. If the array is not cacheable then it is assumed to
have a short lifetime.
void cleanup_nonce(const OSSL_CORE_HANDLE *handle,
unsigned char *buf, size_t len);
+ /* Functions for querying the providers in the application library context */
+ int provider_register_child_cb(const OSSL_CORE_HANDLE *handle,
+ int (*create_cb)(const OSSL_CORE_HANDLE *provider,
+ void *cbdata),
+ int (*remove_cb)(const OSSL_CORE_HANDLE *provider,
+ void *cbdata),
+ void *cbdata);
+ void provider_deregister_child_cb(const OSSL_CORE_HANDLE *handle);
+ const char *provider_name(const OSSL_CORE_HANDLE *prov);
+ void *provider_get0_provider_ctx(const OSSL_CORE_HANDLE *prov);
+ const OSSL_DISPATCH *provider_get0_dispatch(const OSSL_CORE_HANDLE *prov);
+ int provider_up_ref(const OSSL_CORE_HANDLE *prov, int activate);
+ int provider_free(const OSSL_CORE_HANDLE *prov, int deactivate);
+
+
/* Functions offered by the provider to libcrypto */
void provider_teardown(void *provctx);
const OSSL_ITEM *provider_gettable_params(void *provctx);
get_nonce(). The nonce pointer returned by get_nonce() is passed in
B<buf> and its length in B<len>.
+provider_register_child_cb() registers callbacks for being informed about the
+loading and unloading of providers in the application's library context.
+I<handle> is this provider's handle and I<cbdata> is this provider's data
+that will be passed back to the callbacks. It returns 1 on success or 0
+otherwise.
+
+I<create_cb> is a callback that will be called when a new provider is loaded
+into the application's library context. It is also called for any providers that
+are already loaded at the point that this callback is registered. The callback
+is passed the handle being used for the new provider being loadded and this
+provider's data in I<cbdata>. It should return 1 on success or 0 on failure.
+
+I<remove_cb> is a callback that will be called when a new provider is unloaded
+from the application's library context. It is passed the handle being used for
+the provider being unloaded and this provider's data in I<cbdata>. It should
+return 1 on success or 0 on failure.
+
+provider_deregister_child_cb() unregisters callbacks previously registered via
+provider_register_child_cb(). If provider_register_child_cb() has been called
+then provider_deregister_child_cb() should be called at or before the point that
+this provider's teardown function is called.
+
+provider_name() returns a string giving the name of the provider identified by
+I<handle>.
+
+provider_get0_provider_ctx() returns the provider context that is associated
+with the provider identified by I<prov>.
+
+provider_get0_dispatch() gets the dispatch table registered by the provider
+identified by I<prov> when it initialised.
+
+provider_up_ref() increments the reference count on the provider I<prov>. If
+I<activate> is nonzero then the provider is also loaded if it is not already
+loaded. It returns 1 on success or 0 on failure.
+
+provider_free() decrements the reference count on the provider I<prov>. If
+I<deactivate> is nonzero then the provider is also unloaded if it is not
+already loaded. It returns 1 on success or 0 on failure.
+
=head2 Provider functions
provider_teardown() is called when a provider is shut down and removed