Latest update.
This commit is contained in:
@@ -15,10 +15,10 @@ ossl_method_store_cache_get, ossl_method_store_cache_set
|
||||
|
||||
typedef struct ossl_method_store_st OSSL_METHOD_STORE;
|
||||
|
||||
OSSL_METHOD_STORE *ossl_method_store_new(void);
|
||||
OSSL_METHOD_STORE *ossl_method_store_new(OPENSSL_CTX *ctx);
|
||||
void ossl_method_store_free(OSSL_METHOD_STORE *store);
|
||||
int ossl_method_store_init(void);
|
||||
void ossl_method_store_cleanup(void);
|
||||
int ossl_method_store_init(OPENSSL_CTX *ctx);
|
||||
void ossl_method_store_cleanup(OPENSSL_CTX *ctx);
|
||||
int ossl_method_store_add(OSSL_METHOD_STORE *store,
|
||||
int nid, const char *properties,
|
||||
void *method, void (*method_destruct)(void *));
|
||||
@@ -51,12 +51,14 @@ separately (see L</Cache Functions> below).
|
||||
|
||||
=head2 Store Functions
|
||||
|
||||
ossl_method_store_init() initialises the method store subsystem.
|
||||
ossl_method_store_init() initialises the method store subsystem in the scope of
|
||||
the library context B<ctx>.
|
||||
|
||||
ossl_method_store_cleanup() cleans up and shuts down the implementation method
|
||||
store subsystem.
|
||||
store subsystem in the scope of the library context B<ctx>.
|
||||
|
||||
ossl_method_store_new() create a new empty method store.
|
||||
ossl_method_store_new() create a new empty method store using the supplied
|
||||
B<ctx> to allow access to the required underlying property data.
|
||||
|
||||
ossl_method_store_free() frees resources allocated to B<store>.
|
||||
|
||||
|
||||
@@ -10,17 +10,16 @@ evp_generic_fetch - generic algorithm fetcher and method creator for EVP
|
||||
#include "evp_locl.h"
|
||||
|
||||
void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
const char *algorithm, const char *properties,
|
||||
void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
|
||||
const char *name, const char *properties,
|
||||
void *(*new_method)(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov),
|
||||
int (*upref_method)(void *),
|
||||
void (*free_method)(void *),
|
||||
int (*nid_method)(void *));
|
||||
void (*free_method)(void *));
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
evp_generic_fetch() calls ossl_method_construct() with the given
|
||||
C<libctx>, C<operation_id>, C<algorithm>, and C<properties> and uses
|
||||
C<libctx>, C<operation_id>, C<name>, and C<properties> and uses
|
||||
it to create an EVP method with the help of the functions
|
||||
C<new_method>, C<upref_method>, and C<free_method>.
|
||||
|
||||
@@ -42,10 +41,6 @@ one.
|
||||
|
||||
frees the given method.
|
||||
|
||||
=item nid_method()
|
||||
|
||||
returns the nid associated with the given method.
|
||||
|
||||
=back
|
||||
|
||||
=head1 RETURN VALUES
|
||||
@@ -80,7 +75,6 @@ And here's the implementation of the FOO method fetcher:
|
||||
/* typedef struct evp_foo_st EVP_FOO */
|
||||
struct evp_foo_st {
|
||||
OSSL_PROVIDER *prov;
|
||||
int nid;
|
||||
CRYPTO_REF_COUNT refcnt;
|
||||
OSSL_OP_foo_newctx_fn *newctx;
|
||||
OSSL_OP_foo_init_fn *init;
|
||||
@@ -93,7 +87,7 @@ And here's the implementation of the FOO method fetcher:
|
||||
* In this example, we have a public method creator and destructor.
|
||||
* It's not absolutely necessary, but is in the spirit of OpenSSL.
|
||||
*/
|
||||
EVP_FOO *EVP_FOO_meth_from_dispatch(int foo_type, const OSSL_DISPATCH *fns,
|
||||
EVP_FOO *EVP_FOO_meth_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
EVP_FOO *foo = NULL;
|
||||
@@ -120,7 +114,6 @@ And here's the implementation of the FOO method fetcher:
|
||||
break;
|
||||
}
|
||||
}
|
||||
foo->nid = foo_type;
|
||||
foo->prov = prov;
|
||||
if (prov)
|
||||
ossl_provider_upref(prov);
|
||||
@@ -138,10 +131,10 @@ And here's the implementation of the FOO method fetcher:
|
||||
}
|
||||
}
|
||||
|
||||
static void *foo_from_dispatch(int nid, const OSSL_DISPATCH *fns,
|
||||
static void *foo_from_dispatch(const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
return EVP_FOO_meth_from_dispatch(nid, fns, prov);
|
||||
return EVP_FOO_meth_from_dispatch(fns, prov);
|
||||
}
|
||||
|
||||
static int foo_upref(void *vfoo)
|
||||
@@ -159,11 +152,21 @@ And here's the implementation of the FOO method fetcher:
|
||||
}
|
||||
|
||||
EVP_FOO *EVP_FOO_fetch(OPENSSL_CTX *ctx,
|
||||
const char *algorithm,
|
||||
const char *name,
|
||||
const char *properties)
|
||||
{
|
||||
return evp_generic_fetch(ctx, OSSL_OP_FOO, algorithm, properties,
|
||||
foo_from_dispatch, foo_upref, foo_free);
|
||||
EVP_FOO *foo =
|
||||
evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
|
||||
foo_from_dispatch, foo_upref, foo_free);
|
||||
|
||||
/*
|
||||
* If this method exists in legacy form, with a constant NID for the
|
||||
* given |name|, this is the spot to find that NID and set it in
|
||||
* the newly constructed EVP_FOO instance.
|
||||
*/
|
||||
|
||||
return foo;
|
||||
|
||||
}
|
||||
|
||||
And finally, the library functions:
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
openssl_ctx_new_index, openssl_ctx_get_data - internal OPENSSL_CTX routines
|
||||
openssl_ctx_get_data, openssl_ctx_run_once, openssl_ctx_onfree
|
||||
- internal OPENSSL_CTX routines
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
@@ -10,12 +11,16 @@ openssl_ctx_new_index, openssl_ctx_get_data - internal OPENSSL_CTX routines
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
typedef struct openssl_ctx_method {
|
||||
void *(*new_func)(void);
|
||||
void *(*new_func)(OPENSSL_CTX *ctx);
|
||||
void (*free_func)(void *);
|
||||
} OPENSSL_CTX_METHOD;
|
||||
|
||||
int openssl_ctx_new_index(const OPENSSL_CTX_METHOD *meth);
|
||||
void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index);
|
||||
void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index,
|
||||
const OPENSSL_CTX_METHOD *meth);
|
||||
|
||||
int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx,
|
||||
openssl_ctx_run_once_fn run_once_fn);
|
||||
int openssl_ctx_onfree(OPENSSL_CTX *ctx, openssl_ctx_onfree_fn onfreefn);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
@@ -23,27 +28,33 @@ Internally, the OpenSSL library context C<OPENSSL_CTX> is implemented
|
||||
as a C<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.
|
||||
associated with it. Unlike normal CRYPTO_EX_DATA objects we use static indexes
|
||||
to identify data items. These are mapped transparetnly to CRYPTO_EX_DATA dynamic
|
||||
indexes internally to the implementation.
|
||||
See the example further down to see how that's done.
|
||||
|
||||
openssl_ctx_new_index() allocates a new library context index, and
|
||||
associates it with the functions given through C<meth>.
|
||||
The functions given through that 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
|
||||
openssl_ctx_get_data() is used to retrieve a pointer to the data in
|
||||
the library context C<ctx> associated with the given C<index>. An
|
||||
OPENSSL_CTX_METHOD must be defined and given in the C<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.
|
||||
|
||||
openssl_ctx_get_data() is used to retrieve a pointer to the data in
|
||||
the library context C<ctx> associated with the given C<index>.
|
||||
openssl_ctx_run_once is used to run some initialisation routine C<run_once_fn>
|
||||
exactly once per library context C<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 openssl_ctx_onfree. This associates an "on free" routine C<onfreefn> with
|
||||
the library context C<ctx>. When C<ctx> is freed all associated "on free"
|
||||
routines are called.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
openssl_ctx_new_index() returns -1 on error, otherwise the allocated
|
||||
index number.
|
||||
|
||||
openssl_ctx_get_data() returns a pointer on success, or C<NULL> on
|
||||
failure.
|
||||
|
||||
@@ -53,17 +64,14 @@ failure.
|
||||
|
||||
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 a new index.
|
||||
|
||||
/* The index will always be entirely global, and dynamically allocated */
|
||||
static int foo_index = -1;
|
||||
and a destructor to an index.
|
||||
|
||||
typedef struct foo_st {
|
||||
int i;
|
||||
void *data;
|
||||
} FOO;
|
||||
|
||||
static void *foo_new(void)
|
||||
static void *foo_new(OPENSSL_CTX *ctx)
|
||||
{
|
||||
FOO *ptr = OPENSSL_zalloc(sizeof(*foo));
|
||||
if (ptr != NULL)
|
||||
@@ -74,27 +82,49 @@ and a destructor to a new index.
|
||||
{
|
||||
OPENSSL_free(ptr);
|
||||
}
|
||||
static const OPENSSL_CTX_METHOD foo_method = {
|
||||
|
||||
/*
|
||||
* Include a reference to this in the methods table in context.c
|
||||
* OPENSSL_CTX_FOO_INDEX should be added to internal/cryptlib.h
|
||||
*/
|
||||
const OPENSSL_CTX_METHOD foo_method = {
|
||||
foo_new,
|
||||
foo_free
|
||||
};
|
||||
|
||||
static int foo_init(void)
|
||||
{
|
||||
foo_index = openssl_ctx_new_index(foo_method);
|
||||
|
||||
return foo_index != -1;
|
||||
}
|
||||
|
||||
=head2 Usage
|
||||
|
||||
To get and use the data stored in the library context, simply do this:
|
||||
|
||||
/*
|
||||
* ctx is received from a caller,
|
||||
* foo_index comes from the example above
|
||||
*/
|
||||
FOO *data = openssl_ctx_get_data(ctx, foo_index);
|
||||
FOO *data = openssl_ctx_get_data(ctx, OPENSSL_CTX_FOO_INDEX, &foo_method);
|
||||
|
||||
=head2 Run Once
|
||||
|
||||
void foo_cleanup(OPENSSL_CTX *ctx)
|
||||
{
|
||||
/* Free foo resources associated with ctx */
|
||||
}
|
||||
|
||||
static openssl_ctx_run_once_fn do_foo_init;
|
||||
static int do_foo_init(OPENSSL_CTX *ctx)
|
||||
{
|
||||
/* Allocate and initialise some foo resources and associated with ctx */
|
||||
return openssl_ctx_onfree(ctx, &foo_cleanup)
|
||||
}
|
||||
|
||||
int foo_some_function(OPENSSL_CTX *ctx)
|
||||
{
|
||||
if (!openssl_ctx_run_once(ctx,
|
||||
OPENSSL_CTX_FOO_RUN_ONCE_INDEX,
|
||||
do_foo_init))
|
||||
return 0;
|
||||
|
||||
/* Do some work using foo resources in ctx */
|
||||
}
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
||||
@@ -11,17 +11,17 @@ OSSL_METHOD_CONSTRUCT_METHOD, ossl_method_construct
|
||||
|
||||
struct ossl_method_construct_method_st {
|
||||
/* Create store */
|
||||
void *(*alloc_tmp_store)(void);
|
||||
void *(*alloc_tmp_store)(OPENSSL_CTX *ctx);
|
||||
/* Remove a store */
|
||||
void (*dealloc_tmp_store)(void *store);
|
||||
/* Get an already existing method from a store */
|
||||
void *(*get)(OPENSSL_CTX *libctx, void *store, const char *propquery,
|
||||
void *data);
|
||||
void *(*get)(OPENSSL_CTX *libctx, void *store, const char *name,
|
||||
const char *propquery, void *data);
|
||||
/* Store a method in a store */
|
||||
int (*put)(OPENSSL_CTX *libctx, void *store, const char *propdef,
|
||||
void *method, void *data);
|
||||
int (*put)(OPENSSL_CTX *libctx, void *store, void *method,
|
||||
const char *name, const char *propdef, void *data);
|
||||
/* Construct a new method */
|
||||
void *(*construct)(const char *algorithm_name, const OSSL_DISPATCH *fns,
|
||||
void *(*construct)(const char *name, const OSSL_DISPATCH *fns,
|
||||
OSSL_PROVIDER *prov, void *data);
|
||||
/* Destruct a method */
|
||||
void (*destruct)(void *method);
|
||||
@@ -33,6 +33,7 @@ OSSL_METHOD_CONSTRUCT_METHOD, ossl_method_construct
|
||||
int force_cache,
|
||||
OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data);
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
All libcrypto sub-systems that want to create their own methods based
|
||||
@@ -65,7 +66,7 @@ function pointers:
|
||||
|
||||
=item alloc_tmp_store()
|
||||
|
||||
Create a temporary method store.
|
||||
Create a temporary method store in the scope of the library context C<ctx>.
|
||||
This store is used to temporarily store methods for easier lookup, for
|
||||
when the provider doesn't want its dispatch table stored in a longer
|
||||
term cache.
|
||||
@@ -76,14 +77,15 @@ Remove a temporary store.
|
||||
|
||||
=item get()
|
||||
|
||||
Look up an already existing method from a store.
|
||||
Look up an already existing method from a store by name.
|
||||
|
||||
The store may be given with C<store>.
|
||||
B<NULL> is a valid value and means that a sub-system default store
|
||||
must be used.
|
||||
This default store should be stored in the library context C<libctx>.
|
||||
|
||||
The method to be looked up should be identified with data from C<data>
|
||||
The method to be looked up should be identified with the given C<name> and
|
||||
data from C<data>
|
||||
(which is the C<mcm_data> that was passed to ossl_construct_method())
|
||||
and the provided property query C<propquery>.
|
||||
|
||||
@@ -99,15 +101,15 @@ B<NULL> is a valid value and means that a sub-system default store
|
||||
must be used.
|
||||
This default store should be stored in the library context C<libctx>.
|
||||
|
||||
The method should be associated with the given property definition
|
||||
C<propdef> and any identification data given through C<data> (which is
|
||||
The method should be associated with the given C<name> and property definition
|
||||
C<propdef> as well as any identification data given through C<data> (which is
|
||||
the C<mcm_data> that was passed to ossl_construct_method()).
|
||||
|
||||
This function is expected to increment the C<method>'s reference count.
|
||||
|
||||
=item construct()
|
||||
|
||||
Constructs a sub-system method for the given C<algorithm_name> and the given
|
||||
Constructs a sub-system method for the given C<name> and the given
|
||||
dispatch table C<fns>.
|
||||
|
||||
The associated I<provider object> C<prov> is passed as well, to make
|
||||
@@ -132,7 +134,7 @@ B<NULL> on error.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
This functionality was added to OpenSSL 3.0.0.
|
||||
This functionality was added to OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored,
|
||||
ossl_namemap_add, ossl_namemap_name, ossl_namemap_number
|
||||
- internal number E<lt>-E<gt> name map
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx);
|
||||
|
||||
OSSL_NAMEMAP *ossl_namemap_new(void);
|
||||
void ossl_namemap_free(OSSL_NAMEMAP *namemap);
|
||||
|
||||
int ossl_namemap_add(OSSL_NAMEMAP *namemap, const char *name);
|
||||
const char *ossl_namemap_name(const OSSL_NAMEMAP *namemap, int number);
|
||||
int ossl_namemap_number(const OSSL_NAMEMAP *namemap, const char *name);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
A B<OSSL_NAMEMAP> is a simple number E<lt>-E<gt> name map, which can
|
||||
be used to give any arbitrary name (any string) a unique dynamic
|
||||
identity that is valid throughout the lifetime of the associated
|
||||
library context.
|
||||
|
||||
ossl_namemap_new() and ossl_namemap_free() construct and destruct a
|
||||
new B<OSSL_NAMEMAP>.
|
||||
This is suitable to use when the B<OSSL_NAMEMAP> is embedded in other
|
||||
structures, or should be independent for any reason.
|
||||
|
||||
ossl_namemap_stored() finds or auto-creates the default namemap in the
|
||||
given library context.
|
||||
The returned B<OSSL_NAMEMAP> can't be destructed using
|
||||
ossl_namemap_free().
|
||||
|
||||
ossl_namemap_add() adds a new name to the namemap if it's not already
|
||||
present.
|
||||
|
||||
ossl_namemap_name() finds the name corresponding to the given number.
|
||||
|
||||
ossl_namemap_number() finds the number corresponding to the given
|
||||
name.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
ossl_namemap_new() and ossl_namemap_stored() return the pointer to a
|
||||
B<OSSL_NAMEMAP>, or NULL on error.
|
||||
|
||||
ossl_namemap_add() returns the number associated with the added
|
||||
string, or zero on error.
|
||||
|
||||
ossl_namemap_name() returns a pointer to the name corresponding to the
|
||||
given number, or NULL if it's undefined in the given B<OSSL_NAMEMAP>.
|
||||
|
||||
ossl_namemap_number() returns the number corresponding to the given
|
||||
name, or 0 if it's undefined in the given B<OSSL_NAMEMAP>.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
The functions described here were all added in OpenSSL 3.0.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2019 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
|
||||
@@ -5,7 +5,7 @@
|
||||
ossl_provider_find, ossl_provider_new, ossl_provider_upref,
|
||||
ossl_provider_free, ossl_provider_add_module_location,
|
||||
ossl_provider_set_fallback, ossl_provider_activate,
|
||||
ossl_provider_forall_loaded,
|
||||
ossl_provider_ctx, ossl_provider_forall_loaded,
|
||||
ossl_provider_name, ossl_provider_dso,
|
||||
ossl_provider_module_name, ossl_provider_module_path,
|
||||
ossl_provider_teardown, ossl_provider_get_param_types,
|
||||
@@ -29,6 +29,9 @@ ossl_provider_get_params, ossl_provider_query_operation
|
||||
/* Load and initialize the Provider */
|
||||
int ossl_provider_activate(OSSL_PROVIDER *prov);
|
||||
|
||||
/* Return pointer to the provider's context */
|
||||
void *ossl_provider_ctx(const OSSL_PROVIDER *prov);
|
||||
|
||||
/* Iterate over all loaded providers */
|
||||
int ossl_provider_forall_loaded(OPENSSL_CTX *,
|
||||
int (*cb)(OSSL_PROVIDER *provider,
|
||||
@@ -121,6 +124,10 @@ be located in that module, and called.
|
||||
|
||||
=back
|
||||
|
||||
ossl_provider_ctx() returns a context created by the provider.
|
||||
Outside of the provider, it's completely opaque, but it needs to be
|
||||
passed back to some of the provider functions.
|
||||
|
||||
ossl_provider_forall_loaded() iterates over all the currently
|
||||
"activated" providers, and calls C<cb> for each of them.
|
||||
If no providers have been "activated" yet, it tries to activate all
|
||||
|
||||
Reference in New Issue
Block a user