openssl-prebuild/linux_amd64/ssl/share/doc/openssl/html/man7/provider-base.html
2020-03-02 16:50:34 +00:00

524 lines
20 KiB
HTML
Executable File

<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>provider-base</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rev="made" href="mailto:root@localhost" />
</head>
<body style="background-color: white">
<!-- INDEX BEGIN -->
<div name="index">
<p><a name="__index__"></a></p>
<ul>
<li><a href="#name">NAME</a></li>
<li><a href="#synopsis">SYNOPSIS</a></li>
<li><a href="#description">DESCRIPTION</a></li>
<ul>
<li><a href="#core_functions">Core functions</a></li>
<li><a href="#provider_functions">Provider functions</a></li>
<li><a href="#core_parameters">Core parameters</a></li>
</ul>
<li><a href="#examples">EXAMPLES</a></li>
<li><a href="#see_also">SEE ALSO</a></li>
<li><a href="#history">HISTORY</a></li>
<li><a href="#copyright">COPYRIGHT</a></li>
</ul>
<hr name="index" />
</div>
<!-- INDEX END -->
<p>
</p>
<hr />
<h1><a name="name">NAME</a></h1>
<p>provider-base
- The basic OpenSSL library &lt;-&gt; provider functions</p>
<p>
</p>
<hr />
<h1><a name="synopsis">SYNOPSIS</a></h1>
<pre>
#include &lt;openssl/core_numbers.h&gt;</pre>
<pre>
/*
* None of these are actual functions, but are displayed like this for
* the function signatures for functions that are offered as function
* pointers in OSSL_DISPATCH arrays.
*/</pre>
<pre>
/* Functions offered by libcrypto to the providers */
const OSSL_ITEM *core_gettable_params(const OSSL_PROVIDER *prov);
int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]);
int core_thread_start(const OSSL_PROVIDER *prov,
OSSL_thread_stop_handler_fn handfn);
OPENSSL_CTX *core_get_library_context(const OSSL_PROVIDER *prov);
void core_new_error(const OSSL_PROVIDER *prov);
void core_set_error_debug(const OSSL_PROVIDER *prov,
const char *file, int line, const char *func);
void core_vset_error(const OSSL_PROVIDER *prov,
uint32_t reason, const char *fmt, va_list args);</pre>
<pre>
/*
* Some OpenSSL functionality is directly offered to providers via
* dispatch
*/
void *CRYPTO_malloc(size_t num, const char *file, int line);
void *CRYPTO_zalloc(size_t num, const char *file, int line);
void *CRYPTO_memdup(const void *str, size_t siz,
const char *file, int line);
char *CRYPTO_strdup(const char *str, const char *file, int line);
char *CRYPTO_strndup(const char *str, size_t s,
const char *file, int line);
void CRYPTO_free(void *ptr, const char *file, int line);
void CRYPTO_clear_free(void *ptr, size_t num,
const char *file, int line);
void *CRYPTO_realloc(void *addr, size_t num,
const char *file, int line);
void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num,
const char *file, int line);
void *CRYPTO_secure_malloc(size_t num, const char *file, int line);
void *CRYPTO_secure_zalloc(size_t num, const char *file, int line);
void CRYPTO_secure_free(void *ptr, const char *file, int line);
void CRYPTO_secure_clear_free(void *ptr, size_t num,
const char *file, int line);
int CRYPTO_secure_allocated(const void *ptr);
void OPENSSL_cleanse(void *ptr, size_t len);
unsigned char *OPENSSL_hexstr2buf(const char *str, long *len);</pre>
<pre>
/* Functions offered by the provider to libcrypto */
void provider_teardown(void *provctx);
const OSSL_ITEM *provider_gettable_params(void *provctx);
int provider_get_params(void *provctx, OSSL_PARAM params[]);
const OSSL_ALGORITHM *provider_query_operation(void *provctx,
int operation_id,
const int *no_store);
const OSSL_ITEM *provider_get_reason_strings(void *provctx);</pre>
<p>
</p>
<hr />
<h1><a name="description">DESCRIPTION</a></h1>
<p>All &quot;functions&quot; mentioned here are passed as function pointers between
<em class="file">libcrypto</em> and the provider in <strong>OSSL_DISPATCH</strong> arrays, in the call
of the provider initialization function. See <em>provider(7)/Provider</em>
for a description of the initialization function.</p>
<p>All these &quot;functions&quot; have a corresponding function type definition
named <strong>OSSL_{name}_fn</strong>, and a helper function to retrieve the
function pointer from a <strong>OSSL_DISPATCH</strong> element named
<strong>OSSL_get_{name}</strong>.
For example, the &quot;function&quot; <code>core_gettable_params()</code> has these:</p>
<pre>
typedef OSSL_ITEM *
(OSSL_core_gettable_params_fn)(const OSSL_PROVIDER *prov);
static ossl_inline OSSL_NAME_core_gettable_params_fn
OSSL_get_core_gettable_params(const OSSL_DISPATCH *opf);</pre>
<p><strong>OSSL_DISPATCH</strong> arrays are indexed by numbers that are provided as
macros in <em>openssl-core_numbers.h(7)</em>, as follows:</p>
<p>For <em>in</em> (the <strong>OSSL_DISPATCH</strong> array passed from <em class="file">libcrypto</em> to the
provider):</p>
<pre>
core_gettable_params OSSL_FUNC_CORE_GETTABLE_PARAMS
core_get_params OSSL_FUNC_CORE_GET_PARAMS
core_thread_start OSSL_FUNC_CORE_THREAD_START
core_get_library_context OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT
core_new_error OSSL_FUNC_CORE_NEW_ERROR
core_set_error_debug OSSL_FUNC_CORE_SET_ERROR_DEBUG
core_set_error OSSL_FUNC_CORE_SET_ERROR
CRYPTO_malloc OSSL_FUNC_CRYPTO_MALLOC
CRYPTO_zalloc OSSL_FUNC_CRYPTO_ZALLOC
CRYPTO_memdup OSSL_FUNC_CRYPTO_MEMDUP
CRYPTO_strdup OSSL_FUNC_CRYPTO_STRDUP
CRYPTO_strndup OSSL_FUNC_CRYPTO_STRNDUP
CRYPTO_free OSSL_FUNC_CRYPTO_FREE
CRYPTO_clear_free OSSL_FUNC_CRYPTO_CLEAR_FREE
CRYPTO_realloc OSSL_FUNC_CRYPTO_REALLOC
CRYPTO_clear_realloc OSSL_FUNC_CRYPTO_CLEAR_REALLOC
CRYPTO_secure_malloc OSSL_FUNC_CRYPTO_SECURE_MALLOC
CRYPTO_secure_zalloc OSSL_FUNC_CRYPTO_SECURE_ZALLOC
CRYPTO_secure_free OSSL_FUNC_CRYPTO_SECURE_FREE
CRYPTO_secure_clear_free OSSL_FUNC_CRYPTO_SECURE_CLEAR_FREE
CRYPTO_secure_allocated OSSL_FUNC_CRYPTO_SECURE_ALLOCATED
BIO_new_file OSSL_FUNC_BIO_NEW_FILE
BIO_new_mem_buf OSSL_FUNC_BIO_NEW_MEMBUF
BIO_read_ex OSSL_FUNC_BIO_READ_EX
BIO_free OSSL_FUNC_BIO_FREE
BIO_vprintf OSSL_FUNC_BIO_VPRINTF
OPENSSL_cleanse OSSL_FUNC_OPENSSL_CLEANSE
OPENSSL_hexstr2buf OSSL_FUNC_OPENSSL_HEXSTR2BUF
OSSL_SELF_TEST_set_callback OSSL_FUNC_SELF_TEST_CB</pre>
<p>For <em>*out</em> (the <strong>OSSL_DISPATCH</strong> array passed from the provider to
<em class="file">libcrypto</em>):</p>
<pre>
provider_teardown OSSL_FUNC_PROVIDER_TEARDOWN
provider_gettable_params OSSL_FUNC_PROVIDER_GETTABLE_PARAMS
provider_get_params OSSL_FUNC_PROVIDER_GET_PARAMS
provider_query_operation OSSL_FUNC_PROVIDER_QUERY_OPERATION
provider_get_reason_strings OSSL_FUNC_PROVIDER_GET_REASON_STRINGS</pre>
<p>
</p>
<h2><a name="core_functions">Core functions</a></h2>
<p><code>core_gettable_params()</code> returns a constant array of descriptor
<strong>OSSL_PARAM</strong>, for parameters that <code>core_get_params()</code> can handle.</p>
<p><code>core_get_params()</code> retrieves <em>prov</em> parameters from the core.
See <a href="#core_parameters">Core parameters</a> below for a description of currently known
parameters.</p>
<p><code>core_get_library_context()</code> retrieves the library context in which the
<strong>OSSL_PROVIDER</strong> object <em>prov</em> is stored.
This may sometimes be useful if the provider wishes to store a
reference to its context in the same library context.</p>
<p><a href="#core_new_error"><code>core_new_error()</code></a>, <a href="#core_set_error_debug"><code>core_set_error_debug()</code></a> and <a href="#core_set_error"><code>core_set_error()</code></a> are
building blocks for reporting an error back to the core, with
reference to the provider object <em>prov</em>.</p>
<dl>
<dt><strong><a name="core_new_error" class="item"><code>core_new_error()</code></a></strong></dt>
<dd>
<p>allocates a new thread specific error record.</p>
<p>This corresponds to the OpenSSL function <em>ERR_new(3)</em>.</p>
</dd>
<dt><strong><a name="core_set_error_debug" class="item"><code>core_set_error_debug()</code></a></strong></dt>
<dd>
<p>sets debugging information in the current thread specific error
record.
The debugging information includes the name of the file <em>file</em>, the
line <em>line</em> and the function name <em>func</em> where the error occurred.</p>
<p>This corresponds to the OpenSSL function <em>ERR_set_debug(3)</em>.</p>
</dd>
<dt><strong><a name="core_set_error" class="item"><code>core_set_error()</code></a></strong></dt>
<dd>
<p>sets the <em>reason</em> for the error, along with any addition data.
The <em>reason</em> is a number defined by the provider and used to index
the reason strings table that's returned by
<code>provider_get_reason_strings()</code>.
The additional data is given as a format string <em>fmt</em> and a set of
arguments <em>args</em>, which are treated in the same manner as with
<code>BIO_vsnprintf()</code>.
<em>file</em> and <em>line</em> may also be passed to indicate exactly where the
error occurred or was reported.</p>
<p>This corresponds to the OpenSSL function <em>ERR_vset_error(3)</em>.</p>
</dd>
</dl>
<p><code>CRYPTO_malloc()</code>, <code>CRYPTO_zalloc()</code>, <code>CRYPTO_memdup()</code>, <code>CRYPTO_strdup()</code>,
<code>CRYPTO_strndup()</code>, <code>CRYPTO_free()</code>, <code>CRYPTO_clear_free()</code>,
<code>CRYPTO_realloc()</code>, <code>CRYPTO_clear_realloc()</code>, <code>CRYPTO_secure_malloc()</code>,
<code>CRYPTO_secure_zalloc()</code>, <code>CRYPTO_secure_free()</code>,
<code>CRYPTO_secure_clear_free()</code>, <code>CRYPTO_secure_allocated()</code>,
<code>BIO_new_file()</code>, <code>BIO_new_mem_buf()</code>, <code>BIO_read_ex()</code>, <code>BIO_free()</code>,
<code>BIO_vprintf()</code>, <code>OPENSSL_cleanse()</code>, and OPENSSL_hexstr2buf()
correspond exactly to the public functions with the same name.
As a matter of fact, the pointers in the <strong>OSSL_DISPATCH</strong> array are
direct pointers to those public functions.
<code>OSSL_SELF_TEST_set_callback()</code> is used to set an optional callback that can be
passed into a provider. This may be ignored by a provider.</p>
<p>
</p>
<h2><a name="provider_functions">Provider functions</a></h2>
<p><code>provider_teardown()</code> is called when a provider is shut down and removed
from the core's provider store.
It must free the passed <em>provctx</em>.</p>
<p><code>provider_gettable_params()</code> should return a constant array of
descriptor <strong>OSSL_PARAM</strong>, for parameters that <code>provider_get_params()</code>
can handle.</p>
<p><code>provider_get_params()</code> should process the <strong>OSSL_PARAM</strong> array
<em>params</em>, setting the values of the parameters it understands.</p>
<p><code>provider_query_operation()</code> should return a constant <strong>OSSL_ALGORITHM</strong>
that corresponds to the given <em>operation_id</em>.
It should indicate if the core may store a reference to this array by
setting <em>*no_store</em> to 0 (core may store a reference) or 1 (core may
not store a reference).</p>
<p><code>provider_get_reason_strings()</code> should return a constant <strong>OSSL_ITEM</strong>
array that provides reason strings for reason codes the provider may
use when reporting errors using <code>core_put_error()</code>.</p>
<p>None of these functions are mandatory, but a provider is fairly
useless without at least <code>provider_query_operation()</code>, and
<code>provider_gettable_params()</code> is fairly useless if not accompanied by
<code>provider_get_params()</code>.</p>
<p>
</p>
<h2><a name="core_parameters">Core parameters</a></h2>
<p><code>core_get_params()</code> understands the following known parameters:</p>
<dl>
<dt><strong><a name="openssl_version" class="item">&quot;openssl-version&quot;</a></strong></dt>
<dd>
<p>This is a <strong>OSSL_PARAM_UTF8_PTR</strong> type of parameter, pointing at the
OpenSSL libraries' full version string, i.e. the string expanded from
the macro <strong>OPENSSL_VERSION_STR</strong>.</p>
</dd>
<dt><strong><a name="provider_name" class="item">&quot;provider-name&quot;</a></strong></dt>
<dd>
<p>This is a <strong>OSSL_PARAM_UTF8_PTR</strong> type of parameter, pointing at the
OpenSSL libraries' idea of what the calling provider is called.</p>
</dd>
</dl>
<p>Additionally, provider specific configuration parameters from the
config file are available, in dotted name form.
The dotted name form is a concatenation of section names and final
config command name separated by periods.</p>
<p>For example, let's say we have the following config example:</p>
<pre>
openssl_conf = openssl_init</pre>
<pre>
[openssl_init]
providers = providers_sect</pre>
<pre>
[providers_sect]
foo = foo_sect</pre>
<pre>
[foo_sect]
activate = 1
data1 = 2
data2 = str
more = foo_more</pre>
<pre>
[foo_more]
data3 = foo,bar</pre>
<p>The provider will have these additional parameters available:</p>
<dl>
<dt><strong><a name="activate" class="item">&quot;activate&quot;</a></strong></dt>
<dd>
<p>pointing at the string &quot;1&quot;</p>
</dd>
<dt><strong><a name="data1" class="item">&quot;data1&quot;</a></strong></dt>
<dd>
<p>pointing at the string &quot;2&quot;</p>
</dd>
<dt><strong><a name="data2" class="item">&quot;data2&quot;</a></strong></dt>
<dd>
<p>pointing at the string &quot;str&quot;</p>
</dd>
<dt><strong><a name="more_data3" class="item">&quot;more.data3&quot;</a></strong></dt>
<dd>
<p>pointing at the string &quot;foo,bar&quot;</p>
</dd>
</dl>
<p>For more information on handling parameters, see <em>OSSL_PARAM(3)</em> as
<em>OSSL_PARAM_int(3)</em>.</p>
<p>
</p>
<hr />
<h1><a name="examples">EXAMPLES</a></h1>
<p>This is an example of a simple provider made available as a
dynamically loadable module.
It implements the fictitious algorithm <code>FOO</code> for the fictitious
operation <code>BAR</code>.</p>
<pre>
#include &lt;malloc.h&gt;
#include &lt;openssl/core.h&gt;
#include &lt;openssl/core_numbers.h&gt;</pre>
<pre>
/* Errors used in this provider */
#define E_MALLOC 1</pre>
<pre>
static const OSSL_ITEM reasons[] = {
{ E_MALLOC, &quot;memory allocation failure&quot; }.
{ 0, NULL } /* Termination */
};</pre>
<pre>
/*
* To ensure we get the function signature right, forward declare
* them using function types provided by openssl/core_numbers.h
*/
OSSL_OP_bar_newctx_fn foo_newctx;
OSSL_OP_bar_freectx_fn foo_freectx;
OSSL_OP_bar_init_fn foo_init;
OSSL_OP_bar_update_fn foo_update;
OSSL_OP_bar_final_fn foo_final;</pre>
<pre>
OSSL_provider_query_operation_fn p_query;
OSSL_provider_get_reason_strings_fn p_reasons;
OSSL_provider_teardown_fn p_teardown;</pre>
<pre>
OSSL_provider_init_fn OSSL_provider_init;</pre>
<pre>
OSSL_core_put_error *c_put_error = NULL;</pre>
<pre>
/* Provider context */
struct prov_ctx_st {
OSSL_PROVIDER *prov;
}</pre>
<pre>
/* operation context for the algorithm FOO */
struct foo_ctx_st {
struct prov_ctx_st *provctx;
int b;
};</pre>
<pre>
static void *foo_newctx(void *provctx)
{
struct foo_ctx_st *fooctx = malloc(sizeof(*fooctx));</pre>
<pre>
if (fooctx != NULL)
fooctx-&gt;provctx = provctx;
else
c_put_error(provctx-&gt;prov, E_MALLOC, __FILE__, __LINE__);
return fooctx;
}</pre>
<pre>
static void foo_freectx(void *fooctx)
{
free(fooctx);
}</pre>
<pre>
static int foo_init(void *vfooctx)
{
struct foo_ctx_st *fooctx = vfooctx;</pre>
<pre>
fooctx-&gt;b = 0x33;
}</pre>
<pre>
static int foo_update(void *vfooctx, unsigned char *in, size_t inl)
{
struct foo_ctx_st *fooctx = vfooctx;</pre>
<pre>
/* did you expect something serious? */
if (inl == 0)
return 1;
for (; inl-- &gt; 0; in++)
*in ^= fooctx-&gt;b;
return 1;
}</pre>
<pre>
static int foo_final(void *vfooctx)
{
struct foo_ctx_st *fooctx = vfooctx;</pre>
<pre>
fooctx-&gt;b = 0x66;
}</pre>
<pre>
static const OSSL_DISPATCH foo_fns[] = {
{ OSSL_FUNC_BAR_NEWCTX, (void (*)(void))foo_newctx },
{ OSSL_FUNC_BAR_FREECTX, (void (*)(void))foo_freectx },
{ OSSL_FUNC_BAR_INIT, (void (*)(void))foo_init },
{ OSSL_FUNC_BAR_UPDATE, (void (*)(void))foo_update },
{ OSSL_FUNC_BAR_FINAL, (void (*)(void))foo_final },
{ 0, NULL }
};</pre>
<pre>
static const OSSL_ALGORITHM bars[] = {
{ &quot;FOO&quot;, &quot;provider=chumbawamba&quot;, foo_fns },
{ NULL, NULL, NULL }
};</pre>
<pre>
static const OSSL_ALGORITHM *p_query(void *provctx, int operation_id,
int *no_store)
{
switch (operation_id) {
case OSSL_OP_BAR:
return bars;
}
return NULL;
}</pre>
<pre>
static const OSSL_ITEM *p_reasons(void *provctx)
{
return reasons;
}</pre>
<pre>
static void p_teardown(void *provctx)
{
free(provctx);
}</pre>
<pre>
static const OSSL_DISPATCH prov_fns[] = {
{ OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))p_teardown },
{ OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))p_query },
{ OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (void (*)(void))p_reasons },
{ 0, NULL }
};</pre>
<pre>
int OSSL_provider_init(const OSSL_PROVIDER *provider,
const OSSL_DISPATCH *in,
const OSSL_DISPATCH **out,
void **provctx)
{
struct prov_ctx_st *pctx = NULL;</pre>
<pre>
for (; in-&gt;function_id != 0; in++)
switch (in-&gt;function_id) {
case OSSL_FUNC_CORE_PUT_ERROR:
c_put_error = OSSL_get_core_put_error(in);
break;
}</pre>
<pre>
*out = prov_fns;</pre>
<pre>
if ((pctx = malloc(sizeof(*pctx))) == NULL) {
/*
* ALEA IACTA EST, if the core retrieves the reason table
* regardless, that string will be displayed, otherwise not.
*/
c_put_error(provider, E_MALLOC, __FILE__, __LINE__);
return 0;
}
return 1;
}</pre>
<p>This relies on a few things existing in <em class="file">openssl/core_numbers.h</em>:</p>
<pre>
#define OSSL_OP_BAR 4711</pre>
<pre>
#define OSSL_FUNC_BAR_NEWCTX 1
typedef void *(OSSL_OP_bar_newctx_fn)(void *provctx);
static ossl_inline OSSL_get_bar_newctx(const OSSL_DISPATCH *opf)
{ return (OSSL_OP_bar_newctx_fn *)opf-&gt;function; }</pre>
<pre>
#define OSSL_FUNC_BAR_FREECTX 2
typedef void (OSSL_OP_bar_freectx_fn)(void *ctx);
static ossl_inline OSSL_get_bar_newctx(const OSSL_DISPATCH *opf)
{ return (OSSL_OP_bar_freectx_fn *)opf-&gt;function; }</pre>
<pre>
#define OSSL_FUNC_BAR_INIT 3
typedef void *(OSSL_OP_bar_init_fn)(void *ctx);
static ossl_inline OSSL_get_bar_init(const OSSL_DISPATCH *opf)
{ return (OSSL_OP_bar_init_fn *)opf-&gt;function; }</pre>
<pre>
#define OSSL_FUNC_BAR_UPDATE 4
typedef void *(OSSL_OP_bar_update_fn)(void *ctx,
unsigned char *in, size_t inl);
static ossl_inline OSSL_get_bar_update(const OSSL_DISPATCH *opf)
{ return (OSSL_OP_bar_update_fn *)opf-&gt;function; }</pre>
<pre>
#define OSSL_FUNC_BAR_FINAL 5
typedef void *(OSSL_OP_bar_final_fn)(void *ctx);
static ossl_inline OSSL_get_bar_final(const OSSL_DISPATCH *opf)
{ return (OSSL_OP_bar_final_fn *)opf-&gt;function; }</pre>
<p>
</p>
<hr />
<h1><a name="see_also">SEE ALSO</a></h1>
<p><em>provider(7)</em></p>
<p>
</p>
<hr />
<h1><a name="history">HISTORY</a></h1>
<p>The concept of providers and everything surrounding them was
introduced in OpenSSL 3.0.</p>
<p>
</p>
<hr />
<h1><a name="copyright">COPYRIGHT</a></h1>
<p>Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.</p>
<p>Licensed under the Apache License 2.0 (the &quot;License&quot;). 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
<a href="https://www.openssl.org/source/license.html">https://www.openssl.org/source/license.html</a>.</p>
</body>
</html>